libzypp  17.2.0
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  if ( ! pkg )
57  {
58  WAR << "Unexpectedly this is no package: " << rpmPackage_r << endl;
59  return false;
60  }
61 
62  std::string prog( pkg->tag_posttransprog() );
63  if ( prog.empty() || prog == "<lua>" ) // by now leave lua to rpm
64  return false;
65 
66  filesystem::TmpFile script( tmpDir(), rpmPackage_r->basename() );
67  filesystem::addmod( script.path(), 0500 );
68  script.autoCleanup( false ); // no autodelete; within a tmpdir
69  {
70  std::ofstream out( script.path().c_str() );
71  out << "#! " << pkg->tag_posttransprog() << endl
72  << pkg->tag_posttrans() << endl;
73  }
74  _scripts.push_back( script.path().basename() );
75  MIL << "COLLECT posttrans: " << PathInfo( script.path() ) << endl;
76  //DBG << "PROG: " << pkg->tag_posttransprog() << endl;
77  //DBG << "SCRPT: " << pkg->tag_posttrans() << endl;
78  return true;
79  }
80 
83  {
84  if ( _scripts.empty() )
85  return;
86 
87  HistoryLog historylog;
88 
89  Pathname noRootScriptDir( ZConfig::instance().update_scriptsPath() / tmpDir().basename() );
90 
91  for ( const auto & script : _scripts )
92  {
93  MIL << "EXECUTE posttrans: " << script << endl;
94  ExternalProgram prog( (noRootScriptDir/script).asString(), ExternalProgram::Stderr_To_Stdout, false, -1, true, _root );
95 
96  str::Str collect;
97  for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
98  {
99  DBG << line;
100  collect << " " << line;
101  }
102  int ret = prog.close();
103  const std::string & scriptmsg( collect );
104 
105  if ( ret != 0 || ! scriptmsg.empty() )
106  {
107  const std::string & pkgident( script.substr( 0, script.size()-6 ) ); // strip tmp file suffix
108 
109  if ( ! scriptmsg.empty() )
110  {
111  str::Str msg;
112  msg << "Output of " << pkgident << " %posttrans script:\n" << scriptmsg;
113  historylog.comment( msg, true /*timestamp*/);
114  JobReport::info( msg );
115  }
116 
117  if ( ret != 0 )
118  {
119  str::Str msg;
120  msg << pkgident << " %posttrans script failed (returned " << ret << ")";
121  WAR << msg << endl;
122  historylog.comment( msg, true /*timestamp*/);
123  JobReport::warning( msg );
124  }
125  }
126  }
127  _scripts.clear();
128  }
129 
132  {
133  if ( _scripts.empty() )
134  return;
135 
136  HistoryLog historylog;
137 
138  str::Str msg;
139  msg << "%posttrans scripts skipped while aborting:\n";
140  for ( const auto & script : _scripts )
141  {
142  const std::string & pkgident( script.substr( 0, script.size()-6 ) ); // strip tmp file suffix
143  WAR << "UNEXECUTED posttrans: " << script << endl;
144  msg << " " << pkgident << "\n";
145  }
146 
147  historylog.comment( msg, true /*timestamp*/);
148  JobReport::warning( msg );
149 
150  _scripts.clear();
151  }
152 
153  private:
156  {
157  if ( !_ptrTmpdir ) _ptrTmpdir.reset( new filesystem::TmpDir( _root / ZConfig::instance().update_scriptsPath(), "posttrans" ) );
158  DBG << _ptrTmpdir->path() << endl;
159  return _ptrTmpdir->path();
160  }
161 
162  private:
164  std::list<std::string> _scripts;
165  boost::scoped_ptr<filesystem::TmpDir> _ptrTmpdir;
166  };
167 
169  inline std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector::Impl & obj )
170  { return str << "RpmPostTransCollector::Impl"; }
171 
173  inline std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector::Impl & obj )
174  { return str << obj; }
175 
177  //
178  // CLASS NAME : RpmPostTransCollector
179  //
181 
183  : _pimpl( new Impl( root_r ) )
184  {}
185 
187  {}
188 
190  { return _pimpl->collectScriptFromPackage( rpmPackage_r ); }
191 
193  { return _pimpl->executeScripts(); }
194 
196  { return _pimpl->discardScripts(); }
197 
198  std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector & obj )
199  { return str << *obj._pimpl; }
200 
201  std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector & obj )
202  { return dumpOn( str, *obj._pimpl ); }
203 
204  } // namespace target
206 } // namespace zypp
#define MIL
Definition: Logger.h:64
intrusive_ptr< const RpmHeader > constPtr
Definition: RpmHeader.h:64
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:125
void discardScripts()
Discard all remembered scrips.
friend std::ostream & dumpOn(std::ostream &str, const Impl &obj)
String related utilities and Regular expression matching.
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Provide a new empty temporary file and delete it when no longer needed.
Definition: TmpPath.h:126
void executeScripts()
Execute te remembered scripts.
RW_pointer< Impl > _pimpl
Implementation class.
RpmPostTransCollector(const Pathname &root_r)
Default ctor.
Extract and remember posttrans scripts for later execution.
Pathname tmpDir()
Lazy create tmpdir on demand.
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
Definition: PathInfo.cc:1054
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition: TmpPath.h:170
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:210
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
#define WAR
Definition: Logger.h:65
RpmPostTransCollector implementation.
std::ostream & operator<<(std::ostream &str, const CommitPackageCache &obj)
boost::scoped_ptr< filesystem::TmpDir > _ptrTmpdir
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
Definition: HistoryLog.h:55
std::string receiveLine()
Read one line from the input stream.
static RpmHeader::constPtr readPackage(const Pathname &path, VERIFICATION verification=VERIFY)
Get an accessible packages data from disk.
Definition: RpmHeader.cc:208
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector &obj)
int close()
Wait for the progamm to complete.
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
void discardScripts()
Discard all remembered scrips.
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:92
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
Definition: HistoryLog.cc:188
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
void executeScripts()
Execute te remembered scripts.
static bool info(const std::string &msg_r, const UserData &userData_r=UserData())
send message text
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
#define DBG
Definition: Logger.h:63
std::ostream & operator<<(std::ostream &str, const RpmPostTransCollector::Impl &obj)