19 #include <sys/types.h> 22 #include <zypp/base/LogTools.h> 23 #include <zypp/base/Exception.h> 24 #include <zypp/base/Iterator.h> 25 #include <zypp/base/Gettext.h> 26 #include <zypp/base/IOStream.h> 28 #include <zypp-core/base/UserRequestException> 33 #include <zypp/PathInfo.h> 38 #include <zypp/TmpPath.h> 40 #include <zypp/ExternalProgram.h> 56 #include <zypp/sat/detail/PoolImpl.h> 60 #include <zypp-core/base/String.h> 61 #include <zypp-core/base/StringV.h> 62 #include <zypp-core/zyppng/base/EventLoop> 63 #include <zypp-core/zyppng/io/AsyncDataSource> 64 #include <zypp-core/zyppng/io/Process> 65 #include <zypp-core/base/IOTools.h> 66 #include <zypp-core/zyppng/rpc/rpc.h> 67 #include <zypp-core/zyppng/base/private/linuxhelpers_p.h> 68 #include <zypp-core/zyppng/base/EventDispatcher> 69 #include <zypp-proto/commit.pb.h> 70 #include <zypp-proto/envelope.pb.h> 71 #include <zypp-core/zyppng/rpc/zerocopystreams.h> 78 #include "tools/zypp-rpm/errorcodes.h" 79 #include <rpm/rpmlog.h> 88 #include <solv/repo_rpmdb.h> 89 #include <solv/chksum.h> 99 AutoDispose<Chksum*> chk { ::solv_chksum_create( REPOKEY_TYPE_SHA1 ), []( Chksum *chk ) ->
void {
100 ::solv_chksum_free( chk,
nullptr );
102 if ( ::rpm_hash_database_state( state, chk ) == 0 )
105 const unsigned char * md5 = ::solv_chksum_get( chk, &md5l );
109 WAR <<
"rpm_hash_database_state failed" << endl;
129 inline void sigMultiversionSpecChanged()
147 for (
const Transaction::Step & step : steps_r )
149 if ( step.stepType() != Transaction::TRANSACTION_IGNORE )
159 static const std::string strType(
"type" );
160 static const std::string strStage(
"stage" );
161 static const std::string strSolvable(
"solvable" );
163 static const std::string strTypeDel(
"-" );
164 static const std::string strTypeIns(
"+" );
165 static const std::string strTypeMul(
"M" );
167 static const std::string strStageDone(
"ok" );
168 static const std::string strStageFailed(
"err" );
170 static const std::string strSolvableN(
"n" );
171 static const std::string strSolvableE(
"e" );
172 static const std::string strSolvableV(
"v" );
173 static const std::string strSolvableR(
"r" );
174 static const std::string strSolvableA(
"a" );
181 case Transaction::TRANSACTION_IGNORE:
break;
182 case Transaction::TRANSACTION_ERASE: ret.
add( strType, strTypeDel );
break;
183 case Transaction::TRANSACTION_INSTALL: ret.
add( strType, strTypeIns );
break;
184 case Transaction::TRANSACTION_MULTIINSTALL: ret.
add( strType, strTypeMul );
break;
189 case Transaction::STEP_TODO:
break;
190 case Transaction::STEP_DONE: ret.
add( strStage, strStageDone );
break;
191 case Transaction::STEP_ERROR: ret.
add( strStage, strStageFailed );
break;
200 ident = solv.ident();
207 ident = step_r.
ident();
209 arch = step_r.
arch();
214 { strSolvableV, ed.
version() },
215 { strSolvableR, ed.
release() },
219 s.add( strSolvableE, epoch );
221 ret.
add( strSolvable, s );
235 class AssertMountedBase
247 MIL <<
"We mounted " <<
_mountpoint <<
" so we unmount it" << endl;
248 execute({
"umount",
"-R",
"-l",
_mountpoint.asString() });
256 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
268 class AssertProcMounted :
private AssertMountedBase
271 AssertProcMounted( Pathname root_r )
274 if ( ! PathInfo(root_r/
"self").isDir() ) {
275 MIL <<
"Try to make sure proc is mounted at" << root_r << endl;
277 && execute({
"mount",
"-t",
"proc",
"/proc", root_r.asString() }) == 0 ) {
281 WAR <<
"Mounting proc at " << root_r <<
" failed" << endl;
289 class AssertDevMounted :
private AssertMountedBase
292 AssertDevMounted( Pathname root_r )
295 if ( ! PathInfo(root_r/
"null").isChr() ) {
296 MIL <<
"Try to make sure dev is mounted at" << root_r << endl;
301 && execute({
"mount",
"--rbind",
"--make-rslave",
"/dev", root_r.asString() }) == 0 ) {
305 WAR <<
"Mounting dev at " << root_r <<
" failed" << endl;
322 std::ifstream infile( historyFile_r.c_str() );
323 for( iostr::EachLine in( infile ); in; in.next() )
325 const char * ch( (*in).c_str() );
327 if ( *ch <
'1' ||
'9' < *ch )
329 const char * sep1 = ::strchr( ch,
'|' );
334 bool installs =
true;
335 if ( ::strncmp( sep1,
"install|", 8 ) )
337 if ( ::strncmp( sep1,
"remove |", 8 ) )
344 const char * sep2 = ::strchr( sep1,
'|' );
345 if ( !sep2 || sep1 == sep2 )
347 (*in)[sep2-ch] =
'\0';
348 IdString pkg( sep1 );
352 onSystemByUserList.erase( pkg );
356 if ( (sep1 = ::strchr( sep2+1,
'|' ))
357 && (sep1 = ::strchr( sep1+1,
'|' ))
358 && (sep2 = ::strchr( sep1+1,
'|' )) )
360 (*in)[sep2-ch] =
'\0';
361 if ( ::strchr( sep1+1,
'@' ) )
364 onSystemByUserList.insert( pkg );
369 MIL <<
"onSystemByUserList found: " << onSystemByUserList.size() << endl;
370 return onSystemByUserList;
380 return PluginFrame( command_r, json::Object {
381 {
"TransactionStepList", steps_r }
391 MIL <<
"Testcases to keep: " << toKeep << endl;
397 WAR <<
"No Target no Testcase!" << endl;
401 std::string stem(
"updateTestcase" );
402 Pathname dir( target->assertRootPrefix(
"/var/log/") );
406 std::list<std::string> content;
408 std::set<std::string> cases;
409 for_( c, content.begin(), content.end() )
414 if ( cases.size() >= toKeep )
416 unsigned toDel = cases.size() - toKeep + 1;
417 for_( c, cases.begin(), cases.end() )
426 MIL <<
"Write new testcase " << next << endl;
427 getZYpp()->resolver()->createSolverTestcase( next.asString(),
false );
444 std::pair<bool,PatchScriptReport::Action> doExecuteScript(
const Pathname & root_r,
454 for ( std::string output = prog.receiveLine(); output.length(); output = prog.receiveLine() )
459 WAR <<
"User request to abort script " << script_r << endl;
468 if ( prog.close() != 0 )
470 ret.second = report_r->problem( prog.execError() );
471 WAR <<
"ACTION" << ret.second <<
"(" << prog.execError() <<
")" << endl;
472 std::ostringstream sstr;
473 sstr << script_r <<
_(
" execution failed") <<
" (" << prog.execError() <<
")" << endl;
474 historylog.
comment(sstr.str(),
true);
486 bool executeScript(
const Pathname & root_r,
487 const Pathname & script_r,
488 callback::SendReport<PatchScriptReport> & report_r )
493 action = doExecuteScript( root_r, script_r, report_r );
497 switch ( action.second )
500 WAR <<
"User request to abort at script " << script_r << endl;
505 WAR <<
"User request to skip script " << script_r << endl;
515 INT <<
"Abort on unknown ACTION request " << action.second <<
" returned" << endl;
524 bool RunUpdateScripts(
const Pathname & root_r,
525 const Pathname & scriptsPath_r,
526 const std::vector<sat::Solvable> & checkPackages_r,
529 if ( checkPackages_r.empty() )
532 MIL <<
"Looking for new update scripts in (" << root_r <<
")" << scriptsPath_r << endl;
534 if ( ! PathInfo( scriptsDir ).isDir() )
537 std::list<std::string> scripts;
539 if ( scripts.empty() )
547 std::map<std::string, Pathname> unify;
548 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
550 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
551 for_( sit, scripts.begin(), scripts.end() )
556 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
559 PathInfo script( scriptsDir / *sit );
560 Pathname localPath( scriptsPath_r/(*sit) );
561 std::string unifytag;
563 if ( script.isFile() )
569 else if ( ! script.isExist() )
577 if ( unifytag.empty() )
581 if ( unify[unifytag].empty() )
583 unify[unifytag] = localPath;
590 std::string msg(
str::form(
_(
"%s already executed as %s)"), localPath.asString().c_str(), unify[unifytag].c_str() ) );
591 MIL <<
"Skip update script: " << msg << endl;
592 HistoryLog().comment( msg,
true );
596 if ( abort || aborting_r )
598 WAR <<
"Aborting: Skip update script " << *sit << endl;
599 HistoryLog().comment(
600 localPath.asString() +
_(
" execution skipped while aborting"),
605 MIL <<
"Found update script " << *sit << endl;
606 callback::SendReport<PatchScriptReport> report;
607 report->start( make<Package>( *it ), script.path() );
609 if ( ! executeScript( root_r, localPath, report ) )
621 inline void copyTo( std::ostream & out_r,
const Pathname & file_r )
623 std::ifstream infile( file_r.c_str() );
624 for( iostr::EachLine in( infile ); in; in.next() )
626 out_r << *in << endl;
630 inline std::string notificationCmdSubst(
const std::string & cmd_r,
const UpdateNotificationFile & notification_r )
632 std::string ret( cmd_r );
633 #define SUBST_IF(PAT,VAL) if ( ret.find( PAT ) != std::string::npos ) ret = str::gsub( ret, PAT, VAL ) 634 SUBST_IF(
"%p", notification_r.solvable().asString() );
635 SUBST_IF(
"%P", notification_r.file().asString() );
640 void sendNotification(
const Pathname & root_r,
643 if ( notifications_r.empty() )
647 MIL <<
"Notification command is '" << cmdspec <<
"'" << endl;
648 if ( cmdspec.empty() )
652 if ( pos == std::string::npos )
654 ERR <<
"Can't send Notification: Missing 'format |' in command spec." << endl;
655 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
660 std::string commandStr(
str::trim( cmdspec.substr( pos + 1 ) ) );
662 enum Format { UNKNOWN, NONE, SINGLE, DIGEST, BULK };
663 Format format = UNKNOWN;
664 if ( formatStr ==
"none" )
666 else if ( formatStr ==
"single" )
668 else if ( formatStr ==
"digest" )
670 else if ( formatStr ==
"bulk" )
674 ERR <<
"Can't send Notification: Unknown format '" << formatStr <<
" |' in command spec." << endl;
675 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
683 if ( format == NONE || format == SINGLE )
685 for_( it, notifications_r.begin(), notifications_r.end() )
687 std::vector<std::string> command;
688 if ( format == SINGLE )
690 str::splitEscaped( notificationCmdSubst( commandStr, *it ), std::back_inserter( command ) );
695 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
699 int ret = prog.close();
702 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
703 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
709 else if ( format == DIGEST || format == BULK )
711 filesystem::TmpFile tmpfile;
712 std::ofstream out( tmpfile.path().c_str() );
713 for_( it, notifications_r.begin(), notifications_r.end() )
715 if ( format == DIGEST )
717 out << it->file() << endl;
719 else if ( format == BULK )
725 std::vector<std::string> command;
726 command.push_back(
"<"+tmpfile.path().asString() );
727 str::splitEscaped( notificationCmdSubst( commandStr, *notifications_r.begin() ), std::back_inserter( command ) );
732 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
736 int ret = prog.close();
739 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
740 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
747 INT <<
"Can't send Notification: Missing handler for 'format |' in command spec." << endl;
748 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
759 void RunUpdateMessages(
const Pathname & root_r,
760 const Pathname & messagesPath_r,
761 const std::vector<sat::Solvable> & checkPackages_r,
762 ZYppCommitResult & result_r )
764 if ( checkPackages_r.empty() )
767 MIL <<
"Looking for new update messages in (" << root_r <<
")" << messagesPath_r << endl;
769 if ( ! PathInfo( messagesDir ).isDir() )
772 std::list<std::string> messages;
774 if ( messages.empty() )
780 HistoryLog historylog;
781 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
783 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
784 for_( sit, messages.begin(), messages.end() )
789 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
792 PathInfo message( messagesDir / *sit );
793 if ( ! message.isFile() || message.size() == 0 )
796 MIL <<
"Found update message " << *sit << endl;
797 Pathname localPath( messagesPath_r/(*sit) );
798 result_r.rUpdateMessages().push_back( UpdateNotificationFile( *it, localPath ) );
799 historylog.comment( str::Str() <<
_(
"New update message") <<
" " << localPath,
true );
802 sendNotification( root_r, result_r.updateMessages() );
808 void logPatchStatusChanges(
const sat::Transaction & transaction_r, TargetImpl & target_r )
811 if ( changedPseudoInstalled.empty() )
819 WAR <<
"Need to recompute the patch status changes as commit is incomplete!" << endl;
825 HistoryLog historylog;
826 for (
const auto & el : changedPseudoInstalled )
827 historylog.patchStateChange( el.first, el.second );
836 const std::vector<sat::Solvable> & checkPackages_r,
838 { RunUpdateMessages( root_r, messagesPath_r, checkPackages_r, result_r ); }
851 , _requestedLocalesFile( home() /
"RequestedLocales" )
852 , _autoInstalledFile( home() /
"AutoInstalled" )
861 sigMultiversionSpecChanged();
862 MIL <<
"Initialized target on " <<
_root << endl;
870 std::ifstream uuidprovider(
"/proc/sys/kernel/random/uuid" );
880 boost::function<
bool ()> condition,
881 boost::function<std::string ()> value )
883 std::string val = value();
891 MIL <<
"updating '" << filename <<
"' content." << endl;
895 std::ofstream filestr;
898 filestr.open( filename.
c_str() );
900 if ( filestr.good() )
936 WAR <<
"Can't create anonymous id file" << endl;
945 Pathname flavorpath(
home() /
"LastDistributionFlavor");
951 WAR <<
"No base product, I won't create flavor cache" << endl;
955 std::string flavor = p->flavor();
967 WAR <<
"Can't create flavor cache" << endl;
980 sigMultiversionSpecChanged();
981 MIL <<
"Targets closed" << endl;
1005 Pathname rpmsolvcookie = base/
"cookie";
1007 bool build_rpm_solv =
true;
1017 MIL <<
"Read cookie: " << cookie << endl;
1022 if ( status == rpmstatus )
1023 build_rpm_solv =
false;
1024 MIL <<
"Read cookie: " << rpmsolvcookie <<
" says: " 1025 << (build_rpm_solv ?
"outdated" :
"uptodate") << endl;
1029 if ( build_rpm_solv )
1043 bool switchingToTmpSolvfile =
false;
1044 Exception ex(
"Failed to cache rpm database.");
1050 rpmsolv = base/
"solv";
1051 rpmsolvcookie = base/
"cookie";
1058 WAR <<
"Using a temporary solv file at " << base << endl;
1059 switchingToTmpSolvfile =
true;
1068 if ( ! switchingToTmpSolvfile )
1078 cmd.push_back(
"rpmdb2solv" );
1080 cmd.push_back(
"-r" );
1083 cmd.push_back(
"-D" );
1085 cmd.push_back(
"-X" );
1087 cmd.push_back(
"-p" );
1090 if ( ! oldSolvFile.
empty() )
1091 cmd.push_back( oldSolvFile.
asString() );
1093 cmd.push_back(
"-o" );
1097 std::string errdetail;
1100 WAR <<
" " << output;
1101 if ( errdetail.empty() ) {
1105 errdetail += output;
1108 int ret = prog.
close();
1129 if (
root() ==
"/" )
1140 if ( !
PathInfo(base/
"solv.idx").isExist() )
1143 return build_rpm_solv;
1161 MIL <<
"New cache built: " << (newCache?
"true":
"false") <<
1162 ", force loading: " << (force?
"true":
"false") << endl;
1167 MIL <<
"adding " << rpmsolv <<
" to pool(" << satpool.
systemRepoAlias() <<
")" << endl;
1174 if ( newCache || force )
1191 MIL <<
"adding " << rpmsolv <<
" to system" << endl;
1197 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1222 if (
PathInfo( historyFile ).isExist() )
1229 if ( onSystemByUser.find( ident ) == onSystemByUser.end() )
1230 onSystemByAuto.insert( ident );
1251 if (
PathInfo( needrebootFile ).isFile() )
1252 needrebootSpec.
parseFrom( needrebootFile );
1255 if (
PathInfo( needrebootDir ).isDir() )
1260 [&](
const Pathname & dir_r,
const char *
const str_r )->
bool 1262 if ( ! isRpmConfigBackup( str_r ) )
1264 Pathname needrebootFile { needrebootDir / str_r };
1265 if (
PathInfo( needrebootFile ).isFile() )
1266 needrebootSpec.
parseFrom( needrebootFile );
1277 if ( ! hardLocks.empty() )
1286 MIL <<
"Target loaded: " << system.
solvablesSize() <<
" resolvables" << endl;
1298 bool explicitDryRun = policy_r.
dryRun();
1308 if (
root() ==
"/" )
1322 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
")" << endl;
1341 steps.push_back( *it );
1348 MIL <<
"Todo: " << result << endl;
1358 if ( commitPlugins )
1359 commitPlugins.
send( transactionPluginFrame(
"COMMITBEGIN", steps ) );
1366 if ( ! policy_r.
dryRun() )
1372 DBG <<
"dryRun: Not writing upgrade testcase." << endl;
1379 if ( ! policy_r.
dryRun() )
1401 DBG <<
"dryRun: Not storing non-package data." << endl;
1408 if ( ! policy_r.
dryRun() )
1410 for_( it, steps.begin(), steps.end() )
1412 if ( ! it->satSolvable().isKind<
Patch>() )
1420 if ( ! patch ||patch->message().empty() )
1423 MIL <<
"Show message for " << patch << endl;
1425 if ( ! report->show( patch ) )
1427 WAR <<
"commit aborted by the user" << endl;
1434 DBG <<
"dryRun: Not checking patch messages." << endl;
1456 for_( it, steps.begin(), steps.end() )
1458 switch ( it->stepType() )
1477 localfile = packageCache.
get( pi );
1480 catch (
const AbortRequestException & exp )
1484 WAR <<
"commit cache preload aborted by the user" << endl;
1488 catch (
const SkipRequestException & exp )
1493 WAR <<
"Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1503 INT <<
"Unexpected Error: Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1513 ERR <<
"Some packages could not be provided. Aborting commit."<< endl;
1517 if ( ! policy_r.
dryRun() )
1524 commit( policy_r, packageCache, result );
1529 DBG <<
"dryRun/downloadOnly: Not installing/deleting anything." << endl;
1530 if ( explicitDryRun ) {
1544 DBG <<
"dryRun: Not downloading/installing/deleting anything." << endl;
1545 if ( explicitDryRun ) {
1557 WAR <<
"(rpm removed in commit?) Inject missing /var/lib/rpm compat symlink to /usr/lib/sysimage/rpm" << endl;
1566 if ( commitPlugins )
1567 commitPlugins.
send( transactionPluginFrame(
"COMMITEND", steps ) );
1572 if ( ! policy_r.
dryRun() )
1577 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
") returns: " << result << endl;
1588 struct NotifyAttemptToModify
1606 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1611 NotifyAttemptToModify attemptToModify( result_r );
1616 AssertProcMounted assertProcMounted(
_root );
1617 AssertDevMounted assertDevMounted(
_root );
1620 std::vector<sat::Solvable> successfullyInstalledPackages;
1623 for_( step, steps.begin(), steps.end() )
1645 localfile = packageCache_r.
get( citem );
1647 catch (
const AbortRequestException &e )
1649 WAR <<
"commit aborted by the user" << endl;
1654 catch (
const SkipRequestException &e )
1657 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1666 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1675 bool success =
false;
1701 if ( progress.aborted() )
1703 WAR <<
"commit aborted by the user" << endl;
1712 auto rebootNeededFile =
root() /
"/run/reboot-needed";
1728 WAR <<
"dry run failed" << endl;
1733 if ( progress.aborted() )
1735 WAR <<
"commit aborted by the user" << endl;
1740 WAR <<
"Install failed" << endl;
1746 if ( success && !policy_r.
dryRun() )
1749 successfullyInstalledPackages.push_back( citem.
satSolvable() );
1758 bool success =
false;
1769 if ( progress.aborted() )
1771 WAR <<
"commit aborted by the user" << endl;
1785 if ( progress.aborted() )
1787 WAR <<
"commit aborted by the user" << endl;
1793 WAR <<
"removal of " << p <<
" failed";
1796 if ( success && !policy_r.
dryRun() )
1803 else if ( ! policy_r.
dryRun() )
1807 if ( ! citem.
buddy() )
1814 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
1820 std::string referenceFilename( p->referenceFilename() );
1821 if ( referenceFilename.empty() )
1823 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
1827 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
1828 if ( !
rpm().hasFile( referencePath.asString() ) )
1833 ERR <<
"Delete orphan product failed: " << referencePath << endl;
1837 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
1864 if ( ! successfullyInstalledPackages.empty() )
1867 successfullyInstalledPackages, abort ) )
1869 WAR <<
"Commit aborted by the user" << endl;
1875 successfullyInstalledPackages,
1882 logPatchStatusChanges( result_r.
transaction(), *this );
1901 void sendLogline(
const std::string & line_r, ReportType::loglevel level_r = ReportType::loglevel::msg )
1904 data.
set(
"line", std::cref(line_r) );
1905 data.set(
"level", level_r );
1911 auto u2rpmlevel = [](
unsigned rpmlevel_r ) -> ReportType::loglevel {
1912 switch ( rpmlevel_r ) {
1913 case RPMLOG_EMERG: [[fallthrough]];
1914 case RPMLOG_ALERT: [[fallthrough]];
1916 return ReportType::loglevel::crt;
1918 return ReportType::loglevel::err;
1919 case RPMLOG_WARNING:
1920 return ReportType::loglevel::war;
1921 default: [[fallthrough]];
1922 case RPMLOG_NOTICE: [[fallthrough]];
1924 return ReportType::loglevel::msg;
1926 return ReportType::loglevel::dbg;
1934 { (*this)->report( userData_r ); }
1947 namespace zpt = zypp::proto::target;
1953 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1958 NotifyAttemptToModify attemptToModify( result_r );
1964 AssertProcMounted assertProcMounted(
_root );
1965 AssertDevMounted assertDevMounted(
_root );
1980 commit.set_flags( flags );
1988 for (
auto &[
_, value] : data ) {
1990 value.resetDispose();
1997 auto &step = steps[stepId];
2014 locCache.value()[stepId] = packageCache_r.
get( citem );
2016 zpt::TransactionStep tStep;
2017 tStep.set_stepid( stepId );
2018 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
2019 tStep.mutable_install()->set_multiversion( p->multiversionInstall() );
2021 *
commit.mutable_steps()->Add( ) = std::move(tStep);
2023 catch (
const AbortRequestException &e )
2025 WAR <<
"commit aborted by the user" << endl;
2030 catch (
const SkipRequestException &e )
2033 WAR <<
"Skipping package " << p <<
" in commit" << endl;
2042 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
2048 zpt::TransactionStep tStep;
2049 tStep.set_stepid( stepId );
2050 tStep.mutable_remove()->set_name( p->name() );
2051 tStep.mutable_remove()->set_version( p->edition().version() );
2052 tStep.mutable_remove()->set_release( p->edition().release() );
2053 tStep.mutable_remove()->set_arch( p->arch().asString() );
2055 *
commit.mutable_steps()->Add() = std::move(tStep);
2066 zpt::TransactionStep tStep;
2067 tStep.set_stepid( stepId );
2068 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
2069 tStep.mutable_install()->set_multiversion(
false );
2070 *
commit.mutable_steps()->Add() = std::move(tStep);
2074 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
2081 std::vector<sat::Solvable> successfullyInstalledPackages;
2083 if (
commit.steps_size() ) {
2086 auto loop = zyppng::EventLoop::create();
2095 int currentStepId = -1;
2101 bool gotEndOfScript =
false;
2104 std::unique_ptr<callback::SendReport <rpm::TransactionReportSA>> transactionreport;
2105 std::unique_ptr<callback::SendReport <rpm::InstallResolvableReportSA>> installreport;
2106 std::unique_ptr<callback::SendReport <rpm::RemoveResolvableReportSA>> uninstallreport;
2107 std::unique_ptr<callback::SendReport <rpm::CommitScriptReportSA>> scriptreport;
2108 std::unique_ptr<callback::SendReport <rpm::CleanupPackageReportSA>> cleanupreport;
2111 std::optional<zpt::TransactionError> transactionError;
2114 std::string currentScriptType;
2115 std::string currentScriptPackage;
2125 unsigned lineno = 0;
2128 auto msgSource = zyppng::AsyncDataSource::create();
2129 auto scriptSource = zyppng::AsyncDataSource::create();
2134 const auto &sendRpmLineToReport = [&](
const std::string &line ){
2136 const auto &sendLogRep = [&](
auto &report,
const auto &cType ){
2138 if ( currentStepId >= 0 )
2139 cmdout.
set(
"solvable", steps.at(currentStepId).satSolvable() );
2140 cmdout.
set(
"line", line );
2144 if ( installreport ) {
2146 }
else if ( uninstallreport ) {
2148 }
else if ( scriptreport ) {
2150 }
else if ( transactionreport ) {
2152 }
else if ( cleanupreport ) {
2155 WAR <<
"Got rpm output without active report " << line;
2160 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2164 if ( line.back() !=
'\n' )
2170 const auto &processDataFromScriptFd = [&](){
2172 while ( scriptSource->canReadLine() ) {
2174 if ( gotEndOfScript )
2177 std::string l = scriptSource->readLine().asString();
2179 gotEndOfScript =
true;
2183 l = l.substr( 0, rawsize );
2185 L_DBG(
"zypp-rpm") <<
"[rpm> " << l;
2186 sendRpmLineToReport( l );
2189 scriptSource->sigReadyRead().connect( processDataFromScriptFd );
2192 const auto &waitForScriptEnd = [&]() {
2195 if ( gotEndOfScript )
2199 processDataFromScriptFd();
2202 while ( scriptSource->readFdOpen() && scriptSource->canRead() && !gotEndOfScript ) {
2205 scriptSource->waitForReadyRead( 100 );
2209 const auto &aboutToStartNewReport = [&](){
2211 if ( transactionreport || installreport || uninstallreport || scriptreport || cleanupreport ) {
2212 ERR <<
"There is still a running report, this is a bug" << std::endl;
2216 gotEndOfScript =
false;
2219 const auto &writeRpmMsgToHistory = [&](){
2220 if ( rpmmsg.size() == 0 )
2224 rpmmsg +=
"[truncated]\n";
2226 std::ostringstream sstr;
2227 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2232 const auto &finalizeCurrentReport = [&]() {
2235 if ( currentStepId >= 0 ) {
2236 step = &steps.at(currentStepId);
2240 if ( installreport ) {
2248 writeRpmMsgToHistory();
2252 ( *installreport)->progress( 100, resObj );
2255 if ( currentStepId >= 0 )
2256 locCache.value().erase( currentStepId );
2257 successfullyInstalledPackages.push_back( step->
satSolvable() );
2263 auto rebootNeededFile =
root() /
"/run/reboot-needed";
2275 writeRpmMsgToHistory();
2278 if ( uninstallreport ) {
2286 writeRpmMsgToHistory();
2290 ( *uninstallreport)->progress( 100, resObj );
2300 writeRpmMsgToHistory();
2303 if ( scriptreport ) {
2305 ( *scriptreport)->progress( 100, resObj );
2308 if ( transactionreport ) {
2310 ( *transactionreport)->progress( 100 );
2313 if ( cleanupreport ) {
2315 ( *cleanupreport)->progress( 100 );
2321 currentScriptType.clear();
2322 currentScriptPackage.clear();
2323 installreport.reset();
2324 uninstallreport.reset();
2325 scriptreport.reset();
2326 transactionreport.reset();
2327 cleanupreport.reset();
2337 constexpr std::string_view zyppRpmBinary(ZYPP_RPM_BINARY);
2339 const char *argv[] = {
2342 zyppRpmBinary.data(),
2345 auto prog = zyppng::Process::create();
2349 auto messagePipe = zyppng::Pipe::create();
2355 auto scriptPipe = zyppng::Pipe::create();
2359 prog->addFd( messagePipe->writeFd );
2360 prog->addFd( scriptPipe->writeFd );
2363 if ( !scriptSource->openFds( std::vector<int>{ scriptPipe->readFd } ) )
2366 prog->sigStarted().connect( [&](){
2369 messagePipe->unrefWrite();
2370 scriptPipe->unrefWrite();
2373 prog->connectFunc( &zyppng::IODevice::sigChannelReadyRead, [&](
int channel ){
2374 while( prog->canReadLine( channel ) ) {
2375 L_ERR(
"zypp-rpm") << ( channel == zyppng::Process::StdOut ?
"<stdout> " :
"<stderr> " ) << prog->channelReadLine( channel ).asStringView();
2381 const auto outFd = prog->stdinFd();
2388 zyppng::rpc::HeaderSizeType msgSize =
commit.ByteSizeLong();
2389 const auto written = zyppng::eintrSafeCall( ::
write, outFd, &msgSize,
sizeof(zyppng::rpc::HeaderSizeType) );
2390 if ( written !=
sizeof(zyppng::rpc::HeaderSizeType) ) {
2391 prog->stop( SIGKILL );
2395 zyppng::FileOutputStream fo ( outFd );
2396 if ( !
commit.SerializeToZeroCopyStream( &fo ) ) {
2397 prog->stop( SIGKILL );
2407 if ( !msgSource->openFds( std::vector<int>{ messagePipe->readFd } ) )
2410 zyppng::rpc::HeaderSizeType pendingMessageSize = 0;
2411 const auto &processMessages = [&] ( ) {
2415 const auto &parseMsgWithStepId = [&steps](
const auto &m,
auto &p ){
2416 if ( !p.ParseFromString( m.value() ) ) {
2417 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2421 auto id = p.stepid();
2422 if ( id < 0 || id >= steps.size() ) {
2423 ERR <<
"Received invalid stepId: " <<
id <<
" in " << m.messagetypename() <<
" message from zypp-rpm, ignoring." << std::endl;
2429 while ( msgSource->bytesAvailable() ) {
2431 if ( pendingMessageSize == 0 ) {
2432 if ( std::size_t(msgSource->bytesAvailable()) >=
sizeof( zyppng::rpc::HeaderSizeType ) ) {
2433 msgSource->read( reinterpret_cast<char *>( &pendingMessageSize ),
sizeof( zyppng::rpc::HeaderSizeType ) );
2437 if ( msgSource->bytesAvailable() < pendingMessageSize ) {
2441 auto bytes = msgSource->read( pendingMessageSize );
2442 pendingMessageSize = 0;
2444 zypp::proto::Envelope m;
2445 if (! m.ParseFromArray( bytes.data(), bytes.size() ) ) {
2448 ERR <<
"Received misformed message from zypp-rpm, ignoring" << std::endl;
2456 const auto &mName = m.messagetypename();
2457 if ( mName ==
"zypp.proto.target.RpmLog" ) {
2460 if ( !p.ParseFromString( m.value() ) ) {
2461 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2464 ( p.level() >= RPMLOG_ERR ?
L_ERR(
"zypp-rpm")
2465 : p.level() >= RPMLOG_WARNING ?
L_WAR(
"zypp-rpm")
2466 :
L_DBG(
"zypp-rpm") ) <<
"[rpm " << p.level() <<
"> " << p.line();
2469 }
else if ( mName ==
"zypp.proto.target.PackageBegin" ) {
2470 finalizeCurrentReport();
2472 zpt::PackageBegin p;
2473 if ( !parseMsgWithStepId( m, p ) )
2476 aboutToStartNewReport();
2478 auto & step = steps.at( p.stepid() );
2479 currentStepId = p.stepid();
2481 uninstallreport = std::make_unique< callback::SendReport <rpm::RemoveResolvableReportSA> > ();
2482 ( *uninstallreport )->start(
makeResObject( step.satSolvable() ) );
2484 installreport = std::make_unique< callback::SendReport <rpm::InstallResolvableReportSA> > ();
2485 ( *installreport )->start(
makeResObject( step.satSolvable() ) );
2488 }
else if ( mName ==
"zypp.proto.target.PackageFinished" ) {
2489 zpt::PackageFinished p;
2490 if ( !parseMsgWithStepId( m, p ) )
2493 if ( p.stepid() < 0 || p.stepid() > steps.size() )
2500 }
else if ( mName ==
"zypp.proto.target.PackageProgress" ) {
2501 zpt::PackageProgress p;
2502 if ( !parseMsgWithStepId( m, p ) )
2505 if ( uninstallreport )
2506 (*uninstallreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2507 else if ( installreport )
2508 (*installreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2510 ERR <<
"Received a " << mName <<
" message but there is no corresponding report running." << std::endl;
2512 }
else if ( mName ==
"zypp.proto.target.PackageError" ) {
2513 zpt::PackageError p;
2514 if ( !parseMsgWithStepId( m, p ) )
2517 if ( p.stepid() >= 0 && p.stepid() < steps.size() )
2520 finalizeCurrentReport();
2522 }
else if ( mName ==
"zypp.proto.target.ScriptBegin" ) {
2523 finalizeCurrentReport();
2526 if ( !p.ParseFromString( m.value() ) ) {
2527 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2531 aboutToStartNewReport();
2534 const auto stepId = p.stepid();
2535 if ( stepId >= 0 && stepId < steps.size() ) {
2539 currentStepId = p.stepid();
2540 scriptreport = std::make_unique< callback::SendReport <rpm::CommitScriptReportSA> > ();
2541 currentScriptType = p.scripttype();
2542 currentScriptPackage = p.scriptpackage();
2543 (*scriptreport)->start( p.scripttype(), p.scriptpackage(), resPtr );
2545 }
else if ( mName ==
"zypp.proto.target.ScriptFinished" ) {
2549 }
else if ( mName ==
"zypp.proto.target.ScriptError" ) {
2552 if ( !p.ParseFromString( m.value() ) ) {
2553 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2558 const auto stepId = p.stepid();
2559 if ( stepId >= 0 && stepId < steps.size() ) {
2569 str::form(
"Failed to execute %s script for %s ", currentScriptType.c_str(), currentScriptPackage.size() ? currentScriptPackage.c_str() :
"unknown" ),
2572 writeRpmMsgToHistory();
2574 if ( !scriptreport ) {
2575 ERR <<
"Received a ScriptError message, but there is no running report. " << std::endl;
2584 scriptreport.reset();
2587 }
else if ( mName ==
"zypp.proto.target.CleanupBegin" ) {
2588 finalizeCurrentReport();
2590 zpt::CleanupBegin beg;
2591 if ( !beg.ParseFromString( m.value() ) ) {
2592 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2596 aboutToStartNewReport();
2597 cleanupreport = std::make_unique< callback::SendReport <rpm::CleanupPackageReportSA> > ();
2598 (*cleanupreport)->start( beg.nvra() );
2599 }
else if ( mName ==
"zypp.proto.target.CleanupFinished" ) {
2601 finalizeCurrentReport();
2603 }
else if ( mName ==
"zypp.proto.target.CleanupProgress" ) {
2604 zpt::CleanupProgress prog;
2605 if ( !prog.ParseFromString( m.value() ) ) {
2606 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2610 if ( !cleanupreport ) {
2611 ERR <<
"Received a CleanupProgress message, but there is no running report. " << std::endl;
2615 (*cleanupreport)->progress( prog.amount() );
2617 }
else if ( mName ==
"zypp.proto.target.TransBegin" ) {
2618 finalizeCurrentReport();
2620 zpt::TransBegin beg;
2621 if ( !beg.ParseFromString( m.value() ) ) {
2622 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2626 aboutToStartNewReport();
2627 transactionreport = std::make_unique< callback::SendReport <rpm::TransactionReportSA> > ();
2628 (*transactionreport)->start( beg.name() );
2629 }
else if ( mName ==
"zypp.proto.target.TransFinished" ) {
2631 finalizeCurrentReport();
2633 }
else if ( mName ==
"zypp.proto.target.TransProgress" ) {
2634 zpt::TransProgress prog;
2635 if ( !prog.ParseFromString( m.value() ) ) {
2636 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2640 if ( !transactionreport ) {
2641 ERR <<
"Received a TransactionProgress message, but there is no running report. " << std::endl;
2645 (*transactionreport)->progress( prog.amount() );
2646 }
else if ( mName ==
"zypp.proto.target.TransactionError" ) {
2648 zpt::TransactionError error;
2649 if ( !error.ParseFromString( m.value() ) ) {
2650 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2655 transactionError = std::move(error);
2658 ERR <<
"Received unexpected message from zypp-rpm: "<< m.messagetypename() <<
", ignoring" << std::endl;
2664 msgSource->connectFunc( &zyppng::AsyncDataSource::sigReadyRead, processMessages );
2667 int zyppRpmExitCode = -1;
2668 prog->connectFunc( &zyppng::Process::sigFinished, [&](
int code ){
2669 zyppRpmExitCode = code;
2673 if ( !prog->start( argv ) ) {
2684 finalizeCurrentReport();
2687 bool readMsgs =
false;
2688 while( prog->canReadLine( zyppng::Process::StdErr ) ) {
2690 MIL <<
"zypp-rpm: " << prog->channelReadLine( zyppng::Process::StdErr ).asStringView();
2692 while( prog->canReadLine( zyppng::Process::StdOut ) ) {
2694 MIL <<
"zypp-rpm: " << prog->channelReadLine( zyppng::Process::StdOut ).asStringView();
2697 while ( scriptSource->canReadLine() ) {
2699 MIL <<
"rpm-script-fd: " << scriptSource->readLine().asStringView();
2701 if ( scriptSource->bytesAvailable() > 0 ) {
2703 MIL <<
"rpm-script-fd: " << scriptSource->readAll().asStringView();
2708 switch ( zyppRpmExitCode ) {
2710 case zypprpm::NoError:
2711 case zypprpm::RpmFinishedWithError:
2713 case zypprpm::RpmFinishedWithTransactionError: {
2715 if ( transactionError ) {
2717 std::ostringstream sstr;
2718 sstr <<
_(
"Executing the transaction failed because of the following problems:") <<
"\n";
2719 for (
const auto & err : transactionError->problems() ) {
2720 sstr <<
" " << err.message() <<
"\n";
2730 case zypprpm::FailedToOpenDb:
2733 case zypprpm::WrongHeaderSize:
2734 case zypprpm::WrongMessageFormat:
2737 case zypprpm::RpmInitFailed:
2740 case zypprpm::FailedToReadPackage:
2743 case zypprpm::FailedToAddStepToTransaction:
2746 case zypprpm::RpmOrderFailed:
2752 auto &step = steps[stepId];
2764 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
2768 std::string referenceFilename( p->referenceFilename() );
2770 if ( referenceFilename.empty() ) {
2771 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
2773 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
2775 if ( !
rpm().hasFile( referencePath.asString() ) ) {
2779 ERR <<
"Delete orphan product failed: " << referencePath << endl;
2781 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
2795 if ( ! successfullyInstalledPackages.empty() )
2798 successfullyInstalledPackages, abort ) )
2800 WAR <<
"Commit aborted by the user" << endl;
2806 successfullyInstalledPackages,
2813 logPatchStatusChanges( result_r.
transaction(), *this );
2841 if ( baseproduct.isFile() )
2854 ERR <<
"baseproduct symlink is dangling or missing: " << baseproduct << endl;
2859 inline Pathname staticGuessRoot(
const Pathname & root_r )
2861 if ( root_r.empty() )
2866 return Pathname(
"/");
2872 inline std::string firstNonEmptyLineIn(
const Pathname & file_r )
2874 std::ifstream idfile( file_r.c_str() );
2875 for( iostr::EachLine in( idfile ); in; in.next() )
2878 if ( ! line.empty() )
2881 return std::string();
2892 if ( p->isTargetDistribution() )
2900 const Pathname needroot( staticGuessRoot(root_r) );
2901 const Target_constPtr target( getZYpp()->getTarget() );
2902 if ( target && target->root() == needroot )
2903 return target->requestedLocales();
2909 MIL <<
"updateAutoInstalled if changed..." << endl;
2917 {
return baseproductdata(
_root ).registerTarget(); }
2920 {
return baseproductdata( staticGuessRoot(root_r) ).registerTarget(); }
2923 {
return baseproductdata(
_root ).registerRelease(); }
2926 {
return baseproductdata( staticGuessRoot(root_r) ).registerRelease();}
2929 {
return baseproductdata(
_root ).registerFlavor(); }
2932 {
return baseproductdata( staticGuessRoot(root_r) ).registerFlavor();}
2965 std::string
distributionVersion = baseproductdata( staticGuessRoot(root_r) ).edition().version();
2972 scoped_ptr<rpm::RpmDb> tmprpmdb;
2978 tmprpmdb->initDatabase( );
2995 return firstNonEmptyLineIn(
home() /
"LastDistributionFlavor" );
3000 return firstNonEmptyLineIn( staticGuessRoot(root_r) /
"/var/lib/zypp/LastDistributionFlavor" );
3006 std::string guessAnonymousUniqueId(
const Pathname & root_r )
3009 std::string ret( firstNonEmptyLineIn( root_r /
"/var/lib/zypp/AnonymousUniqueId" ) );
3010 if ( ret.
empty() && root_r !=
"/" )
3013 ret = firstNonEmptyLineIn(
"/var/lib/zypp/AnonymousUniqueId" );
3021 return guessAnonymousUniqueId(
root() );
3026 return guessAnonymousUniqueId( staticGuessRoot(root_r) );
3033 MIL <<
"New VendorAttr: " << vendorAttr_r << endl;
std::string asString(const Patch::Category &obj)
static bool fileMissing(const Pathname &pathname)
helper functor
static const UserData::ContentType contentRpmout
"zypp-rpm/scriptsa": Additional rpm output (sent immediately).
std::string asJSON() const
JSON representation.
ZYppCommitResult commit(ResPool pool_r, const ZYppCommitPolicy &policy_r)
Commit changes in the pool.
VendorAttr _vendorAttr
vendor equivalence settings.
EstablishedStates::ChangedPseudoInstalled ChangedPseudoInstalled
Map holding pseudo installed items where current and established status differ.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Interface to the rpm program.
Convenience SendReport<rpm::SingleTransReport> wrapper.
sat::Transaction getTransaction()
Return the Transaction computed by the last solver run.
bool upgradingRepos() const
Whether there is at least one UpgradeRepo request pending.
A Solvable object within the sat Pool.
std::vector< sat::Transaction::Step > TransactionStepList
Save and restore locale set from file.
Alternating download and install.
zypp::ContentType ContentType
ZYppCommitPolicy & rpmNoSignature(bool yesNo_r)
Use rpm option –nosignature (default: false)
const LocaleSet & getRequestedLocales() const
Return the requested locales.
ManagedFile provideSrcPackage(const SrcPackage_constPtr &srcPackage_r) const
Provide SrcPackage in a local file.
int assert_file(const Pathname &path, unsigned mode)
Create an empty file if it does not yet exist.
[M] Install(multiversion) item (
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
bool solvfilesPathIsTemp() const
Whether we're using a temp.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Solvable satSolvable() const
Return the corresponding Solvable.
Result returned from ZYpp::commit.
void updateFileContent(const Pathname &filename, boost::function< bool()> condition, boost::function< std::string()> value)
updates the content of filename if condition is true, setting the content the the value returned by v...
static ZConfig & instance()
Singleton ctor.
First download all packages to the local cache.
bool isToBeInstalled() const
void addSolv(const Pathname &file_r)
Load Solvables from a solv-file.
std::string md5sum(const Pathname &file)
Compute a files md5sum.
Command frame for communication with PluginScript.
Pathname _tmpSolvfilesPath
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like 'readlink'.
void setData(const Data &data_r)
Store new Data.
IMPL_PTR_TYPE(TargetImpl)
SolvIdentFile _autoInstalledFile
user/auto installed database
detail::IdType value_type
static ProductFileData scanFile(const Pathname &file_r)
Parse one file (or symlink) and return the ProductFileData parsed.
String matching (STRING|SUBSTRING|GLOB|REGEX).
TargetImpl(const Pathname &root_r="/", bool doRebuild_r=false)
Ctor.
void stampCommand()
Log info about the current process.
Target::commit helper optimizing package provision.
bool isNeedreboot() const
ZYppCommitPolicy & rpmInstFlags(target::rpm::RpmInstFlags newFlags_r)
The default target::rpm::RpmInstFlags.
TransactionStepList & rTransactionStepList()
Manipulate transactionStepList.
const sat::Transaction & transaction() const
The full transaction list.
void discardScripts()
Discard all remembered scrips.
StepStage stepStage() const
Step action result.
const Pathname & file() const
Return the file path.
int chmod(const Pathname &path, mode_t mode)
Like 'chmod'.
int dirForEach(const Pathname &dir_r, const StrMatcher &matcher_r, function< bool(const Pathname &, const char *const)> fnc_r)
ResStatus & status() const
Returns the current status.
static const UserData::ContentType contentLogline
"zypp-rpm/logline" report a line suitable to be written to the screen.
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
ZYppCommitPolicy & dryRun(bool yesNo_r)
Set dry run (default: false).
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
byKind_iterator byKindBegin(const ResKind &kind_r) const
void updateAutoInstalled()
Update the database of autoinstalled packages.
ZYppCommitPolicy & rpmExcludeDocs(bool yesNo_r)
Use rpm option –excludedocs (default: false)
const char * c_str() const
String representation.
std::string _distributionVersion
Cache distributionVersion.
void commitFindFileConflicts(const ZYppCommitPolicy &policy_r, ZYppCommitResult &result_r)
Commit helper checking for file conflicts after download.
Parallel execution of stateful PluginScripts.
void setData(const Data &data_r)
Store new Data.
void setAutoInstalled(const Queue &autoInstalled_r)
Set ident list of all autoinstalled solvables.
sat::Solvable buddy() const
Return the buddy we share our status object with.
Access to the sat-pools string space.
Libsolv transaction wrapper.
Edition represents [epoch:]version[-release]
Attempts to create a lock to prevent the system from going into hibernate/shutdown.
std::string receiveLine()
Read one line from the input stream.
bool resetTransact(TransactByValue causer_r)
Not the same as setTransact( false ).
static const UserData::ContentType contentRpmout
"zypp-rpm/transactionsa": Additional rpm output (sent immediately).
Similar to DownloadInAdvance, but try to split the transaction into heaps, where at the end of each h...
bool providesFile(const std::string &path_str, const std::string &name_str) const
If the package is installed and provides the file Needed to evaluate split provides during Resolver::...
TraitsType::constPtrType constPtr
const_iterator end() const
Iterator behind the last TransactionStep.
Provide a new empty temporary file and delete it when no longer needed.
unsigned epoch_t
Type of an epoch.
void writeUpgradeTestcase()
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Class representing a patch.
void installSrcPackage(const SrcPackage_constPtr &srcPackage_r)
Install a source package on the Target.
std::string targetDistributionFlavor() const
This is register.flavor attribute of the installed base product.
void install(const PoolItem &pi)
Log installation (or update) of a package.
ResObject::constPtr resolvable() const
Returns the ResObject::constPtr.
ChangedPseudoInstalled changedPseudoInstalled() const
Return all pseudo installed items whose current state differs from their initial one.
std::vector< std::string > Arguments
std::string targetDistributionRelease() const
This is register.release attribute of the installed base product.
Define a set of Solvables by ident and provides.
Extract and remember posttrans scripts for later execution.
Subclass to retrieve database content.
void remember(const Exception &old_r)
Store an other Exception as history.
EstablishedStates establishedStates() const
Factory for EstablishedStates.
bool write(const Pathname &path_r, const std::string &key_r, const std::string &val_r, const std::string &newcomment_r)
Add or change a value in sysconfig file path_r.
rpm::RpmDb _rpm
RPM database.
Repository systemRepo()
Return the system repository, create it if missing.
std::string distributionVersion() const
This is version attribute of the installed base product.
const LocaleSet & locales() const
Return the loacale set.
void createLastDistributionFlavorCache() const
generates a cache of the last product flavor
void initRequestedLocales(const LocaleSet &locales_r)
Start tracking changes based on this locales_r.
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
StringQueue autoInstalled() const
Return the ident strings of all packages that would be auto-installed after the transaction is run...
LocaleSet requestedLocales() const
Languages to be supported by the system.
[ ] Nothing (includes implicit deletes due to obsoletes and non-package actions)
bool empty() const
Test for an empty path.
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
void push(value_type val_r)
Push a value to the end off the Queue.
std::string getline(std::istream &str)
Read one line from stream.
const StrMatcher & matchNoDots()
Convenience returning StrMatcher( "[^.]*", Match::GLOB )
Store and operate on date (time_t).
SolvableIterator solvablesEnd() const
Iterator behind the last Solvable.
std::string shortName() const
static Pool instance()
Singleton ctor.
const Data & data() const
Return the data.
std::string version() const
Version.
Pathname _root
Path to the target.
std::string rpmDbStateHash(const Pathname &root_r)
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::string trim(const std::string &s, const Trim trim_r)
int unlink(const Pathname &path)
Like 'unlink'.
bool set(const std::string &key_r, AnyType val_r)
Set the value for key (nonconst version always returns true).
static const std::string & systemRepoAlias()
Reserved system repository alias .
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
static const Pathname & fname()
Get the current log file path.
bool executeScripts()
Execute the remembered scripts.
const std::string & asString() const
String representation.
void send(const PluginFrame &frame_r)
Send PluginFrame to all open plugins.
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
Just download all packages to the local cache.
Options and policies for ZYpp::commit.
bool isExist() const
Return whether valid stat info exists.
libzypp will decide what to do.
A single step within a Transaction.
ZYppCommitPolicy & downloadMode(DownloadMode val_r)
Commit download policy to use.
void parseFrom(const InputStream &istr_r)
Parse file istr_r and add its specs (one per line, #-comments).
RequestedLocalesFile _requestedLocalesFile
Requested Locales database.
void setLocales(const LocaleSet &locales_r)
Store a new locale set.
Pathname rootDir() const
Get rootdir (for file conflicts check)
void getHardLockQueries(HardLockQueries &activeLocks_r)
Suggest a new set of queries based on the current selection.
Pathname dirname() const
Return all but the last component od this path.
static Pathname assertprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r prefixed with root_r, unless it is already prefixed.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
ChangedPseudoInstalled changedPseudoInstalled() const
Return all pseudo installed items whose current state differs from the established one...
std::string release() const
Release.
Interim helper class to collect global options and settings.
Definition of vendor equivalence.
SolvableIterator solvablesBegin() const
Iterator to the first Solvable.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
void sendLoglineRpm(const std::string &line_r, unsigned rpmlevel_r)
Convenience to send a contentLogline translating a rpm loglevel.
std::string summary() const
bool order()
Order transaction steps for commit.
Pathname solvfilesPath() const
The solv file location actually in use (default or temp).
void updateSolvFileIndex(const Pathname &solvfile_r)
Create solv file content digest for zypper bash completion.
std::string targetDistribution() const
This is register.target attribute of the installed base product.
Resolver & resolver() const
The Resolver.
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
TraitsType::constPtrType constPtr
const VendorAttr & vendorAttr() const
The targets current vendor equivalence settings.
void initDatabase(Pathname root_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database below root_r.
int symlink(const Pathname &oldpath, const Pathname &newpath)
Like 'symlink'.
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
ZYppCommitPolicy & restrictToMedia(unsigned mediaNr_r)
Restrict commit to media 1.
std::list< PoolItem > PoolItemList
list of pool items
std::string anonymousUniqueId() const
anonymous unique id
static const UserData::ContentType contentRpmout
"zypp-rpm/installpkgsa": Additional rpm output (sent immediately).
static PoolImpl & myPool()
RepoStatus rpmDbRepoStatus(const Pathname &root_r)
const char * c_str() const
Conversion to const char *
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
std::string toLower(const std::string &s)
Return lowercase version of s.
Pathname home() const
The directory to store things.
int touch(const Pathname &path)
Change file's modification and access times.
void addProvides(Capability provides_r)
A all sat::Solvable matching this provides_r.
static std::string generateRandomId()
generates a random id using uuidgen
void resetDispose()
Set no dispose function.
ManagedFile get(const PoolItem &citem_r)
Provide a package.
HardLocksFile _hardLocksFile
Hard-Locks database.
static void setRoot(const Pathname &root)
Set new root directory to the default history log file path.
int close()
Wait for the progamm to complete.
byKind_iterator byKindEnd(const ResKind &kind_r) const
void setHardLockQueries(const HardLockQueries &newLocks_r)
Set a new set of queries.
void setSingleTransactionMode(bool yesno_r)
#define SUBST_IF(PAT, VAL)
std::list< UpdateNotificationFile > UpdateNotifications
Libsolv Id queue wrapper.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
TraitsType::constPtrType constPtr
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Product::constPtr baseProduct() const
returns the target base installed product, also known as the distribution or platform.
void createAnonymousId() const
generates the unique anonymous id which is called when creating the target
ZYppCommitPolicy & allMedia()
Process all media (default)
const_iterator begin() const
Iterator to the first TransactionStep.
pool::PoolTraits::HardLockQueries Data
#define NON_MOVABLE(CLASS)
Delete move ctor and move assign.
void add(const Value &val_r)
Push JSON Value to Array.
StepType stepType() const
Type of action to perform in this step.
const Data & data() const
Return the data.
Base class for Exception.
bool preloaded() const
Whether preloaded hint is set.
const std::string & command() const
The command we're executing.
void load(const Pathname &path_r)
Find and launch plugins sending PLUGINBEGIN.
Data returned by ProductFileReader.
static Date now()
Return the current time.
std::string asJSON() const
JSON representation.
void remove(const PoolItem &pi)
Log removal of a package.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
Typesafe passing of user data via callbacks.
epoch_t epoch() const
Epoch.
std::string distroverpkg() const
Package telling the "product version" on systems not using /etc/product.d/baseproduct.
Pathname root() const
The root set for this target.
void setNeedrebootSpec(sat::SolvableSpec needrebootSpec_r)
Solvables which should trigger the reboot-needed hint if installed/updated.
virtual ~TargetImpl()
Dtor.
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
void eraseFromPool()
Remove this Repository from its Pool.
bool hasFile(const std::string &file_r, const std::string &name_r="") const
Return true if at least one package owns a certain file (name_r empty) Return true if package name_r ...
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
#define NON_COPYABLE(CLASS)
Delete copy ctor and copy assign.
TraitsType::constPtrType constPtr
static const UserData::ContentType contentRpmout
"zypp-rpm/cleanupkgsa": Additional rpm output (sent immediately).
Wrapper class for ::stat/::lstat.
bool solvablesEmpty() const
Whether Repository contains solvables.
ResObject::Ptr makeResObject(const sat::Solvable &solvable_r)
Create ResObject from sat::Solvable.
sat::Transaction & rTransaction()
Manipulate transaction.
Combining sat::Solvable and ResStatus.
bool singleTransModeEnabled() const
Pathname systemRoot() const
The target root directory.
ManagedFile provideSrcPackage(const SrcPackage_constPtr &srcPackage_r)
Provides a source package on the Target.
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Target::DistributionLabel distributionLabel() const
This is shortName and summary attribute of the installed base product.
Track changing files or directories.
std::string asString() const
Conversion to std::string
bool isKind(const ResKind &kind_r) const
const std::string & asString() const
void XRunUpdateMessages(const Pathname &root_r, const Pathname &messagesPath_r, const std::vector< sat::Solvable > &checkPackages_r, ZYppCommitResult &result_r)
std::string distributionFlavor() const
This is flavor attribute of the installed base product but does not require the target to be loaded a...
static const UserData::ContentType contentRpmout
"zypp-rpm/removepkgsa": Additional rpm output (sent immediately).
size_type solvablesSize() const
Number of solvables in Repository.
void commitInSingleTransaction(const ZYppCommitPolicy &policy_r, CommitPackageCache &packageCache_r, ZYppCommitResult &result_r)
Commit ordered changes (internal helper)
Easy-to use interface to the ZYPP dependency resolver.
std::unordered_set< IdString > Data
Pathname defaultSolvfilesPath() const
The systems default solv file location.
Solvable satSolvable() const
Return the corresponding sat::Solvable.
void add(const String &key_r, const Value &val_r)
Add key/value pair.
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
void setCommitList(std::vector< sat::Solvable > commitList_r)
Download(commit) sequence of solvables to compute read ahead.
bool empty() const
Whether this is an empty object without valid data.
std::unordered_set< Locale > LocaleSet
void report(const callback::UserData &userData_r)
rpm::RpmDb & rpm()
The RPM database.
TraitsType::constPtrType constPtr
void multiversionSpecChanged()
BlockingMode setFDBlocking(int fd, bool mode)
#define MAXRPMMESSAGELINES
ZYppCommitResult & _result
Mime type like 'type/subtype' classification of content.
static ResPool instance()
Singleton ctor.
void sendLogline(const std::string &line_r, ReportType::loglevel level_r=ReportType::loglevel::msg)
Convenience to send a contentLogline.
void load(bool force=true)