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/base/UnixSignalSource> 64 #include <zypp-core/zyppng/io/AsyncDataSource> 65 #include <zypp-core/zyppng/io/Process> 66 #include <zypp-core/base/IOTools.h> 67 #include <zypp-core/zyppng/rpc/rpc.h> 68 #include <zypp-core/zyppng/base/private/linuxhelpers_p.h> 69 #include <zypp-core/zyppng/base/EventDispatcher> 70 #include <zypp-proto/target/commit.pb.h> 71 #include <zypp-proto/core/envelope.pb.h> 72 #include <zypp-core/zyppng/rpc/zerocopystreams.h> 79 #include "tools/zypp-rpm/errorcodes.h" 80 #include <rpm/rpmlog.h> 87 static bool val = [](){
88 const char * env = getenv(
"TRANSACTIONAL_UPDATE");
100 #include <solv/repo_rpmdb.h> 101 #include <solv/chksum.h> 111 AutoDispose<Chksum*> chk { ::solv_chksum_create( REPOKEY_TYPE_SHA1 ), []( Chksum *chk ) ->
void {
112 ::solv_chksum_free( chk,
nullptr );
114 if ( ::rpm_hash_database_state( state, chk ) == 0 )
117 const unsigned char * md5 = ::solv_chksum_get( chk, &md5l );
121 WAR <<
"rpm_hash_database_state failed" << endl;
141 inline void sigMultiversionSpecChanged()
159 for (
const Transaction::Step & step : steps_r )
161 if ( step.stepType() != Transaction::TRANSACTION_IGNORE )
171 static const std::string strType(
"type" );
172 static const std::string strStage(
"stage" );
173 static const std::string strSolvable(
"solvable" );
175 static const std::string strTypeDel(
"-" );
176 static const std::string strTypeIns(
"+" );
177 static const std::string strTypeMul(
"M" );
179 static const std::string strStageDone(
"ok" );
180 static const std::string strStageFailed(
"err" );
182 static const std::string strSolvableN(
"n" );
183 static const std::string strSolvableE(
"e" );
184 static const std::string strSolvableV(
"v" );
185 static const std::string strSolvableR(
"r" );
186 static const std::string strSolvableA(
"a" );
193 case Transaction::TRANSACTION_IGNORE:
break;
194 case Transaction::TRANSACTION_ERASE: ret.
add( strType, strTypeDel );
break;
195 case Transaction::TRANSACTION_INSTALL: ret.
add( strType, strTypeIns );
break;
196 case Transaction::TRANSACTION_MULTIINSTALL: ret.
add( strType, strTypeMul );
break;
201 case Transaction::STEP_TODO:
break;
202 case Transaction::STEP_DONE: ret.
add( strStage, strStageDone );
break;
203 case Transaction::STEP_ERROR: ret.
add( strStage, strStageFailed );
break;
212 ident = solv.ident();
219 ident = step_r.
ident();
221 arch = step_r.
arch();
226 { strSolvableV, ed.
version() },
227 { strSolvableR, ed.
release() },
231 s.add( strSolvableE, epoch );
233 ret.
add( strSolvable, s );
247 class AssertMountedBase
259 MIL <<
"We mounted " <<
_mountpoint <<
" so we unmount it" << endl;
260 execute({
"umount",
"-R",
"-l",
_mountpoint.asString() });
268 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
280 class AssertProcMounted :
private AssertMountedBase
283 AssertProcMounted( Pathname root_r )
286 if ( ! PathInfo(root_r/
"self").isDir() ) {
287 MIL <<
"Try to make sure proc is mounted at" << root_r << endl;
289 && execute({
"mount",
"-t",
"proc",
"/proc", root_r.asString() }) == 0 ) {
293 WAR <<
"Mounting proc at " << root_r <<
" failed" << endl;
301 class AssertDevMounted :
private AssertMountedBase
304 AssertDevMounted( Pathname root_r )
307 if ( ! PathInfo(root_r/
"null").isChr() ) {
308 MIL <<
"Try to make sure dev is mounted at" << root_r << endl;
313 && execute({
"mount",
"--rbind",
"--make-rslave",
"/dev", root_r.asString() }) == 0 ) {
317 WAR <<
"Mounting dev at " << root_r <<
" failed" << endl;
334 std::ifstream infile( historyFile_r.c_str() );
335 for( iostr::EachLine in( infile ); in; in.next() )
337 const char * ch( (*in).c_str() );
339 if ( *ch <
'1' ||
'9' < *ch )
341 const char * sep1 = ::strchr( ch,
'|' );
346 bool installs =
true;
347 if ( ::strncmp( sep1,
"install|", 8 ) )
349 if ( ::strncmp( sep1,
"remove |", 8 ) )
356 const char * sep2 = ::strchr( sep1,
'|' );
357 if ( !sep2 || sep1 == sep2 )
359 (*in)[sep2-ch] =
'\0';
360 IdString pkg( sep1 );
364 onSystemByUserList.erase( pkg );
368 if ( (sep1 = ::strchr( sep2+1,
'|' ))
369 && (sep1 = ::strchr( sep1+1,
'|' ))
370 && (sep2 = ::strchr( sep1+1,
'|' )) )
372 (*in)[sep2-ch] =
'\0';
373 if ( ::strchr( sep1+1,
'@' ) )
376 onSystemByUserList.insert( pkg );
381 MIL <<
"onSystemByUserList found: " << onSystemByUserList.size() << endl;
382 return onSystemByUserList;
392 return PluginFrame( command_r, json::Object {
393 {
"TransactionStepList", steps_r }
403 MIL <<
"Testcases to keep: " << toKeep << endl;
409 WAR <<
"No Target no Testcase!" << endl;
413 std::string stem(
"updateTestcase" );
414 Pathname dir( target->assertRootPrefix(
"/var/log/") );
418 std::list<std::string> content;
420 std::set<std::string> cases;
421 for_( c, content.begin(), content.end() )
426 if ( cases.size() >= toKeep )
428 unsigned toDel = cases.size() - toKeep + 1;
429 for_( c, cases.begin(), cases.end() )
438 MIL <<
"Write new testcase " << next << endl;
439 getZYpp()->resolver()->createSolverTestcase( next.asString(),
false );
456 std::pair<bool,PatchScriptReport::Action> doExecuteScript(
const Pathname & root_r,
466 for ( std::string output = prog.receiveLine(); output.length(); output = prog.receiveLine() )
471 WAR <<
"User request to abort script " << script_r << endl;
480 if ( prog.close() != 0 )
482 ret.second = report_r->problem( prog.execError() );
483 WAR <<
"ACTION" << ret.second <<
"(" << prog.execError() <<
")" << endl;
484 std::ostringstream sstr;
485 sstr << script_r <<
_(
" execution failed") <<
" (" << prog.execError() <<
")" << endl;
486 historylog.
comment(sstr.str(),
true);
498 bool executeScript(
const Pathname & root_r,
499 const Pathname & script_r,
500 callback::SendReport<PatchScriptReport> & report_r )
505 action = doExecuteScript( root_r, script_r, report_r );
509 switch ( action.second )
512 WAR <<
"User request to abort at script " << script_r << endl;
517 WAR <<
"User request to skip script " << script_r << endl;
527 INT <<
"Abort on unknown ACTION request " << action.second <<
" returned" << endl;
536 bool RunUpdateScripts(
const Pathname & root_r,
537 const Pathname & scriptsPath_r,
538 const std::vector<sat::Solvable> & checkPackages_r,
541 if ( checkPackages_r.empty() )
544 MIL <<
"Looking for new update scripts in (" << root_r <<
")" << scriptsPath_r << endl;
546 if ( ! PathInfo( scriptsDir ).isDir() )
549 std::list<std::string> scripts;
551 if ( scripts.empty() )
559 std::map<std::string, Pathname> unify;
560 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
562 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
563 for_( sit, scripts.begin(), scripts.end() )
568 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
571 PathInfo script( scriptsDir / *sit );
572 Pathname localPath( scriptsPath_r/(*sit) );
573 std::string unifytag;
575 if ( script.isFile() )
581 else if ( ! script.isExist() )
589 if ( unifytag.empty() )
593 if ( unify[unifytag].empty() )
595 unify[unifytag] = localPath;
602 std::string msg(
str::form(
_(
"%s already executed as %s)"), localPath.asString().c_str(), unify[unifytag].c_str() ) );
603 MIL <<
"Skip update script: " << msg << endl;
604 HistoryLog().comment( msg,
true );
608 if ( abort || aborting_r )
610 WAR <<
"Aborting: Skip update script " << *sit << endl;
611 HistoryLog().comment(
612 localPath.asString() +
_(
" execution skipped while aborting"),
617 MIL <<
"Found update script " << *sit << endl;
618 callback::SendReport<PatchScriptReport> report;
619 report->start( make<Package>( *it ), script.path() );
621 if ( ! executeScript( root_r, localPath, report ) )
633 inline void copyTo( std::ostream & out_r,
const Pathname & file_r )
635 std::ifstream infile( file_r.c_str() );
636 for( iostr::EachLine in( infile ); in; in.next() )
638 out_r << *in << endl;
642 inline std::string notificationCmdSubst(
const std::string & cmd_r,
const UpdateNotificationFile & notification_r )
644 std::string ret( cmd_r );
645 #define SUBST_IF(PAT,VAL) if ( ret.find( PAT ) != std::string::npos ) ret = str::gsub( ret, PAT, VAL ) 646 SUBST_IF(
"%p", notification_r.solvable().asString() );
647 SUBST_IF(
"%P", notification_r.file().asString() );
652 void sendNotification(
const Pathname & root_r,
655 if ( notifications_r.empty() )
659 MIL <<
"Notification command is '" << cmdspec <<
"'" << endl;
660 if ( cmdspec.empty() )
664 if ( pos == std::string::npos )
666 ERR <<
"Can't send Notification: Missing 'format |' in command spec." << endl;
667 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
672 std::string commandStr(
str::trim( cmdspec.substr( pos + 1 ) ) );
674 enum Format { UNKNOWN, NONE, SINGLE, DIGEST, BULK };
675 Format format = UNKNOWN;
676 if ( formatStr ==
"none" )
678 else if ( formatStr ==
"single" )
680 else if ( formatStr ==
"digest" )
682 else if ( formatStr ==
"bulk" )
686 ERR <<
"Can't send Notification: Unknown format '" << formatStr <<
" |' in command spec." << endl;
687 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
695 if ( format == NONE || format == SINGLE )
697 for_( it, notifications_r.begin(), notifications_r.end() )
699 std::vector<std::string> command;
700 if ( format == SINGLE )
702 str::splitEscaped( notificationCmdSubst( commandStr, *it ), std::back_inserter( command ) );
707 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
711 int ret = prog.close();
714 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
715 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
721 else if ( format == DIGEST || format == BULK )
723 filesystem::TmpFile tmpfile;
724 std::ofstream out( tmpfile.path().c_str() );
725 for_( it, notifications_r.begin(), notifications_r.end() )
727 if ( format == DIGEST )
729 out << it->file() << endl;
731 else if ( format == BULK )
737 std::vector<std::string> command;
738 command.push_back(
"<"+tmpfile.path().asString() );
739 str::splitEscaped( notificationCmdSubst( commandStr, *notifications_r.begin() ), std::back_inserter( command ) );
744 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
748 int ret = prog.close();
751 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
752 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
759 INT <<
"Can't send Notification: Missing handler for 'format |' in command spec." << endl;
760 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
771 void RunUpdateMessages(
const Pathname & root_r,
772 const Pathname & messagesPath_r,
773 const std::vector<sat::Solvable> & checkPackages_r,
774 ZYppCommitResult & result_r )
776 if ( checkPackages_r.empty() )
779 MIL <<
"Looking for new update messages in (" << root_r <<
")" << messagesPath_r << endl;
781 if ( ! PathInfo( messagesDir ).isDir() )
784 std::list<std::string> messages;
786 if ( messages.empty() )
792 HistoryLog historylog;
793 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
795 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
796 for_( sit, messages.begin(), messages.end() )
801 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
804 PathInfo message( messagesDir / *sit );
805 if ( ! message.isFile() || message.size() == 0 )
808 MIL <<
"Found update message " << *sit << endl;
809 Pathname localPath( messagesPath_r/(*sit) );
810 result_r.rUpdateMessages().push_back( UpdateNotificationFile( *it, localPath ) );
811 historylog.comment( str::Str() <<
_(
"New update message") <<
" " << localPath,
true );
814 sendNotification( root_r, result_r.updateMessages() );
820 void logPatchStatusChanges(
const sat::Transaction & transaction_r, TargetImpl & target_r )
823 if ( changedPseudoInstalled.empty() )
831 WAR <<
"Need to recompute the patch status changes as commit is incomplete!" << endl;
837 HistoryLog historylog;
838 for (
const auto & el : changedPseudoInstalled )
839 historylog.patchStateChange( el.first, el.second );
848 const std::vector<sat::Solvable> & checkPackages_r,
850 { RunUpdateMessages( root_r, messagesPath_r, checkPackages_r, result_r ); }
863 , _requestedLocalesFile( home() /
"RequestedLocales" )
864 , _autoInstalledFile( home() /
"AutoInstalled" )
873 sigMultiversionSpecChanged();
874 MIL <<
"Initialized target on " <<
_root << endl;
882 std::ifstream uuidprovider(
"/proc/sys/kernel/random/uuid" );
892 boost::function<
bool ()> condition,
893 boost::function<std::string ()> value )
895 std::string val = value();
903 MIL <<
"updating '" << filename <<
"' content." << endl;
907 std::ofstream filestr;
910 filestr.open( filename.
c_str() );
912 if ( filestr.good() )
948 WAR <<
"Can't create anonymous id file" << endl;
957 Pathname flavorpath(
home() /
"LastDistributionFlavor");
963 WAR <<
"No base product, I won't create flavor cache" << endl;
967 std::string flavor = p->flavor();
979 WAR <<
"Can't create flavor cache" << endl;
992 sigMultiversionSpecChanged();
993 MIL <<
"Closed target on " <<
_root << endl;
1017 Pathname rpmsolvcookie = base/
"cookie";
1019 bool build_rpm_solv =
true;
1029 MIL <<
"Read cookie: " << cookie << endl;
1034 if ( status == rpmstatus )
1035 build_rpm_solv =
false;
1036 MIL <<
"Read cookie: " << rpmsolvcookie <<
" says: " 1037 << (build_rpm_solv ?
"outdated" :
"uptodate") << endl;
1041 if ( build_rpm_solv )
1055 bool switchingToTmpSolvfile =
false;
1056 Exception ex(
"Failed to cache rpm database.");
1062 rpmsolv = base/
"solv";
1063 rpmsolvcookie = base/
"cookie";
1070 WAR <<
"Using a temporary solv file at " << base << endl;
1071 switchingToTmpSolvfile =
true;
1080 if ( ! switchingToTmpSolvfile )
1090 cmd.push_back(
"rpmdb2solv" );
1092 cmd.push_back(
"-r" );
1095 cmd.push_back(
"-D" );
1097 cmd.push_back(
"-X" );
1099 cmd.push_back(
"-p" );
1102 if ( ! oldSolvFile.
empty() )
1103 cmd.push_back( oldSolvFile.
asString() );
1105 cmd.push_back(
"-o" );
1109 std::string errdetail;
1112 WAR <<
" " << output;
1113 if ( errdetail.empty() ) {
1117 errdetail += output;
1120 int ret = prog.
close();
1141 if (
root() ==
"/" )
1152 if ( !
PathInfo(base/
"solv.idx").isExist() )
1155 return build_rpm_solv;
1173 MIL <<
"New cache built: " << (newCache?
"true":
"false") <<
1174 ", force loading: " << (force?
"true":
"false") << endl;
1179 MIL <<
"adding " << rpmsolv <<
" to pool(" << satpool.
systemRepoAlias() <<
")" << endl;
1186 if ( newCache || force )
1203 MIL <<
"adding " << rpmsolv <<
" to system" << endl;
1209 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1234 if (
PathInfo( historyFile ).isExist() )
1241 if ( onSystemByUser.find( ident ) == onSystemByUser.end() )
1242 onSystemByAuto.insert( ident );
1263 if (
PathInfo( needrebootFile ).isFile() )
1264 needrebootSpec.
parseFrom( needrebootFile );
1267 if (
PathInfo( needrebootDir ).isDir() )
1272 [&](
const Pathname & dir_r,
const char *
const str_r )->
bool 1274 if ( ! isRpmConfigBackup( str_r ) )
1276 Pathname needrebootFile { needrebootDir / str_r };
1277 if (
PathInfo( needrebootFile ).isFile() )
1278 needrebootSpec.
parseFrom( needrebootFile );
1289 if ( ! hardLocks.empty() )
1298 MIL <<
"Target loaded: " << system.
solvablesSize() <<
" resolvables" << endl;
1310 bool explicitDryRun = policy_r.
dryRun();
1320 if (
root() ==
"/" )
1334 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
")" << endl;
1353 steps.push_back( *it );
1360 MIL <<
"Todo: " << result << endl;
1371 if ( commitPlugins )
1372 commitPlugins.
send( transactionPluginFrame(
"COMMITBEGIN", steps ) );
1379 if ( ! policy_r.
dryRun() )
1385 DBG <<
"dryRun: Not writing upgrade testcase." << endl;
1392 if ( ! policy_r.
dryRun() )
1414 DBG <<
"dryRun: Not storing non-package data." << endl;
1421 if ( ! policy_r.
dryRun() )
1423 for_( it, steps.begin(), steps.end() )
1425 if ( ! it->satSolvable().isKind<
Patch>() )
1433 if ( ! patch ||patch->message().empty() )
1436 MIL <<
"Show message for " << patch << endl;
1438 if ( ! report->show( patch ) )
1440 WAR <<
"commit aborted by the user" << endl;
1447 DBG <<
"dryRun: Not checking patch messages." << endl;
1469 for_( it, steps.begin(), steps.end() )
1471 switch ( it->stepType() )
1490 localfile = packageCache.
get( pi );
1493 catch (
const AbortRequestException & exp )
1497 WAR <<
"commit cache preload aborted by the user" << endl;
1501 catch (
const SkipRequestException & exp )
1506 WAR <<
"Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1516 INT <<
"Unexpected Error: Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1526 ERR <<
"Some packages could not be provided. Aborting commit."<< endl;
1530 if ( ! policy_r.
dryRun() )
1537 commit( policy_r, packageCache, result );
1542 DBG <<
"dryRun/downloadOnly: Not installing/deleting anything." << endl;
1543 if ( explicitDryRun ) {
1557 DBG <<
"dryRun: Not downloading/installing/deleting anything." << endl;
1558 if ( explicitDryRun ) {
1570 WAR <<
"(rpm removed in commit?) Inject missing /var/lib/rpm compat symlink to /usr/lib/sysimage/rpm" << endl;
1579 if ( commitPlugins )
1580 commitPlugins.
send( transactionPluginFrame(
"COMMITEND", steps ) );
1585 if ( ! policy_r.
dryRun() )
1590 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
") returns: " << result << endl;
1601 struct NotifyAttemptToModify
1619 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1624 NotifyAttemptToModify attemptToModify( result_r );
1629 AssertProcMounted assertProcMounted(
_root );
1630 AssertDevMounted assertDevMounted(
_root );
1633 std::vector<sat::Solvable> successfullyInstalledPackages;
1636 for_( step, steps.begin(), steps.end() )
1658 localfile = packageCache_r.
get( citem );
1660 catch (
const AbortRequestException &e )
1662 WAR <<
"commit aborted by the user" << endl;
1667 catch (
const SkipRequestException &e )
1670 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1679 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1688 bool success =
false;
1712 if ( progress.aborted() )
1714 WAR <<
"commit aborted by the user" << endl;
1723 auto rebootNeededFile =
root() /
"/run/reboot-needed";
1739 WAR <<
"dry run failed" << endl;
1744 if ( progress.aborted() )
1746 WAR <<
"commit aborted by the user" << endl;
1751 WAR <<
"Install failed" << endl;
1757 if ( success && !policy_r.
dryRun() )
1760 successfullyInstalledPackages.push_back( citem.
satSolvable() );
1769 bool success =
false;
1780 if ( progress.aborted() )
1782 WAR <<
"commit aborted by the user" << endl;
1796 if ( progress.aborted() )
1798 WAR <<
"commit aborted by the user" << endl;
1804 WAR <<
"removal of " << p <<
" failed";
1807 if ( success && !policy_r.
dryRun() )
1814 else if ( ! policy_r.
dryRun() )
1818 if ( ! citem.
buddy() )
1825 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
1831 std::string referenceFilename( p->referenceFilename() );
1832 if ( referenceFilename.empty() )
1834 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
1838 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
1839 if ( !
rpm().hasFile( referencePath.asString() ) )
1844 ERR <<
"Delete orphan product failed: " << referencePath << endl;
1848 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
1877 if ( ! successfullyInstalledPackages.empty() )
1880 successfullyInstalledPackages, abort ) )
1882 WAR <<
"Commit aborted by the user" << endl;
1888 successfullyInstalledPackages,
1895 logPatchStatusChanges( result_r.
transaction(), *this );
1914 void sendLogline(
const std::string & line_r, ReportType::loglevel level_r = ReportType::loglevel::msg )
1917 data.
set(
"line", std::cref(line_r) );
1918 data.set(
"level", level_r );
1924 auto u2rpmlevel = [](
unsigned rpmlevel_r ) -> ReportType::loglevel {
1925 switch ( rpmlevel_r ) {
1926 case RPMLOG_EMERG: [[fallthrough]];
1927 case RPMLOG_ALERT: [[fallthrough]];
1929 return ReportType::loglevel::crt;
1931 return ReportType::loglevel::err;
1932 case RPMLOG_WARNING:
1933 return ReportType::loglevel::war;
1934 default: [[fallthrough]];
1935 case RPMLOG_NOTICE: [[fallthrough]];
1937 return ReportType::loglevel::msg;
1939 return ReportType::loglevel::dbg;
1947 { (*this)->report( userData_r ); }
1960 namespace zpt = zypp::proto::target;
1966 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1971 NotifyAttemptToModify attemptToModify( result_r );
1977 AssertProcMounted assertProcMounted(
_root );
1978 AssertDevMounted assertDevMounted(
_root );
1993 commit.set_flags( flags );
2002 for (
auto &[
_, value] : data ) {
2004 value.resetDispose();
2011 auto &step = steps[stepId];
2028 locCache.value()[stepId] = packageCache_r.
get( citem );
2030 zpt::TransactionStep tStep;
2031 tStep.set_stepid( stepId );
2032 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
2033 tStep.mutable_install()->set_multiversion( p->multiversionInstall() );
2035 *
commit.mutable_steps()->Add( ) = std::move(tStep);
2037 catch (
const AbortRequestException &e )
2039 WAR <<
"commit aborted by the user" << endl;
2044 catch (
const SkipRequestException &e )
2047 WAR <<
"Skipping package " << p <<
" in commit" << endl;
2056 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
2062 zpt::TransactionStep tStep;
2063 tStep.set_stepid( stepId );
2064 tStep.mutable_remove()->set_name( p->name() );
2065 tStep.mutable_remove()->set_version( p->edition().version() );
2066 tStep.mutable_remove()->set_release( p->edition().release() );
2067 tStep.mutable_remove()->set_arch( p->arch().asString() );
2069 *
commit.mutable_steps()->Add() = std::move(tStep);
2080 zpt::TransactionStep tStep;
2081 tStep.set_stepid( stepId );
2082 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
2083 tStep.mutable_install()->set_multiversion(
false );
2084 *
commit.mutable_steps()->Add() = std::move(tStep);
2088 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
2095 std::vector<sat::Solvable> successfullyInstalledPackages;
2097 if (
commit.steps_size() ) {
2100 auto loop = zyppng::EventLoop::create();
2104 const std::vector<int> interceptedSignals {
2111 auto unixSignals = loop->eventDispatcher()->unixSignalSource();
2112 unixSignals->sigReceived ().connect ([](
int signum ){
2114 JobReport::error (
str::Format(
_(
"Received signal :\"%1% (%2%)\", to ensure the consistency of the system it is not possible to cancel a running rpm transaction.") ) % strsignal(signum) % signum );
2116 for(
const auto &sig : interceptedSignals )
2117 unixSignals->addSignal ( sig );
2120 for(
const auto &sig : interceptedSignals )
2121 unixSignals->removeSignal ( sig );
2128 int currentStepId = -1;
2134 bool gotEndOfScript =
false;
2137 std::unique_ptr<callback::SendReport <rpm::TransactionReportSA>> transactionreport;
2138 std::unique_ptr<callback::SendReport <rpm::InstallResolvableReportSA>> installreport;
2139 std::unique_ptr<callback::SendReport <rpm::RemoveResolvableReportSA>> uninstallreport;
2140 std::unique_ptr<callback::SendReport <rpm::CommitScriptReportSA>> scriptreport;
2141 std::unique_ptr<callback::SendReport <rpm::CleanupPackageReportSA>> cleanupreport;
2144 std::optional<zpt::TransactionError> transactionError;
2147 std::string currentScriptType;
2148 std::string currentScriptPackage;
2158 unsigned lineno = 0;
2161 auto msgSource = zyppng::AsyncDataSource::create();
2162 auto scriptSource = zyppng::AsyncDataSource::create();
2167 const auto &sendRpmLineToReport = [&](
const std::string &line ){
2169 const auto &sendLogRep = [&](
auto &report,
const auto &cType ){
2171 if ( currentStepId >= 0 )
2172 cmdout.
set(
"solvable", steps.at(currentStepId).satSolvable() );
2173 cmdout.
set(
"line", line );
2177 if ( installreport ) {
2179 }
else if ( uninstallreport ) {
2181 }
else if ( scriptreport ) {
2183 }
else if ( transactionreport ) {
2185 }
else if ( cleanupreport ) {
2188 WAR <<
"Got rpm output without active report " << line;
2193 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2197 if ( line.back() !=
'\n' )
2203 const auto &processDataFromScriptFd = [&](){
2205 while ( scriptSource->canReadLine() ) {
2207 if ( gotEndOfScript )
2210 std::string l = scriptSource->readLine().asString();
2212 gotEndOfScript =
true;
2216 l = l.substr( 0, rawsize );
2218 L_DBG(
"zypp-rpm") <<
"[rpm> " << l;
2219 sendRpmLineToReport( l );
2222 scriptSource->sigReadyRead().connect( processDataFromScriptFd );
2225 const auto &waitForScriptEnd = [&]() {
2228 if ( gotEndOfScript )
2232 processDataFromScriptFd();
2235 while ( scriptSource->readFdOpen() && scriptSource->canRead() && !gotEndOfScript ) {
2238 scriptSource->waitForReadyRead( 100 );
2242 const auto &aboutToStartNewReport = [&](){
2244 if ( transactionreport || installreport || uninstallreport || scriptreport || cleanupreport ) {
2245 ERR <<
"There is still a running report, this is a bug" << std::endl;
2249 gotEndOfScript =
false;
2252 const auto &writeRpmMsgToHistory = [&](){
2253 if ( rpmmsg.size() == 0 )
2257 rpmmsg +=
"[truncated]\n";
2259 std::ostringstream sstr;
2260 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2265 const auto &finalizeCurrentReport = [&]() {
2268 if ( currentStepId >= 0 ) {
2269 step = &steps.at(currentStepId);
2273 if ( installreport ) {
2281 writeRpmMsgToHistory();
2285 ( *installreport)->progress( 100, resObj );
2288 if ( currentStepId >= 0 )
2289 locCache.value().erase( currentStepId );
2290 successfullyInstalledPackages.push_back( step->
satSolvable() );
2296 auto rebootNeededFile =
root() /
"/run/reboot-needed";
2308 writeRpmMsgToHistory();
2311 if ( uninstallreport ) {
2319 writeRpmMsgToHistory();
2323 ( *uninstallreport)->progress( 100, resObj );
2333 writeRpmMsgToHistory();
2336 if ( scriptreport ) {
2338 ( *scriptreport)->progress( 100, resObj );
2341 if ( transactionreport ) {
2343 ( *transactionreport)->progress( 100 );
2346 if ( cleanupreport ) {
2348 ( *cleanupreport)->progress( 100 );
2354 currentScriptType.clear();
2355 currentScriptPackage.clear();
2356 installreport.reset();
2357 uninstallreport.reset();
2358 scriptreport.reset();
2359 transactionreport.reset();
2360 cleanupreport.reset();
2370 constexpr std::string_view zyppRpmBinary(ZYPP_RPM_BINARY);
2372 const char *argv[] = {
2375 zyppRpmBinary.data(),
2378 auto prog = zyppng::Process::create();
2382 auto messagePipe = zyppng::Pipe::create();
2388 auto scriptPipe = zyppng::Pipe::create();
2392 prog->addFd( messagePipe->writeFd );
2393 prog->addFd( scriptPipe->writeFd );
2396 if ( !scriptSource->openFds( std::vector<int>{ scriptPipe->readFd } ) )
2399 prog->sigStarted().connect( [&](){
2402 messagePipe->unrefWrite();
2403 scriptPipe->unrefWrite();
2406 prog->connectFunc( &zyppng::IODevice::sigChannelReadyRead, [&](
int channel ){
2407 while( prog->canReadLine( channel ) ) {
2408 L_ERR(
"zypp-rpm") << ( channel == zyppng::Process::StdOut ?
"<stdout> " :
"<stderr> " ) << prog->channelReadLine( channel ).asStringView();
2414 const auto outFd = prog->stdinFd();
2421 zyppng::rpc::HeaderSizeType msgSize =
commit.ByteSizeLong();
2422 const auto written = zyppng::eintrSafeCall( ::
write, outFd, &msgSize,
sizeof(zyppng::rpc::HeaderSizeType) );
2423 if ( written !=
sizeof(zyppng::rpc::HeaderSizeType) ) {
2424 prog->stop( SIGKILL );
2428 zyppng::FileOutputStream fo ( outFd );
2429 if ( !
commit.SerializeToZeroCopyStream( &fo ) ) {
2430 prog->stop( SIGKILL );
2440 if ( !msgSource->openFds( std::vector<int>{ messagePipe->readFd } ) )
2443 zyppng::rpc::HeaderSizeType pendingMessageSize = 0;
2444 const auto &processMessages = [&] ( ) {
2448 const auto &parseMsgWithStepId = [&steps](
const auto &m,
auto &p ){
2449 if ( !p.ParseFromString( m.value() ) ) {
2450 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2454 auto id = p.stepid();
2455 if ( id < 0 || id >= steps.size() ) {
2456 ERR <<
"Received invalid stepId: " <<
id <<
" in " << m.messagetypename() <<
" message from zypp-rpm, ignoring." << std::endl;
2462 while ( msgSource->bytesAvailable() ) {
2464 if ( pendingMessageSize == 0 ) {
2465 if ( std::size_t(msgSource->bytesAvailable()) >=
sizeof( zyppng::rpc::HeaderSizeType ) ) {
2466 msgSource->read( reinterpret_cast<char *>( &pendingMessageSize ),
sizeof( zyppng::rpc::HeaderSizeType ) );
2470 if ( msgSource->bytesAvailable() < pendingMessageSize ) {
2474 auto bytes = msgSource->read( pendingMessageSize );
2475 pendingMessageSize = 0;
2477 zypp::proto::Envelope m;
2478 if (! m.ParseFromArray( bytes.data(), bytes.size() ) ) {
2481 ERR <<
"Received misformed message from zypp-rpm, ignoring" << std::endl;
2489 const auto &mName = m.messagetypename();
2490 if ( mName ==
"zypp.proto.target.RpmLog" ) {
2493 if ( !p.ParseFromString( m.value() ) ) {
2494 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2497 ( p.level() >= RPMLOG_ERR ?
L_ERR(
"zypp-rpm")
2498 : p.level() >= RPMLOG_WARNING ?
L_WAR(
"zypp-rpm")
2499 :
L_DBG(
"zypp-rpm") ) <<
"[rpm " << p.level() <<
"> " << p.line();
2502 }
else if ( mName ==
"zypp.proto.target.PackageBegin" ) {
2503 finalizeCurrentReport();
2505 zpt::PackageBegin p;
2506 if ( !parseMsgWithStepId( m, p ) )
2509 aboutToStartNewReport();
2511 auto & step = steps.at( p.stepid() );
2512 currentStepId = p.stepid();
2514 uninstallreport = std::make_unique< callback::SendReport <rpm::RemoveResolvableReportSA> > ();
2515 ( *uninstallreport )->start(
makeResObject( step.satSolvable() ) );
2517 installreport = std::make_unique< callback::SendReport <rpm::InstallResolvableReportSA> > ();
2518 ( *installreport )->start(
makeResObject( step.satSolvable() ) );
2521 }
else if ( mName ==
"zypp.proto.target.PackageFinished" ) {
2522 zpt::PackageFinished p;
2523 if ( !parseMsgWithStepId( m, p ) )
2526 if ( p.stepid() < 0 || p.stepid() > steps.size() )
2533 }
else if ( mName ==
"zypp.proto.target.PackageProgress" ) {
2534 zpt::PackageProgress p;
2535 if ( !parseMsgWithStepId( m, p ) )
2538 if ( uninstallreport )
2539 (*uninstallreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2540 else if ( installreport )
2541 (*installreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2543 ERR <<
"Received a " << mName <<
" message but there is no corresponding report running." << std::endl;
2545 }
else if ( mName ==
"zypp.proto.target.PackageError" ) {
2546 zpt::PackageError p;
2547 if ( !parseMsgWithStepId( m, p ) )
2550 if ( p.stepid() >= 0 && p.stepid() < steps.size() )
2553 finalizeCurrentReport();
2555 }
else if ( mName ==
"zypp.proto.target.ScriptBegin" ) {
2556 finalizeCurrentReport();
2559 if ( !p.ParseFromString( m.value() ) ) {
2560 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2564 aboutToStartNewReport();
2567 const auto stepId = p.stepid();
2568 if ( stepId >= 0 && stepId < steps.size() ) {
2572 currentStepId = p.stepid();
2573 scriptreport = std::make_unique< callback::SendReport <rpm::CommitScriptReportSA> > ();
2574 currentScriptType = p.scripttype();
2575 currentScriptPackage = p.scriptpackage();
2576 (*scriptreport)->start( p.scripttype(), p.scriptpackage(), resPtr );
2578 }
else if ( mName ==
"zypp.proto.target.ScriptFinished" ) {
2582 }
else if ( mName ==
"zypp.proto.target.ScriptError" ) {
2585 if ( !p.ParseFromString( m.value() ) ) {
2586 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2591 const auto stepId = p.stepid();
2592 if ( stepId >= 0 && stepId < steps.size() ) {
2602 str::form(
"Failed to execute %s script for %s ", currentScriptType.c_str(), currentScriptPackage.size() ? currentScriptPackage.c_str() :
"unknown" ),
2605 writeRpmMsgToHistory();
2607 if ( !scriptreport ) {
2608 ERR <<
"Received a ScriptError message, but there is no running report. " << std::endl;
2617 scriptreport.reset();
2620 }
else if ( mName ==
"zypp.proto.target.CleanupBegin" ) {
2621 finalizeCurrentReport();
2623 zpt::CleanupBegin beg;
2624 if ( !beg.ParseFromString( m.value() ) ) {
2625 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2629 aboutToStartNewReport();
2630 cleanupreport = std::make_unique< callback::SendReport <rpm::CleanupPackageReportSA> > ();
2631 (*cleanupreport)->start( beg.nvra() );
2632 }
else if ( mName ==
"zypp.proto.target.CleanupFinished" ) {
2634 finalizeCurrentReport();
2636 }
else if ( mName ==
"zypp.proto.target.CleanupProgress" ) {
2637 zpt::CleanupProgress prog;
2638 if ( !prog.ParseFromString( m.value() ) ) {
2639 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2643 if ( !cleanupreport ) {
2644 ERR <<
"Received a CleanupProgress message, but there is no running report. " << std::endl;
2648 (*cleanupreport)->progress( prog.amount() );
2650 }
else if ( mName ==
"zypp.proto.target.TransBegin" ) {
2651 finalizeCurrentReport();
2653 zpt::TransBegin beg;
2654 if ( !beg.ParseFromString( m.value() ) ) {
2655 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2659 aboutToStartNewReport();
2660 transactionreport = std::make_unique< callback::SendReport <rpm::TransactionReportSA> > ();
2661 (*transactionreport)->start( beg.name() );
2662 }
else if ( mName ==
"zypp.proto.target.TransFinished" ) {
2664 finalizeCurrentReport();
2666 }
else if ( mName ==
"zypp.proto.target.TransProgress" ) {
2667 zpt::TransProgress prog;
2668 if ( !prog.ParseFromString( m.value() ) ) {
2669 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2673 if ( !transactionreport ) {
2674 ERR <<
"Received a TransactionProgress message, but there is no running report. " << std::endl;
2678 (*transactionreport)->progress( prog.amount() );
2679 }
else if ( mName ==
"zypp.proto.target.TransactionError" ) {
2681 zpt::TransactionError error;
2682 if ( !error.ParseFromString( m.value() ) ) {
2683 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2688 transactionError = std::move(error);
2691 ERR <<
"Received unexpected message from zypp-rpm: "<< m.messagetypename() <<
", ignoring" << std::endl;
2697 msgSource->connectFunc( &zyppng::AsyncDataSource::sigReadyRead, processMessages );
2700 int zyppRpmExitCode = -1;
2701 prog->connectFunc( &zyppng::Process::sigFinished, [&](
int code ){
2702 zyppRpmExitCode = code;
2706 if ( !prog->start( argv ) ) {
2717 finalizeCurrentReport();
2720 bool readMsgs =
false;
2721 while( prog->canReadLine( zyppng::Process::StdErr ) ) {
2723 MIL <<
"zypp-rpm: " << prog->channelReadLine( zyppng::Process::StdErr ).asStringView();
2725 while( prog->canReadLine( zyppng::Process::StdOut ) ) {
2727 MIL <<
"zypp-rpm: " << prog->channelReadLine( zyppng::Process::StdOut ).asStringView();
2730 while ( scriptSource->canReadLine() ) {
2732 MIL <<
"rpm-script-fd: " << scriptSource->readLine().asStringView();
2734 if ( scriptSource->bytesAvailable() > 0 ) {
2736 MIL <<
"rpm-script-fd: " << scriptSource->readAll().asStringView();
2741 switch ( zyppRpmExitCode ) {
2743 case zypprpm::NoError:
2744 case zypprpm::RpmFinishedWithError:
2746 case zypprpm::RpmFinishedWithTransactionError: {
2748 if ( transactionError ) {
2750 std::ostringstream sstr;
2751 sstr <<
_(
"Executing the transaction failed because of the following problems:") <<
"\n";
2752 for (
const auto & err : transactionError->problems() ) {
2753 sstr <<
" " << err.message() <<
"\n";
2763 case zypprpm::FailedToOpenDb:
2766 case zypprpm::WrongHeaderSize:
2767 case zypprpm::WrongMessageFormat:
2770 case zypprpm::RpmInitFailed:
2773 case zypprpm::FailedToReadPackage:
2776 case zypprpm::FailedToAddStepToTransaction:
2779 case zypprpm::RpmOrderFailed:
2782 case zypprpm::FailedToCreateLock:
2788 auto &step = steps[stepId];
2800 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
2804 std::string referenceFilename( p->referenceFilename() );
2806 if ( referenceFilename.empty() ) {
2807 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
2809 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
2811 if ( !
rpm().hasFile( referencePath.asString() ) ) {
2815 ERR <<
"Delete orphan product failed: " << referencePath << endl;
2817 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
2831 if ( ! successfullyInstalledPackages.empty() )
2834 successfullyInstalledPackages, abort ) )
2836 WAR <<
"Commit aborted by the user" << endl;
2842 successfullyInstalledPackages,
2849 logPatchStatusChanges( result_r.
transaction(), *this );
2877 if ( baseproduct.isFile() )
2890 ERR <<
"baseproduct symlink is dangling or missing: " << baseproduct << endl;
2895 inline Pathname staticGuessRoot(
const Pathname & root_r )
2897 if ( root_r.empty() )
2902 return Pathname(
"/");
2908 inline std::string firstNonEmptyLineIn(
const Pathname & file_r )
2910 std::ifstream idfile( file_r.c_str() );
2911 for( iostr::EachLine in( idfile ); in; in.next() )
2914 if ( ! line.empty() )
2917 return std::string();
2928 if ( p->isTargetDistribution() )
2936 const Pathname needroot( staticGuessRoot(root_r) );
2937 const Target_constPtr target( getZYpp()->getTarget() );
2938 if ( target && target->root() == needroot )
2939 return target->requestedLocales();
2945 MIL <<
"updateAutoInstalled if changed..." << endl;
2953 {
return baseproductdata(
_root ).registerTarget(); }
2956 {
return baseproductdata( staticGuessRoot(root_r) ).registerTarget(); }
2959 {
return baseproductdata(
_root ).registerRelease(); }
2962 {
return baseproductdata( staticGuessRoot(root_r) ).registerRelease();}
2965 {
return baseproductdata(
_root ).registerFlavor(); }
2968 {
return baseproductdata( staticGuessRoot(root_r) ).registerFlavor();}
3001 std::string
distributionVersion = baseproductdata( staticGuessRoot(root_r) ).edition().version();
3008 scoped_ptr<rpm::RpmDb> tmprpmdb;
3014 tmprpmdb->initDatabase( );
3031 return firstNonEmptyLineIn(
home() /
"LastDistributionFlavor" );
3036 return firstNonEmptyLineIn( staticGuessRoot(root_r) /
"/var/lib/zypp/LastDistributionFlavor" );
3042 std::string guessAnonymousUniqueId(
const Pathname & root_r )
3045 std::string ret( firstNonEmptyLineIn( root_r /
"/var/lib/zypp/AnonymousUniqueId" ) );
3046 if ( ret.
empty() && root_r !=
"/" )
3049 ret = firstNonEmptyLineIn(
"/var/lib/zypp/AnonymousUniqueId" );
3057 return guessAnonymousUniqueId(
root() );
3062 return guessAnonymousUniqueId( staticGuessRoot(root_r) );
3069 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.
static bool error(const std::string &msg_r, const UserData &userData_r=UserData())
send error text
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 scripts and/or or dump_posttrans lines.
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 .
static const Pathname & fname()
Get the current log file path.
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
void executeScripts(rpm::RpmDb &rpm_r)
Execute the remembered scripts and/or or dump_posttrans lines.
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.
bool TRANSACTIONAL_UPDATE()
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
Typesafe passing of user data via callbacks.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
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)
static zypp::Pathname lockfileDir()
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)