libzypp  16.20.4
RpmPostTransCollector.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
11 #include <iostream>
12 #include <fstream>
13 #include "zypp/base/LogTools.h"
14 #include "zypp/base/NonCopyable.h"
16 
17 #include "zypp/TmpPath.h"
18 #include "zypp/PathInfo.h"
19 #include "zypp/HistoryLog.h"
20 #include "zypp/ZYppCallbacks.h"
21 #include "zypp/ExternalProgram.h"
23 #include "zypp/ZConfig.h"
24 
25 using std::endl;
26 #undef ZYPP_BASE_LOGGER_LOGGROUP
27 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::posttrans"
28 
30 namespace zypp
31 {
33  namespace target
34  {
35 
41  {
42  friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
43  friend std::ostream & dumpOn( std::ostream & str, const Impl & obj );
44  public:
45  Impl( const Pathname & root_r )
46  : _root( root_r )
47  {}
48 
50  { if ( !_scripts.empty() ) discardScripts(); }
51 
54  {
56 
57  std::string prog( pkg->tag_posttransprog() );
58  if ( prog.empty() || prog == "<lua>" ) // by now leave lua to rpm
59  return false;
60 
61  filesystem::TmpFile script( tmpDir(), rpmPackage_r->basename() );
62  filesystem::addmod( script.path(), 0500 );
63  script.autoCleanup( false ); // no autodelete; within a tmpdir
64  {
65  std::ofstream out( script.path().c_str() );
66  out << "#! " << pkg->tag_posttransprog() << endl
67  << pkg->tag_posttrans() << endl;
68  }
69  _scripts.push_back( script.path().basename() );
70  MIL << "COLLECT posttrans: " << PathInfo( script.path() ) << endl;
71  //DBG << "PROG: " << pkg->tag_posttransprog() << endl;
72  //DBG << "SCRPT: " << pkg->tag_posttrans() << endl;
73  return true;
74  }
75 
78  {
79  if ( _scripts.empty() )
80  return;
81 
82  HistoryLog historylog;
83 
84  Pathname noRootScriptDir( ZConfig::instance().update_scriptsPath() / tmpDir().basename() );
85 
86  for ( const auto & script : _scripts )
87  {
88  MIL << "EXECUTE posttrans: " << script << endl;
89  ExternalProgram prog( (noRootScriptDir/script).asString(), ExternalProgram::Stderr_To_Stdout, false, -1, true, _root );
90 
91  str::Str collect;
92  for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
93  {
94  DBG << line;
95  collect << " " << line;
96  }
97  int ret = prog.close();
98  const std::string & scriptmsg( collect );
99 
100  if ( ret != 0 || ! scriptmsg.empty() )
101  {
102  const std::string & pkgident( script.substr( 0, script.size()-6 ) ); // strip tmp file suffix
103 
104  if ( ! scriptmsg.empty() )
105  {
106  str::Str msg;
107  msg << "Output of " << pkgident << " %posttrans script:\n" << scriptmsg;
108  historylog.comment( msg, true /*timestamp*/);
109  JobReport::info( msg );
110  }
111 
112  if ( ret != 0 )
113  {
114  str::Str msg;
115  msg << pkgident << " %posttrans script failed (returned " << ret << ")";
116  WAR << msg << endl;
117  historylog.comment( msg, true /*timestamp*/);
118  JobReport::warning( msg );
119  }
120  }
121  }
122  _scripts.clear();
123  }
124 
127  {
128  if ( _scripts.empty() )
129  return;
130 
131  HistoryLog historylog;
132 
133  str::Str msg;
134  msg << "%posttrans scripts skipped while aborting:\n";
135  for ( const auto & script : _scripts )
136  {
137  const std::string & pkgident( script.substr( 0, script.size()-6 ) ); // strip tmp file suffix
138  WAR << "UNEXECUTED posttrans: " << script << endl;
139  msg << " " << pkgident << "\n";
140  }
141 
142  historylog.comment( msg, true /*timestamp*/);
143  JobReport::warning( msg );
144 
145  _scripts.clear();
146  }
147 
148  private:
151  {
152  if ( !_ptrTmpdir ) _ptrTmpdir.reset( new filesystem::TmpDir( _root / ZConfig::instance().update_scriptsPath(), "posttrans" ) );
153  DBG << _ptrTmpdir->path() << endl;
154  return _ptrTmpdir->path();
155  }
156 
157  private:
159  std::list<std::string> _scripts;
160  boost::scoped_ptr<filesystem::TmpDir> _ptrTmpdir;
161  };
162 
164  inline std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector::Impl & obj )
165  { return str << "RpmPostTransCollector::Impl"; }
166 
168  inline std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector::Impl & obj )
169  { return str << obj; }
170 
172  //
173  // CLASS NAME : RpmPostTransCollector
174  //
176 
178  : _pimpl( new Impl( root_r ) )
179  {}
180 
182  {}
183 
185  { return _pimpl->collectScriptFromPackage( rpmPackage_r ); }
186 
188  { return _pimpl->executeScripts(); }
189 
191  { return _pimpl->discardScripts(); }
192 
193  std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector & obj )
194  { return str << *obj._pimpl; }
195 
196  std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector & obj )
197  { return dumpOn( str, *obj._pimpl ); }
198 
199  } // namespace target
201 } // namespace zypp
#define DBG
Definition: Logger.h:63
#define MIL
Definition: Logger.h:64
#define WAR
Definition: Logger.h:65
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:93
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
int close()
Wait for the progamm to complete.
Writing the zypp history file.
Definition: HistoryLog.h:56
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
Definition: HistoryLog.cc:188
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:125
std::string receiveLine()
Read one line from the input stream.
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:127
const char * c_str() const
String representation.
Definition: Pathname.h:109
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition: TmpPath.h:171
Provide a new empty temporary file and delete it when no longer needed.
Definition: TmpPath.h:127
Pathname path() const
Definition: TmpPath.cc:146
bool autoCleanup() const
Whether path is valid and deleted when the last reference drops.
Definition: TmpPath.cc:163
RpmPostTransCollector implementation.
void discardScripts()
Discard all remembered scrips.
boost::scoped_ptr< filesystem::TmpDir > _ptrTmpdir
Pathname tmpDir()
Lazy create tmpdir on demand.
friend std::ostream & dumpOn(std::ostream &str, const Impl &obj)
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
void executeScripts()
Execute te remembered scripts.
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Verbose stream output.
std::ostream & operator<<(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Stream output.
Extract and remember posttrans scripts for later execution.
RpmPostTransCollector(const Pathname &root_r)
Default ctor.
RW_pointer< Impl > _pimpl
Implementation class.
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
void executeScripts()
Execute te remembered scripts.
void discardScripts()
Discard all remembered scrips.
static RpmHeader::constPtr readPackage(const Pathname &path, VERIFICATION verification=VERIFY)
Get an accessible packages data from disk.
Definition: RpmHeader.cc:208
intrusive_ptr< const RpmHeader > constPtr
Definition: RpmHeader.h:64
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
Definition: PathInfo.cc:1054
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.
Definition: CodePitfalls.doc:2
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
static bool info(const std::string &msg_r, const UserData &userData_r=UserData())
send message text
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:211