libzypp  17.25.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>
15 #include <zypp/base/Gettext.h>
17 
18 #include <zypp/TmpPath.h>
19 #include <zypp/PathInfo.h>
20 #include <zypp/HistoryLog.h>
21 #include <zypp/ZYppCallbacks.h>
22 #include <zypp/ExternalProgram.h>
25 #include <zypp/ZConfig.h>
26 #include <zypp/ZYppCallbacks.h>
27 
28 using std::endl;
29 #undef ZYPP_BASE_LOGGER_LOGGROUP
30 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::posttrans"
31 
33 namespace zypp
34 {
36  namespace target
37  {
38 
44  {
45  friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
46  friend std::ostream & dumpOn( std::ostream & str, const Impl & obj );
47  public:
48  Impl( const Pathname & root_r )
49  : _root( root_r )
50  {}
51 
53  { if ( !_scripts.empty() ) discardScripts(); }
54 
57  {
59  if ( ! pkg )
60  {
61  WAR << "Unexpectedly this is no package: " << rpmPackage_r << endl;
62  return false;
63  }
64 
65  std::string prog( pkg->tag_posttransprog() );
66  if ( prog.empty() || prog == "<lua>" ) // by now leave lua to rpm
67  return false;
68 
69  filesystem::TmpFile script( tmpDir(), rpmPackage_r->basename() );
70  filesystem::addmod( script.path(), 0500 );
71  script.autoCleanup( false ); // no autodelete; within a tmpdir
72  {
73  std::ofstream out( script.path().c_str() );
74  out << "#! " << pkg->tag_posttransprog() << endl
75  << pkg->tag_posttrans() << endl;
76  }
77  _scripts.push_back( std::make_pair( script.path().basename(), pkg->tag_name() ) );
78  MIL << "COLLECT posttrans: '" << PathInfo( script.path() ) << "' for package: '" << pkg->tag_name() << "'" << endl;
79  //DBG << "PROG: " << pkg->tag_posttransprog() << endl;
80  //DBG << "SCRPT: " << pkg->tag_posttrans() << endl;
81  return true;
82  }
83 
86  {
87  if ( _scripts.empty() )
88  return true;
89 
90  HistoryLog historylog;
91 
92  Pathname noRootScriptDir( ZConfig::instance().update_scriptsPath() / tmpDir().basename() );
93 
94  ProgressData scriptProgress( static_cast<ProgressData::value_type>(_scripts.size()) );
97 
98  bool firstScript = true;
99  while ( ! _scripts.empty() )
100  {
101  const auto &scriptPair = _scripts.front();
102  const std::string & script = scriptPair.first;
103  const std::string & pkgident( script.substr( 0, script.size()-6 ) ); // strip tmp file suffix
104 
105  scriptProgress.name( str::Format(_("Executing %%posttrans script '%1%'")) % pkgident );
106 
107  bool canContinue = true;
108  if (firstScript) {
109  firstScript = false;
110  canContinue = scriptProgress.toMin();
111  } else {
112  canContinue = scriptProgress.incr();
113  }
114 
115  if (!canContinue) {
116  str::Str msg;
117  msg << "Execution of %posttrans scripts cancelled";
118  WAR << msg << endl;
119  historylog.comment( msg, true /*timestamp*/);
120  JobReport::warning( msg );
121  return false;
122  }
123 
124  int npkgs = 0;
126  for ( it.findByName( scriptPair.second ); *it; ++it )
127  npkgs++;
128 
129  MIL << "EXECUTE posttrans: " << script << " with argument: " << npkgs << endl;
130  ExternalProgram prog( (noRootScriptDir/script).asString() + " " +str::numstring( npkgs ), ExternalProgram::Stderr_To_Stdout, false, -1, true, _root );
131 
132  str::Str collect;
133  for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
134  {
135  DBG << line;
136  collect << " " << line;
137  }
138 
139  //script was executed, remove it from the list
140  _scripts.pop_front();
141 
142  int ret = prog.close();
143  const std::string & scriptmsg( collect );
144 
145  if ( ret != 0 || ! scriptmsg.empty() )
146  {
147  if ( ! scriptmsg.empty() )
148  {
149  str::Str msg;
150  msg << "Output of " << pkgident << " %posttrans script:\n" << scriptmsg;
151  historylog.comment( msg, true /*timestamp*/);
152  JobReport::UserData userData( "cmdout", "%posttrans" );
153  JobReport::info( msg, userData );
154  }
155 
156  if ( ret != 0 )
157  {
158  str::Str msg;
159  msg << pkgident << " %posttrans script failed (returned " << ret << ")";
160  WAR << msg << endl;
161  historylog.comment( msg, true /*timestamp*/);
162  JobReport::warning( msg );
163  }
164  }
165  }
166 
167  //show a final message
168  scriptProgress.name( _("Executing %posttrans scripts") );
169  scriptProgress.toMax();
170  _scripts.clear();
171  return true;
172  }
173 
176  {
177  if ( _scripts.empty() )
178  return;
179 
180  HistoryLog historylog;
181 
182  str::Str msg;
183  msg << "%posttrans scripts skipped while aborting:\n";
184  for ( const auto & script : _scripts )
185  {
186  const std::string & pkgident( script.first.substr( 0, script.first.size()-6 ) ); // strip tmp file suffix
187  WAR << "UNEXECUTED posttrans: " << script.first << endl;
188  msg << " " << pkgident << "\n";
189  }
190 
191  historylog.comment( msg, true /*timestamp*/);
192  JobReport::warning( msg );
193 
194  _scripts.clear();
195  }
196 
197 
198  private:
201  {
202  if ( !_ptrTmpdir ) _ptrTmpdir.reset( new filesystem::TmpDir( _root / ZConfig::instance().update_scriptsPath(), "posttrans" ) );
203  DBG << _ptrTmpdir->path() << endl;
204  return _ptrTmpdir->path();
205  }
206 
207  private:
209  std::list< std::pair< std::string, std::string > > _scripts;
210  boost::scoped_ptr<filesystem::TmpDir> _ptrTmpdir;
211  };
212 
214  inline std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector::Impl & obj )
215  { return str << "RpmPostTransCollector::Impl"; }
216 
218  inline std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector::Impl & obj )
219  { return str << obj; }
220 
222  //
223  // CLASS NAME : RpmPostTransCollector
224  //
226 
228  : _pimpl( new Impl( root_r ) )
229  {}
230 
232  {}
233 
235  { return _pimpl->collectScriptFromPackage( rpmPackage_r ); }
236 
238  { return _pimpl->executeScripts(); }
239 
241  { return _pimpl->discardScripts(); }
242 
243  std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector & obj )
244  { return str << *obj._pimpl; }
245 
246  std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector & obj )
247  { return dumpOn( str, *obj._pimpl ); }
248 
249  } // namespace target
251 } // namespace zypp
ExternalProgram.h
zypp::ExternalProgram::Stderr_To_Stdout
Definition: ExternalProgram.h:73
zypp::target::RpmPostTransCollector::executeScripts
bool executeScripts()
Execute the remembered scripts.
Definition: RpmPostTransCollector.cc:237
TmpPath.h
PathInfo.h
zypp::target::RpmPostTransCollector::Impl::_root
Pathname _root
Definition: RpmPostTransCollector.cc:208
zypp::target::RpmPostTransCollector::Impl::dumpOn
friend std::ostream & dumpOn(std::ostream &str, const Impl &obj)
zypp::callback::SendReport
Definition: Callback.h:236
zypp::target::RpmPostTransCollector::Impl::_scripts
std::list< std::pair< std::string, std::string > > _scripts
Definition: RpmPostTransCollector.cc:209
RpmHeader.h
zypp::target::dumpOn
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector &obj)
Definition: RpmPostTransCollector.cc:246
ZConfig.h
zypp::target::rpm::RpmHeader::constPtr
intrusive_ptr< const RpmHeader > constPtr
Definition: RpmHeader.h:64
MIL
#define MIL
Definition: Logger.h:79
zypp::target::RpmPostTransCollector::Impl
RpmPostTransCollector implementation.
Definition: RpmPostTransCollector.cc:43
zypp::target::RpmPostTransCollector::Impl::Impl
Impl(const Pathname &root_r)
Definition: RpmPostTransCollector.cc:48
HistoryLog.h
zypp::ProgressReportAdaptor
Definition: ZYppCallbacks.h:58
zypp::JobReport::info
static bool info(const std::string &msg_r, const UserData &userData_r=UserData())
send message text
Definition: ZYppCallbacks.h:822
zypp::target::RpmPostTransCollector::Impl::dumpOn
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Definition: RpmPostTransCollector.cc:218
zypp::ExternalProgram
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
Definition: ExternalProgram.h:59
report
callback::SendReport< DownloadProgressReport > * report
Definition: MediaCurl.cc:70
zypp::callback::UserData
Typesafe passing of user data via callbacks.
Definition: UserData.h:38
zypp::ProgressData::name
void name(const std::string &name_r)
Set counter name.
Definition: ProgressData.h:222
zypp::target::RpmPostTransCollector::~RpmPostTransCollector
~RpmPostTransCollector()
Dtor.
Definition: RpmPostTransCollector.cc:231
zypp::target::RpmPostTransCollector::_pimpl
RW_pointer< Impl > _pimpl
Implementation class.
Definition: RpmPostTransCollector.h:58
zypp::target::RpmPostTransCollector
Extract and remember posttrans scripts for later execution.
Definition: RpmPostTransCollector.h:31
zypp::target::RpmPostTransCollector::discardScripts
void discardScripts()
Discard all remembered scrips.
Definition: RpmPostTransCollector.cc:240
LogTools.h
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
zypp::target::operator<<
std::ostream & operator<<(std::ostream &str, const CommitPackageCache &obj)
Definition: CommitPackageCache.cc:155
zypp::filesystem::TmpFile
Provide a new empty temporary file and delete it when no longer needed.
Definition: TmpPath.h:127
zypp::filesystem::TmpDir
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition: TmpPath.h:177
zypp::target::RpmPostTransCollector::Impl::tmpDir
Pathname tmpDir()
Lazy create tmpdir on demand.
Definition: RpmPostTransCollector.cc:200
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
zypp::HistoryLog
Writing the zypp history file.
Definition: HistoryLog.h:56
WAR
#define WAR
Definition: Logger.h:80
ZYppCallbacks.h
zypp::target::RpmPostTransCollector::Impl::_ptrTmpdir
boost::scoped_ptr< filesystem::TmpDir > _ptrTmpdir
Definition: RpmPostTransCollector.cc:210
_
#define _(MSG)
Definition: Gettext.h:37
zypp::ZConfig::instance
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:126
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition: String.h:286
zypp::target::RpmPostTransCollector::RpmPostTransCollector
RpmPostTransCollector(const Pathname &root_r)
Default ctor.
Definition: RpmPostTransCollector.cc:227
librpmDb.h
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:208
zypp::ExternalProgram::close
int close()
Wait for the progamm to complete.
Definition: ExternalProgram.cc:456
zypp::target::RpmPostTransCollector::Impl::collectScriptFromPackage
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
Definition: RpmPostTransCollector.cc:56
zypp::target::RpmPostTransCollector::collectScriptFromPackage
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
Definition: RpmPostTransCollector.cc:234
zypp::target::rpm::librpmDb::db_const_iterator
Subclass to retrieve database content.
Definition: librpmDb.h:322
zypp::target::rpm::librpmDb::db_const_iterator::findByName
bool findByName(const std::string &name_r)
Reset to iterate all packages with a certain name.
Definition: librpmDb.cc:764
zypp::filesystem::addmod
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
Definition: PathInfo.cc:1049
zypp::asString
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
Definition: DefaultIntegral.h:98
zypp::ProgressData::ReceiverFnc
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: ProgressData.h:139
Gettext.h
zypp::AutoDispose
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:92
zypp::ProgressData::sendTo
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: ProgressData.h:226
zypp::target::rpm::RpmHeader::readPackage
static RpmHeader::constPtr readPackage(const Pathname &path, VERIFICATION verification=VERIFY)
Get an accessible packages data from disk.
Definition: RpmHeader.cc:208
zypp::ProgressData::toMax
bool toMax()
Set counter value to current max value (unless no range).
Definition: ProgressData.h:273
RpmPostTransCollector.h
zypp::externalprogram::ExternalDataSource::receiveLine
std::string receiveLine()
Read one line from the input stream.
Definition: ExternalDataSource.cc:115
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:44
zypp::JobReport::warning
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
Definition: ZYppCallbacks.h:826
zypp::target::RpmPostTransCollector::Impl::~Impl
~Impl()
Definition: RpmPostTransCollector.cc:52
DBG
#define DBG
Definition: Logger.h:78
zypp::ProgressData::toMin
bool toMin()
Set counter value to current min value.
Definition: ProgressData.h:269
zypp::target::RpmPostTransCollector::Impl::discardScripts
void discardScripts()
Discard all remembered scrips.
Definition: RpmPostTransCollector.cc:175
zypp::target::RpmPostTransCollector::Impl::executeScripts
bool executeScripts()
Execute the remembered scripts.
Definition: RpmPostTransCollector.cc:85
zypp::str::Format
Convenient building of std::string with boost::format. Basically a boost::format autoconvertible to s...
Definition: String.h:249
zypp::target::rpm::RpmHeader::NOVERIFY
Definition: RpmHeader.h:195
str
String related utilities and Regular expression matching.
zypp::target::RpmPostTransCollector::Impl::operator<<
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
zypp::HistoryLog::comment
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
Definition: HistoryLog.cc:188
zypp::target::RpmPostTransCollector::Impl::operator<<
std::ostream & operator<<(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Definition: RpmPostTransCollector.cc:214
zypp::ProgressData
Maintain [min,max] and counter (value) for progress counting.
Definition: ProgressData.h:130
NonCopyable.h
zypp::ProgressData::incr
bool incr(value_type val_r=1)
Increment counter value (default by 1).
Definition: ProgressData.h:261