19 #include <sys/types.h> 22 #include <zypp/base/LogTools.h> 23 #include <zypp/base/Exception.h> 24 #include <zypp/base/Iterator.h> 25 #include <zypp/base/Gettext.h> 26 #include <zypp/base/IOStream.h> 28 #include <zypp-core/base/UserRequestException> 33 #include <zypp/PathInfo.h> 38 #include <zypp/TmpPath.h> 40 #include <zypp/ExternalProgram.h> 56 #include <zypp/sat/detail/PoolImpl.h> 60 #include <zypp-core/base/String.h> 61 #include <zypp-core/base/StringV.h> 62 #include <zypp-core/zyppng/base/EventLoop> 63 #include <zypp-core/zyppng/io/AsyncDataSource> 64 #include <zypp-core/zyppng/io/Process> 65 #include <zypp-core/base/IOTools.h> 66 #include <zypp-core/zyppng/rpc/rpc.h> 67 #include <zypp-core/zyppng/base/private/linuxhelpers_p.h> 68 #include <zypp-core/zyppng/base/EventDispatcher> 69 #include <zypp-proto/commit.pb.h> 70 #include <zypp-proto/envelope.pb.h> 71 #include <zypp-core/zyppng/rpc/zerocopystreams.h> 78 #include "tools/zypp-rpm/errorcodes.h" 79 #include <rpm/rpmlog.h> 88 #include <solv/repo_rpmdb.h> 89 #include <solv/chksum.h> 99 AutoDispose<Chksum*> chk { ::solv_chksum_create( REPOKEY_TYPE_SHA1 ), []( Chksum *chk ) ->
void {
100 ::solv_chksum_free( chk,
nullptr );
102 if ( ::rpm_hash_database_state( state, chk ) == 0 )
105 const unsigned char * md5 = ::solv_chksum_get( chk, &md5l );
109 WAR <<
"rpm_hash_database_state failed" << endl;
129 inline void sigMultiversionSpecChanged()
147 for (
const Transaction::Step & step : steps_r )
149 if ( step.stepType() != Transaction::TRANSACTION_IGNORE )
159 static const std::string strType(
"type" );
160 static const std::string strStage(
"stage" );
161 static const std::string strSolvable(
"solvable" );
163 static const std::string strTypeDel(
"-" );
164 static const std::string strTypeIns(
"+" );
165 static const std::string strTypeMul(
"M" );
167 static const std::string strStageDone(
"ok" );
168 static const std::string strStageFailed(
"err" );
170 static const std::string strSolvableN(
"n" );
171 static const std::string strSolvableE(
"e" );
172 static const std::string strSolvableV(
"v" );
173 static const std::string strSolvableR(
"r" );
174 static const std::string strSolvableA(
"a" );
181 case Transaction::TRANSACTION_IGNORE:
break;
182 case Transaction::TRANSACTION_ERASE: ret.
add( strType, strTypeDel );
break;
183 case Transaction::TRANSACTION_INSTALL: ret.
add( strType, strTypeIns );
break;
184 case Transaction::TRANSACTION_MULTIINSTALL: ret.
add( strType, strTypeMul );
break;
189 case Transaction::STEP_TODO:
break;
190 case Transaction::STEP_DONE: ret.
add( strStage, strStageDone );
break;
191 case Transaction::STEP_ERROR: ret.
add( strStage, strStageFailed );
break;
200 ident = solv.ident();
207 ident = step_r.
ident();
209 arch = step_r.
arch();
214 { strSolvableV, ed.
version() },
215 { strSolvableR, ed.
release() },
219 s.add( strSolvableE, epoch );
221 ret.
add( strSolvable, s );
237 class AssertProcMounted
243 AssertProcMounted( Pathname root_r )
246 if ( ! PathInfo(root_r/
"self").isDir() ) {
247 MIL <<
"Try to make sure proc is mounted at" <<
_mountpoint << endl;
249 && execute({
"mount",
"-t",
"proc",
"proc", root_r.asString() }) == 0 ) {
258 ~AssertProcMounted( )
262 MIL <<
"We mounted " <<
_mountpoint <<
" so we unmount it" << endl;
263 execute({
"umount",
"-l",
_mountpoint.asString() });
271 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
290 std::ifstream infile( historyFile_r.c_str() );
291 for( iostr::EachLine in( infile ); in; in.next() )
293 const char * ch( (*in).c_str() );
295 if ( *ch <
'1' ||
'9' < *ch )
297 const char * sep1 = ::strchr( ch,
'|' );
302 bool installs =
true;
303 if ( ::strncmp( sep1,
"install|", 8 ) )
305 if ( ::strncmp( sep1,
"remove |", 8 ) )
312 const char * sep2 = ::strchr( sep1,
'|' );
313 if ( !sep2 || sep1 == sep2 )
315 (*in)[sep2-ch] =
'\0';
316 IdString pkg( sep1 );
320 onSystemByUserList.erase( pkg );
324 if ( (sep1 = ::strchr( sep2+1,
'|' ))
325 && (sep1 = ::strchr( sep1+1,
'|' ))
326 && (sep2 = ::strchr( sep1+1,
'|' )) )
328 (*in)[sep2-ch] =
'\0';
329 if ( ::strchr( sep1+1,
'@' ) )
332 onSystemByUserList.insert( pkg );
337 MIL <<
"onSystemByUserList found: " << onSystemByUserList.size() << endl;
338 return onSystemByUserList;
348 return PluginFrame( command_r, json::Object {
349 {
"TransactionStepList", steps_r }
359 MIL <<
"Testcases to keep: " << toKeep << endl;
365 WAR <<
"No Target no Testcase!" << endl;
369 std::string stem(
"updateTestcase" );
370 Pathname dir( target->assertRootPrefix(
"/var/log/") );
374 std::list<std::string> content;
376 std::set<std::string> cases;
377 for_( c, content.begin(), content.end() )
382 if ( cases.size() >= toKeep )
384 unsigned toDel = cases.size() - toKeep + 1;
385 for_( c, cases.begin(), cases.end() )
394 MIL <<
"Write new testcase " << next << endl;
395 getZYpp()->resolver()->createSolverTestcase( next.asString(),
false );
412 std::pair<bool,PatchScriptReport::Action> doExecuteScript(
const Pathname & root_r,
422 for ( std::string output = prog.receiveLine(); output.length(); output = prog.receiveLine() )
427 WAR <<
"User request to abort script " << script_r << endl;
436 if ( prog.close() != 0 )
438 ret.second = report_r->problem( prog.execError() );
439 WAR <<
"ACTION" << ret.second <<
"(" << prog.execError() <<
")" << endl;
440 std::ostringstream sstr;
441 sstr << script_r <<
_(
" execution failed") <<
" (" << prog.execError() <<
")" << endl;
442 historylog.
comment(sstr.str(),
true);
454 bool executeScript(
const Pathname & root_r,
455 const Pathname & script_r,
456 callback::SendReport<PatchScriptReport> & report_r )
461 action = doExecuteScript( root_r, script_r, report_r );
465 switch ( action.second )
468 WAR <<
"User request to abort at script " << script_r << endl;
473 WAR <<
"User request to skip script " << script_r << endl;
483 INT <<
"Abort on unknown ACTION request " << action.second <<
" returned" << endl;
492 bool RunUpdateScripts(
const Pathname & root_r,
493 const Pathname & scriptsPath_r,
494 const std::vector<sat::Solvable> & checkPackages_r,
497 if ( checkPackages_r.empty() )
500 MIL <<
"Looking for new update scripts in (" << root_r <<
")" << scriptsPath_r << endl;
502 if ( ! PathInfo( scriptsDir ).isDir() )
505 std::list<std::string> scripts;
507 if ( scripts.empty() )
515 std::map<std::string, Pathname> unify;
516 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
518 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
519 for_( sit, scripts.begin(), scripts.end() )
524 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
527 PathInfo script( scriptsDir / *sit );
528 Pathname localPath( scriptsPath_r/(*sit) );
529 std::string unifytag;
531 if ( script.isFile() )
537 else if ( ! script.isExist() )
545 if ( unifytag.empty() )
549 if ( unify[unifytag].empty() )
551 unify[unifytag] = localPath;
558 std::string msg(
str::form(
_(
"%s already executed as %s)"), localPath.asString().c_str(), unify[unifytag].c_str() ) );
559 MIL <<
"Skip update script: " << msg << endl;
560 HistoryLog().comment( msg,
true );
564 if ( abort || aborting_r )
566 WAR <<
"Aborting: Skip update script " << *sit << endl;
567 HistoryLog().comment(
568 localPath.asString() +
_(
" execution skipped while aborting"),
573 MIL <<
"Found update script " << *sit << endl;
574 callback::SendReport<PatchScriptReport> report;
575 report->start( make<Package>( *it ), script.path() );
577 if ( ! executeScript( root_r, localPath, report ) )
589 inline void copyTo( std::ostream & out_r,
const Pathname & file_r )
591 std::ifstream infile( file_r.c_str() );
592 for( iostr::EachLine in( infile ); in; in.next() )
594 out_r << *in << endl;
598 inline std::string notificationCmdSubst(
const std::string & cmd_r,
const UpdateNotificationFile & notification_r )
600 std::string ret( cmd_r );
601 #define SUBST_IF(PAT,VAL) if ( ret.find( PAT ) != std::string::npos ) ret = str::gsub( ret, PAT, VAL ) 602 SUBST_IF(
"%p", notification_r.solvable().asString() );
603 SUBST_IF(
"%P", notification_r.file().asString() );
608 void sendNotification(
const Pathname & root_r,
611 if ( notifications_r.empty() )
615 MIL <<
"Notification command is '" << cmdspec <<
"'" << endl;
616 if ( cmdspec.empty() )
620 if ( pos == std::string::npos )
622 ERR <<
"Can't send Notification: Missing 'format |' in command spec." << endl;
623 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
628 std::string commandStr(
str::trim( cmdspec.substr( pos + 1 ) ) );
630 enum Format { UNKNOWN, NONE, SINGLE, DIGEST, BULK };
631 Format format = UNKNOWN;
632 if ( formatStr ==
"none" )
634 else if ( formatStr ==
"single" )
636 else if ( formatStr ==
"digest" )
638 else if ( formatStr ==
"bulk" )
642 ERR <<
"Can't send Notification: Unknown format '" << formatStr <<
" |' in command spec." << endl;
643 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
651 if ( format == NONE || format == SINGLE )
653 for_( it, notifications_r.begin(), notifications_r.end() )
655 std::vector<std::string> command;
656 if ( format == SINGLE )
658 str::splitEscaped( notificationCmdSubst( commandStr, *it ), std::back_inserter( command ) );
663 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
667 int ret = prog.close();
670 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
671 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
677 else if ( format == DIGEST || format == BULK )
679 filesystem::TmpFile tmpfile;
680 std::ofstream out( tmpfile.path().c_str() );
681 for_( it, notifications_r.begin(), notifications_r.end() )
683 if ( format == DIGEST )
685 out << it->file() << endl;
687 else if ( format == BULK )
693 std::vector<std::string> command;
694 command.push_back(
"<"+tmpfile.path().asString() );
695 str::splitEscaped( notificationCmdSubst( commandStr, *notifications_r.begin() ), std::back_inserter( command ) );
700 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
704 int ret = prog.close();
707 ERR <<
"Notification command returned with error (" << ret <<
")." << endl;
708 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
715 INT <<
"Can't send Notification: Missing handler for 'format |' in command spec." << endl;
716 HistoryLog().comment( str::Str() <<
_(
"Error sending update message notification."),
true );
727 void RunUpdateMessages(
const Pathname & root_r,
728 const Pathname & messagesPath_r,
729 const std::vector<sat::Solvable> & checkPackages_r,
730 ZYppCommitResult & result_r )
732 if ( checkPackages_r.empty() )
735 MIL <<
"Looking for new update messages in (" << root_r <<
")" << messagesPath_r << endl;
737 if ( ! PathInfo( messagesDir ).isDir() )
740 std::list<std::string> messages;
742 if ( messages.empty() )
748 HistoryLog historylog;
749 for_( it, checkPackages_r.begin(), checkPackages_r.end() )
751 std::string prefix(
str::form(
"%s-%s", it->name().c_str(), it->edition().c_str() ) );
752 for_( sit, messages.begin(), messages.end() )
757 if ( (*sit)[prefix.size()] !=
'\0' && (*sit)[prefix.size()] !=
'-' )
760 PathInfo message( messagesDir / *sit );
761 if ( ! message.isFile() || message.size() == 0 )
764 MIL <<
"Found update message " << *sit << endl;
765 Pathname localPath( messagesPath_r/(*sit) );
766 result_r.rUpdateMessages().push_back( UpdateNotificationFile( *it, localPath ) );
767 historylog.comment( str::Str() <<
_(
"New update message") <<
" " << localPath,
true );
770 sendNotification( root_r, result_r.updateMessages() );
776 void logPatchStatusChanges(
const sat::Transaction & transaction_r, TargetImpl & target_r )
779 if ( changedPseudoInstalled.empty() )
787 WAR <<
"Need to recompute the patch status changes as commit is incomplete!" << endl;
793 HistoryLog historylog;
794 for (
const auto & el : changedPseudoInstalled )
795 historylog.patchStateChange( el.first, el.second );
804 const std::vector<sat::Solvable> & checkPackages_r,
806 { RunUpdateMessages( root_r, messagesPath_r, checkPackages_r, result_r ); }
819 , _requestedLocalesFile( home() /
"RequestedLocales" )
820 , _autoInstalledFile( home() /
"AutoInstalled" )
829 sigMultiversionSpecChanged();
830 MIL <<
"Initialized target on " <<
_root << endl;
838 std::ifstream uuidprovider(
"/proc/sys/kernel/random/uuid" );
848 boost::function<
bool ()> condition,
849 boost::function<std::string ()> value )
851 std::string val = value();
859 MIL <<
"updating '" << filename <<
"' content." << endl;
863 std::ofstream filestr;
866 filestr.open( filename.
c_str() );
868 if ( filestr.good() )
904 WAR <<
"Can't create anonymous id file" << endl;
913 Pathname flavorpath(
home() /
"LastDistributionFlavor");
919 WAR <<
"No base product, I won't create flavor cache" << endl;
923 std::string flavor = p->flavor();
935 WAR <<
"Can't create flavor cache" << endl;
948 sigMultiversionSpecChanged();
949 MIL <<
"Targets closed" << endl;
973 Pathname rpmsolvcookie = base/
"cookie";
975 bool build_rpm_solv =
true;
985 MIL <<
"Read cookie: " << cookie << endl;
990 if ( status == rpmstatus )
991 build_rpm_solv =
false;
992 MIL <<
"Read cookie: " << rpmsolvcookie <<
" says: " 993 << (build_rpm_solv ?
"outdated" :
"uptodate") << endl;
997 if ( build_rpm_solv )
1011 bool switchingToTmpSolvfile =
false;
1012 Exception ex(
"Failed to cache rpm database.");
1018 rpmsolv = base/
"solv";
1019 rpmsolvcookie = base/
"cookie";
1026 WAR <<
"Using a temporary solv file at " << base << endl;
1027 switchingToTmpSolvfile =
true;
1036 if ( ! switchingToTmpSolvfile )
1046 cmd.push_back(
"rpmdb2solv" );
1048 cmd.push_back(
"-r" );
1051 cmd.push_back(
"-D" );
1053 cmd.push_back(
"-X" );
1055 cmd.push_back(
"-p" );
1058 if ( ! oldSolvFile.
empty() )
1059 cmd.push_back( oldSolvFile.
asString() );
1061 cmd.push_back(
"-o" );
1065 std::string errdetail;
1068 WAR <<
" " << output;
1069 if ( errdetail.empty() ) {
1073 errdetail += output;
1076 int ret = prog.
close();
1097 if (
root() ==
"/" )
1108 if ( !
PathInfo(base/
"solv.idx").isExist() )
1111 return build_rpm_solv;
1129 MIL <<
"New cache built: " << (newCache?
"true":
"false") <<
1130 ", force loading: " << (force?
"true":
"false") << endl;
1135 MIL <<
"adding " << rpmsolv <<
" to pool(" << satpool.
systemRepoAlias() <<
")" << endl;
1142 if ( newCache || force )
1159 MIL <<
"adding " << rpmsolv <<
" to system" << endl;
1165 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1190 if (
PathInfo( historyFile ).isExist() )
1197 if ( onSystemByUser.find( ident ) == onSystemByUser.end() )
1198 onSystemByAuto.insert( ident );
1220 if (
PathInfo( needrebootFile ).isFile() )
1221 needrebootSpec.
parseFrom( needrebootFile );
1224 if (
PathInfo( needrebootDir ).isDir() )
1229 [&](
const Pathname & dir_r,
const char *
const str_r )->
bool 1231 if ( ! isRpmConfigBackup( str_r ) )
1233 Pathname needrebootFile { needrebootDir / str_r };
1234 if (
PathInfo( needrebootFile ).isFile() )
1235 needrebootSpec.
parseFrom( needrebootFile );
1246 if ( ! hardLocks.empty() )
1255 MIL <<
"Target loaded: " << system.
solvablesSize() <<
" resolvables" << endl;
1267 bool explicitDryRun = policy_r.
dryRun();
1277 if (
root() ==
"/" )
1291 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
")" << endl;
1310 steps.push_back( *it );
1317 MIL <<
"Todo: " << result << endl;
1327 if ( commitPlugins )
1328 commitPlugins.
send( transactionPluginFrame(
"COMMITBEGIN", steps ) );
1335 if ( ! policy_r.
dryRun() )
1341 DBG <<
"dryRun: Not writing upgrade testcase." << endl;
1348 if ( ! policy_r.
dryRun() )
1370 DBG <<
"dryRun: Not storing non-package data." << endl;
1377 if ( ! policy_r.
dryRun() )
1379 for_( it, steps.begin(), steps.end() )
1381 if ( ! it->satSolvable().isKind<
Patch>() )
1389 if ( ! patch ||patch->message().empty() )
1392 MIL <<
"Show message for " << patch << endl;
1394 if ( ! report->show( patch ) )
1396 WAR <<
"commit aborted by the user" << endl;
1403 DBG <<
"dryRun: Not checking patch messages." << endl;
1425 for_( it, steps.begin(), steps.end() )
1427 switch ( it->stepType() )
1446 localfile = packageCache.
get( pi );
1449 catch (
const AbortRequestException & exp )
1453 WAR <<
"commit cache preload aborted by the user" << endl;
1457 catch (
const SkipRequestException & exp )
1462 WAR <<
"Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1472 INT <<
"Unexpected Error: Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1482 ERR <<
"Some packages could not be provided. Aborting commit."<< endl;
1486 if ( ! policy_r.
dryRun() )
1493 commit( policy_r, packageCache, result );
1498 DBG <<
"dryRun/downloadOnly: Not installing/deleting anything." << endl;
1499 if ( explicitDryRun ) {
1513 DBG <<
"dryRun: Not downloading/installing/deleting anything." << endl;
1514 if ( explicitDryRun ) {
1526 WAR <<
"(rpm removed in commit?) Inject missing /var/lib/rpm compat symlink to /usr/lib/sysimage/rpm" << endl;
1535 if ( commitPlugins )
1536 commitPlugins.
send( transactionPluginFrame(
"COMMITEND", steps ) );
1541 if ( ! policy_r.
dryRun() )
1546 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
") returns: " << result << endl;
1557 struct NotifyAttemptToModify
1575 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1580 NotifyAttemptToModify attemptToModify( result_r );
1585 AssertProcMounted assertProcMounted(
_root );
1588 std::vector<sat::Solvable> successfullyInstalledPackages;
1591 for_( step, steps.begin(), steps.end() )
1613 localfile = packageCache_r.
get( citem );
1615 catch (
const AbortRequestException &e )
1617 WAR <<
"commit aborted by the user" << endl;
1622 catch (
const SkipRequestException &e )
1625 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1634 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1643 bool success =
false;
1669 if ( progress.aborted() )
1671 WAR <<
"commit aborted by the user" << endl;
1680 auto rebootNeededFile =
root() /
"/run/reboot-needed";
1696 WAR <<
"dry run failed" << endl;
1701 if ( progress.aborted() )
1703 WAR <<
"commit aborted by the user" << endl;
1708 WAR <<
"Install failed" << endl;
1714 if ( success && !policy_r.
dryRun() )
1717 successfullyInstalledPackages.push_back( citem.
satSolvable() );
1726 bool success =
false;
1737 if ( progress.aborted() )
1739 WAR <<
"commit aborted by the user" << endl;
1753 if ( progress.aborted() )
1755 WAR <<
"commit aborted by the user" << endl;
1761 WAR <<
"removal of " << p <<
" failed";
1764 if ( success && !policy_r.
dryRun() )
1771 else if ( ! policy_r.
dryRun() )
1775 if ( ! citem.
buddy() )
1782 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
1788 std::string referenceFilename( p->referenceFilename() );
1789 if ( referenceFilename.empty() )
1791 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
1795 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
1796 if ( !
rpm().hasFile( referencePath.asString() ) )
1801 ERR <<
"Delete orphan product failed: " << referencePath << endl;
1805 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
1832 if ( ! successfullyInstalledPackages.empty() )
1835 successfullyInstalledPackages, abort ) )
1837 WAR <<
"Commit aborted by the user" << endl;
1843 successfullyInstalledPackages,
1850 logPatchStatusChanges( result_r.
transaction(), *this );
1869 void sendLogline(
const std::string & line_r, ReportType::loglevel level_r = ReportType::loglevel::msg )
1872 data.
set(
"line", std::cref(line_r) );
1873 data.set(
"level", level_r );
1879 auto u2rpmlevel = [](
unsigned rpmlevel_r ) -> ReportType::loglevel {
1880 switch ( rpmlevel_r ) {
1881 case RPMLOG_EMERG: [[fallthrough]];
1882 case RPMLOG_ALERT: [[fallthrough]];
1884 return ReportType::loglevel::crt;
1886 return ReportType::loglevel::err;
1887 case RPMLOG_WARNING:
1888 return ReportType::loglevel::war;
1889 default: [[fallthrough]];
1890 case RPMLOG_NOTICE: [[fallthrough]];
1892 return ReportType::loglevel::msg;
1894 return ReportType::loglevel::dbg;
1902 { (*this)->report( userData_r ); }
1915 namespace zpt = zypp::proto::target;
1921 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1926 NotifyAttemptToModify attemptToModify( result_r );
1932 AssertProcMounted assertProcMounted(
_root );
1947 commit.set_flags( flags );
1955 for (
auto &[
_, value] : data ) {
1957 value.resetDispose();
1964 auto &step = steps[stepId];
1981 locCache.value()[stepId] = packageCache_r.
get( citem );
1983 zpt::TransactionStep tStep;
1984 tStep.set_stepid( stepId );
1985 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
1986 tStep.mutable_install()->set_multiversion( p->multiversionInstall() );
1988 *
commit.mutable_steps()->Add( ) = std::move(tStep);
1990 catch (
const AbortRequestException &e )
1992 WAR <<
"commit aborted by the user" << endl;
1997 catch (
const SkipRequestException &e )
2000 WAR <<
"Skipping package " << p <<
" in commit" << endl;
2009 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
2015 zpt::TransactionStep tStep;
2016 tStep.set_stepid( stepId );
2017 tStep.mutable_remove()->set_name( p->name() );
2018 tStep.mutable_remove()->set_version( p->edition().version() );
2019 tStep.mutable_remove()->set_release( p->edition().release() );
2020 tStep.mutable_remove()->set_arch( p->arch().asString() );
2022 *
commit.mutable_steps()->Add() = std::move(tStep);
2033 zpt::TransactionStep tStep;
2034 tStep.set_stepid( stepId );
2035 tStep.mutable_install()->set_pathname( locCache.value()[stepId]->asString() );
2036 tStep.mutable_install()->set_multiversion(
false );
2037 *
commit.mutable_steps()->Add() = std::move(tStep);
2041 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
2048 std::vector<sat::Solvable> successfullyInstalledPackages;
2050 if (
commit.steps_size() ) {
2053 auto loop = zyppng::EventLoop::create();
2062 int currentStepId = -1;
2068 bool gotEndOfScript =
false;
2071 std::unique_ptr<callback::SendReport <rpm::TransactionReportSA>> transactionreport;
2072 std::unique_ptr<callback::SendReport <rpm::InstallResolvableReportSA>> installreport;
2073 std::unique_ptr<callback::SendReport <rpm::RemoveResolvableReportSA>> uninstallreport;
2074 std::unique_ptr<callback::SendReport <rpm::CommitScriptReportSA>> scriptreport;
2075 std::unique_ptr<callback::SendReport <rpm::CleanupPackageReportSA>> cleanupreport;
2078 std::optional<zpt::TransactionError> transactionError;
2081 std::string currentScriptType;
2082 std::string currentScriptPackage;
2092 unsigned lineno = 0;
2095 auto msgSource = zyppng::AsyncDataSource::create();
2096 auto scriptSource = zyppng::AsyncDataSource::create();
2101 const auto &sendRpmLineToReport = [&](
const std::string &line ){
2103 const auto &sendLogRep = [&](
auto &report,
const auto &cType ){
2105 if ( currentStepId >= 0 )
2106 cmdout.
set(
"solvable", steps.at(currentStepId).satSolvable() );
2107 cmdout.
set(
"line", line );
2111 if ( installreport ) {
2113 }
else if ( uninstallreport ) {
2115 }
else if ( scriptreport ) {
2117 }
else if ( transactionreport ) {
2119 }
else if ( cleanupreport ) {
2122 WAR <<
"Got rpm output without active report " << line;
2127 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2131 if ( line.back() !=
'\n' )
2137 const auto &processDataFromScriptFd = [&](){
2139 while ( scriptSource->canReadLine() ) {
2141 if ( gotEndOfScript )
2144 std::string l = scriptSource->readLine().asString();
2146 gotEndOfScript =
true;
2150 l = l.substr( 0, rawsize );
2152 L_DBG(
"zypp-rpm") <<
"[rpm> " << l;
2153 sendRpmLineToReport( l );
2156 scriptSource->sigReadyRead().connect( processDataFromScriptFd );
2159 const auto &waitForScriptEnd = [&]() {
2162 if ( gotEndOfScript )
2166 processDataFromScriptFd();
2169 while ( scriptSource->readFdOpen() && scriptSource->canRead() && !gotEndOfScript ) {
2172 scriptSource->waitForReadyRead( 100 );
2176 const auto &aboutToStartNewReport = [&](){
2178 if ( transactionreport || installreport || uninstallreport || scriptreport || cleanupreport ) {
2179 ERR <<
"There is still a running report, this is a bug" << std::endl;
2183 gotEndOfScript =
false;
2186 const auto &writeRpmMsgToHistory = [&](){
2187 if ( rpmmsg.size() == 0 )
2191 rpmmsg +=
"[truncated]\n";
2193 std::ostringstream sstr;
2194 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2199 const auto &finalizeCurrentReport = [&]() {
2202 if ( currentStepId >= 0 ) {
2203 step = &steps.at(currentStepId);
2207 if ( installreport ) {
2215 writeRpmMsgToHistory();
2219 ( *installreport)->progress( 100, resObj );
2222 if ( currentStepId >= 0 )
2223 locCache.value().erase( currentStepId );
2224 successfullyInstalledPackages.push_back( step->
satSolvable() );
2230 auto rebootNeededFile =
root() /
"/run/reboot-needed";
2242 writeRpmMsgToHistory();
2245 if ( uninstallreport ) {
2253 writeRpmMsgToHistory();
2257 ( *uninstallreport)->progress( 100, resObj );
2267 writeRpmMsgToHistory();
2270 if ( scriptreport ) {
2272 ( *scriptreport)->progress( 100, resObj );
2275 if ( transactionreport ) {
2277 ( *transactionreport)->progress( 100 );
2280 if ( cleanupreport ) {
2282 ( *cleanupreport)->progress( 100 );
2288 currentScriptType.clear();
2289 currentScriptPackage.clear();
2290 installreport.reset();
2291 uninstallreport.reset();
2292 scriptreport.reset();
2293 transactionreport.reset();
2294 cleanupreport.reset();
2304 constexpr std::string_view zyppRpmBinary(ZYPP_RPM_BINARY);
2306 const char *argv[] = {
2309 zyppRpmBinary.data(),
2312 auto prog = zyppng::Process::create();
2316 auto messagePipe = zyppng::Pipe::create();
2322 auto scriptPipe = zyppng::Pipe::create();
2326 prog->addFd( messagePipe->writeFd );
2327 prog->addFd( scriptPipe->writeFd );
2330 if ( !scriptSource->open( scriptPipe->readFd ) )
2333 prog->sigStarted().connect( [&](){
2336 messagePipe->unrefWrite();
2337 scriptPipe->unrefWrite();
2340 prog->stdoutDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2341 while( prog->stdoutDevice()->canReadLine() ) {
2342 L_DBG(
"zypp-rpm") <<
"<stdout> " << prog->stdoutDevice()->readLine().asStringView();
2347 prog->stderrDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2348 while( prog->stderrDevice()->canReadLine() ) {
2349 L_ERR(
"zypp-rpm") <<
"<stderr> " << prog->stderrDevice()->readLine().asStringView();
2355 const auto outFd = prog->stdinFd();
2362 zyppng::rpc::HeaderSizeType msgSize =
commit.ByteSizeLong();
2363 const auto written = zyppng::eintrSafeCall( ::
write, outFd, &msgSize,
sizeof(zyppng::rpc::HeaderSizeType) );
2364 if ( written !=
sizeof(zyppng::rpc::HeaderSizeType) ) {
2365 prog->stop( SIGKILL );
2369 zyppng::FileOutputStream fo ( outFd );
2370 if ( !
commit.SerializeToZeroCopyStream( &fo ) ) {
2371 prog->stop( SIGKILL );
2381 if ( !msgSource->open( messagePipe->readFd ) )
2384 zyppng::rpc::HeaderSizeType pendingMessageSize = 0;
2385 const auto &processMessages = [&] ( ) {
2389 const auto &parseMsgWithStepId = [&steps](
const auto &m,
auto &p ){
2390 if ( !p.ParseFromString( m.value() ) ) {
2391 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2395 auto id = p.stepid();
2396 if ( id < 0 || id >= steps.size() ) {
2397 ERR <<
"Received invalid stepId: " <<
id <<
" in " << m.messagetypename() <<
" message from zypp-rpm, ignoring." << std::endl;
2403 while ( msgSource->bytesAvailable() ) {
2405 if ( pendingMessageSize == 0 ) {
2406 if ( msgSource->bytesAvailable() >=
sizeof( zyppng::rpc::HeaderSizeType ) ) {
2407 msgSource->read( reinterpret_cast<char *>( &pendingMessageSize ),
sizeof( zyppng::rpc::HeaderSizeType ) );
2411 if ( msgSource->bytesAvailable() < pendingMessageSize ) {
2415 auto bytes = msgSource->read( pendingMessageSize );
2416 pendingMessageSize = 0;
2418 zypp::proto::Envelope m;
2419 if (! m.ParseFromArray( bytes.data(), bytes.size() ) ) {
2422 ERR <<
"Received misformed message from zypp-rpm, ignoring" << std::endl;
2430 const auto &mName = m.messagetypename();
2431 if ( mName ==
"zypp.proto.target.RpmLog" ) {
2434 if ( !p.ParseFromString( m.value() ) ) {
2435 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2438 ( p.level() >= RPMLOG_ERR ?
L_ERR(
"zypp-rpm")
2439 : p.level() >= RPMLOG_WARNING ?
L_WAR(
"zypp-rpm")
2440 :
L_DBG(
"zypp-rpm") ) <<
"[rpm " << p.level() <<
"> " << p.line();
2443 }
else if ( mName ==
"zypp.proto.target.PackageBegin" ) {
2444 finalizeCurrentReport();
2446 zpt::PackageBegin p;
2447 if ( !parseMsgWithStepId( m, p ) )
2450 aboutToStartNewReport();
2452 auto & step = steps.at( p.stepid() );
2453 currentStepId = p.stepid();
2455 uninstallreport = std::make_unique< callback::SendReport <rpm::RemoveResolvableReportSA> > ();
2456 ( *uninstallreport )->start(
makeResObject( step.satSolvable() ) );
2458 installreport = std::make_unique< callback::SendReport <rpm::InstallResolvableReportSA> > ();
2459 ( *installreport )->start(
makeResObject( step.satSolvable() ) );
2462 }
else if ( mName ==
"zypp.proto.target.PackageFinished" ) {
2463 zpt::PackageFinished p;
2464 if ( !parseMsgWithStepId( m, p ) )
2467 if ( p.stepid() < 0 || p.stepid() > steps.size() )
2474 }
else if ( mName ==
"zypp.proto.target.PackageProgress" ) {
2475 zpt::PackageProgress p;
2476 if ( !parseMsgWithStepId( m, p ) )
2479 if ( uninstallreport )
2480 (*uninstallreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2481 else if ( installreport )
2482 (*installreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2484 ERR <<
"Received a " << mName <<
" message but there is no corresponding report running." << std::endl;
2486 }
else if ( mName ==
"zypp.proto.target.PackageError" ) {
2487 zpt::PackageError p;
2488 if ( !parseMsgWithStepId( m, p ) )
2491 if ( p.stepid() >= 0 && p.stepid() < steps.size() )
2494 finalizeCurrentReport();
2496 }
else if ( mName ==
"zypp.proto.target.ScriptBegin" ) {
2497 finalizeCurrentReport();
2500 if ( !p.ParseFromString( m.value() ) ) {
2501 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2505 aboutToStartNewReport();
2508 const auto stepId = p.stepid();
2509 if ( stepId >= 0 && stepId < steps.size() ) {
2513 currentStepId = p.stepid();
2514 scriptreport = std::make_unique< callback::SendReport <rpm::CommitScriptReportSA> > ();
2515 currentScriptType = p.scripttype();
2516 currentScriptPackage = p.scriptpackage();
2517 (*scriptreport)->start( p.scripttype(), p.scriptpackage(), resPtr );
2519 }
else if ( mName ==
"zypp.proto.target.ScriptFinished" ) {
2523 }
else if ( mName ==
"zypp.proto.target.ScriptError" ) {
2526 if ( !p.ParseFromString( m.value() ) ) {
2527 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2532 const auto stepId = p.stepid();
2533 if ( stepId >= 0 && stepId < steps.size() ) {
2543 str::form(
"Failed to execute %s script for %s ", currentScriptType.c_str(), currentScriptPackage.size() ? currentScriptPackage.c_str() :
"unknown" ),
2546 writeRpmMsgToHistory();
2548 if ( !scriptreport ) {
2549 ERR <<
"Received a ScriptError message, but there is no running report. " << std::endl;
2558 scriptreport.reset();
2561 }
else if ( mName ==
"zypp.proto.target.CleanupBegin" ) {
2562 finalizeCurrentReport();
2564 zpt::CleanupBegin beg;
2565 if ( !beg.ParseFromString( m.value() ) ) {
2566 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2570 aboutToStartNewReport();
2571 cleanupreport = std::make_unique< callback::SendReport <rpm::CleanupPackageReportSA> > ();
2572 (*cleanupreport)->start( beg.nvra() );
2573 }
else if ( mName ==
"zypp.proto.target.CleanupFinished" ) {
2575 finalizeCurrentReport();
2577 }
else if ( mName ==
"zypp.proto.target.CleanupProgress" ) {
2578 zpt::CleanupProgress prog;
2579 if ( !prog.ParseFromString( m.value() ) ) {
2580 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2584 if ( !cleanupreport ) {
2585 ERR <<
"Received a CleanupProgress message, but there is no running report. " << std::endl;
2589 (*cleanupreport)->progress( prog.amount() );
2591 }
else if ( mName ==
"zypp.proto.target.TransBegin" ) {
2592 finalizeCurrentReport();
2594 zpt::TransBegin beg;
2595 if ( !beg.ParseFromString( m.value() ) ) {
2596 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2600 aboutToStartNewReport();
2601 transactionreport = std::make_unique< callback::SendReport <rpm::TransactionReportSA> > ();
2602 (*transactionreport)->start( beg.name() );
2603 }
else if ( mName ==
"zypp.proto.target.TransFinished" ) {
2605 finalizeCurrentReport();
2607 }
else if ( mName ==
"zypp.proto.target.TransProgress" ) {
2608 zpt::TransProgress prog;
2609 if ( !prog.ParseFromString( m.value() ) ) {
2610 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2614 if ( !transactionreport ) {
2615 ERR <<
"Received a TransactionProgress message, but there is no running report. " << std::endl;
2619 (*transactionreport)->progress( prog.amount() );
2620 }
else if ( mName ==
"zypp.proto.target.TransactionError" ) {
2622 zpt::TransactionError error;
2623 if ( !error.ParseFromString( m.value() ) ) {
2624 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2629 transactionError = std::move(error);
2632 ERR <<
"Received unexpected message from zypp-rpm: "<< m.messagetypename() <<
", ignoring" << std::endl;
2638 msgSource->connectFunc( &zyppng::AsyncDataSource::sigReadyRead, processMessages );
2641 int zyppRpmExitCode = -1;
2642 prog->connectFunc( &zyppng::Process::sigFinished, [&](
int code ){
2643 zyppRpmExitCode = code;
2647 if ( !prog->start( argv ) ) {
2658 finalizeCurrentReport();
2661 bool readMsgs =
false;
2662 while( prog->stderrDevice()->canReadLine() ) {
2664 MIL <<
"zypp-rpm: " << prog->stderrDevice()->readLine().asStringView();
2666 while( prog->stdoutDevice()->canReadLine() ) {
2668 MIL <<
"zypp-rpm: " << prog->stdoutDevice()->readLine().asStringView();
2671 while ( scriptSource->canReadLine() ) {
2673 MIL <<
"rpm-script-fd: " << scriptSource->readLine().asStringView();
2675 if ( scriptSource->bytesAvailable() > 0 ) {
2677 MIL <<
"rpm-script-fd: " << scriptSource->readAll().asStringView();
2682 switch ( zyppRpmExitCode ) {
2684 case zypprpm::NoError:
2685 case zypprpm::RpmFinishedWithError:
2687 case zypprpm::RpmFinishedWithTransactionError: {
2689 if ( transactionError ) {
2691 std::ostringstream sstr;
2692 sstr <<
_(
"Executing the transaction failed because of the following problems:") <<
"\n";
2693 for (
const auto & err : transactionError->problems() ) {
2694 sstr <<
" " << err.message() <<
"\n";
2704 case zypprpm::FailedToOpenDb:
2707 case zypprpm::WrongHeaderSize:
2708 case zypprpm::WrongMessageFormat:
2711 case zypprpm::RpmInitFailed:
2714 case zypprpm::FailedToReadPackage:
2717 case zypprpm::FailedToAddStepToTransaction:
2720 case zypprpm::RpmOrderFailed:
2726 auto &step = steps[stepId];
2738 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
2742 std::string referenceFilename( p->referenceFilename() );
2744 if ( referenceFilename.empty() ) {
2745 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
2747 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
2749 if ( !
rpm().hasFile( referencePath.asString() ) ) {
2753 ERR <<
"Delete orphan product failed: " << referencePath << endl;
2755 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
2769 if ( ! successfullyInstalledPackages.empty() )
2772 successfullyInstalledPackages, abort ) )
2774 WAR <<
"Commit aborted by the user" << endl;
2780 successfullyInstalledPackages,
2787 logPatchStatusChanges( result_r.
transaction(), *this );
2815 if ( baseproduct.isFile() )
2828 ERR <<
"baseproduct symlink is dangling or missing: " << baseproduct << endl;
2833 inline Pathname staticGuessRoot(
const Pathname & root_r )
2835 if ( root_r.empty() )
2840 return Pathname(
"/");
2846 inline std::string firstNonEmptyLineIn(
const Pathname & file_r )
2848 std::ifstream idfile( file_r.c_str() );
2849 for( iostr::EachLine in( idfile ); in; in.next() )
2852 if ( ! line.empty() )
2855 return std::string();
2866 if ( p->isTargetDistribution() )
2874 const Pathname needroot( staticGuessRoot(root_r) );
2875 const Target_constPtr target( getZYpp()->getTarget() );
2876 if ( target && target->root() == needroot )
2877 return target->requestedLocales();
2883 MIL <<
"updateAutoInstalled if changed..." << endl;
2891 {
return baseproductdata(
_root ).registerTarget(); }
2894 {
return baseproductdata( staticGuessRoot(root_r) ).registerTarget(); }
2897 {
return baseproductdata(
_root ).registerRelease(); }
2900 {
return baseproductdata( staticGuessRoot(root_r) ).registerRelease();}
2903 {
return baseproductdata(
_root ).registerFlavor(); }
2906 {
return baseproductdata( staticGuessRoot(root_r) ).registerFlavor();}
2939 std::string
distributionVersion = baseproductdata( staticGuessRoot(root_r) ).edition().version();
2946 scoped_ptr<rpm::RpmDb> tmprpmdb;
2952 tmprpmdb->initDatabase( );
2969 return firstNonEmptyLineIn(
home() /
"LastDistributionFlavor" );
2974 return firstNonEmptyLineIn( staticGuessRoot(root_r) /
"/var/lib/zypp/LastDistributionFlavor" );
2980 std::string guessAnonymousUniqueId(
const Pathname & root_r )
2983 std::string ret( firstNonEmptyLineIn( root_r /
"/var/lib/zypp/AnonymousUniqueId" ) );
2984 if ( ret.
empty() && root_r !=
"/" )
2987 ret = firstNonEmptyLineIn(
"/var/lib/zypp/AnonymousUniqueId" );
2995 return guessAnonymousUniqueId(
root() );
3000 return guessAnonymousUniqueId( staticGuessRoot(root_r) );
3007 MIL <<
"New VendorAttr: " << vendorAttr_r << endl;
std::string asString(const Patch::Category &obj)
static bool fileMissing(const Pathname &pathname)
helper functor
static const UserData::ContentType contentRpmout
"zypp-rpm/scriptsa": Additional rpm output (sent immediately).
std::string asJSON() const
JSON representation.
ZYppCommitResult commit(ResPool pool_r, const ZYppCommitPolicy &policy_r)
Commit changes in the pool.
VendorAttr _vendorAttr
vendor equivalence settings.
EstablishedStates::ChangedPseudoInstalled ChangedPseudoInstalled
Map holding pseudo installed items where current and established status differ.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Interface to the rpm program.
Convenience SendReport<rpm::SingleTransReport> wrapper.
sat::Transaction getTransaction()
Return the Transaction computed by the last solver run.
bool upgradingRepos() const
Whether there is at least one UpgradeRepo request pending.
A Solvable object within the sat Pool.
std::vector< sat::Transaction::Step > TransactionStepList
Save and restore locale set from file.
Alternating download and install.
zypp::ContentType ContentType
ZYppCommitPolicy & rpmNoSignature(bool yesNo_r)
Use rpm option –nosignature (default: false)
const LocaleSet & getRequestedLocales() const
Return the requested locales.
ManagedFile provideSrcPackage(const SrcPackage_constPtr &srcPackage_r) const
Provide SrcPackage in a local file.
int assert_file(const Pathname &path, unsigned mode)
Create an empty file if it does not yet exist.
[M] Install(multiversion) item (
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
bool solvfilesPathIsTemp() const
Whether we're using a temp.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Solvable satSolvable() const
Return the corresponding Solvable.
Result returned from ZYpp::commit.
void updateFileContent(const Pathname &filename, boost::function< bool()> condition, boost::function< std::string()> value)
updates the content of filename if condition is true, setting the content the the value returned by v...
static ZConfig & instance()
Singleton ctor.
First download all packages to the local cache.
bool isToBeInstalled() const
void addSolv(const Pathname &file_r)
Load Solvables from a solv-file.
std::string md5sum(const Pathname &file)
Compute a files md5sum.
Command frame for communication with PluginScript.
Pathname _tmpSolvfilesPath
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like 'readlink'.
void setData(const Data &data_r)
Store new Data.
IMPL_PTR_TYPE(TargetImpl)
SolvIdentFile _autoInstalledFile
user/auto installed database
detail::IdType value_type
static ProductFileData scanFile(const Pathname &file_r)
Parse one file (or symlink) and return the ProductFileData parsed.
String matching (STRING|SUBSTRING|GLOB|REGEX).
TargetImpl(const Pathname &root_r="/", bool doRebuild_r=false)
Ctor.
void stampCommand()
Log info about the current process.
Target::commit helper optimizing package provision.
bool isNeedreboot() const
ZYppCommitPolicy & rpmInstFlags(target::rpm::RpmInstFlags newFlags_r)
The default target::rpm::RpmInstFlags.
TransactionStepList & rTransactionStepList()
Manipulate transactionStepList.
const sat::Transaction & transaction() const
The full transaction list.
void discardScripts()
Discard all remembered scrips.
StepStage stepStage() const
Step action result.
const Pathname & file() const
Return the file path.
int chmod(const Pathname &path, mode_t mode)
Like 'chmod'.
int dirForEach(const Pathname &dir_r, const StrMatcher &matcher_r, function< bool(const Pathname &, const char *const)> fnc_r)
ResStatus & status() const
Returns the current status.
static const UserData::ContentType contentLogline
"zypp-rpm/logline" report a line suitable to be written to the screen.
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
ZYppCommitPolicy & dryRun(bool yesNo_r)
Set dry run (default: false).
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
byKind_iterator byKindBegin(const ResKind &kind_r) const
void updateAutoInstalled()
Update the database of autoinstalled packages.
ZYppCommitPolicy & rpmExcludeDocs(bool yesNo_r)
Use rpm option –excludedocs (default: false)
const char * c_str() const
String representation.
std::string _distributionVersion
Cache distributionVersion.
void commitFindFileConflicts(const ZYppCommitPolicy &policy_r, ZYppCommitResult &result_r)
Commit helper checking for file conflicts after download.
Parallel execution of stateful PluginScripts.
void setData(const Data &data_r)
Store new Data.
void setAutoInstalled(const Queue &autoInstalled_r)
Set ident list of all autoinstalled solvables.
sat::Solvable buddy() const
Return the buddy we share our status object with.
Access to the sat-pools string space.
Libsolv transaction wrapper.
Edition represents [epoch:]version[-release]
Attempts to create a lock to prevent the system from going into hibernate/shutdown.
std::string receiveLine()
Read one line from the input stream.
bool resetTransact(TransactByValue causer_r)
Not the same as setTransact( false ).
static const UserData::ContentType contentRpmout
"zypp-rpm/transactionsa": Additional rpm output (sent immediately).
Similar to DownloadInAdvance, but try to split the transaction into heaps, where at the end of each h...
bool providesFile(const std::string &path_str, const std::string &name_str) const
If the package is installed and provides the file Needed to evaluate split provides during Resolver::...
TraitsType::constPtrType constPtr
const_iterator end() const
Iterator behind the last TransactionStep.
Provide a new empty temporary file and delete it when no longer needed.
unsigned epoch_t
Type of an epoch.
void writeUpgradeTestcase()
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Class representing a patch.
void installSrcPackage(const SrcPackage_constPtr &srcPackage_r)
Install a source package on the Target.
std::string targetDistributionFlavor() const
This is register.flavor attribute of the installed base product.
void install(const PoolItem &pi)
Log installation (or update) of a package.
ResObject::constPtr resolvable() const
Returns the ResObject::constPtr.
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 its specs (one per line, #-comments).
RequestedLocalesFile _requestedLocalesFile
Requested Locales database.
void setLocales(const LocaleSet &locales_r)
Store a new locale set.
Pathname rootDir() const
Get rootdir (for file conflicts check)
void getHardLockQueries(HardLockQueries &activeLocks_r)
Suggest a new set of queries based on the current selection.
Pathname dirname() const
Return all but the last component od this path.
static Pathname assertprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r prefixed with root_r, unless it is already prefixed.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
ChangedPseudoInstalled changedPseudoInstalled() const
Return all pseudo installed items whose current state differs from the established one...
std::string release() const
Release.
Interim helper class to collect global options and settings.
Definition of vendor equivalence.
SolvableIterator solvablesBegin() const
Iterator to the first Solvable.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
void sendLoglineRpm(const std::string &line_r, unsigned rpmlevel_r)
Convenience to send a contentLogline translating a rpm loglevel.
std::string summary() const
bool order()
Order transaction steps for commit.
Pathname solvfilesPath() const
The solv file location actually in use (default or temp).
void updateSolvFileIndex(const Pathname &solvfile_r)
Create solv file content digest for zypper bash completion.
std::string targetDistribution() const
This is register.target attribute of the installed base product.
Resolver & resolver() const
The Resolver.
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
TraitsType::constPtrType constPtr
const VendorAttr & vendorAttr() const
The targets current vendor equivalence settings.
void initDatabase(Pathname root_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database below root_r.
int symlink(const Pathname &oldpath, const Pathname &newpath)
Like 'symlink'.
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
ZYppCommitPolicy & restrictToMedia(unsigned mediaNr_r)
Restrict commit to media 1.
std::list< PoolItem > PoolItemList
list of pool items
std::string anonymousUniqueId() const
anonymous unique id
static const UserData::ContentType contentRpmout
"zypp-rpm/installpkgsa": Additional rpm output (sent immediately).
static PoolImpl & myPool()
RepoStatus rpmDbRepoStatus(const Pathname &root_r)
const char * c_str() const
Conversion to const char *
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
std::string toLower(const std::string &s)
Return lowercase version of s.
Pathname home() const
The directory to store things.
int touch(const Pathname &path)
Change file's modification and access times.
void addProvides(Capability provides_r)
A all sat::Solvable matching this provides_r.
static std::string generateRandomId()
generates a random id using uuidgen
void resetDispose()
Set no dispose function.
ManagedFile get(const PoolItem &citem_r)
Provide a package.
HardLocksFile _hardLocksFile
Hard-Locks database.
static void setRoot(const Pathname &root)
Set new root directory to the default history log file path.
int close()
Wait for the progamm to complete.
byKind_iterator byKindEnd(const ResKind &kind_r) const
void setHardLockQueries(const HardLockQueries &newLocks_r)
Set a new set of queries.
void setSingleTransactionMode(bool yesno_r)
#define SUBST_IF(PAT, VAL)
std::list< UpdateNotificationFile > UpdateNotifications
Libsolv Id queue wrapper.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
TraitsType::constPtrType constPtr
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Product::constPtr baseProduct() const
returns the target base installed product, also known as the distribution or platform.
void createAnonymousId() const
generates the unique anonymous id which is called when creating the target
ZYppCommitPolicy & allMedia()
Process all media (default)
const_iterator begin() const
Iterator to the first TransactionStep.
pool::PoolTraits::HardLockQueries Data
#define NON_MOVABLE(CLASS)
Delete move ctor and move assign.
void add(const Value &val_r)
Push JSON Value to Array.
StepType stepType() const
Type of action to perform in this step.
const Data & data() const
Return the data.
Base class for Exception.
bool preloaded() const
Whether preloaded hint is set.
const std::string & command() const
The command we're executing.
void load(const Pathname &path_r)
Find and launch plugins sending PLUGINBEGIN.
Data returned by ProductFileReader.
static Date now()
Return the current time.
std::string asJSON() const
JSON representation.
void remove(const PoolItem &pi)
Log removal of a package.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
Typesafe passing of user data via callbacks.
epoch_t epoch() const
Epoch.
std::string distroverpkg() const
Package telling the "product version" on systems not using /etc/product.d/baseproduct.
Pathname root() const
The root set for this target.
void setNeedrebootSpec(sat::SolvableSpec needrebootSpec_r)
Solvables which should trigger the reboot-needed hint if installed/updated.
virtual ~TargetImpl()
Dtor.
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
void eraseFromPool()
Remove this Repository from its Pool.
bool hasFile(const std::string &file_r, const std::string &name_r="") const
Return true if at least one package owns a certain file (name_r empty) Return true if package name_r ...
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
#define NON_COPYABLE(CLASS)
Delete copy ctor and copy assign.
TraitsType::constPtrType constPtr
static const UserData::ContentType contentRpmout
"zypp-rpm/cleanupkgsa": Additional rpm output (sent immediately).
Wrapper class for ::stat/::lstat.
bool solvablesEmpty() const
Whether Repository contains solvables.
ResObject::Ptr makeResObject(const sat::Solvable &solvable_r)
Create ResObject from sat::Solvable.
sat::Transaction & rTransaction()
Manipulate transaction.
Combining sat::Solvable and ResStatus.
bool singleTransModeEnabled() const
Pathname systemRoot() const
The target root directory.
ManagedFile provideSrcPackage(const SrcPackage_constPtr &srcPackage_r)
Provides a source package on the Target.
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Target::DistributionLabel distributionLabel() const
This is shortName and summary attribute of the installed base product.
Track changing files or directories.
std::string asString() const
Conversion to std::string
bool isKind(const ResKind &kind_r) const
const std::string & asString() const
void XRunUpdateMessages(const Pathname &root_r, const Pathname &messagesPath_r, const std::vector< sat::Solvable > &checkPackages_r, ZYppCommitResult &result_r)
std::string distributionFlavor() const
This is flavor attribute of the installed base product but does not require the target to be loaded a...
static const UserData::ContentType contentRpmout
"zypp-rpm/removepkgsa": Additional rpm output (sent immediately).
size_type solvablesSize() const
Number of solvables in Repository.
void commitInSingleTransaction(const ZYppCommitPolicy &policy_r, CommitPackageCache &packageCache_r, ZYppCommitResult &result_r)
Commit ordered changes (internal helper)
Easy-to use interface to the ZYPP dependency resolver.
std::unordered_set< IdString > Data
Pathname defaultSolvfilesPath() const
The systems default solv file location.
Solvable satSolvable() const
Return the corresponding sat::Solvable.
void add(const String &key_r, const Value &val_r)
Add key/value pair.
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
void setCommitList(std::vector< sat::Solvable > commitList_r)
Download(commit) sequence of solvables to compute read ahead.
bool empty() const
Whether this is an empty object without valid data.
std::unordered_set< Locale > LocaleSet
void report(const callback::UserData &userData_r)
rpm::RpmDb & rpm()
The RPM database.
TraitsType::constPtrType constPtr
void multiversionSpecChanged()
BlockingMode setFDBlocking(int fd, bool mode)
#define MAXRPMMESSAGELINES
ZYppCommitResult & _result
Mime type like 'type/subtype' classification of content.
static ResPool instance()
Singleton ctor.
void sendLogline(const std::string &line_r, ReportType::loglevel level_r=ReportType::loglevel::msg)
Convenience to send a contentLogline.
void load(bool force=true)