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" )
828 sigMultiversionSpecChanged();
829 MIL <<
"Initialized target on " <<
_root << endl;
837 std::ifstream uuidprovider(
"/proc/sys/kernel/random/uuid" );
847 boost::function<
bool ()> condition,
848 boost::function<std::string ()> value )
850 std::string val = value();
858 MIL <<
"updating '" << filename <<
"' content." << endl;
862 std::ofstream filestr;
865 filestr.open( filename.
c_str() );
867 if ( filestr.good() )
903 WAR <<
"Can't create anonymous id file" << endl;
912 Pathname flavorpath(
home() /
"LastDistributionFlavor");
918 WAR <<
"No base product, I won't create flavor cache" << endl;
922 std::string flavor = p->flavor();
934 WAR <<
"Can't create flavor cache" << endl;
947 sigMultiversionSpecChanged();
948 MIL <<
"Targets closed" << endl;
972 Pathname rpmsolvcookie = base/
"cookie";
974 bool build_rpm_solv =
true;
984 MIL <<
"Read cookie: " << cookie << endl;
989 if ( status == rpmstatus )
990 build_rpm_solv =
false;
991 MIL <<
"Read cookie: " << rpmsolvcookie <<
" says: " 992 << (build_rpm_solv ?
"outdated" :
"uptodate") << endl;
996 if ( build_rpm_solv )
1010 bool switchingToTmpSolvfile =
false;
1011 Exception ex(
"Failed to cache rpm database.");
1017 rpmsolv = base/
"solv";
1018 rpmsolvcookie = base/
"cookie";
1025 WAR <<
"Using a temporary solv file at " << base << endl;
1026 switchingToTmpSolvfile =
true;
1035 if ( ! switchingToTmpSolvfile )
1045 cmd.push_back(
"rpmdb2solv" );
1047 cmd.push_back(
"-r" );
1050 cmd.push_back(
"-D" );
1052 cmd.push_back(
"-X" );
1054 cmd.push_back(
"-p" );
1057 if ( ! oldSolvFile.
empty() )
1058 cmd.push_back( oldSolvFile.
asString() );
1060 cmd.push_back(
"-o" );
1064 std::string errdetail;
1067 WAR <<
" " << output;
1068 if ( errdetail.empty() ) {
1072 errdetail += output;
1075 int ret = prog.
close();
1096 if (
root() ==
"/" )
1107 if ( !
PathInfo(base/
"solv.idx").isExist() )
1110 return build_rpm_solv;
1128 MIL <<
"New cache built: " << (newCache?
"true":
"false") <<
1129 ", force loading: " << (force?
"true":
"false") << endl;
1134 MIL <<
"adding " << rpmsolv <<
" to pool(" << satpool.
systemRepoAlias() <<
")" << endl;
1141 if ( newCache || force )
1158 MIL <<
"adding " << rpmsolv <<
" to system" << endl;
1164 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1189 if (
PathInfo( historyFile ).isExist() )
1196 if ( onSystemByUser.find( ident ) == onSystemByUser.end() )
1197 onSystemByAuto.insert( ident );
1219 if (
PathInfo( needrebootFile ).isFile() )
1220 needrebootSpec.
parseFrom( needrebootFile );
1223 if (
PathInfo( needrebootDir ).isDir() )
1228 [&](
const Pathname & dir_r,
const char *
const str_r )->
bool 1230 if ( ! isRpmConfigBackup( str_r ) )
1232 Pathname needrebootFile { needrebootDir / str_r };
1233 if (
PathInfo( needrebootFile ).isFile() )
1234 needrebootSpec.
parseFrom( needrebootFile );
1245 if ( ! hardLocks.empty() )
1254 MIL <<
"Target loaded: " << system.
solvablesSize() <<
" resolvables" << endl;
1266 bool explicitDryRun = policy_r.
dryRun();
1276 if (
root() ==
"/" )
1290 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
")" << endl;
1309 steps.push_back( *it );
1316 MIL <<
"Todo: " << result << endl;
1326 if ( commitPlugins )
1327 commitPlugins.
send( transactionPluginFrame(
"COMMITBEGIN", steps ) );
1334 if ( ! policy_r.
dryRun() )
1340 DBG <<
"dryRun: Not writing upgrade testcase." << endl;
1347 if ( ! policy_r.
dryRun() )
1369 DBG <<
"dryRun: Not stroring non-package data." << endl;
1376 if ( ! policy_r.
dryRun() )
1378 for_( it, steps.begin(), steps.end() )
1380 if ( ! it->satSolvable().isKind<
Patch>() )
1388 if ( ! patch ||patch->message().empty() )
1391 MIL <<
"Show message for " << patch << endl;
1393 if ( ! report->show( patch ) )
1395 WAR <<
"commit aborted by the user" << endl;
1402 DBG <<
"dryRun: Not checking patch messages." << endl;
1424 for_( it, steps.begin(), steps.end() )
1426 switch ( it->stepType() )
1445 localfile = packageCache.
get( pi );
1448 catch (
const AbortRequestException & exp )
1452 WAR <<
"commit cache preload aborted by the user" << endl;
1456 catch (
const SkipRequestException & exp )
1461 WAR <<
"Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1471 INT <<
"Unexpected Error: Skipping cache preload package " << pi->asKind<
Package>() <<
" in commit" << endl;
1481 ERR <<
"Some packages could not be provided. Aborting commit."<< endl;
1489 if ( ! policy_r.
dryRun() )
1493 commit( policy_r, packageCache, result );
1497 DBG <<
"dryRun/downloadOnly: Not installing/deleting anything." << endl;
1498 if ( explicitDryRun ) {
1508 DBG <<
"dryRun: Not downloading/installing/deleting anything." << endl;
1509 if ( explicitDryRun ) {
1521 WAR <<
"(rpm removed in commit?) Inject missing /var/lib/rpm compat symlink to /usr/lib/sysimage/rpm" << endl;
1530 if ( commitPlugins )
1531 commitPlugins.
send( transactionPluginFrame(
"COMMITEND", steps ) );
1536 if ( ! policy_r.
dryRun() )
1541 MIL <<
"TargetImpl::commit(<pool>, " << policy_r <<
") returns: " << result << endl;
1552 struct NotifyAttemptToModify
1570 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1575 NotifyAttemptToModify attemptToModify( result_r );
1580 AssertProcMounted assertProcMounted(
_root );
1583 std::vector<sat::Solvable> successfullyInstalledPackages;
1586 for_( step, steps.begin(), steps.end() )
1608 localfile = packageCache_r.
get( citem );
1610 catch (
const AbortRequestException &e )
1612 WAR <<
"commit aborted by the user" << endl;
1617 catch (
const SkipRequestException &e )
1620 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1629 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1638 bool success =
false;
1664 if ( progress.aborted() )
1666 WAR <<
"commit aborted by the user" << endl;
1675 auto rebootNeededFile =
root() /
"/run/reboot-needed";
1691 WAR <<
"dry run failed" << endl;
1696 if ( progress.aborted() )
1698 WAR <<
"commit aborted by the user" << endl;
1703 WAR <<
"Install failed" << endl;
1709 if ( success && !policy_r.
dryRun() )
1712 successfullyInstalledPackages.push_back( citem.
satSolvable() );
1721 bool success =
false;
1732 if ( progress.aborted() )
1734 WAR <<
"commit aborted by the user" << endl;
1748 if ( progress.aborted() )
1750 WAR <<
"commit aborted by the user" << endl;
1756 WAR <<
"removal of " << p <<
" failed";
1759 if ( success && !policy_r.
dryRun() )
1766 else if ( ! policy_r.
dryRun() )
1770 if ( ! citem.
buddy() )
1777 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
1783 std::string referenceFilename( p->referenceFilename() );
1784 if ( referenceFilename.empty() )
1786 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
1790 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
1791 if ( !
rpm().hasFile( referencePath.asString() ) )
1796 ERR <<
"Delete orphan product failed: " << referencePath << endl;
1800 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
1827 if ( ! successfullyInstalledPackages.empty() )
1830 successfullyInstalledPackages, abort ) )
1832 WAR <<
"Commit aborted by the user" << endl;
1838 successfullyInstalledPackages,
1845 logPatchStatusChanges( result_r.
transaction(), *this );
1862 namespace zpt = zypp::proto::target;
1865 MIL <<
"TargetImpl::commit(<list>" << policy_r <<
")" << steps.size() << endl;
1870 NotifyAttemptToModify attemptToModify( result_r );
1876 AssertProcMounted assertProcMounted(
_root );
1891 commit.set_flags( flags );
1898 std::vector<ManagedFile> locFiles;
1902 auto &step = steps[stepId];
1919 locFiles.push_back( packageCache_r.
get( citem ) );
1921 zpt::TransactionStep tStep;
1922 tStep.set_stepid( stepId );
1923 tStep.mutable_install()->set_pathname( locFiles.back()->asString() );
1924 tStep.mutable_install()->set_multiversion( p->multiversionInstall() );
1926 *
commit.mutable_steps()->Add( ) = std::move(tStep);
1928 catch (
const AbortRequestException &e )
1930 WAR <<
"commit aborted by the user" << endl;
1935 catch (
const SkipRequestException &e )
1938 WAR <<
"Skipping package " << p <<
" in commit" << endl;
1947 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1953 zpt::TransactionStep tStep;
1954 tStep.set_stepid( stepId );
1955 tStep.mutable_remove()->set_name( p->name() );
1956 tStep.mutable_remove()->set_version( p->edition().version() );
1957 tStep.mutable_remove()->set_release( p->edition().release() );
1958 tStep.mutable_remove()->set_arch( p->arch().asString() );
1960 *
commit.mutable_steps()->Add() = std::move(tStep);
1971 zpt::TransactionStep tStep;
1972 tStep.set_stepid( stepId );
1973 tStep.mutable_install()->set_pathname( locFiles.back()->asString() );
1974 tStep.mutable_install()->set_multiversion(
false );
1975 *
commit.mutable_steps()->Add() = std::move(tStep);
1979 INT <<
"Unexpected Error: Skipping package " << p <<
" in commit" << endl;
1986 std::vector<sat::Solvable> successfullyInstalledPackages;
1988 if (
commit.steps_size() ) {
1991 auto loop = zyppng::EventLoop::create();
2000 int currentStepId = -1;
2006 bool gotEndOfScript =
false;
2009 std::unique_ptr<callback::SendReport <rpm::TransactionReportSA>> transactionreport;
2010 std::unique_ptr<callback::SendReport <rpm::InstallResolvableReportSA>> installreport;
2011 std::unique_ptr<callback::SendReport <rpm::RemoveResolvableReportSA>> uninstallreport;
2012 std::unique_ptr<callback::SendReport <rpm::CommitScriptReportSA>> scriptreport;
2013 std::unique_ptr<callback::SendReport <rpm::CleanupPackageReportSA>> cleanupreport;
2016 std::optional<zpt::TransactionError> transactionError;
2019 std::string currentScriptType;
2020 std::string currentScriptPackage;
2030 unsigned lineno = 0;
2033 auto msgSource = zyppng::AsyncDataSource::create();
2034 auto scriptSource = zyppng::AsyncDataSource::create();
2039 const auto &sendRpmLineToReport = [&](
const std::string &line ){
2041 const auto &sendLogRep = [&](
auto &report,
const auto &cType ){
2043 if ( currentStepId >= 0 )
2044 cmdout.
set(
"solvable", steps.at(currentStepId).satSolvable() );
2045 cmdout.
set(
"line", line );
2046 report->report(cmdout);
2049 if ( installreport ) {
2051 }
else if ( uninstallreport ) {
2053 }
else if ( scriptreport ) {
2055 }
else if ( transactionreport ) {
2057 }
else if ( cleanupreport ) {
2060 WAR <<
"Got rpm output without active report " << line << std::endl;
2065 if ( line.find(
" scriptlet failed, " ) == std::string::npos )
2069 if ( line.back() !=
'\n' )
2075 const auto &processDataFromScriptFd = [&](){
2077 while ( scriptSource->canReadLine() ) {
2079 if ( gotEndOfScript )
2082 std::string l = scriptSource->readLine().asString();
2084 DBG <<
"Received end of script tag" << std::endl;
2085 gotEndOfScript =
true;
2086 l = l.substr( 0, l.size() - endOfScriptTag.size() );
2087 if ( l.size() == 0 )
2091 sendRpmLineToReport( l );
2094 scriptSource->sigReadyRead().connect( processDataFromScriptFd );
2097 const auto &waitForScriptEnd = [&]() {
2100 if ( gotEndOfScript )
2104 processDataFromScriptFd();
2107 while ( scriptSource->canRead() && !gotEndOfScript ) {
2110 scriptSource->waitForReadyRead( 100 );
2114 const auto &aboutToStartNewReport = [&](){
2116 if ( transactionreport || installreport || uninstallreport || scriptreport || cleanupreport ) {
2117 ERR <<
"There is still a running report, this is a bug" << std::endl;
2121 DBG <<
"Starting new report, setting gotEndOfScript to false" << std::endl;
2122 gotEndOfScript =
false;
2125 const auto &writeRpmMsgToHistory = [&](){
2126 if ( rpmmsg.size() == 0 )
2130 rpmmsg +=
"[truncated]\n";
2132 std::ostringstream sstr;
2133 sstr <<
"rpm output:" << endl << rpmmsg << endl;
2138 const auto &finalizeCurrentReport = [&]() {
2141 if ( currentStepId >= 0 ) {
2142 step = &steps.at(currentStepId);
2146 if ( installreport ) {
2154 writeRpmMsgToHistory();
2158 ( *installreport)->progress( 100, resObj );
2161 successfullyInstalledPackages.push_back( step->
satSolvable() );
2167 auto rebootNeededFile =
root() /
"/run/reboot-needed";
2179 writeRpmMsgToHistory();
2182 if ( uninstallreport ) {
2190 writeRpmMsgToHistory();
2194 ( *uninstallreport)->progress( 100, resObj );
2204 writeRpmMsgToHistory();
2207 if ( scriptreport ) {
2209 ( *scriptreport)->progress( 100, resObj );
2212 if ( transactionreport ) {
2214 ( *transactionreport)->progress( 100 );
2217 if ( cleanupreport ) {
2219 ( *cleanupreport)->progress( 100 );
2222 DBG <<
"Report finalized" << std::endl;
2226 currentScriptType.clear();
2227 currentScriptPackage.clear();
2228 installreport.reset();
2229 uninstallreport.reset();
2230 scriptreport.reset();
2231 transactionreport.reset();
2232 cleanupreport.reset();
2242 constexpr std::string_view zyppRpmBinary(ZYPP_RPM_BINARY);
2244 const char *argv[] = {
2247 zyppRpmBinary.data(),
2250 auto prog = zyppng::Process::create();
2254 auto messagePipe = zyppng::Pipe::create();
2260 auto scriptPipe = zyppng::Pipe::create();
2264 prog->addFd( messagePipe->writeFd );
2265 prog->addFd( scriptPipe->writeFd );
2268 if ( !scriptSource->open( scriptPipe->readFd ) )
2271 prog->sigStarted().connect( [&](){
2274 messagePipe->unrefWrite();
2275 scriptPipe->unrefWrite();
2278 prog->stdoutDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2279 while( prog->stdoutDevice()->canReadLine() ) {
2280 MIL <<
"zypp-rpm stdout: " << prog->stdoutDevice()->readLine().asStringView() << std::endl;
2285 prog->stderrDevice()->connectFunc( &zyppng::IODevice::sigReadyRead, [&](){
2286 while( prog->stderrDevice()->canReadLine() ) {
2287 MIL <<
"zypp-rpm stderr: " << prog->stderrDevice()->readLine().asStringView() << std::endl;
2293 const auto outFd = prog->stdinFd();
2300 zyppng::rpc::HeaderSizeType msgSize =
commit.ByteSizeLong();
2301 const auto written = zyppng::eintrSafeCall( ::
write, outFd, &msgSize,
sizeof(zyppng::rpc::HeaderSizeType) );
2302 if ( written !=
sizeof(zyppng::rpc::HeaderSizeType) ) {
2303 prog->stop( SIGKILL );
2307 zyppng::FileOutputStream fo ( outFd );
2308 if ( !
commit.SerializeToZeroCopyStream( &fo ) ) {
2309 prog->stop( SIGKILL );
2319 if ( !msgSource->open( messagePipe->readFd ) )
2322 size_t pendingMessageSize = 0;
2323 const auto &processMessages = [&] ( ) {
2327 const auto &parseMsgWithStepId = [&steps](
const auto &m,
auto &p ){
2328 if ( !p.ParseFromString( m.value() ) ) {
2329 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2333 auto id = p.stepid();
2334 if ( id < 0 || id >= steps.size() ) {
2335 ERR <<
"Received invalid stepId: " <<
id <<
" in " << m.messagetypename() <<
" message from zypp-rpm, ignoring." << std::endl;
2341 while ( msgSource->bytesAvailable() ) {
2343 if ( pendingMessageSize == 0 ) {
2344 if ( msgSource->bytesAvailable() >=
sizeof( zyppng::rpc::HeaderSizeType ) ) {
2345 msgSource->read( reinterpret_cast<char *>( &pendingMessageSize ),
sizeof( zyppng::rpc::HeaderSizeType ) );
2349 if ( msgSource->bytesAvailable() < pendingMessageSize ) {
2353 auto bytes = msgSource->read( pendingMessageSize );
2354 pendingMessageSize = 0;
2356 zypp::proto::Envelope m;
2357 if (! m.ParseFromArray( bytes.data(), bytes.size() ) ) {
2360 ERR <<
"Received misformed message from zypp-rpm, ignoring" << std::endl;
2368 const auto &mName = m.messagetypename();
2369 if ( mName ==
"zypp.proto.target.RpmLog" ) {
2372 if ( !p.ParseFromString( m.value() ) ) {
2373 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2377 sendRpmLineToReport( p.line() );
2380 }
else if ( mName ==
"zypp.proto.target.PackageBegin" ) {
2381 finalizeCurrentReport();
2383 zpt::PackageBegin p;
2384 if ( !parseMsgWithStepId( m, p ) )
2387 aboutToStartNewReport();
2389 auto & step = steps.at( p.stepid() );
2390 currentStepId = p.stepid();
2392 uninstallreport = std::make_unique< callback::SendReport <rpm::RemoveResolvableReportSA> > ();
2393 ( *uninstallreport )->start(
makeResObject( step.satSolvable() ) );
2395 installreport = std::make_unique< callback::SendReport <rpm::InstallResolvableReportSA> > ();
2396 ( *installreport )->start(
makeResObject( step.satSolvable() ) );
2399 }
else if ( mName ==
"zypp.proto.target.PackageFinished" ) {
2400 zpt::PackageFinished p;
2401 if ( !parseMsgWithStepId( m, p ) )
2404 if ( p.stepid() < 0 || p.stepid() > steps.size() )
2411 }
else if ( mName ==
"zypp.proto.target.PackageProgress" ) {
2412 zpt::PackageProgress p;
2413 if ( !parseMsgWithStepId( m, p ) )
2416 if ( uninstallreport )
2417 (*uninstallreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2418 else if ( installreport )
2419 (*installreport)->progress( p.amount(),
makeResObject( steps.at( p.stepid() ) ));
2421 ERR <<
"Received a " << mName <<
" message but there is no corresponding report running." << std::endl;
2423 }
else if ( mName ==
"zypp.proto.target.PackageError" ) {
2424 zpt::PackageError p;
2425 if ( !parseMsgWithStepId( m, p ) )
2428 if ( p.stepid() >= 0 && p.stepid() < steps.size() )
2431 finalizeCurrentReport();
2433 }
else if ( mName ==
"zypp.proto.target.ScriptBegin" ) {
2434 finalizeCurrentReport();
2437 if ( !p.ParseFromString( m.value() ) ) {
2438 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2442 aboutToStartNewReport();
2445 const auto stepId = p.stepid();
2446 if ( stepId >= 0 && stepId < steps.size() ) {
2450 currentStepId = p.stepid();
2451 scriptreport = std::make_unique< callback::SendReport <rpm::CommitScriptReportSA> > ();
2452 currentScriptType = p.scripttype();
2453 currentScriptPackage = p.scriptpackage();
2454 (*scriptreport)->start( p.scripttype(), p.scriptpackage(), resPtr );
2456 }
else if ( mName ==
"zypp.proto.target.ScriptFinished" ) {
2459 MIL <<
"Received" << mName <<
" from zypp-rpm" << std::endl;
2461 }
else if ( mName ==
"zypp.proto.target.ScriptError" ) {
2464 if ( !p.ParseFromString( m.value() ) ) {
2465 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2470 const auto stepId = p.stepid();
2471 if ( stepId >= 0 && stepId < steps.size() ) {
2481 str::form(
"Failed to execute %s script for %s ", currentScriptType.c_str(), currentScriptPackage.size() ? currentScriptPackage.c_str() :
"unknown" ),
2484 writeRpmMsgToHistory();
2486 if ( !scriptreport ) {
2487 ERR <<
"Received a ScriptError message, but there is no running report. " << std::endl;
2496 scriptreport.reset();
2499 }
else if ( mName ==
"zypp.proto.target.CleanupBegin" ) {
2500 finalizeCurrentReport();
2502 zpt::CleanupBegin beg;
2503 if ( !beg.ParseFromString( m.value() ) ) {
2504 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2508 aboutToStartNewReport();
2509 cleanupreport = std::make_unique< callback::SendReport <rpm::CleanupPackageReportSA> > ();
2510 (*cleanupreport)->start( beg.nvra() );
2511 }
else if ( mName ==
"zypp.proto.target.CleanupFinished" ) {
2513 finalizeCurrentReport();
2515 }
else if ( mName ==
"zypp.proto.target.CleanupProgress" ) {
2516 zpt::CleanupProgress prog;
2517 if ( !prog.ParseFromString( m.value() ) ) {
2518 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2522 if ( !cleanupreport ) {
2523 ERR <<
"Received a CleanupProgress message, but there is no running report. " << std::endl;
2527 (*cleanupreport)->progress( prog.amount() );
2529 }
else if ( mName ==
"zypp.proto.target.TransBegin" ) {
2530 finalizeCurrentReport();
2532 zpt::TransBegin beg;
2533 if ( !beg.ParseFromString( m.value() ) ) {
2534 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2538 aboutToStartNewReport();
2539 transactionreport = std::make_unique< callback::SendReport <rpm::TransactionReportSA> > ();
2540 (*transactionreport)->start( beg.name() );
2541 }
else if ( mName ==
"zypp.proto.target.TransFinished" ) {
2543 finalizeCurrentReport();
2545 }
else if ( mName ==
"zypp.proto.target.TransProgress" ) {
2546 zpt::TransProgress prog;
2547 if ( !prog.ParseFromString( m.value() ) ) {
2548 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2552 if ( !transactionreport ) {
2553 ERR <<
"Received a TransactionProgress message, but there is no running report. " << std::endl;
2557 (*transactionreport)->progress( prog.amount() );
2558 }
else if ( mName ==
"zypp.proto.target.TransactionError" ) {
2560 zpt::TransactionError error;
2561 if ( !error.ParseFromString( m.value() ) ) {
2562 ERR <<
"Failed to parse " << m.messagetypename() <<
" message from zypp-rpm." << std::endl;
2567 transactionError = std::move(error);
2570 ERR <<
"Received unexpected message from zypp-rpm: "<< m.messagetypename() <<
", ignoring" << std::endl;
2576 msgSource->connectFunc( &zyppng::AsyncDataSource::sigReadyRead, processMessages );
2579 int zyppRpmExitCode = -1;
2580 prog->connectFunc( &zyppng::Process::sigFinished, [&](
int code ){
2581 zyppRpmExitCode = code;
2585 if ( !prog->start( argv ) ) {
2596 finalizeCurrentReport();
2599 bool readMsgs =
false;
2600 while( prog->stderrDevice()->canReadLine() ) {
2602 MIL <<
"zypp-rpm: " << prog->stderrDevice()->readLine().asStringView();
2604 while( prog->stdoutDevice()->canReadLine() ) {
2606 MIL <<
"zypp-rpm: " << prog->stdoutDevice()->readLine().asStringView();
2609 while ( scriptSource->canReadLine() ) {
2611 MIL <<
"rpm-script-fd: " << scriptSource->readLine().asStringView();
2613 if ( scriptSource->bytesAvailable() > 0 ) {
2615 MIL <<
"rpm-script-fd: " << scriptSource->readAll().asStringView();
2620 switch ( zyppRpmExitCode ) {
2622 case zypprpm::NoError:
2623 case zypprpm::RpmFinishedWithError:
2625 case zypprpm::RpmFinishedWithTransactionError: {
2627 if ( transactionError ) {
2629 std::ostringstream sstr;
2630 sstr <<
_(
"Executing the transaction failed because of the following problems:") <<
"\n";
2631 for (
const auto & err : transactionError->problems() ) {
2632 sstr <<
" " << err.message() <<
"\n";
2642 case zypprpm::FailedToOpenDb:
2645 case zypprpm::WrongHeaderSize:
2646 case zypprpm::WrongMessageFormat:
2649 case zypprpm::RpmInitFailed:
2652 case zypprpm::FailedToReadPackage:
2655 case zypprpm::FailedToAddStepToTransaction:
2658 case zypprpm::RpmOrderFailed:
2664 auto &step = steps[stepId];
2676 ERR <<
"Can't install orphan product without release-package! " << citem << endl;
2680 std::string referenceFilename( p->referenceFilename() );
2682 if ( referenceFilename.empty() ) {
2683 ERR <<
"Can't remove orphan product without 'referenceFilename'! " << citem << endl;
2685 Pathname referencePath {
Pathname(
"/etc/products.d") / referenceFilename };
2687 if ( !
rpm().hasFile( referencePath.asString() ) ) {
2691 ERR <<
"Delete orphan product failed: " << referencePath << endl;
2693 WAR <<
"Won't remove orphan product: '/etc/products.d/" << referenceFilename <<
"' is owned by a package." << endl;
2707 if ( ! successfullyInstalledPackages.empty() )
2710 successfullyInstalledPackages, abort ) )
2712 WAR <<
"Commit aborted by the user" << endl;
2718 successfullyInstalledPackages,
2725 logPatchStatusChanges( result_r.
transaction(), *this );
2753 if ( baseproduct.isFile() )
2766 ERR <<
"baseproduct symlink is dangling or missing: " << baseproduct << endl;
2771 inline Pathname staticGuessRoot(
const Pathname & root_r )
2773 if ( root_r.empty() )
2778 return Pathname(
"/");
2784 inline std::string firstNonEmptyLineIn(
const Pathname & file_r )
2786 std::ifstream idfile( file_r.c_str() );
2787 for( iostr::EachLine in( idfile ); in; in.next() )
2790 if ( ! line.empty() )
2793 return std::string();
2804 if ( p->isTargetDistribution() )
2812 const Pathname needroot( staticGuessRoot(root_r) );
2813 const Target_constPtr target( getZYpp()->getTarget() );
2814 if ( target && target->root() == needroot )
2815 return target->requestedLocales();
2821 MIL <<
"updateAutoInstalled if changed..." << endl;
2829 {
return baseproductdata(
_root ).registerTarget(); }
2832 {
return baseproductdata( staticGuessRoot(root_r) ).registerTarget(); }
2835 {
return baseproductdata(
_root ).registerRelease(); }
2838 {
return baseproductdata( staticGuessRoot(root_r) ).registerRelease();}
2841 {
return baseproductdata(
_root ).registerFlavor(); }
2844 {
return baseproductdata( staticGuessRoot(root_r) ).registerFlavor();}
2877 std::string
distributionVersion = baseproductdata( staticGuessRoot(root_r) ).edition().version();
2884 scoped_ptr<rpm::RpmDb> tmprpmdb;
2890 tmprpmdb->initDatabase( );
2907 return firstNonEmptyLineIn(
home() /
"LastDistributionFlavor" );
2912 return firstNonEmptyLineIn( staticGuessRoot(root_r) /
"/var/lib/zypp/LastDistributionFlavor" );
2918 std::string guessAnonymousUniqueId(
const Pathname & root_r )
2921 std::string ret( firstNonEmptyLineIn( root_r /
"/var/lib/zypp/AnonymousUniqueId" ) );
2922 if ( ret.
empty() && root_r !=
"/" )
2925 ret = firstNonEmptyLineIn(
"/var/lib/zypp/AnonymousUniqueId" );
2933 return guessAnonymousUniqueId(
root() );
2938 return guessAnonymousUniqueId( staticGuessRoot(root_r) );
2945 MIL <<
"New VendorAttr: " << vendorAttr_r << endl;
static bool fileMissing(const Pathname &pathname)
helper functor
static const UserData::ContentType contentRpmout
"zypp-rpm/scriptsa": Additional rpm output (sent immediately).
std::string asJSON() const
JSON representation.
ZYppCommitResult commit(ResPool pool_r, const ZYppCommitPolicy &policy_r)
Commit changes in the pool.
VendorAttr _vendorAttr
vendor equivalence settings.
EstablishedStates::ChangedPseudoInstalled ChangedPseudoInstalled
Map holding pseudo installed items where current and established status differ.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Interface to the rpm program.
sat::Transaction getTransaction()
Return the Transaction computed by the last solver run.
bool upgradingRepos() const
Whether there is at least one UpgradeRepo request pending.
A Solvable object within the sat Pool.
std::vector< sat::Transaction::Step > TransactionStepList
Save and restore locale set from file.
Alternating download and install.
ZYppCommitPolicy & rpmNoSignature(bool yesNo_r)
Use rpm option –nosignature (default: false)
const LocaleSet & getRequestedLocales() const
Return the requested locales.
ManagedFile provideSrcPackage(const SrcPackage_constPtr &srcPackage_r) const
Provide SrcPackage in a local file.
int assert_file(const Pathname &path, unsigned mode)
Create an empty file if it does not yet exist.
[M] Install(multiversion) item (
unsigned splitEscaped(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, bool withEmpty=false)
Split line_r into words with respect to escape delimeters.
bool solvfilesPathIsTemp() const
Whether we're using a temp.
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Solvable satSolvable() const
Return the corresponding Solvable.
Result returned from ZYpp::commit.
void updateFileContent(const Pathname &filename, boost::function< bool()> condition, boost::function< std::string()> value)
updates the content of filename if condition is true, setting the content the the value returned by v...
static ZConfig & instance()
Singleton ctor.
First download all packages to the local cache.
bool isToBeInstalled() const
void addSolv(const Pathname &file_r)
Load Solvables from a solv-file.
std::string md5sum(const Pathname &file)
Compute a files md5sum.
Command frame for communication with PluginScript.
Pathname _tmpSolvfilesPath
bool findByProvides(const std::string &tag_r)
Reset to iterate all packages that provide a certain tag.
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like 'readlink'.
void setData(const Data &data_r)
Store new Data.
IMPL_PTR_TYPE(TargetImpl)
SolvIdentFile _autoInstalledFile
user/auto installed database
detail::IdType value_type
static ProductFileData scanFile(const Pathname &file_r)
Parse one file (or symlink) and return the ProductFileData parsed.
String matching (STRING|SUBSTRING|GLOB|REGEX).
TargetImpl(const Pathname &root_r="/", bool doRebuild_r=false)
Ctor.
void stampCommand()
Log info about the current process.
Target::commit helper optimizing package provision.
bool isNeedreboot() const
ZYppCommitPolicy & rpmInstFlags(target::rpm::RpmInstFlags newFlags_r)
The default target::rpm::RpmInstFlags.
TransactionStepList & rTransactionStepList()
Manipulate transactionStepList.
const sat::Transaction & transaction() const
The full transaction list.
void discardScripts()
Discard all remembered scrips.
StepStage stepStage() const
Step action result.
const Pathname & file() const
Return the file path.
int chmod(const Pathname &path, mode_t mode)
Like 'chmod'.
int dirForEach(const Pathname &dir_r, const StrMatcher &matcher_r, function< bool(const Pathname &, const char *const)> fnc_r)
ResStatus & status() const
Returns the current status.
void installPackage(const Pathname &filename, RpmInstFlags flags=RPMINST_NONE)
install rpm package
ZYppCommitPolicy & dryRun(bool yesNo_r)
Set dry run (default: false).
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
byKind_iterator byKindBegin(const ResKind &kind_r) const
void updateAutoInstalled()
Update the database of autoinstalled packages.
ZYppCommitPolicy & rpmExcludeDocs(bool yesNo_r)
Use rpm option –excludedocs (default: false)
const char * c_str() const
String representation.
std::string _distributionVersion
Cache distributionVersion.
void commitFindFileConflicts(const ZYppCommitPolicy &policy_r, ZYppCommitResult &result_r)
Commit helper checking for file conflicts after download.
Parallel execution of stateful PluginScripts.
void setData(const Data &data_r)
Store new Data.
void setAutoInstalled(const Queue &autoInstalled_r)
Set ident list of all autoinstalled solvables.
sat::Solvable buddy() const
Return the buddy we share our status object with.
Access to the sat-pools string space.
Libsolv transaction wrapper.
Edition represents [epoch:]version[-release]
Attempts to create a lock to prevent the system from going into hibernate/shutdown.
std::string receiveLine()
Read one line from the input stream.
bool resetTransact(TransactByValue causer_r)
Not the same as setTransact( false ).
static const UserData::ContentType contentRpmout
"zypp-rpm/transactionsa": Additional rpm output (sent immediately).
Similar to DownloadInAdvance, but try to split the transaction into heaps, where at the end of each h...
bool providesFile(const std::string &path_str, const std::string &name_str) const
If the package is installed and provides the file Needed to evaluate split provides during Resolver::...
TraitsType::constPtrType constPtr
const_iterator end() const
Iterator behind the last TransactionStep.
Provide a new empty temporary file and delete it when no longer needed.
unsigned epoch_t
Type of an epoch.
void writeUpgradeTestcase()
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Class representing a patch.
void installSrcPackage(const SrcPackage_constPtr &srcPackage_r)
Install a source package on the Target.
std::string targetDistributionFlavor() const
This is register.flavor attribute of the installed base product.
void install(const PoolItem &pi)
Log installation (or update) of a package.
ResObject::constPtr resolvable() const
Returns the ResObject::constPtr.
void addIdent(IdString ident_r)
Add all sat::Solvable with this ident_r.
ChangedPseudoInstalled changedPseudoInstalled() const
Return all pseudo installed items whose current state differs from their initial one.
std::vector< std::string > Arguments
std::string targetDistributionRelease() const
This is register.release attribute of the installed base product.
Define a set of Solvables by ident and provides.
Extract and remember posttrans scripts for later execution.
Subclass to retrieve database content.
void remember(const Exception &old_r)
Store an other Exception as history.
EstablishedStates establishedStates() const
Factory for EstablishedStates.
bool write(const Pathname &path_r, const std::string &key_r, const std::string &val_r, const std::string &newcomment_r)
Add or change a value in sysconfig file path_r.
rpm::RpmDb _rpm
RPM database.
Repository systemRepo()
Return the system repository, create it if missing.
std::string distributionVersion() const
This is version attribute of the installed base product.
const LocaleSet & locales() const
Return the loacale set.
void createLastDistributionFlavorCache() const
generates a cache of the last product flavor
void initRequestedLocales(const LocaleSet &locales_r)
Start tracking changes based on this locales_r.
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
StringQueue autoInstalled() const
Return the ident strings of all packages that would be auto-installed after the transaction is run...
LocaleSet requestedLocales() const
Languages to be supported by the system.
[ ] Nothing (includes implicit deletes due to obsoletes and non-package actions)
bool empty() const
Test for an empty path.
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
void push(value_type val_r)
Push a value to the end off the Queue.
std::string getline(std::istream &str)
Read one line from stream.
const StrMatcher & matchNoDots()
Convenience returning StrMatcher( "[^.]*", Match::GLOB )
Store and operate on date (time_t).
SolvableIterator solvablesEnd() const
Iterator behind the last Solvable.
std::string shortName() const
static Pool instance()
Singleton ctor.
const Data & data() const
Return the data.
std::string version() const
Version.
Pathname _root
Path to the target.
std::string rpmDbStateHash(const Pathname &root_r)
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::string trim(const std::string &s, const Trim trim_r)
int unlink(const Pathname &path)
Like 'unlink'.
bool set(const std::string &key_r, AnyType val_r)
Set the value for key (nonconst version always returns true).
static const std::string & systemRepoAlias()
Reserved system repository alias .
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
static const Pathname & fname()
Get the current log file path.
bool executeScripts()
Execute the remembered scripts.
const std::string & asString() const
String representation.
void send(const PluginFrame &frame_r)
Send PluginFrame to all open plugins.
int rename(const Pathname &oldpath, const Pathname &newpath)
Like 'rename'.
Just download all packages to the local cache.
Options and policies for ZYpp::commit.
bool isExist() const
Return whether valid stat info exists.
libzypp will decide what to do.
A single step within a Transaction.
ZYppCommitPolicy & downloadMode(DownloadMode val_r)
Commit download policy to use.
void parseFrom(const InputStream &istr_r)
Parse file istr_r and add it's specs (one per line, #-comments).
RequestedLocalesFile _requestedLocalesFile
Requested Locales database.
void setLocales(const LocaleSet &locales_r)
Store a new locale set.
Pathname rootDir() const
Get rootdir (for file conflicts check)
void getHardLockQueries(HardLockQueries &activeLocks_r)
Suggest a new set of queries based on the current selection.
Pathname dirname() const
Return all but the last component od this path.
static Pathname assertprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r prefixed with root_r, unless it is already prefixed.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
ChangedPseudoInstalled changedPseudoInstalled() const
Return all pseudo installed items whose current state differs from the established one...
std::string release() const
Release.
Interim helper class to collect global options and settings.
Definition of vendor equivalence.
SolvableIterator solvablesBegin() const
Iterator to the first Solvable.
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
std::string summary() const
bool order()
Order transaction steps for commit.
Pathname solvfilesPath() const
The solv file location actually in use (default or temp).
void updateSolvFileIndex(const Pathname &solvfile_r)
Create solv file content digest for zypper bash completion.
std::string targetDistribution() const
This is register.target attribute of the installed base product.
Resolver & resolver() const
The Resolver.
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
TraitsType::constPtrType constPtr
const VendorAttr & vendorAttr() const
The targets current vendor equivalence settings.
void initDatabase(Pathname root_r=Pathname(), bool doRebuild_r=false)
Prepare access to the rpm database below root_r.
int symlink(const Pathname &oldpath, const Pathname &newpath)
Like 'symlink'.
void closeDatabase()
Block further access to the rpm database and go back to uninitialized state.
ZYppCommitPolicy & restrictToMedia(unsigned mediaNr_r)
Restrict commit to media 1.
std::list< PoolItem > PoolItemList
list of pool items
std::string anonymousUniqueId() const
anonymous unique id
static const UserData::ContentType contentRpmout
"zypp-rpm/installpkgsa": Additional rpm output (sent immediately).
static PoolImpl & myPool()
RepoStatus rpmDbRepoStatus(const Pathname &root_r)
const char * c_str() const
Conversion to const char *
bool endsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasSuffix
std::string toLower(const std::string &s)
Return lowercase version of s.
Pathname home() const
The directory to store things.
int touch(const Pathname &path)
Change file's modification and access times.
void addProvides(Capability provides_r)
A all sat::Solvable matching this provides_r.
static std::string generateRandomId()
generates a random id using uuidgen
void resetDispose()
Set no dispose function.
ManagedFile get(const PoolItem &citem_r)
Provide a package.
HardLocksFile _hardLocksFile
Hard-Locks database.
static void setRoot(const Pathname &root)
Set new root directory to the default history log file path.
int close()
Wait for the progamm to complete.
byKind_iterator byKindEnd(const ResKind &kind_r) const
void setHardLockQueries(const HardLockQueries &newLocks_r)
Set a new set of queries.
void setSingleTransactionMode(bool yesno_r)
#define SUBST_IF(PAT, VAL)
std::list< UpdateNotificationFile > UpdateNotifications
Libsolv Id queue wrapper.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
TraitsType::constPtrType constPtr
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Product::constPtr baseProduct() const
returns the target base installed product, also known as the distribution or platform.
void createAnonymousId() const
generates the unique anonymous id which is called when creating the target
ZYppCommitPolicy & allMedia()
Process all media (default)
const_iterator begin() const
Iterator to the first TransactionStep.
pool::PoolTraits::HardLockQueries Data
#define NON_MOVABLE(CLASS)
Delete move ctor and move assign.
void add(const Value &val_r)
Push JSON Value to Array.
StepType stepType() const
Type of action to perform in this step.
const Data & data() const
Return the data.
Base class for Exception.
bool preloaded() const
Whether preloaded hint is set.
const std::string & command() const
The command we're executing.
void load(const Pathname &path_r)
Find and launch plugins sending PLUGINBEGIN.
Data returned by ProductFileReader.
static Date now()
Return the current time.
std::string asJSON() const
JSON representation.
void remove(const PoolItem &pi)
Log removal of a package.
void removePackage(const std::string &name_r, RpmInstFlags flags=RPMINST_NONE)
remove rpm package
Typesafe passing of user data via callbacks.
epoch_t epoch() const
Epoch.
std::string distroverpkg() const
Package telling the "product version" on systems not using /etc/product.d/baseproduct.
Pathname root() const
The root set for this target.
void setNeedrebootSpec(sat::SolvableSpec needrebootSpec_r)
Solvables which should trigger the reboot-needed hint if installed/updated.
virtual ~TargetImpl()
Dtor.
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
void eraseFromPool()
Remove this Repository from it's Pool.
bool hasFile(const std::string &file_r, const std::string &name_r="") const
Return true if at least one package owns a certain file (name_r empty) Return true if package name_r ...
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
#define NON_COPYABLE(CLASS)
Delete copy ctor and copy assign.
TraitsType::constPtrType constPtr
static const UserData::ContentType contentRpmout
"zypp-rpm/cleanupkgsa": Additional rpm output (sent immediately).
Wrapper class for ::stat/::lstat.
bool solvablesEmpty() const
Whether Repository contains solvables.
ResObject::Ptr makeResObject(const sat::Solvable &solvable_r)
Create ResObject from sat::Solvable.
sat::Transaction & rTransaction()
Manipulate transaction.
Combining sat::Solvable and ResStatus.
bool singleTransModeEnabled() const
Pathname systemRoot() const
The target root directory.
ManagedFile provideSrcPackage(const SrcPackage_constPtr &srcPackage_r)
Provides a source package on the Target.
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Target::DistributionLabel distributionLabel() const
This is shortName and summary attribute of the installed base product.
Track changing files or directories.
std::string asString() const
Conversion to std::string
bool isKind(const ResKind &kind_r) const
const std::string & asString() const
void XRunUpdateMessages(const Pathname &root_r, const Pathname &messagesPath_r, const std::vector< sat::Solvable > &checkPackages_r, ZYppCommitResult &result_r)
std::string distributionFlavor() const
This is flavor attribute of the installed base product but does not require the target to be loaded a...
static const UserData::ContentType contentRpmout
"zypp-rpm/removepkgsa": Additional rpm output (sent immediately).
size_type solvablesSize() const
Number of solvables in Repository.
void commitInSingleTransaction(const ZYppCommitPolicy &policy_r, CommitPackageCache &packageCache_r, ZYppCommitResult &result_r)
Commit ordered changes (internal helper)
Easy-to use interface to the ZYPP dependency resolver.
std::unordered_set< IdString > Data
Pathname defaultSolvfilesPath() const
The systems default solv file location.
Solvable satSolvable() const
Return the corresponding sat::Solvable.
void add(const String &key_r, const Value &val_r)
Add key/value pair.
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
void setCommitList(std::vector< sat::Solvable > commitList_r)
Download(commit) sequence of solvables to compute read ahead.
bool empty() const
Whether this is an empty object without valid data.
std::unordered_set< Locale > LocaleSet
rpm::RpmDb & rpm()
The RPM database.
TraitsType::constPtrType constPtr
void multiversionSpecChanged()
BlockingMode setFDBlocking(int fd, bool mode)
#define MAXRPMMESSAGELINES
ZYppCommitResult & _result
Mime type like 'type/subtype' classification of content.
static ResPool instance()
Singleton ctor.
void load(bool force=true)