libzypp: zypp/target/RpmPostTransCollector.cc Source File

libzypp 17.25.10

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>
16 #include <zypp/target/RpmPostTransCollector.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>
23 #include <zypp/target/rpm/RpmHeader.h>
24 #include <zypp/target/rpm/librpmDb.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
43 class RpmPostTransCollector::Impl : private base::NonCopyable
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
52 ~Impl()
53 { if ( !_scripts.empty() ) discardScripts(); }
54
56 bool collectScriptFromPackage( ManagedFile rpmPackage_r )
57 {
58 rpm::RpmHeader::constPtr pkg( rpm::RpmHeader::readPackage( rpmPackage_r, rpm::RpmHeader::NOVERIFY ) );
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
85 bool executeScripts()
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()) );
95 callback::SendReport<ProgressReport> report;
96 scriptProgress.sendTo( ProgressReportAdaptor( ProgressData::ReceiverFnc(), report ) );
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;
125 rpm::librpmDb::db_const_iterator it;
126 for ( it.findByName( scriptPair.second ); *it; ++it )
127 npkgs++;
128
129 MIL << "EXECUTE posttrans: " << script << " with argument: " << npkgs << endl;
130 ExternalProgram::Arguments cmd {
131 "/bin/sh",
132 (noRootScriptDir/script).asString(),
133 str::numstring( npkgs )
134 };
135 ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout, false, -1, true, _root );
136
137 str::Str collect;
138 for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
139 {
140 DBG << line;
141 collect << " " << line;
142 }
143
144 //script was executed, remove it from the list
145 _scripts.pop_front();
146
147 int ret = prog.close();
148 const std::string & scriptmsg( collect );
149
150 if ( ret != 0 || ! scriptmsg.empty() )
151 {
152 if ( ! scriptmsg.empty() )
153 {
154 str::Str msg;
155 msg << "Output of " << pkgident << " %posttrans script:\n" << scriptmsg;
156 historylog.comment( msg, true /*timestamp*/);
157 JobReport::UserData userData( "cmdout", "%posttrans" );
158 JobReport::info( msg, userData );
159 }
160
161 if ( ret != 0 )
162 {
163 str::Str msg;
164 msg << pkgident << " %posttrans script failed (returned " << ret << ")";
165 WAR << msg << endl;
166 historylog.comment( msg, true /*timestamp*/);
167 JobReport::warning( msg );
168 }
169 }
170 }
171
172 //show a final message
173 scriptProgress.name( _("Executing %posttrans scripts") );
174 scriptProgress.toMax();
175 _scripts.clear();
176 return true;
177 }
178
180 void discardScripts()
181 {
182 if ( _scripts.empty() )
183 return;
184
185 HistoryLog historylog;
186
187 str::Str msg;
188 msg << "%posttrans scripts skipped while aborting:\n";
189 for ( const auto & script : _scripts )
190 {
191 const std::string & pkgident( script.first.substr( 0, script.first.size()-6 ) ); // strip tmp file suffix
192 WAR << "UNEXECUTED posttrans: " << script.first << endl;
193 msg << " " << pkgident << "\n";
194 }
195
196 historylog.comment( msg, true /*timestamp*/);
197 JobReport::warning( msg );
198
199 _scripts.clear();
200 }
201
202
203 private:
205 Pathname tmpDir()
206 {
207 if ( !_ptrTmpdir ) _ptrTmpdir.reset( new filesystem::TmpDir( _root / ZConfig::instance().update_scriptsPath(), "posttrans" ) );
208 DBG << _ptrTmpdir->path() << endl;
209 return _ptrTmpdir->path();
210 }
211
212 private:
213 Pathname _root;
214 std::list< std::pair< std::string, std::string > > _scripts;
215 boost::scoped_ptr<filesystem::TmpDir> _ptrTmpdir;
216 };
217
219 inline std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector::Impl & obj )
220 { return str << "RpmPostTransCollector::Impl"; }
221
223 inline std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector::Impl & obj )
224 { return str << obj; }
225
227 //
228 // CLASS NAME : RpmPostTransCollector
229 //
231
232 RpmPostTransCollector::RpmPostTransCollector( const Pathname & root_r )
233 : _pimpl( new Impl( root_r ) )
234 {}
235
236 RpmPostTransCollector::~RpmPostTransCollector()
237 {}
238
239 bool RpmPostTransCollector::collectScriptFromPackage( ManagedFile rpmPackage_r )
240 { return _pimpl->collectScriptFromPackage( rpmPackage_r ); }
241
242 bool RpmPostTransCollector::executeScripts()
243 { return _pimpl->executeScripts(); }
244
245 void RpmPostTransCollector::discardScripts()
246 { return _pimpl->discardScripts(); }
247
248 std::ostream & operator<<( std::ostream & str, const RpmPostTransCollector & obj )
249 { return str << *obj._pimpl; }
250
251 std::ostream & dumpOn( std::ostream & str, const RpmPostTransCollector & obj )
252 { return dumpOn( str, *obj._pimpl ); }
253
254 } // namespace target
256 } // namespace zypp
ExternalProgram.h
Gettext.h
Interface to gettext.
_
#define _(MSG)
Definition: Gettext.h:37
HistoryLog.h
LogTools.h
DBG
#define DBG
Definition: Logger.h:90
MIL
#define MIL
Definition: Logger.h:91
WAR
#define WAR
Definition: Logger.h:92
report
callback::SendReport< DownloadProgressReport > * report
Definition: MediaCurl.cc:70
NonCopyable.h
PathInfo.h
RpmHeader.h
RpmPostTransCollector.h
TmpPath.h
ZConfig.h
ZYppCallbacks.h
zypp::AutoDispose
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:93
zypp::ExternalProgram
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
Definition: ExternalProgram.h:60
zypp::ExternalProgram::Arguments
std::vector< std::string > Arguments
Definition: ExternalProgram.h:64
zypp::ExternalProgram::close
int close()
Wait for the progamm to complete.
Definition: ExternalProgram.cc:456
zypp::ExternalProgram::Stderr_To_Stdout
@ Stderr_To_Stdout
Definition: ExternalProgram.h:73
zypp::HistoryLog
Writing the zypp history file.
Definition: HistoryLog.h:57
zypp::HistoryLog::comment
void comment(const std::string &comment, bool timestamp=false)
Log a comment (even multiline).
Definition: HistoryLog.cc:188
zypp::ProgressData
Maintain [min,max] and counter (value) for progress counting.
Definition: ProgressData.h:131
zypp::ProgressData::value_type
long long value_type
Definition: ProgressData.h:133
zypp::ProgressData::sendTo
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: ProgressData.h:226
zypp::ProgressData::toMax
bool toMax()
Set counter value to current max value (unless no range).
Definition: ProgressData.h:273
zypp::ProgressData::name
void name(const std::string &name_r)
Set counter name.
Definition: ProgressData.h:222
zypp::ProgressData::ReceiverFnc
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: ProgressData.h:139
zypp::ProgressData::incr
bool incr(value_type val_r=1)
Increment counter value (default by 1).
Definition: ProgressData.h:261
zypp::ProgressData::toMin
bool toMin()
Set counter value to current min value.
Definition: ProgressData.h:269
zypp::ZConfig::instance
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:126
zypp::callback::UserData
Typesafe passing of user data via callbacks.
Definition: UserData.h:39
zypp::externalprogram::ExternalDataSource::receiveLine
std::string receiveLine()
Read one line from the input stream.
Definition: ExternalDataSource.cc:115
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:45
zypp::filesystem::Pathname::basename
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition: Pathname.h:110
zypp::filesystem::TmpDir
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition: TmpPath.h:178
zypp::filesystem::TmpFile
Provide a new empty temporary file and delete it when no longer needed.
Definition: TmpPath.h:128
zypp::filesystem::TmpPath::path
Pathname path() const
Definition: TmpPath.cc:146
zypp::filesystem::TmpPath::autoCleanup
bool autoCleanup() const
Whether path is valid and deleted when the last reference drops.
Definition: TmpPath.cc:163
zypp::target::RpmPostTransCollector::Impl
RpmPostTransCollector implementation.
Definition: RpmPostTransCollector.cc:44
zypp::target::RpmPostTransCollector::Impl::executeScripts
bool executeScripts()
Execute the remembered scripts.
Definition: RpmPostTransCollector.cc:85
zypp::target::RpmPostTransCollector::Impl::discardScripts
void discardScripts()
Discard all remembered scrips.
Definition: RpmPostTransCollector.cc:180
zypp::target::RpmPostTransCollector::Impl::~Impl
~Impl()
Definition: RpmPostTransCollector.cc:52
zypp::target::RpmPostTransCollector::Impl::_ptrTmpdir
boost::scoped_ptr< filesystem::TmpDir > _ptrTmpdir
Definition: RpmPostTransCollector.cc:215
zypp::target::RpmPostTransCollector::Impl::tmpDir
Pathname tmpDir()
Lazy create tmpdir on demand.
Definition: RpmPostTransCollector.cc:205
zypp::target::RpmPostTransCollector::Impl::_scripts
std::list< std::pair< std::string, std::string > > _scripts
Definition: RpmPostTransCollector.cc:214
zypp::target::RpmPostTransCollector::Impl::dumpOn
friend std::ostream & dumpOn(std::ostream &str, const Impl &obj)
zypp::target::RpmPostTransCollector::Impl::_root
Pathname _root
Definition: RpmPostTransCollector.cc:213
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::Impl::operator<<
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
zypp::target::RpmPostTransCollector::Impl::dumpOn
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Verbose stream output.
Definition: RpmPostTransCollector.cc:223
zypp::target::RpmPostTransCollector::Impl::operator<<
std::ostream & operator<<(std::ostream &str, const RpmPostTransCollector::Impl &obj)
Stream output.
Definition: RpmPostTransCollector.cc:219
zypp::target::RpmPostTransCollector::Impl::Impl
Impl(const Pathname &root_r)
Definition: RpmPostTransCollector.cc:48
zypp::target::RpmPostTransCollector
Extract and remember posttrans scripts for later execution.
Definition: RpmPostTransCollector.h:32
zypp::target::RpmPostTransCollector::RpmPostTransCollector
RpmPostTransCollector(const Pathname &root_r)
Default ctor.
Definition: RpmPostTransCollector.cc:232
zypp::target::RpmPostTransCollector::_pimpl
RW_pointer< Impl > _pimpl
Implementation class.
Definition: RpmPostTransCollector.h:58
zypp::target::RpmPostTransCollector::collectScriptFromPackage
bool collectScriptFromPackage(ManagedFile rpmPackage_r)
Extract and remember a packages posttrans script for later execution.
Definition: RpmPostTransCollector.cc:239
zypp::target::RpmPostTransCollector::executeScripts
bool executeScripts()
Execute the remembered scripts.
Definition: RpmPostTransCollector.cc:242
zypp::target::RpmPostTransCollector::~RpmPostTransCollector
~RpmPostTransCollector()
Dtor.
Definition: RpmPostTransCollector.cc:236
zypp::target::RpmPostTransCollector::discardScripts
void discardScripts()
Discard all remembered scrips.
Definition: RpmPostTransCollector.cc:245
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::target::rpm::RpmHeader::constPtr
intrusive_ptr< const RpmHeader > constPtr
Definition: RpmHeader.h:64
zypp::target::rpm::RpmHeader::NOVERIFY
@ NOVERIFY
Definition: RpmHeader.h:195
zypp::target::rpm::librpmDb::db_const_iterator
Subclass to retrieve database content.
Definition: librpmDb.h:337
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:776
librpmDb.h
str
String related utilities and Regular expression matching.
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
zypp::filesystem::addmod
int addmod(const Pathname &path, mode_t mode)
Add the mode bits to the file given by path.
Definition: PathInfo.cc:1063
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition: String.h:286
zypp::target::dumpOn
std::ostream & dumpOn(std::ostream &str, const RpmPostTransCollector &obj)
Definition: RpmPostTransCollector.cc:251
zypp::target::operator<<
std::ostream & operator<<(std::ostream &str, const CommitPackageCache &obj)
Definition: CommitPackageCache.cc:156
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
zypp::asString
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
Definition: DefaultIntegral.h:98
zypp::JobReport::warning
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
Definition: ZYppCallbacks.h:826
zypp::JobReport::info
static bool info(const std::string &msg_r, const UserData &userData_r=UserData())
send message text
Definition: ZYppCallbacks.h:822
zypp::ProgressReportAdaptor
Definition: ZYppCallbacks.h:59
zypp::callback::SendReport
Definition: Callback.h:237
zypp::str::Format
Convenient building of std::string with boost::format.
Definition: String.h:250
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:209