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> 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" 87 #include <solv/repo_rpmdb.h> 97 AutoDispose<Chksum*> chk { ::solv_chksum_create( REPOKEY_TYPE_SHA1 ), []( Chksum *chk ) ->
void {
98 ::solv_chksum_free( chk,
nullptr );
100 if ( ::rpm_hash_database_state( state, chk ) == 0 )
103 const unsigned char * md5 = ::solv_chksum_get( chk, &md5l );
107 WAR <<
"rpm_hash_database_state failed" << endl;
127 inline void sigMultiversionSpecChanged()
145 for (
const Transaction::Step & step : steps_r )
147 if ( step.stepType() != Transaction::TRANSACTION_IGNORE )
157 static const std::string strType(
"type" );
158 static const std::string strStage(
"stage" );
159 static const std::string strSolvable(
"solvable" );
161 static const std::string strTypeDel(
"-" );
162 static const std::string strTypeIns(
"+" );
163 static const std::string strTypeMul(
"M" );
165 static const std::string strStageDone(
"ok" );
166 static const std::string strStageFailed(
"err" );
168 static const std::string strSolvableN(
"n" );
169 static const std::string strSolvableE(
"e" );
170 static const std::string strSolvableV(
"v" );
171 static const std::string strSolvableR(
"r" );
172 static const std::string strSolvableA(
"a" );
179 case Transaction::TRANSACTION_IGNORE:
break;
180 case Transaction::TRANSACTION_ERASE: ret.
add( strType, strTypeDel );
break;
181 case Transaction::TRANSACTION_INSTALL: ret.
add( strType, strTypeIns );
break;
182 case Transaction::TRANSACTION_MULTIINSTALL: ret.
add( strType, strTypeMul );
break;
187 case Transaction::STEP_TODO:
break;
188 case Transaction::STEP_DONE: ret.
add( strStage, strStageDone );
break;
189 case Transaction::STEP_ERROR: ret.
add( strStage, strStageFailed );
break;
198 ident = solv.ident();
205 ident = step_r.
ident();
207 arch = step_r.
arch();
212 { strSolvableV, ed.
version() },
213 { strSolvableR, ed.
release() },
217 s.add( strSolvableE, epoch );
219 ret.
add( strSolvable, s );
235 class AssertProcMounted
241 AssertProcMounted( Pathname root_r )
244 if ( ! PathInfo(root_r/
"self").isDir() ) {
245 MIL <<
"Try to make sure proc is mounted at" <<
_mountpoint << endl;
247 && execute({
"mount",
"-t",
"proc",
"proc", root_r.asString() }) == 0 ) {
256 ~AssertProcMounted( )
260 MIL <<
"We mounted " <<
_mountpoint <<
" so we unmount it" << endl;
261 execute({
"umount",
"-l",
_mountpoint.asString() });
269 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
288 std::ifstream infile( historyFile_r.c_str() );
289 for( iostr::EachLine in( infile ); in; in.next() )
291 const char * ch( (*in).c_str() );
293 if ( *ch <
'1' ||
'9' < *ch )
295 const char * sep1 = ::strchr( ch,
'|' );
300 bool installs =
true;
301 if ( ::strncmp( sep1,
"install|", 8 ) )
303 if ( ::strncmp( sep1,
"remove |", 8 ) )
310 const char * sep2 = ::strchr( sep1,
'|' );
311 if ( !sep2 || sep1 == sep2 )
313 (*in)[sep2-ch] =
'\0';
314 IdString pkg( sep1 );
318 onSystemByUserList.erase( pkg );
322 if ( (sep1 = ::strchr( sep2+1,
'|' ))
323 && (sep1 = ::strchr( sep1+1,
'|' ))
324 && (sep2 = ::strchr( sep1+1,
'|' )) )
326 (*in)[sep2-ch] =
'\0';
327 if ( ::strchr( sep1+1,
'@' ) )
330 onSystemByUserList.insert( pkg );
335 MIL <<
"onSystemByUserList found: " << onSystemByUserList.size() << endl;
336 return onSystemByUserList;
346 return PluginFrame( command_r, json::Object {
347 {
"TransactionStepList", steps_r }
357 MIL <<
"Testcases to keep: " << toKeep << endl;
363 WAR <<
"No Target no Testcase!" << endl;
367 std::string stem(
"updateTestcase" );
368 Pathname dir( target->assertRootPrefix(
"/var/log/") );
372 std::list<std::string> content;
374 std::set<std::string> cases;
375 for_( c, content.begin(), content.end() )
380 if ( cases.size() >= toKeep )
382 unsigned toDel = cases.size() - toKeep + 1;
383 for_( c, cases.begin(), cases.end() )
392 MIL <<
"Write new testcase " << next << endl;
393 getZYpp()->resolver()->createSolverTestcase( next.asString(),
false );
410 std::pair<bool,PatchScriptReport::Action> doExecuteScript(
const Pathname & root_r,
420 for ( std::string output = prog.receiveLine(); output.length(); output = prog.receiveLine() )
425 WAR <<
"User request to abort script " << script_r << endl;
434 if ( prog.close() != 0 )
436 ret.second = report_r->problem( prog.execError() );
437 WAR <<
"ACTION" << ret.second <<
"(" << prog.execError() <<
")" << endl;
438 std::ostringstream sstr;
439 sstr << script_r <<
_(
" execution failed") <<
" (" << prog.execError() <<
")" << endl;
440 historylog.
comment(sstr.str(),
true);
452 bool executeScript(
const Pathname & root_r,
453 const Pathname & script_r,
454 callback::SendReport<PatchScriptReport> & report_r )
459 action = doExecuteScript( root_r, script_r, report_r );
463 switch ( action.second )
466 WAR <<
"User request to abort at script " << script_r << endl;
471 WAR <<
"User request to skip script " << script_r << endl;
481 INT <<
"Abort on unknown ACTION request " << action.second <<
" returned" << endl;
490 bool RunUpdateScripts(
const Pathname & root_r,
491 const Pathname & scriptsPath_r,
492 const std::vector<sat::Solvable> & checkPackages_r,
495 if ( checkPackages_r.empty() )
498 MIL <<
"Looking for new update scripts in (" << root_r <<
")" << scriptsPath_r << endl;
500 if ( ! PathInfo( scriptsDir ).isDir() )
503 std::list<std::string> scripts;
505 if ( scripts.empty() )
513 std::map<std::string, Pathname> unify;
514 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
516 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
517 for_( sit, scripts.begin(), scripts.end() )
522 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
525 PathInfo script( scriptsDir / *sit );
526 Pathname localPath( scriptsPath_r/(*sit) );
527 std::string unifytag;
529 if ( script.isFile() )
535 else if ( ! script.isExist() )
543 if ( unifytag.empty() )
547 if ( unify[unifytag].empty() )
549 unify[unifytag] = localPath;
556 std::string msg(
str::form(
_(
"%s already executed as %s)"), localPath.asString().c_str(), unify[unifytag].c_str() ) );
557 MIL <<
"Skip update script: " << msg << endl;
558 HistoryLog().comment( msg,
true );
562 if ( abort || aborting_r )
564 WAR <<
"Aborting: Skip update script " << *sit << endl;
565 HistoryLog().comment(
566 localPath.asString() +
_(
" execution skipped while aborting"),
571 MIL <<
"Found update script " << *sit << endl;
572 callback::SendReport<PatchScriptReport> report;
573 report->start( make<Package>( *it ), script.path() );
575 if ( ! executeScript( root_r, localPath, report ) )
587 inline void copyTo( std::ostream & out_r,
const Pathname & file_r )
589 std::ifstream infile( file_r.c_str() );
590 for( iostr::EachLine in( infile ); in; in.next() )
592 out_r << *in << endl;
596 inline std::string notificationCmdSubst(
const std::string & cmd_r,
const UpdateNotificationFile & notification_r )
598 std::string ret( cmd_r );
599 #define SUBST_IF(PAT,VAL) if ( ret.find( PAT ) != std::string::npos ) ret = str::gsub( ret, PAT, VAL ) 600 SUBST_IF(
"%p", notification_r.solvable().asString() );
601 SUBST_IF(
"%P", notification_r.file().asString() );
606 void sendNotification(
const Pathname & root_r,
609 if ( notifications_r.empty() )
613 MIL <<
"Notification command is '" << cmdspec <<
"'" << endl;
614 if ( cmdspec.empty() )
618 if ( pos == std::string::npos )
620 ERR <<
"Can't send Notification: Missing 'format |' in command spec." << endl;
621 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
626 std::string commandStr(
str::trim( cmdspec.substr( pos + 1 ) ) );
628 enum Format { UNKNOWN, NONE, SINGLE, DIGEST, BULK };
629 Format format = UNKNOWN;
630 if ( formatStr ==
"none" )
632 else if ( formatStr ==
"single" )
634 else if ( formatStr ==
"digest" )
636 else if ( formatStr ==
"bulk" )
640 ERR <<
"Can't send Notification: Unknown format '" << formatStr <<
" |' in command spec." << endl;
641 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
649 if ( format == NONE || format == SINGLE )
651 for_( it, notifications_r.begin(), notifications_r.end() )
653 std::vector<std::string> command;
654 if ( format == SINGLE )
656 str::splitEscaped( notificationCmdSubst( commandStr, *it ), std::back_inserter( command ) );
661 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
665 int ret = prog.close();
668 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
669 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
675 else if ( format == DIGEST || format == BULK )
677 filesystem::TmpFile tmpfile;
678 std::ofstream out( tmpfile.path().c_str() );
679 for_( it, notifications_r.begin(), notifications_r.end() )
681 if ( format == DIGEST )
683 out << it->file() << endl;
685 else if ( format == BULK )
691 std::vector<std::string> command;
692 command.push_back(
"<"+tmpfile.path().asString() );
693 str::splitEscaped( notificationCmdSubst( commandStr, *notifications_r.begin() ), std::back_inserter( command ) );
698 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
702 int ret = prog.close();
705 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
706 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
713 INT <<
"Can't send Notification: Missing handler for 'format |' in command spec." << endl;
714 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
725 void RunUpdateMessages(
const Pathname & root_r,
726 const Pathname & messagesPath_r,
727 const std::vector<sat::Solvable> & checkPackages_r,
728 ZYppCommitResult & result_r )
730 if ( checkPackages_r.empty() )
733 MIL <<
"Looking for new update messages in (" << root_r <<
")" << messagesPath_r << endl;
735 if ( ! PathInfo( messagesDir ).isDir() )
738 std::list<std::string> messages;
740 if ( messages.empty() )
746 HistoryLog historylog;
747 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
749 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
750 for_( sit, messages.begin(), messages.end() )
755 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
758 PathInfo message( messagesDir / *sit );
759 if ( ! message.isFile() || message.size() == 0 )
762 MIL <<
"Found update message " << *sit << endl;
763 Pathname localPath( messagesPath_r/(*sit) );
764 result_r.rUpdateMessages().push_back( UpdateNotificationFile( *it, localPath ) );
765 historylog.comment( str::Str() <<
_(
"New update message") <<
" " << localPath,
true );
768 sendNotification( root_r, result_r.updateMessages() );
774 void logPatchStatusChanges(
const sat::Transaction & transaction_r, TargetImpl & target_r )
777 if ( changedPseudoInstalled.empty() )
785 WAR <<
"Need to recompute the patch status changes as commit is incomplete!" << endl;
791 HistoryLog historylog;
792 for (
const auto & el : changedPseudoInstalled )
793 historylog.patchStateChange( el.first, el.second );
802 const std::vector<sat::Solvable> & checkPackages_r,
804 { RunUpdateMessages( root_r, messagesPath_r, checkPackages_r, result_r ); }
817 , _requestedLocalesFile( home() /
"RequestedLocales" )
818 , _autoInstalledFile( home() /
"AutoInstalled" )
827 sigMultiversionSpecChanged();
828 MIL <<
"Initialized target on " <<
_root << endl;
836 std::ifstream uuidprovider(
"/proc/sys/kernel/random/uuid" );
846 boost::function<
bool ()> condition,
847 boost::function<std::string ()> value )
849 std::string val = value();
857 MIL <<
"updating '" << filename <<
"' content." << endl;
861 std::ofstream filestr;
864 filestr.open( filename.
c_str() );
866 if ( filestr.good() )
902 WAR <<
"Can't create anonymous id file" << endl;
911 Pathname flavorpath(
home() /
"LastDistributionFlavor");
917 WAR <<
"No base product, I won't create flavor cache" << endl;
921 std::string flavor = p->flavor();
933 WAR <<
"Can't create flavor cache" << endl;
946 sigMultiversionSpecChanged();
947 MIL <<
"Targets closed" << endl;
971 Pathname rpmsolvcookie = base/
"cookie";
973 bool build_rpm_solv =
true;
983 MIL <<
"Read cookie: " << cookie << endl;
988 if ( status == rpmstatus )
989 build_rpm_solv =
false;
990 MIL <<
"Read cookie: " << rpmsolvcookie <<
" says: " 991 << (build_rpm_solv ?
"outdated" :
"uptodate") << endl;
995 if ( build_rpm_solv )
1009 bool switchingToTmpSolvfile =
false;
1010 Exception ex(
"Failed to cache rpm database.");
1016 rpmsolv = base/
"solv";
1017 rpmsolvcookie = base/
"cookie";
1024 WAR <<
"Using a temporary solv file at " << base << endl;
1025 switchingToTmpSolvfile =
true;
1034 if ( ! switchingToTmpSolvfile )
1044 cmd.push_back(
"rpmdb2solv" );
1046 cmd.push_back(
"-r" );
1049 cmd.push_back(
"-D" );
1051 cmd.push_back(
"-X" );
1053 cmd.push_back(
"-p" );
1056 if ( ! oldSolvFile.
empty() )
1057 cmd.push_back( oldSolvFile.
asString() );
1059 cmd.push_back(
"-o" );
1063 std::string errdetail;
1066 WAR <<
" " << output;
1067 if ( errdetail.empty() ) {
1071 errdetail += output;
1074 int ret = prog.
close();
1095 if (
root() ==
"/" )
1106 if ( !
PathInfo(base/
"solv.idx").isExist() )
1109 return build_rpm_solv;
1127 MIL <<
"New cache built: " << (newCache?
"true":
"false") <<
1128 ", force loading: " << (force?
"true":
"false") << endl;
1133 MIL <<
"adding " << rpmsolv <<
" to pool(" << satpool.
systemRepoAlias() <<
")" << endl;
1140 if ( newCache || force )
1157 MIL <<
"adding " << rpmsolv <<
" to system" << endl;
1163 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1188 if (
PathInfo( historyFile ).isExist() )
1195 if ( onSystemByUser.find( ident ) == onSystemByUser.end() )
1196 onSystemByAuto.insert( ident );
1218 if (
PathInfo( needrebootFile ).isFile() )
1219 needrebootSpec.
parseFrom( needrebootFile );
1222 if (
PathInfo( needrebootDir ).isDir() )
1227 [&](
const Pathname & dir_r,
const char *
const str_r )->
bool 1229 if ( ! isRpmConfigBackup( str_r ) )
1231 Pathname needrebootFile { needrebootDir / str_r };
1232 if (
PathInfo( needrebootFile ).isFile() )
1233 needrebootSpec.
parseFrom( needrebootFile );
1244 if ( ! hardLocks.empty() )
1253 MIL <<
"Target loaded: " << system.
solvablesSize() <<
" resolvables" << endl;
1265 bool explicitDryRun = policy_r.
dryRun();
1275 if (
root() ==
"/" )
1289 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
")" << endl;
1308 steps.push_back( *it );
1315 MIL <<
"Todo: " << result << endl;
1325 if ( commitPlugins )
1326 commitPlugins.
send( transactionPluginFrame(
"COMMITBEGIN", steps ) );
1333 if ( ! policy_r.
dryRun() )
1339 DBG <<
"dryRun: Not writing upgrade testcase." << endl;
1346 if ( ! policy_r.
dryRun() )
1368 DBG <<
"dryRun: Not stroring non-package data." << endl;
1375 if ( ! policy_r.
dryRun() )
1377 for_( it, steps.begin(), steps.end() )
1379 if ( ! it->satSolvable().isKind<
Patch>() )
1387 if ( ! patch ||patch->message().empty() )
1390 MIL <<
"Show message for " << patch << endl;
1392 if ( ! report->show( patch ) )
1394 WAR <<
"commit aborted by the user" << endl;
1401 DBG <<
"dryRun: Not checking patch messages." << endl;
1423 for_( it, steps.begin(), steps.end() )
1425 switch ( it->stepType() )
1444 localfile = packageCache.
get( pi );
1447 catch (
const AbortRequestException & exp )
1451 WAR <<
"commit cache preload aborted by the user" << endl;
1455 catch (
const SkipRequestException & exp )
1460 WAR <<
"Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1470 INT <<
"Unexpected Error: Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1480 ERR <<
"Some packages could not be provided. Aborting commit."<< endl;
1488 if ( ! policy_r.
dryRun() )
1492 commit( policy_r, packageCache, result );
1496 DBG <<
"dryRun/downloadOnly: Not installing/deleting anything." << endl;
1497 if ( explicitDryRun ) {
1507 DBG <<
"dryRun: Not downloading/installing/deleting anything." << endl;
1508 if ( explicitDryRun ) {
1520 WAR <<
"(rpm removed in commit?) Inject missing /var/lib/rpm compat symlink to /usr/lib/sysimage/rpm" << endl;
1529 if ( commitPlugins )
1530 commitPlugins.
send( transactionPluginFrame(
"COMMITEND", steps ) );
1535 if ( ! policy_r.
dryRun() )
1540 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
") returns: " << result << endl;
1551 struct NotifyAttemptToModify
1569 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1574 NotifyAttemptToModify attemptToModify( result_r );
1579 AssertProcMounted assertProcMounted(
_root );
1582 std::vector<sat::Solvable> successfullyInstalledPackages;
1585 for_( step, steps.begin(), steps.end() )
1607 localfile = packageCache_r.
get( citem );
1609 catch (
const AbortRequestException &e )
1611 WAR <<
"commit aborted by the user" << endl;
1616 catch (
const SkipRequestException &e )
1619 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1628 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1637 bool success =
false;
1663 if ( progress.aborted() )
1665 WAR <<
"commit aborted by the user" << endl;
1674 auto rebootNeededFile =
root() /
"/run/reboot-needed";
1690 WAR <<
"dry run failed" << endl;
1695 if ( progress.aborted() )
1697 WAR <<
"commit aborted by the user" << endl;
1702 WAR <<
"Install failed" << endl;
1708 if ( success && !policy_r.
dryRun() )
1711 successfullyInstalledPackages.push_back( citem.
satSolvable() );
1720 bool success =
false;
1731 if ( progress.aborted() )
1733 WAR <<
"commit aborted by the user" << endl;
1747 if ( progress.aborted() )
1749 WAR <<
"commit aborted by the user" << endl;
1755 WAR <<
"removal of " << p <<
" failed";
1758 if ( success && !policy_r.
dryRun() )
1765 else if ( ! policy_r.
dryRun() )
1769 if ( ! citem.
buddy() )
1776 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
1782 std::string referenceFilename( p->referenceFilename() );
1783 if ( referenceFilename.empty() )
1785 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
1789 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
1790 if ( !
rpm().hasFile( referencePath.asString() ) )
1795 ERR <<
"Delete orphan product failed: " << referencePath << endl;
1799 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
1826 if ( ! successfullyInstalledPackages.empty() )
1829 successfullyInstalledPackages, abort ) )
1831 WAR <<
"Commit aborted by the user" << endl;
1837 successfullyInstalledPackages,
1844 logPatchStatusChanges( result_r.
transaction(), *this );
1861 namespace zpt = zypp::proto::target;
1864 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1869 NotifyAttemptToModify attemptToModify( result_r );
1875 AssertProcMounted assertProcMounted(
_root );
1893 commit.set_flags( flags );
1900 std::vector<ManagedFile> locFiles;
1904 auto &step = steps[stepId];
1921 locFiles.push_back( packageCache_r.
get( citem ) );
1923 zpt::TransactionStep tStep;
1924 tStep.set_stepid( stepId );
1925 tStep.mutable_install()->set_pathname( locFiles.back()->asString() );
1926 tStep.mutable_install()->set_multiversion( p->multiversionInstall() );
1928 *
commit.mutable_steps()->Add( ) = std::move(tStep);
1930 catch (
const AbortRequestException &e )
1932 WAR <<
"commit aborted by the user" << endl;
1937 catch (
const SkipRequestException &e )
1940 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1949 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1955 zpt::TransactionStep tStep;
1956 tStep.set_stepid( stepId );
1957 tStep.mutable_remove()->set_name( p->name() );
1958 tStep.mutable_remove()->set_version( p->edition().version() );
1959 tStep.mutable_remove()->set_release( p->edition().release() );
1960 tStep.mutable_remove()->set_arch( p->arch().asString() );
1962 *
commit.mutable_steps()->Add() = std::move(tStep);
1973 zpt::TransactionStep tStep;
1974 tStep.set_stepid( stepId );
1975 tStep.mutable_install()->set_pathname( locFiles.back()->asString() );
1976 tStep.mutable_install()->set_multiversion(
false );
1977 *
commit.mutable_steps()->Add() = std::move(tStep);
1981 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1988 std::vector<sat::Solvable> successfullyInstalledPackages;
1990 if (
commit.steps_size() ) {
1993 auto loop = zyppng::EventLoop::create();
2002 int currentStepId = -1;
2008 bool gotEndOfScript =
false;
2011 std::unique_ptr<callback::SendReport <rpm::TransactionReportSA>> transactionreport;
2012 std::unique_ptr<callback::SendReport <rpm::InstallResolvableReportSA>> installreport;
2013 std::unique_ptr<callback::SendReport <rpm::RemoveResolvableReportSA>> uninstallreport;
2014 std::unique_ptr<callback::SendReport <rpm::CommitScriptReportSA>> scriptreport;
2015 std::unique_ptr<callback::SendReport <rpm::CleanupPackageReportSA>> cleanupreport;
2018 std::optional<zpt::TransactionError> transactionError;
2021 std::string currentScriptType;
2022 std::string currentScriptPackage;
2032 unsigned lineno = 0;
2035 auto msgSource = zyppng::AsyncDataSource::create();
2036 auto scriptSource = zyppng::AsyncDataSource::create();
2041 const auto &sendRpmLineToReport = [&](
const std::string &line ){
2043 const auto &sendLogRep = [&](
auto &report,
const auto &cType ){
2045 if ( currentStepId >= 0 )
2046 cmdout.
set(
"solvable", steps.at(currentStepId).satSolvable() );
2047 cmdout.
set(
"line", line );
2048 report->report(cmdout);
2051 if ( installreport ) {
2053 }
else if ( uninstallreport ) {
2055 }
else if ( scriptreport ) {
2057 }
else if ( transactionreport ) {
2059 }
else if ( cleanupreport ) {
2062 WAR <<
"Got rpm output without active report " << line << std::endl;
2067 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2071 if ( line.back() !=
'\n' )
2077 const auto &processDataFromScriptFd = [&](){
2079 while ( scriptSource->canReadLine() ) {
2081 if ( gotEndOfScript )
2084 std::string l = scriptSource->readLine().asString();
2086 DBG <<
"Received end of script tag" << std::endl;
2087 gotEndOfScript =
true;
2088 l = l.substr( 0, l.size() - endOfScriptTag.size() );
2089 if ( l.size() == 0 )
2093 sendRpmLineToReport( l );
2096 scriptSource->sigReadyRead().connect( processDataFromScriptFd );
2099 const auto &waitForScriptEnd = [&]() {
2102 if ( gotEndOfScript )
2106 processDataFromScriptFd();
2109 while ( scriptSource->canRead() && !gotEndOfScript ) {
2112 scriptSource->waitForReadyRead( 100 );
2116 const auto &aboutToStartNewReport = [&](){
2118 if ( transactionreport || installreport || uninstallreport || scriptreport || cleanupreport ) {
2119 ERR <<
"There is still a running report, this is a bug" << std::endl;
2123 DBG <<
"Starting new report, setting gotEndOfScript to false" << std::endl;
2124 gotEndOfScript =
false;
2127 const auto &writeRpmMsgToHistory = [&](){
2128 if ( rpmmsg.size() == 0 )
2132 rpmmsg +=
"[truncated]\n";
2134 std::ostringstream sstr;
2135 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2140 const auto &finalizeCurrentReport = [&]() {
2143 if ( currentStepId >= 0 ) {
2144 step = &steps.at(currentStepId);
2148 if ( installreport ) {
2156 writeRpmMsgToHistory();
2160 ( *installreport)->progress( 100, resObj );
2163 successfullyInstalledPackages.push_back( step->
satSolvable() );
2169 auto rebootNeededFile =
root() /
"/run/reboot-needed";
2181 writeRpmMsgToHistory();
2184 if ( uninstallreport ) {
2192 writeRpmMsgToHistory();
2196 ( *uninstallreport)->progress( 100, resObj );
2206 writeRpmMsgToHistory();
2209 if ( scriptreport ) {
2211 ( *scriptreport)->progress( 100, resObj );
2214 if ( transactionreport ) {
2216 ( *transactionreport)->progress( 100 );
2219 if ( cleanupreport ) {
2221 ( *cleanupreport)->progress( 100 );
2224 DBG <<
"Report finalized" << std::endl;
2228 currentScriptType.clear();
2229 currentScriptPackage.clear();
2230 installreport.reset();
2231 uninstallreport.reset();
2232 scriptreport.reset();
2233 transactionreport.reset();
2234 cleanupreport.reset();
2244 constexpr std::string_view zyppRpmBinary(ZYPP_RPM_BINARY);
2246 const char *argv[] = {
2249 zyppRpmBinary.data(),
2252 auto prog = zyppng::Process::create();
2256 auto messagePipe = zyppng::Pipe::create();
2262 auto scriptPipe = zyppng::Pipe::create();
2266 prog->addFd( messagePipe->writeFd );
2267 prog->addFd( scriptPipe->writeFd );
2270 if ( !scriptSource->open( scriptPipe->readFd ) )
2273 prog->sigStarted().connect( [&](){
2276 messagePipe->unrefWrite();
2277 scriptPipe->unrefWrite();
2280 prog->stdoutDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2281 while( prog->stdoutDevice()->canReadLine() ) {
2282 MIL <<
"zypp-rpm stdout: " << prog->stdoutDevice()->readLine().asStringView() << std::endl;
2287 prog->stderrDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2288 while( prog->stderrDevice()->canReadLine() ) {
2289 MIL <<
"zypp-rpm stderr: " << prog->stderrDevice()->readLine().asStringView() << std::endl;
2295 const auto outFd = prog->stdinFd();
2302 zyppng::rpc::HeaderSizeType msgSize =
commit.ByteSizeLong();
2303 const auto written = zyppng::eintrSafeCall( ::
write, outFd, &msgSize,
sizeof(zyppng::rpc::HeaderSizeType) );
2304 if ( written !=
sizeof(zyppng::rpc::HeaderSizeType) ) {
2305 prog->stop( SIGKILL );
2309 zyppng::FileOutputStream fo ( outFd );
2310 if ( !
commit.SerializeToZeroCopyStream( &fo ) ) {
2311 prog->stop( SIGKILL );
2321 if ( !msgSource->open( messagePipe->readFd ) )
2324 size_t pendingMessageSize = 0;
2325 const auto &processMessages = [&] ( ) {
2329 const auto &parseMsgWithStepId = [&steps](
const auto &m,
auto &p ){
2330 if ( !p.ParseFromString( m.value() ) ) {
2331 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2335 auto id = p.stepid();
2336 if ( id < 0 || id >= steps.size() ) {
2337 ERR <<
"Received invalid stepId: " <<
id <<
" in " << m.messagetypename() <<
" message from zypp-rpm, ignoring." << std::endl;
2343 while ( msgSource->bytesAvailable() ) {
2345 if ( pendingMessageSize == 0 ) {
2346 if ( msgSource->bytesAvailable() >=
sizeof( zyppng::rpc::HeaderSizeType ) ) {
2347 msgSource->read( reinterpret_cast<char *>( &pendingMessageSize ),
sizeof( zyppng::rpc::HeaderSizeType ) );
2351 if ( msgSource->bytesAvailable() < pendingMessageSize ) {
2355 auto bytes = msgSource->read( pendingMessageSize );
2356 pendingMessageSize = 0;
2358 zypp::proto::Envelope m;
2359 if (! m.ParseFromArray( bytes.data(), bytes.size() ) ) {
2362 ERR <<
"Received misformed message from zypp-rpm, ignoring" << std::endl;
2370 const auto &mName = m.messagetypename();
2371 if ( mName ==
"zypp.proto.target.RpmLog" ) {
2374 if ( !p.ParseFromString( m.value() ) ) {
2375 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2379 sendRpmLineToReport( p.line() );
2382 }
else if ( mName ==
"zypp.proto.target.PackageBegin" ) {
2383 finalizeCurrentReport();
2385 zpt::PackageBegin p;
2386 if ( !parseMsgWithStepId( m, p ) )
2389 aboutToStartNewReport();
2391 auto & step = steps.at( p.stepid() );
2392 currentStepId = p.stepid();
2394 uninstallreport = std::make_unique< callback::SendReport <rpm::RemoveResolvableReportSA> > ();
2395 ( *uninstallreport )->start(
makeResObject( step.satSolvable() ) );
2397 installreport = std::make_unique< callback::SendReport <rpm::InstallResolvableReportSA> > ();
2398 ( *installreport )->start(
makeResObject( step.satSolvable() ) );
2401 }
else if ( mName ==
"zypp.proto.target.PackageFinished" ) {
2402 zpt::PackageFinished p;
2403 if ( !parseMsgWithStepId( m, p ) )
2406 if ( p.stepid() < 0 || p.stepid() > steps.size() )
2413 }
else if ( mName ==
"zypp.proto.target.PackageProgress" ) {
2414 zpt::PackageProgress p;
2415 if ( !parseMsgWithStepId( m, p ) )
2418 if ( uninstallreport )
2419 (*uninstallreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2420 else if ( installreport )
2421 (*installreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2423 ERR <<
"Received a " << mName <<
" message but there is no corresponding report running." << std::endl;
2425 }
else if ( mName ==
"zypp.proto.target.PackageError" ) {
2426 zpt::PackageError p;
2427 if ( !parseMsgWithStepId( m, p ) )
2430 if ( p.stepid() >= 0 && p.stepid() < steps.size() )
2433 finalizeCurrentReport();
2435 }
else if ( mName ==
"zypp.proto.target.ScriptBegin" ) {
2436 finalizeCurrentReport();
2439 if ( !p.ParseFromString( m.value() ) ) {
2440 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2444 aboutToStartNewReport();
2447 const auto stepId = p.stepid();
2448 if ( stepId >= 0 && stepId < steps.size() ) {
2452 currentStepId = p.stepid();
2453 scriptreport = std::make_unique< callback::SendReport <rpm::CommitScriptReportSA> > ();
2454 currentScriptType = p.scripttype();
2455 currentScriptPackage = p.scriptpackage();
2456 (*scriptreport)->start( p.scripttype(), p.scriptpackage(), resPtr );
2458 }
else if ( mName ==
"zypp.proto.target.ScriptFinished" ) {
2461 MIL <<
"Received" << mName <<
" from zypp-rpm" << std::endl;
2463 }
else if ( mName ==
"zypp.proto.target.ScriptError" ) {
2466 if ( !p.ParseFromString( m.value() ) ) {
2467 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2472 const auto stepId = p.stepid();
2473 if ( stepId >= 0 && stepId < steps.size() ) {
2483 str::form(
"Failed to execute %s script for %s ", currentScriptType.c_str(), currentScriptPackage.size() ? currentScriptPackage.c_str() :
"unknown" ),
2486 writeRpmMsgToHistory();
2488 if ( !scriptreport ) {
2489 ERR <<
"Received a ScriptError message, but there is no running report. " << std::endl;
2498 scriptreport.reset();
2501 }
else if ( mName ==
"zypp.proto.target.CleanupBegin" ) {
2502 finalizeCurrentReport();
2504 zpt::CleanupBegin beg;
2505 if ( !beg.ParseFromString( m.value() ) ) {
2506 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2510 aboutToStartNewReport();
2511 cleanupreport = std::make_unique< callback::SendReport <rpm::CleanupPackageReportSA> > ();
2512 (*cleanupreport)->start( beg.nvra() );
2513 }
else if ( mName ==
"zypp.proto.target.CleanupFinished" ) {
2515 finalizeCurrentReport();
2517 }
else if ( mName ==
"zypp.proto.target.CleanupProgress" ) {
2518 zpt::CleanupProgress prog;
2519 if ( !prog.ParseFromString( m.value() ) ) {
2520 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2524 if ( !cleanupreport ) {
2525 ERR <<
"Received a CleanupProgress message, but there is no running report. " << std::endl;
2529 (*cleanupreport)->progress( prog.amount() );
2531 }
else if ( mName ==
"zypp.proto.target.TransBegin" ) {
2532 finalizeCurrentReport();
2534 zpt::TransBegin beg;
2535 if ( !beg.ParseFromString( m.value() ) ) {
2536 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2540 aboutToStartNewReport();
2541 transactionreport = std::make_unique< callback::SendReport <rpm::TransactionReportSA> > ();
2542 (*transactionreport)->start( beg.name() );
2543 }
else if ( mName ==
"zypp.proto.target.TransFinished" ) {
2545 finalizeCurrentReport();
2547 }
else if ( mName ==
"zypp.proto.target.TransProgress" ) {
2548 zpt::TransProgress prog;
2549 if ( !prog.ParseFromString( m.value() ) ) {
2550 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2554 if ( !transactionreport ) {
2555 ERR <<
"Received a TransactionProgress message, but there is no running report. " << std::endl;
2559 (*transactionreport)->progress( prog.amount() );
2560 }
else if ( mName ==
"zypp.proto.target.TransactionError" ) {
2562 zpt::TransactionError error;
2563 if ( !error.ParseFromString( m.value() ) ) {
2564 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2569 transactionError = std::move(error);
2572 ERR <<
"Received unexpected message from zypp-rpm: "<< m.messagetypename() <<
", ignoring" << std::endl;
2578 msgSource->connectFunc( &zyppng::AsyncDataSource::sigReadyRead, processMessages );
2581 int zyppRpmExitCode = -1;
2582 prog->connectFunc( &zyppng::Process::sigFinished, [&](
int code ){
2583 zyppRpmExitCode = code;
2587 if ( !prog->start( argv ) ) {
2598 finalizeCurrentReport();
2601 bool readMsgs =
false;
2602 while( prog->stderrDevice()->canReadLine() ) {
2604 MIL <<
"zypp-rpm: " << prog->stderrDevice()->readLine().asStringView();
2606 while( prog->stdoutDevice()->canReadLine() ) {
2608 MIL <<
"zypp-rpm: " << prog->stdoutDevice()->readLine().asStringView();
2611 while ( scriptSource->canReadLine() ) {
2613 MIL <<
"rpm-script-fd: " << scriptSource->readLine().asStringView();
2615 if ( scriptSource->bytesAvailable() > 0 ) {
2617 MIL <<
"rpm-script-fd: " << scriptSource->readAll().asStringView();
2622 switch ( zyppRpmExitCode ) {
2624 case zypprpm::NoError:
2625 case zypprpm::RpmFinishedWithError:
2627 case zypprpm::RpmFinishedWithTransactionError: {
2629 if ( transactionError ) {
2631 std::ostringstream sstr;
2632 sstr <<
_(
"Executing the transaction failed because of the following problems:") <<
"\n";
2633 for (
const auto & err : transactionError->problems() ) {
2634 sstr <<
" " << err.message() <<
"\n";
2644 case zypprpm::FailedToOpenDb:
2647 case zypprpm::WrongHeaderSize:
2648 case zypprpm::WrongMessageFormat:
2651 case zypprpm::RpmInitFailed:
2654 case zypprpm::FailedToReadPackage:
2657 case zypprpm::FailedToAddStepToTransaction:
2660 case zypprpm::RpmOrderFailed:
2666 auto &step = steps[stepId];
2678 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
2682 std::string referenceFilename( p->referenceFilename() );
2684 if ( referenceFilename.empty() ) {
2685 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
2687 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
2689 if ( !
rpm().hasFile( referencePath.asString() ) ) {
2693 ERR <<
"Delete orphan product failed: " << referencePath << endl;
2695 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
2709 if ( ! successfullyInstalledPackages.empty() )
2712 successfullyInstalledPackages, abort ) )
2714 WAR <<
"Commit aborted by the user" << endl;
2720 successfullyInstalledPackages,
2727 logPatchStatusChanges( result_r.
transaction(), *this );
2755 if ( baseproduct.isFile() )
2768 ERR <<
"baseproduct symlink is dangling or missing: " << baseproduct << endl;
2773 inline Pathname staticGuessRoot(
const Pathname & root_r )
2775 if ( root_r.empty() )
2780 return Pathname(
"/");
2786 inline std::string firstNonEmptyLineIn(
const Pathname & file_r )
2788 std::ifstream idfile( file_r.c_str() );
2789 for( iostr::EachLine in( idfile ); in; in.next() )
2792 if ( ! line.empty() )
2795 return std::string();
2806 if ( p->isTargetDistribution() )
2814 const Pathname needroot( staticGuessRoot(root_r) );
2815 const Target_constPtr target( getZYpp()->getTarget() );
2816 if ( target && target->root() == needroot )
2817 return target->requestedLocales();
2823 MIL <<
"updateAutoInstalled if changed..." << endl;
2831 {
return baseproductdata(
_root ).registerTarget(); }
2834 {
return baseproductdata( staticGuessRoot(root_r) ).registerTarget(); }
2837 {
return baseproductdata(
_root ).registerRelease(); }
2840 {
return baseproductdata( staticGuessRoot(root_r) ).registerRelease();}
2843 {
return baseproductdata(
_root ).registerFlavor(); }
2846 {
return baseproductdata( staticGuessRoot(root_r) ).registerFlavor();}
2879 std::string
distributionVersion = baseproductdata( staticGuessRoot(root_r) ).edition().version();
2886 scoped_ptr<rpm::RpmDb> tmprpmdb;
2892 tmprpmdb->initDatabase( );
2909 return firstNonEmptyLineIn(
home() /
"LastDistributionFlavor" );
2914 return firstNonEmptyLineIn( staticGuessRoot(root_r) /
"/var/lib/zypp/LastDistributionFlavor" );
2920 std::string guessAnonymousUniqueId(
const Pathname & root_r )
2923 std::string ret( firstNonEmptyLineIn( root_r /
"/var/lib/zypp/AnonymousUniqueId" ) );
2924 if ( ret.
empty() && root_r !=
"/" )
2927 ret = firstNonEmptyLineIn(
"/var/lib/zypp/AnonymousUniqueId" );
2935 return guessAnonymousUniqueId(
root() );
2940 return guessAnonymousUniqueId( staticGuessRoot(root_r) );
2947 MIL <<
"New VendorAttr: " << vendorAttr_r << endl;
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.
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.
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.
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
#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.
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.
void addIdent(IdString ident_r)
Add all sat::Solvable with this ident_r.
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 it's 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
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 it's 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
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 load(bool force=true)