35#undef ZYPP_BASE_LOGGER_LOGGROUP 
   36#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::posttrans" 
   54      using ScriptList = std::list< std::pair<std::string,std::string> >;
 
  102              std::ofstream out( script.
path().
c_str() );
 
  103              out << 
"#! " << pkg->tag_posttransprog() << endl
 
  104                  << pkg->tag_posttrans() << endl;
 
  108            MIL << 
"COLLECT posttrans: '" << 
PathInfo( script.
path() ) << 
"' for package: '" << pkg->tag_name() << 
"'" << endl;
 
 
  122          if ( runposttrans_r.empty()  ) {
 
  124              MIL << 
"LOST dump_posttrans support" <<  endl;
 
  135            MIL << 
"COLLECT dump_posttrans to '" << 
_dumpfile->_dumpfile << endl;
 
  138          std::ofstream out( 
_dumpfile->_dumpfile.c_str(), std::ios_base::app );
 
  139          for ( 
const auto & s : runposttrans_r ) {
 
  142          _dumpfile->_numscripts += runposttrans_r.size();
 
  143          MIL << 
"COLLECT " << runposttrans_r.size() << 
" dump_posttrans lines" << endl;
 
 
  160            MIL << 
"Extract missing %posttrans scripts and prepend them to the scripts." << endl;
 
  163            std::optional<ScriptList> savedscripts;
 
  165              savedscripts = std::move(*
_scripts);
 
  170            recallFromDumpfile( 
_dumpfile->_dumpfile, [&]( 
const std::string& n_r, 
const std::string& v_r, 
const std::string& r_r, 
const std::string& a_r ) -> 
void {
 
  171              if ( it.findPackage( n_r, Edition( v_r, r_r ) ) && headerHasPosttrans( *it ) )
 
  172                collectScriptFromHeader( *it );
 
  176            if ( savedscripts ) {
 
  180                _scripts = std::move(*savedscripts);
 
  201          std::string scriptProgressName { 
_(
"Running post-transaction scripts") };
 
  203          str::Format fmtScriptProgressRun { 
_(
"Running %1% script") };
 
  206          std::string sendRipoff;
 
  211          auto startNewScript = [&] ( 
const std::string & scriptident_r ) -> 
void {
 
  213            sendRipoff = fmtRipoff % scriptident_r;
 
  214            scriptProgress.name( fmtScriptProgressRun % scriptident_r );
 
  215            scriptProgress.incr();
 
  219          auto sendScriptOutput = [&] ( 
const std::string & line_r ) -> 
void {
 
  221            if ( not sendRipoff.empty() ) {
 
  222              historylog.
comment( sendRipoff, 
true );
 
  224              cleanup.setDispose( [&]() -> 
void {
 
  234          scriptProgress.name( scriptProgressName );
 
  235          scriptProgress.toMin();
 
  241            str::Format fmtScriptFailedMsg { 
"warning: %%posttrans(%1%) scriptlet failed, exit status %2%\n" };
 
  246              const auto &scriptPair = 
_scripts->front();
 
  247              const std::string & script = scriptPair.first;
 
  248              const std::string & pkgident( script.substr( 0, script.size()-6 ) ); 
 
  249              startNewScript( fmtPosttrans % pkgident );
 
  251              int npkgs = obsoletedPackages_r.count( 
IdString(scriptPair.second) ) ? 2 : 1; 
 
  252              MIL << 
"EXECUTE posttrans: " << script << 
" with argument: " << npkgs << endl;
 
  255                (noRootScriptDir/script).
asString(),
 
  261                sendScriptOutput( line );
 
  266              int ret = prog.
close();
 
  269                std::string msg { fmtScriptFailedMsg % pkgident % ret };
 
  271                sendScriptOutput( msg ); 
 
  281              if ( str::startsWith( line_r, 
"RIPOFF:" ) )
 
  282                startNewScript( line_r.substr( 7 ) ); 
 
  284                sendScriptOutput( line_r );
 
  293          scriptProgress.name( scriptProgressName );
 
  295            scriptProgress.toMax(); 
 
 
  312            msg << 
"%posttrans scripts skipped while aborting:" << endl;
 
  313            for ( 
const auto & script : *
_scripts )
 
  315              WAR << 
"UNEXECUTED posttrans: " << script.first << endl;
 
  316              const std::string & pkgident( script.first.substr( 0, script.first.size()-6 ) ); 
 
  317              msg << 
"    " << pkgident << 
"\n";
 
  323            msg << 
"%posttrans and %transfiletrigger scripts are not executed when aborting!" << endl;
 
  328          historylog.
comment( msg, 
true );
 
 
  346            std::string prog( pkg_r->tag_posttransprog() );
 
  347            if ( not prog.empty() && prog != 
"<lua>" )  
 
 
  366            WAR << 
"Unexpectedly this is no package: " << rpmPackage_r << endl;
 
 
  376          static const str::regex rxInstalled { 
"^dump_posttrans: +install +[0-9]+ +(.+)-([^-]+)-([^-]+)\\.([^.]+)" };
 
  380              consume_r( what[1], what[2], what[3], what[4] );
 
 
 
  398    { 
return str << 
"RpmPostTransCollector::Impl"; }
 
 
  402    { 
return str << obj; }
 
 
  418    { 
return _pimpl->hasPosttransScript( rpmPackage_r ); }
 
 
  421    { 
_pimpl->collectPosttransInfo( rpmPackage_r, runposttrans_r ); }
 
 
  424    { 
_pimpl->collectPosttransInfo( runposttrans_r ); }
 
 
  427    { 
_pimpl->executeScripts( rpm_r, obsoletedPackages_r ); }
 
 
  430    { 
return _pimpl->discardScripts(); }
 
 
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
int close() override
Wait for the progamm to complete.
std::vector< std::string > Arguments
Writing the zypp history file.
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
Access to the sat-pools string space.
Maintain [min,max] and counter (value) for progress counting.
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
static ZConfig & instance()
Singleton ctor.
std::string receiveLine()
Read one line from the input stream.
Wrapper class for stat/lstat.
const char * c_str() const
String representation.
std::string basename() const
Return the last component of this path.
Provide a new empty temporary directory and recursively delete it when no longer needed.
Provide a new empty temporary file and delete it when no longer needed.
bool autoCleanup() const
Whether path is valid and deleted when the last reference drops.
Regular expression match result.
RpmPostTransCollector implementation.
UserDataJobReport _myJobReport
JobReport with ContentType "cmdout/%posttrans".
Impl(const Impl &)=delete
void discardScripts()
Discard all remembered scrips.
Impl & operator=(const Impl &)=delete
void collectPosttransInfo(const std::vector< std::string > &runposttrans_r)
void recallFromDumpfile(const Pathname &dumpfile_r, std::function< void(std::string, std::string, std::string, std::string)> consume_r)
Retrieve "dump_posttrans: install" lines from dumpfile_r and pass n,v,r,a to the consumer_r.
rpm::RpmHeader::constPtr getHeaderIfPosttrans(const Pathname &rpmPackage_r)
Cache RpmHeader for consecutive hasPosttransScript / collectScriptForPackage calls.
Pathname tmpDir()
Lazy create tmpdir on demand.
std::optional< Dumpfile > _dumpfile
bool collectDumpPosttransLines(const std::vector< std::string > &runposttrans_r)
Return whether runposttrans lines were collected.
std::optional< ScriptList > _scripts
void collectPosttransInfo(const Pathname &rpmPackage_r, const std::vector< std::string > &runposttrans_r)
scoped_ptr< filesystem::TmpDir > _ptrTmpdir
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
std::list< std::pair< std::string, std::string > > ScriptList
<posttrans script basename, pkgname> pairs.
bool hasPosttransScript(const Pathname &rpmPackage_r)
Impl & operator=(Impl &&)=delete
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Verbose stream output.
void executeScripts(rpm::RpmDb &rpm_r, const IdStringSet &obsoletedPackages_r)
Execute the remembered scripts.
void collectScriptFromHeader(const rpm::RpmHeader::constPtr &pkg)
std::pair< Pathname, rpm::RpmHeader::constPtr > _headercache
std::ostream & operator<<(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Stream output.
friend std::ostream & dumpOn(std::ostream &str, const Impl &obj)
void collectScriptForPackage(const Pathname &rpmPackage_r)
bool headerHasPosttrans(const rpm::RpmHeader::constPtr &pkg_r) const
Return whether RpmHeader has a posttrans.
void collectPosttransInfo(const Pathname &rpmPackage_r, const std::vector< std::string > &runposttrans_r)
Extract and remember a packages posttrans script or dump_posttrans lines for later execution.
RW_pointer< Impl > _pimpl
Implementation class.
RpmPostTransCollector(Pathname root_r)
Default ctor.
bool hasPosttransScript(const Pathname &rpmPackage_r)
Test whether a package defines a posttrans script.
void executeScripts(rpm::RpmDb &rpm_r, const IdStringSet &obsoletedPackages_r)
Execute the remembered scripts and/or or dump_posttrans lines.
~RpmPostTransCollector()
Dtor.
void discardScripts()
Discard all remembered scripts and/or or dump_posttrans lines.
Interface to the rpm program.
int runposttrans(const Pathname &filename_r, const std::function< void(const std::string &)> &output_r)
Run collected posttrans and transfiletrigger(postun|in) if rpm --runposttrans is supported.
db_const_iterator dbConstIterator() const
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
int forEachLine(std::istream &str_r, const function< bool(int, std::string)> &consume_r)
Simple lineparser: Call functor consume_r for each line.
std::string numstring(char n, int w=0)
bool regex_match(const std::string &s, smatch &matches, const regex ®ex)
\relates regex \ingroup ZYPP_STR_REGEX    \relates regex \ingroup ZYPP_STR_REGEX
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector &obj)
std::ostream & operator<<(std::ostream &str, const CommitPackageCache &obj)
Easy-to use interface to the ZYPP dependency resolver.
std::unordered_set< IdString > IdStringSet
AutoDispose< void > OnScopeExit
std::string asString(const Patch::Category &obj)
JobReport convenience sending this instance of UserData with each message.
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Data regarding the dumpfile used if rpm --runposttrans is supported.
bool _runposttrans
Set to false if rpm lost –runposttrans support during transaction.
Dumpfile(Pathname dumpfile_r)
Pathname _dumpfile
The file holding the collected dump_posttrans: lines.
size_t _numscripts
Number of scripts we collected (roughly estimated)
Wrapper providing a librpmDb::db_const_iterator for this RpmDb.