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> 88 #include <solv/chksum.h> 98 AutoDispose<Chksum*> chk { ::solv_chksum_create( REPOKEY_TYPE_SHA1 ), []( Chksum *chk ) ->
void {
99 ::solv_chksum_free( chk,
nullptr );
101 if ( ::rpm_hash_database_state( state, chk ) == 0 )
104 const unsigned char * md5 = ::solv_chksum_get( chk, &md5l );
108 WAR <<
"rpm_hash_database_state failed" << endl;
128 inline void sigMultiversionSpecChanged()
146 for (
const Transaction::Step & step : steps_r )
148 if ( step.stepType() != Transaction::TRANSACTION_IGNORE )
158 static const std::string strType(
"type" );
159 static const std::string strStage(
"stage" );
160 static const std::string strSolvable(
"solvable" );
162 static const std::string strTypeDel(
"-" );
163 static const std::string strTypeIns(
"+" );
164 static const std::string strTypeMul(
"M" );
166 static const std::string strStageDone(
"ok" );
167 static const std::string strStageFailed(
"err" );
169 static const std::string strSolvableN(
"n" );
170 static const std::string strSolvableE(
"e" );
171 static const std::string strSolvableV(
"v" );
172 static const std::string strSolvableR(
"r" );
173 static const std::string strSolvableA(
"a" );
180 case Transaction::TRANSACTION_IGNORE:
break;
181 case Transaction::TRANSACTION_ERASE: ret.
add( strType, strTypeDel );
break;
182 case Transaction::TRANSACTION_INSTALL: ret.
add( strType, strTypeIns );
break;
183 case Transaction::TRANSACTION_MULTIINSTALL: ret.
add( strType, strTypeMul );
break;
188 case Transaction::STEP_TODO:
break;
189 case Transaction::STEP_DONE: ret.
add( strStage, strStageDone );
break;
190 case Transaction::STEP_ERROR: ret.
add( strStage, strStageFailed );
break;
199 ident = solv.ident();
206 ident = step_r.
ident();
208 arch = step_r.
arch();
213 { strSolvableV, ed.
version() },
214 { strSolvableR, ed.
release() },
218 s.add( strSolvableE, epoch );
220 ret.
add( strSolvable, s );
236 class AssertProcMounted
242 AssertProcMounted( Pathname root_r )
245 if ( ! PathInfo(root_r/
"self").isDir() ) {
246 MIL <<
"Try to make sure proc is mounted at" <<
_mountpoint << endl;
248 && execute({
"mount",
"-t",
"proc",
"proc", root_r.asString() }) == 0 ) {
257 ~AssertProcMounted( )
261 MIL <<
"We mounted " <<
_mountpoint <<
" so we unmount it" << endl;
262 execute({
"umount",
"-l",
_mountpoint.asString() });
270 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
289 std::ifstream infile( historyFile_r.c_str() );
290 for( iostr::EachLine in( infile ); in; in.next() )
292 const char * ch( (*in).c_str() );
294 if ( *ch <
'1' ||
'9' < *ch )
296 const char * sep1 = ::strchr( ch,
'|' );
301 bool installs =
true;
302 if ( ::strncmp( sep1,
"install|", 8 ) )
304 if ( ::strncmp( sep1,
"remove |", 8 ) )
311 const char * sep2 = ::strchr( sep1,
'|' );
312 if ( !sep2 || sep1 == sep2 )
314 (*in)[sep2-ch] =
'\0';
315 IdString pkg( sep1 );
319 onSystemByUserList.erase( pkg );
323 if ( (sep1 = ::strchr( sep2+1,
'|' ))
324 && (sep1 = ::strchr( sep1+1,
'|' ))
325 && (sep2 = ::strchr( sep1+1,
'|' )) )
327 (*in)[sep2-ch] =
'\0';
328 if ( ::strchr( sep1+1,
'@' ) )
331 onSystemByUserList.insert( pkg );
336 MIL <<
"onSystemByUserList found: " << onSystemByUserList.size() << endl;
337 return onSystemByUserList;
347 return PluginFrame( command_r, json::Object {
348 {
"TransactionStepList", steps_r }
358 MIL <<
"Testcases to keep: " << toKeep << endl;
364 WAR <<
"No Target no Testcase!" << endl;
368 std::string stem(
"updateTestcase" );
369 Pathname dir( target->assertRootPrefix(
"/var/log/") );
373 std::list<std::string> content;
375 std::set<std::string> cases;
376 for_( c, content.begin(), content.end() )
381 if ( cases.size() >= toKeep )
383 unsigned toDel = cases.size() - toKeep + 1;
384 for_( c, cases.begin(), cases.end() )
393 MIL <<
"Write new testcase " << next << endl;
394 getZYpp()->resolver()->createSolverTestcase( next.asString(),
false );
411 std::pair<bool,PatchScriptReport::Action> doExecuteScript(
const Pathname & root_r,
421 for ( std::string output = prog.receiveLine(); output.length(); output = prog.receiveLine() )
426 WAR <<
"User request to abort script " << script_r << endl;
435 if ( prog.close() != 0 )
437 ret.second = report_r->problem( prog.execError() );
438 WAR <<
"ACTION" << ret.second <<
"(" << prog.execError() <<
")" << endl;
439 std::ostringstream sstr;
440 sstr << script_r <<
_(
" execution failed") <<
" (" << prog.execError() <<
")" << endl;
441 historylog.
comment(sstr.str(),
true);
453 bool executeScript(
const Pathname & root_r,
454 const Pathname & script_r,
455 callback::SendReport<PatchScriptReport> & report_r )
460 action = doExecuteScript( root_r, script_r, report_r );
464 switch ( action.second )
467 WAR <<
"User request to abort at script " << script_r << endl;
472 WAR <<
"User request to skip script " << script_r << endl;
482 INT <<
"Abort on unknown ACTION request " << action.second <<
" returned" << endl;
491 bool RunUpdateScripts(
const Pathname & root_r,
492 const Pathname & scriptsPath_r,
493 const std::vector<sat::Solvable> & checkPackages_r,
496 if ( checkPackages_r.empty() )
499 MIL <<
"Looking for new update scripts in (" << root_r <<
")" << scriptsPath_r << endl;
501 if ( ! PathInfo( scriptsDir ).isDir() )
504 std::list<std::string> scripts;
506 if ( scripts.empty() )
514 std::map<std::string, Pathname> unify;
515 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
517 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
518 for_( sit, scripts.begin(), scripts.end() )
523 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
526 PathInfo script( scriptsDir / *sit );
527 Pathname localPath( scriptsPath_r/(*sit) );
528 std::string unifytag;
530 if ( script.isFile() )
536 else if ( ! script.isExist() )
544 if ( unifytag.empty() )
548 if ( unify[unifytag].empty() )
550 unify[unifytag] = localPath;
557 std::string msg(
str::form(
_(
"%s already executed as %s)"), localPath.asString().c_str(), unify[unifytag].c_str() ) );
558 MIL <<
"Skip update script: " << msg << endl;
559 HistoryLog().comment( msg,
true );
563 if ( abort || aborting_r )
565 WAR <<
"Aborting: Skip update script " << *sit << endl;
566 HistoryLog().comment(
567 localPath.asString() +
_(
" execution skipped while aborting"),
572 MIL <<
"Found update script " << *sit << endl;
573 callback::SendReport<PatchScriptReport> report;
574 report->start( make<Package>( *it ), script.path() );
576 if ( ! executeScript( root_r, localPath, report ) )
588 inline void copyTo( std::ostream & out_r,
const Pathname & file_r )
590 std::ifstream infile( file_r.c_str() );
591 for( iostr::EachLine in( infile ); in; in.next() )
593 out_r << *in << endl;
597 inline std::string notificationCmdSubst(
const std::string & cmd_r,
const UpdateNotificationFile & notification_r )
599 std::string ret( cmd_r );
600 #define SUBST_IF(PAT,VAL) if ( ret.find( PAT ) != std::string::npos ) ret = str::gsub( ret, PAT, VAL ) 601 SUBST_IF(
"%p", notification_r.solvable().asString() );
602 SUBST_IF(
"%P", notification_r.file().asString() );
607 void sendNotification(
const Pathname & root_r,
610 if ( notifications_r.empty() )
614 MIL <<
"Notification command is '" << cmdspec <<
"'" << endl;
615 if ( cmdspec.empty() )
619 if ( pos == std::string::npos )
621 ERR <<
"Can't send Notification: Missing 'format |' in command spec." << endl;
622 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
627 std::string commandStr(
str::trim( cmdspec.substr( pos + 1 ) ) );
629 enum Format { UNKNOWN, NONE, SINGLE, DIGEST, BULK };
630 Format format = UNKNOWN;
631 if ( formatStr ==
"none" )
633 else if ( formatStr ==
"single" )
635 else if ( formatStr ==
"digest" )
637 else if ( formatStr ==
"bulk" )
641 ERR <<
"Can't send Notification: Unknown format '" << formatStr <<
" |' in command spec." << endl;
642 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
650 if ( format == NONE || format == SINGLE )
652 for_( it, notifications_r.begin(), notifications_r.end() )
654 std::vector<std::string> command;
655 if ( format == SINGLE )
657 str::splitEscaped( notificationCmdSubst( commandStr, *it ), std::back_inserter( command ) );
662 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
666 int ret = prog.close();
669 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
670 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
676 else if ( format == DIGEST || format == BULK )
678 filesystem::TmpFile tmpfile;
679 std::ofstream out( tmpfile.path().c_str() );
680 for_( it, notifications_r.begin(), notifications_r.end() )
682 if ( format == DIGEST )
684 out << it->file() << endl;
686 else if ( format == BULK )
692 std::vector<std::string> command;
693 command.push_back(
"<"+tmpfile.path().asString() );
694 str::splitEscaped( notificationCmdSubst( commandStr, *notifications_r.begin() ), std::back_inserter( command ) );
699 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
703 int ret = prog.close();
706 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
707 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
714 INT <<
"Can't send Notification: Missing handler for 'format |' in command spec." << endl;
715 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
726 void RunUpdateMessages(
const Pathname & root_r,
727 const Pathname & messagesPath_r,
728 const std::vector<sat::Solvable> & checkPackages_r,
729 ZYppCommitResult & result_r )
731 if ( checkPackages_r.empty() )
734 MIL <<
"Looking for new update messages in (" << root_r <<
")" << messagesPath_r << endl;
736 if ( ! PathInfo( messagesDir ).isDir() )
739 std::list<std::string> messages;
741 if ( messages.empty() )
747 HistoryLog historylog;
748 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
750 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
751 for_( sit, messages.begin(), messages.end() )
756 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
759 PathInfo message( messagesDir / *sit );
760 if ( ! message.isFile() || message.size() == 0 )
763 MIL <<
"Found update message " << *sit << endl;
764 Pathname localPath( messagesPath_r/(*sit) );
765 result_r.rUpdateMessages().push_back( UpdateNotificationFile( *it, localPath ) );
766 historylog.comment( str::Str() <<
_(
"New update message") <<
" " << localPath,
true );
769 sendNotification( root_r, result_r.updateMessages() );
775 void logPatchStatusChanges(
const sat::Transaction & transaction_r, TargetImpl & target_r )
778 if ( changedPseudoInstalled.empty() )
786 WAR <<
"Need to recompute the patch status changes as commit is incomplete!" << endl;
792 HistoryLog historylog;
793 for (
const auto & el : changedPseudoInstalled )
794 historylog.patchStateChange( el.first, el.second );
803 const std::vector<sat::Solvable> & checkPackages_r,
805 { RunUpdateMessages( root_r, messagesPath_r, checkPackages_r, result_r ); }
818 , _requestedLocalesFile( home() /
"RequestedLocales" )
819 , _autoInstalledFile( home() /
"AutoInstalled" )
831 sigMultiversionSpecChanged();
832 MIL <<
"Initialized target on " <<
_root << endl;
839 static std::string generateRandomId()
841 std::ifstream uuidprovider(
"/proc/sys/kernel/random/uuid" );
850 void updateFileContent(
const Pathname &filename,
851 boost::function<
bool ()> condition,
852 boost::function<std::string ()> value )
854 std::string val = value();
862 MIL <<
"updating '" << filename <<
"' content." << endl;
866 std::ofstream filestr;
869 filestr.open( filename.
c_str() );
871 if ( filestr.good() )
885 static bool fileMissing(
const Pathname &pathname )
887 return ! PathInfo(pathname).isExist();
890 void TargetImpl::createAnonymousId()
const 897 Pathname idpath(
home() /
"AnonymousUniqueId");
901 updateFileContent( idpath,
902 boost::bind(fileMissing, idpath),
905 catch (
const Exception &e )
907 WAR <<
"Can't create anonymous id file" << endl;
912 void TargetImpl::createLastDistributionFlavorCache()
const 916 Pathname flavorpath(
home() /
"LastDistributionFlavor");
922 WAR <<
"No base product, I won't create flavor cache" << endl;
926 std::string flavor = p->flavor();
931 updateFileContent( flavorpath,
933 functor::Constant<bool>( ! flavor.empty() ),
934 functor::Constant<std::string>(flavor) );
936 catch (
const Exception &e )
938 WAR <<
"Can't create flavor cache" << endl;
952 sigMultiversionSpecChanged();
953 MIL <<
"Targets closed" << endl;
977 Pathname rpmsolvcookie = base/
"cookie";
979 bool build_rpm_solv =
true;
989 MIL <<
"Read cookie: " << cookie << endl;
994 if ( status == rpmstatus )
995 build_rpm_solv =
false;
996 MIL <<
"Read cookie: " << rpmsolvcookie <<
" says: " 997 << (build_rpm_solv ?
"outdated" :
"uptodate") << endl;
1001 if ( build_rpm_solv )
1015 bool switchingToTmpSolvfile =
false;
1016 Exception ex(
"Failed to cache rpm database.");
1022 rpmsolv = base/
"solv";
1023 rpmsolvcookie = base/
"cookie";
1030 WAR <<
"Using a temporary solv file at " << base << endl;
1031 switchingToTmpSolvfile =
true;
1040 if ( ! switchingToTmpSolvfile )
1050 cmd.push_back(
"rpmdb2solv" );
1052 cmd.push_back(
"-r" );
1055 cmd.push_back(
"-D" );
1057 cmd.push_back(
"-X" );
1059 cmd.push_back(
"-p" );
1062 if ( ! oldSolvFile.
empty() )
1063 cmd.push_back( oldSolvFile.
asString() );
1065 cmd.push_back(
"-o" );
1069 std::string errdetail;
1072 WAR <<
" " << output;
1073 if ( errdetail.empty() ) {
1077 errdetail += output;
1080 int ret = prog.
close();
1101 if (
root() ==
"/" )
1112 if ( !
PathInfo(base/
"solv.idx").isExist() )
1115 return build_rpm_solv;
1133 MIL <<
"New cache built: " << (newCache?
"true":
"false") <<
1134 ", force loading: " << (force?
"true":
"false") << endl;
1139 MIL <<
"adding " << rpmsolv <<
" to pool(" << satpool.
systemRepoAlias() <<
")" << endl;
1146 if ( newCache || force )
1163 MIL <<
"adding " << rpmsolv <<
" to system" << endl;
1169 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1194 if (
PathInfo( historyFile ).isExist() )
1201 if ( onSystemByUser.find( ident ) == onSystemByUser.end() )
1202 onSystemByAuto.insert( ident );
1224 if (
PathInfo( needrebootFile ).isFile() )
1225 needrebootSpec.
parseFrom( needrebootFile );
1228 if (
PathInfo( needrebootDir ).isDir() )
1233 [&](
const Pathname & dir_r,
const char *
const str_r )->
bool 1235 if ( ! isRpmConfigBackup( str_r ) )
1237 Pathname needrebootFile { needrebootDir / str_r };
1238 if (
PathInfo( needrebootFile ).isFile() )
1239 needrebootSpec.
parseFrom( needrebootFile );
1250 if ( ! hardLocks.empty() )
1259 createLastDistributionFlavorCache();
1262 MIL <<
"Target loaded: " << system.
solvablesSize() <<
" resolvables" << endl;
1274 bool explicitDryRun = policy_r.
dryRun();
1284 if (
root() ==
"/" )
1298 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
")" << endl;
1317 steps.push_back( *it );
1324 MIL <<
"Todo: " << result << endl;
1334 if ( commitPlugins )
1335 commitPlugins.
send( transactionPluginFrame(
"COMMITBEGIN", steps ) );
1342 if ( ! policy_r.
dryRun() )
1348 DBG <<
"dryRun: Not writing upgrade testcase." << endl;
1355 if ( ! policy_r.
dryRun() )
1377 DBG <<
"dryRun: Not stroring non-package data." << endl;
1384 if ( ! policy_r.
dryRun() )
1386 for_( it, steps.begin(), steps.end() )
1388 if ( ! it->satSolvable().isKind<
Patch>() )
1396 if ( ! patch ||patch->message().empty() )
1399 MIL <<
"Show message for " << patch << endl;
1401 if ( ! report->show( patch ) )
1403 WAR <<
"commit aborted by the user" << endl;
1410 DBG <<
"dryRun: Not checking patch messages." << endl;
1432 for_( it, steps.begin(), steps.end() )
1434 switch ( it->stepType() )
1453 localfile = packageCache.
get( pi );
1456 catch (
const AbortRequestException & exp )
1460 WAR <<
"commit cache preload aborted by the user" << endl;
1464 catch (
const SkipRequestException & exp )
1469 WAR <<
"Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1479 INT <<
"Unexpected Error: Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1489 ERR <<
"Some packages could not be provided. Aborting commit."<< endl;
1497 if ( ! policy_r.
dryRun() )
1501 commit( policy_r, packageCache, result );
1505 DBG <<
"dryRun/downloadOnly: Not installing/deleting anything." << endl;
1506 if ( explicitDryRun ) {
1516 DBG <<
"dryRun: Not downloading/installing/deleting anything." << endl;
1517 if ( explicitDryRun ) {
1529 WAR <<
"(rpm removed in commit?) Inject missing /var/lib/rpm compat symlink to /usr/lib/sysimage/rpm" << endl;
1538 if ( commitPlugins )
1539 commitPlugins.
send( transactionPluginFrame(
"COMMITEND", steps ) );
1544 if ( ! policy_r.
dryRun() )
1549 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
") returns: " << result << endl;
1560 struct NotifyAttemptToModify
1578 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1583 NotifyAttemptToModify attemptToModify( result_r );
1588 AssertProcMounted assertProcMounted(
_root );
1591 std::vector<sat::Solvable> successfullyInstalledPackages;
1594 for_( step, steps.begin(), steps.end() )
1616 localfile = packageCache_r.
get( citem );
1618 catch (
const AbortRequestException &e )
1620 WAR <<
"commit aborted by the user" << endl;
1625 catch (
const SkipRequestException &e )
1628 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1637 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1646 bool success =
false;
1672 if ( progress.aborted() )
1674 WAR <<
"commit aborted by the user" << endl;
1683 auto rebootNeededFile =
root() /
"/run/reboot-needed";
1699 WAR <<
"dry run failed" << endl;
1704 if ( progress.aborted() )
1706 WAR <<
"commit aborted by the user" << endl;
1711 WAR <<
"Install failed" << endl;
1717 if ( success && !policy_r.
dryRun() )
1720 successfullyInstalledPackages.push_back( citem.
satSolvable() );
1729 bool success =
false;
1740 if ( progress.aborted() )
1742 WAR <<
"commit aborted by the user" << endl;
1756 if ( progress.aborted() )
1758 WAR <<
"commit aborted by the user" << endl;
1764 WAR <<
"removal of " << p <<
" failed";
1767 if ( success && !policy_r.
dryRun() )
1774 else if ( ! policy_r.
dryRun() )
1778 if ( ! citem.
buddy() )
1785 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
1791 std::string referenceFilename( p->referenceFilename() );
1792 if ( referenceFilename.empty() )
1794 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
1798 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
1799 if ( !
rpm().hasFile( referencePath.asString() ) )
1804 ERR <<
"Delete orphan product failed: " << referencePath << endl;
1808 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
1835 if ( ! successfullyInstalledPackages.empty() )
1838 successfullyInstalledPackages, abort ) )
1840 WAR <<
"Commit aborted by the user" << endl;
1846 successfullyInstalledPackages,
1853 logPatchStatusChanges( result_r.
transaction(), *this );
1870 namespace zpt = zypp::proto::target;
1873 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1878 NotifyAttemptToModify attemptToModify( result_r );
1884 AssertProcMounted assertProcMounted(
_root );
1899 commit.set_flags( flags );
1907 for (
auto &[key, value] : data ) {
1908 value.resetDispose();
1915 auto &step = steps[stepId];
1932 locCache.value()[stepId] = packageCache_r.
get( citem );
1934 zpt::TransactionStep tStep;
1935 tStep.set_stepid( stepId );
1936 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
1937 tStep.mutable_install()->set_multiversion( p->multiversionInstall() );
1939 *
commit.mutable_steps()->Add( ) = std::move(tStep);
1941 catch (
const AbortRequestException &e )
1943 WAR <<
"commit aborted by the user" << endl;
1948 catch (
const SkipRequestException &e )
1951 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1960 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1966 zpt::TransactionStep tStep;
1967 tStep.set_stepid( stepId );
1968 tStep.mutable_remove()->set_name( p->name() );
1969 tStep.mutable_remove()->set_version( p->edition().version() );
1970 tStep.mutable_remove()->set_release( p->edition().release() );
1971 tStep.mutable_remove()->set_arch( p->arch().asString() );
1973 *
commit.mutable_steps()->Add() = std::move(tStep);
1984 zpt::TransactionStep tStep;
1985 tStep.set_stepid( stepId );
1986 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
1987 tStep.mutable_install()->set_multiversion(
false );
1988 *
commit.mutable_steps()->Add() = std::move(tStep);
1992 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1999 std::vector<sat::Solvable> successfullyInstalledPackages;
2001 if (
commit.steps_size() ) {
2004 auto loop = zyppng::EventLoop::create();
2013 int currentStepId = -1;
2019 bool gotEndOfScript =
false;
2022 std::unique_ptr<callback::SendReport <rpm::TransactionReportSA>> transactionreport;
2023 std::unique_ptr<callback::SendReport <rpm::InstallResolvableReportSA>> installreport;
2024 std::unique_ptr<callback::SendReport <rpm::RemoveResolvableReportSA>> uninstallreport;
2025 std::unique_ptr<callback::SendReport <rpm::CommitScriptReportSA>> scriptreport;
2026 std::unique_ptr<callback::SendReport <rpm::CleanupPackageReportSA>> cleanupreport;
2029 std::optional<zpt::TransactionError> transactionError;
2032 std::string currentScriptType;
2033 std::string currentScriptPackage;
2043 unsigned lineno = 0;
2046 auto msgSource = zyppng::AsyncDataSource::create();
2047 auto scriptSource = zyppng::AsyncDataSource::create();
2052 const auto &sendRpmLineToReport = [&](
const std::string &line ){
2054 const auto &sendLogRep = [&](
auto &report,
const auto &cType ){
2056 if ( currentStepId >= 0 )
2057 cmdout.
set(
"solvable", steps.at(currentStepId).satSolvable() );
2058 cmdout.
set(
"line", line );
2059 report->report(cmdout);
2062 if ( installreport ) {
2064 }
else if ( uninstallreport ) {
2066 }
else if ( scriptreport ) {
2068 }
else if ( transactionreport ) {
2070 }
else if ( cleanupreport ) {
2073 WAR <<
"Got rpm output without active report " << line << std::endl;
2078 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2082 if ( line.back() !=
'\n' )
2088 const auto &processDataFromScriptFd = [&](){
2090 while ( scriptSource->canReadLine() ) {
2092 if ( gotEndOfScript )
2095 std::string l = scriptSource->readLine().asString();
2097 DBG <<
"Received end of script tag" << std::endl;
2098 gotEndOfScript =
true;
2099 l = l.substr( 0, l.size() - endOfScriptTag.size() );
2100 if ( l.size() == 0 )
2104 sendRpmLineToReport( l );
2107 scriptSource->sigReadyRead().connect( processDataFromScriptFd );
2110 const auto &waitForScriptEnd = [&]() {
2113 if ( gotEndOfScript )
2117 processDataFromScriptFd();
2120 while ( scriptSource->canRead() && !gotEndOfScript ) {
2123 scriptSource->waitForReadyRead( 100 );
2127 const auto &aboutToStartNewReport = [&](){
2129 if ( transactionreport || installreport || uninstallreport || scriptreport || cleanupreport ) {
2130 ERR <<
"There is still a running report, this is a bug" << std::endl;
2134 DBG <<
"Starting new report, setting gotEndOfScript to false" << std::endl;
2135 gotEndOfScript =
false;
2138 const auto &writeRpmMsgToHistory = [&](){
2139 if ( rpmmsg.size() == 0 )
2143 rpmmsg +=
"[truncated]\n";
2145 std::ostringstream sstr;
2146 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2151 const auto &finalizeCurrentReport = [&]() {
2154 if ( currentStepId >= 0 ) {
2155 step = &steps.at(currentStepId);
2159 if ( installreport ) {
2167 writeRpmMsgToHistory();
2171 ( *installreport)->progress( 100, resObj );
2174 if ( currentStepId >= 0 )
2175 locCache.value().erase( currentStepId );
2176 successfullyInstalledPackages.push_back( step->
satSolvable() );
2182 auto rebootNeededFile =
root() /
"/run/reboot-needed";
2194 writeRpmMsgToHistory();
2197 if ( uninstallreport ) {
2205 writeRpmMsgToHistory();
2209 ( *uninstallreport)->progress( 100, resObj );
2219 writeRpmMsgToHistory();
2222 if ( scriptreport ) {
2224 ( *scriptreport)->progress( 100, resObj );
2227 if ( transactionreport ) {
2229 ( *transactionreport)->progress( 100 );
2232 if ( cleanupreport ) {
2234 ( *cleanupreport)->progress( 100 );
2237 DBG <<
"Report finalized" << std::endl;
2241 currentScriptType.clear();
2242 currentScriptPackage.clear();
2243 installreport.reset();
2244 uninstallreport.reset();
2245 scriptreport.reset();
2246 transactionreport.reset();
2247 cleanupreport.reset();
2257 constexpr std::string_view zyppRpmBinary(ZYPP_RPM_BINARY);
2259 const char *argv[] = {
2262 zyppRpmBinary.data(),
2265 auto prog = zyppng::Process::create();
2269 auto messagePipe = zyppng::Pipe::create();
2275 auto scriptPipe = zyppng::Pipe::create();
2279 prog->addFd( messagePipe->writeFd );
2280 prog->addFd( scriptPipe->writeFd );
2283 if ( !scriptSource->open( scriptPipe->readFd ) )
2286 prog->sigStarted().connect( [&](){
2289 messagePipe->unrefWrite();
2290 scriptPipe->unrefWrite();
2293 prog->stdoutDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2294 while( prog->stdoutDevice()->canReadLine() ) {
2295 MIL <<
"zypp-rpm stdout: " << prog->stdoutDevice()->readLine().asStringView() << std::endl;
2300 prog->stderrDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2301 while( prog->stderrDevice()->canReadLine() ) {
2302 MIL <<
"zypp-rpm stderr: " << prog->stderrDevice()->readLine().asStringView() << std::endl;
2308 const auto outFd = prog->stdinFd();
2315 zyppng::rpc::HeaderSizeType msgSize =
commit.ByteSizeLong();
2316 const auto written = zyppng::eintrSafeCall( ::
write, outFd, &msgSize,
sizeof(zyppng::rpc::HeaderSizeType) );
2317 if ( written !=
sizeof(zyppng::rpc::HeaderSizeType) ) {
2318 prog->stop( SIGKILL );
2322 zyppng::FileOutputStream fo ( outFd );
2323 if ( !
commit.SerializeToZeroCopyStream( &fo ) ) {
2324 prog->stop( SIGKILL );
2334 if ( !msgSource->open( messagePipe->readFd ) )
2337 size_t pendingMessageSize = 0;
2338 const auto &processMessages = [&] ( ) {
2342 const auto &parseMsgWithStepId = [&steps](
const auto &m,
auto &p ){
2343 if ( !p.ParseFromString( m.value() ) ) {
2344 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2348 auto id = p.stepid();
2349 if ( id < 0 || id >= steps.size() ) {
2350 ERR <<
"Received invalid stepId: " <<
id <<
" in " << m.messagetypename() <<
" message from zypp-rpm, ignoring." << std::endl;
2356 while ( msgSource->bytesAvailable() ) {
2358 if ( pendingMessageSize == 0 ) {
2359 if ( msgSource->bytesAvailable() >=
sizeof( zyppng::rpc::HeaderSizeType ) ) {
2360 msgSource->read( reinterpret_cast<char *>( &pendingMessageSize ),
sizeof( zyppng::rpc::HeaderSizeType ) );
2364 if ( msgSource->bytesAvailable() < pendingMessageSize ) {
2368 auto bytes = msgSource->read( pendingMessageSize );
2369 pendingMessageSize = 0;
2371 zypp::proto::Envelope m;
2372 if (! m.ParseFromArray( bytes.data(), bytes.size() ) ) {
2375 ERR <<
"Received misformed message from zypp-rpm, ignoring" << std::endl;
2383 const auto &mName = m.messagetypename();
2384 if ( mName ==
"zypp.proto.target.RpmLog" ) {
2387 if ( !p.ParseFromString( m.value() ) ) {
2388 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2392 sendRpmLineToReport( p.line() );
2395 }
else if ( mName ==
"zypp.proto.target.PackageBegin" ) {
2396 finalizeCurrentReport();
2398 zpt::PackageBegin p;
2399 if ( !parseMsgWithStepId( m, p ) )
2402 aboutToStartNewReport();
2404 auto & step = steps.at( p.stepid() );
2405 currentStepId = p.stepid();
2407 uninstallreport = std::make_unique< callback::SendReport <rpm::RemoveResolvableReportSA> > ();
2408 ( *uninstallreport )->start(
makeResObject( step.satSolvable() ) );
2410 installreport = std::make_unique< callback::SendReport <rpm::InstallResolvableReportSA> > ();
2411 ( *installreport )->start(
makeResObject( step.satSolvable() ) );
2414 }
else if ( mName ==
"zypp.proto.target.PackageFinished" ) {
2415 zpt::PackageFinished p;
2416 if ( !parseMsgWithStepId( m, p ) )
2419 if ( p.stepid() < 0 || p.stepid() > steps.size() )
2426 }
else if ( mName ==
"zypp.proto.target.PackageProgress" ) {
2427 zpt::PackageProgress p;
2428 if ( !parseMsgWithStepId( m, p ) )
2431 if ( uninstallreport )
2432 (*uninstallreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2433 else if ( installreport )
2434 (*installreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2436 ERR <<
"Received a " << mName <<
" message but there is no corresponding report running." << std::endl;
2438 }
else if ( mName ==
"zypp.proto.target.PackageError" ) {
2439 zpt::PackageError p;
2440 if ( !parseMsgWithStepId( m, p ) )
2443 if ( p.stepid() >= 0 && p.stepid() < steps.size() )
2446 finalizeCurrentReport();
2448 }
else if ( mName ==
"zypp.proto.target.ScriptBegin" ) {
2449 finalizeCurrentReport();
2452 if ( !p.ParseFromString( m.value() ) ) {
2453 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2457 aboutToStartNewReport();
2460 const auto stepId = p.stepid();
2461 if ( stepId >= 0 && stepId < steps.size() ) {
2465 currentStepId = p.stepid();
2466 scriptreport = std::make_unique< callback::SendReport <rpm::CommitScriptReportSA> > ();
2467 currentScriptType = p.scripttype();
2468 currentScriptPackage = p.scriptpackage();
2469 (*scriptreport)->start( p.scripttype(), p.scriptpackage(), resPtr );
2471 }
else if ( mName ==
"zypp.proto.target.ScriptFinished" ) {
2474 MIL <<
"Received" << mName <<
" from zypp-rpm" << std::endl;
2476 }
else if ( mName ==
"zypp.proto.target.ScriptError" ) {
2479 if ( !p.ParseFromString( m.value() ) ) {
2480 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2485 const auto stepId = p.stepid();
2486 if ( stepId >= 0 && stepId < steps.size() ) {
2496 str::form(
"Failed to execute %s script for %s ", currentScriptType.c_str(), currentScriptPackage.size() ? currentScriptPackage.c_str() :
"unknown" ),
2499 writeRpmMsgToHistory();
2501 if ( !scriptreport ) {
2502 ERR <<
"Received a ScriptError message, but there is no running report. " << std::endl;
2511 scriptreport.reset();
2514 }
else if ( mName ==
"zypp.proto.target.CleanupBegin" ) {
2515 finalizeCurrentReport();
2517 zpt::CleanupBegin beg;
2518 if ( !beg.ParseFromString( m.value() ) ) {
2519 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2523 aboutToStartNewReport();
2524 cleanupreport = std::make_unique< callback::SendReport <rpm::CleanupPackageReportSA> > ();
2525 (*cleanupreport)->start( beg.nvra() );
2526 }
else if ( mName ==
"zypp.proto.target.CleanupFinished" ) {
2528 finalizeCurrentReport();
2530 }
else if ( mName ==
"zypp.proto.target.CleanupProgress" ) {
2531 zpt::CleanupProgress prog;
2532 if ( !prog.ParseFromString( m.value() ) ) {
2533 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2537 if ( !cleanupreport ) {
2538 ERR <<
"Received a CleanupProgress message, but there is no running report. " << std::endl;
2542 (*cleanupreport)->progress( prog.amount() );
2544 }
else if ( mName ==
"zypp.proto.target.TransBegin" ) {
2545 finalizeCurrentReport();
2547 zpt::TransBegin beg;
2548 if ( !beg.ParseFromString( m.value() ) ) {
2549 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2553 aboutToStartNewReport();
2554 transactionreport = std::make_unique< callback::SendReport <rpm::TransactionReportSA> > ();
2555 (*transactionreport)->start( beg.name() );
2556 }
else if ( mName ==
"zypp.proto.target.TransFinished" ) {
2558 finalizeCurrentReport();
2560 }
else if ( mName ==
"zypp.proto.target.TransProgress" ) {
2561 zpt::TransProgress prog;
2562 if ( !prog.ParseFromString( m.value() ) ) {
2563 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2567 if ( !transactionreport ) {
2568 ERR <<
"Received a TransactionProgress message, but there is no running report. " << std::endl;
2572 (*transactionreport)->progress( prog.amount() );
2573 }
else if ( mName ==
"zypp.proto.target.TransactionError" ) {
2575 zpt::TransactionError error;
2576 if ( !error.ParseFromString( m.value() ) ) {
2577 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2582 transactionError = std::move(error);
2585 ERR <<
"Received unexpected message from zypp-rpm: "<< m.messagetypename() <<
", ignoring" << std::endl;
2591 msgSource->connectFunc( &zyppng::AsyncDataSource::sigReadyRead, processMessages );
2594 int zyppRpmExitCode = -1;
2595 prog->connectFunc( &zyppng::Process::sigFinished, [&](
int code ){
2596 zyppRpmExitCode = code;
2600 if ( !prog->start( argv ) ) {
2611 finalizeCurrentReport();
2614 bool readMsgs =
false;
2615 while( prog->stderrDevice()->canReadLine() ) {
2617 MIL <<
"zypp-rpm: " << prog->stderrDevice()->readLine().asStringView();
2619 while( prog->stdoutDevice()->canReadLine() ) {
2621 MIL <<
"zypp-rpm: " << prog->stdoutDevice()->readLine().asStringView();
2624 while ( scriptSource->canReadLine() ) {
2626 MIL <<
"rpm-script-fd: " << scriptSource->readLine().asStringView();
2628 if ( scriptSource->bytesAvailable() > 0 ) {
2630 MIL <<
"rpm-script-fd: " << scriptSource->readAll().asStringView();
2635 switch ( zyppRpmExitCode ) {
2637 case zypprpm::NoError:
2638 case zypprpm::RpmFinishedWithError:
2640 case zypprpm::RpmFinishedWithTransactionError: {
2642 if ( transactionError ) {
2644 std::ostringstream sstr;
2645 sstr <<
_(
"Executing the transaction failed because of the following problems:") <<
"\n";
2646 for (
const auto & err : transactionError->problems() ) {
2647 sstr <<
" " << err.message() <<
"\n";
2657 case zypprpm::FailedToOpenDb:
2660 case zypprpm::WrongHeaderSize:
2661 case zypprpm::WrongMessageFormat:
2664 case zypprpm::RpmInitFailed:
2667 case zypprpm::FailedToReadPackage:
2670 case zypprpm::FailedToAddStepToTransaction:
2673 case zypprpm::RpmOrderFailed:
2679 auto &step = steps[stepId];
2691 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
2695 std::string referenceFilename( p->referenceFilename() );
2697 if ( referenceFilename.empty() ) {
2698 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
2700 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
2702 if ( !
rpm().hasFile( referencePath.asString() ) ) {
2706 ERR <<
"Delete orphan product failed: " << referencePath << endl;
2708 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
2722 if ( ! successfullyInstalledPackages.empty() )
2725 successfullyInstalledPackages, abort ) )
2727 WAR <<
"Commit aborted by the user" << endl;
2733 successfullyInstalledPackages,
2740 logPatchStatusChanges( result_r.
transaction(), *this );
2768 if ( baseproduct.isFile() )
2781 ERR <<
"baseproduct symlink is dangling or missing: " << baseproduct << endl;
2786 inline Pathname staticGuessRoot(
const Pathname & root_r )
2788 if ( root_r.empty() )
2793 return Pathname(
"/");
2799 inline std::string firstNonEmptyLineIn(
const Pathname & file_r )
2801 std::ifstream idfile( file_r.c_str() );
2802 for( iostr::EachLine in( idfile ); in; in.next() )
2805 if ( ! line.empty() )
2808 return std::string();
2819 if ( p->isTargetDistribution() )
2827 const Pathname needroot( staticGuessRoot(root_r) );
2828 const Target_constPtr target( getZYpp()->getTarget() );
2829 if ( target && target->root() == needroot )
2830 return target->requestedLocales();
2836 MIL <<
"updateAutoInstalled if changed..." << endl;
2844 {
return baseproductdata(
_root ).registerTarget(); }
2847 {
return baseproductdata( staticGuessRoot(root_r) ).registerTarget(); }
2850 {
return baseproductdata(
_root ).registerRelease(); }
2853 {
return baseproductdata( staticGuessRoot(root_r) ).registerRelease();}
2856 {
return baseproductdata(
_root ).registerFlavor(); }
2859 {
return baseproductdata( staticGuessRoot(root_r) ).registerFlavor();}
2892 std::string
distributionVersion = baseproductdata( staticGuessRoot(root_r) ).edition().version();
2899 scoped_ptr<rpm::RpmDb> tmprpmdb;
2905 tmprpmdb->initDatabase( );
2921 std::string TargetImpl::distributionFlavor()
const 2923 return firstNonEmptyLineIn(
home() /
"LastDistributionFlavor" );
2926 std::string TargetImpl::distributionFlavor(
const Pathname & root_r )
2928 return firstNonEmptyLineIn( staticGuessRoot(root_r) /
"/var/lib/zypp/LastDistributionFlavor" );
2934 std::string guessAnonymousUniqueId(
const Pathname & root_r )
2937 std::string ret( firstNonEmptyLineIn( root_r /
"/var/lib/zypp/AnonymousUniqueId" ) );
2938 if ( ret.
empty() && root_r !=
"/" )
2941 ret = firstNonEmptyLineIn(
"/var/lib/zypp/AnonymousUniqueId" );
2947 std::string TargetImpl::anonymousUniqueId()
const 2949 return guessAnonymousUniqueId(
root() );
2952 std::string TargetImpl::anonymousUniqueId(
const Pathname & root_r )
2954 return guessAnonymousUniqueId( staticGuessRoot(root_r) );
2962 MIL <<
"New VendorAttr: " << vendorAttr_r << endl;
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.
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 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
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.
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.
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)
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)