libzypp 17.37.5
ZYppCommitPolicy.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12
13#include <iostream>
14
17
18#include <zypp/ZConfig.h>
19#include <zypp-core/APIConfig.h>
22#include <zypp-core/TriBool.h>
23#include <zypp/PathInfo.h>
24#include <zypp/ZYppCallbacks.h>
25#include <zypp/ZYppFactory.h>
26
28namespace zypp
29{
30
32#ifdef SUSE
33
34#if APIConfig(LIBZYPP_CONFIG_USE_CLASSIC_RPMTRANS_BY_DEFAULT)
35 // In old codebases it can be explicitly enabled for zypper only via ZYPP_SINGLE_RPMTRANS.
36 inline bool ImZYPPER()
37 {
38 static bool ret = filesystem::readlink( "/proc/self/exe" ).basename() == "zypper";
39 return ret;
40 }
41 inline bool singleTransInEnv()
42 {
43 const char *val = ::getenv("ZYPP_SINGLE_RPMTRANS");
44 return ( val && str::strToFalse( val ) );
45 }
46 inline bool singleTransEnabled()
47 { return ImZYPPER() && singleTransInEnv(); }
48#else
49 // SUSE using singletrans as default may allow to explicitly disable it via ZYPP_SINGLE_RPMTRANS.
50 // NOTE: singleTransInEnv() here is no real enablement because it defaults to false
51 // if ZYPP_SINGLE_RPMTRANS is undefined. By now it just allows using singletrans
52 // with all applications, not just zypper. In case it actually becomes the
53 // default on SUSE, we may just want a method to explicitly disable it.
54 inline bool singleTransInEnv()
55 {
56 const char *val = ::getenv("ZYPP_SINGLE_RPMTRANS");
57 return ( val && str::strToFalse( val ) );
58 }
59 inline bool singleTransEnabled()
60 { return singleTransInEnv(); }
61#endif
62
63#else // not SUSE
64 inline bool singleTransEnabled()
65 { return true; }
66#endif
68
69 inline bool isPreUsrmerge( const Pathname & root_r )
70 {
71 // If systems /lib is a directory and not a symlink.
72 return PathInfo( root_r / "lib", PathInfo::LSTAT ).isDir();
73 }
74
76 {
77 // A package providing "may-perform-usrmerge" is going to be installed.
78 const sat::WhatProvides q { Capability("may-perform-usrmerge") };
79 for ( const auto & pi : q.poolItem() ) {
80 if ( pi.status().isToBeInstalled() )
81 return true;
82 }
83 return false;
84 }
85
86 inline bool pendingUsrmerge()
87 {
88 // NOTE: Bug 1189788 - UsrMerge: filesystem package breaks system when
89 // upgraded in a single rpm transaction. Target::Commit must amend this
90 // request depending on whether a UsrMerge may be performed by the
91 // transaction.
92 Target_Ptr target { getZYpp()->getTarget() };
93 bool ret = target && isPreUsrmerge( target->root() ) && transactionWillUsrmerge();
94 return ret;
95 }
96
98 //
99 // CLASS NAME : ZYppCommitPolicy::Impl
100 //
102
104 {
105 public:
107 : _restrictToMedia ( 0 )
108 , _downloadMode ( ZConfig::instance().commit_downloadMode() )
109 , _rpmInstFlags ( ZConfig::instance().rpmInstallFlags() )
110 , _syncPoolAfterCommit ( true )
112 {}
113
114 public:
117 target::rpm::RpmInstFlags _rpmInstFlags;
119 mutable bool _singleTransMode; // mutable: [bsc#1189788] pending usrmerge must disable singletrans
120
121 private:
122 friend Impl * rwcowClone<Impl>( const Impl * rhs );
124 Impl * clone() const { return new Impl( *this ); }
125 };
126
128 //
129 // CLASS NAME : ZYppCommitPolicy
130 //
132
136
137
139 { _pimpl->_restrictToMedia = ( mediaNr_r == 1 ) ? 1 : 0; return *this; }
140
142 { return _pimpl->_restrictToMedia; }
143
144
146 { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_TEST, yesNo_r ); return *this; }
147
149 { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_TEST );}
150
152 { _pimpl->_downloadMode = val_r; return *this; }
153
155 {
156 if ( singleTransModeEnabled() && _pimpl->_downloadMode == DownloadAsNeeded ) {
157 DBG << _pimpl->_downloadMode << " is not compatible with singleTransMode, falling back to " << DownloadInAdvance << std::endl;
158 return DownloadInAdvance;
159 }
160 return _pimpl->_downloadMode;
161 }
162
163 ZYppCommitPolicy & ZYppCommitPolicy::rpmInstFlags( target::rpm::RpmInstFlags newFlags_r )
164 { _pimpl->_rpmInstFlags = newFlags_r; return *this; }
165
167 { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_NOSIGNATURE, yesNo_r ); return *this; }
168
170 { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_EXCLUDEDOCS, yesNo_r ); return *this; }
171
172 target::rpm::RpmInstFlags ZYppCommitPolicy::rpmInstFlags() const
173 { return _pimpl->_rpmInstFlags; }
174
176 { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_NOSIGNATURE ); }
177
179 { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_EXCLUDEDOCS ); }
180
182 { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_ALLOWDOWNGRADE, yesNo_r ); return *this; }
183
185 { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_ALLOWDOWNGRADE ); }
186
188 { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_REPLACEFILES, yesNo_r ); return *this; }
189
191 { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_REPLACEFILES ); }
192
194 { _pimpl->_syncPoolAfterCommit = yesNo_r; return *this; }
195
197 { return _pimpl->_syncPoolAfterCommit; }
198
200 {
201 if ( _pimpl->_singleTransMode and pendingUsrmerge() ) {
202 WAR << "Ignore $ZYPP_SINGLE_RPMTRANS=1: Bug 1189788 - UsrMerge: filesystem package breaks system when upgraded in a single rpm transaction" << std::endl;
204 "[bsc#1189788] The filesystem package seems to be unable to perform the pending\n"
205 " UsrMerge reliably in a single transaction. The single_rpmtrans\n"
206 " backend will therefore be IGNORED and the transaction is performed\n"
207 " by the classic_rpmtrans backend."
208 , JobReport::UserData( "cmdout", "[bsc#1189788]" ) );
209 _pimpl->_singleTransMode = false;
210 }
211 return _pimpl->_singleTransMode;
212 }
213
214 std::ostream & operator<<( std::ostream & str, const ZYppCommitPolicy & obj )
215 {
216 str << "CommitPolicy(";
217 if ( obj.restrictToMedia() )
218 str << " restrictToMedia:" << obj.restrictToMedia();
219 if ( obj.dryRun() )
220 str << " dryRun";
221 str << " " << obj.downloadMode();
222 if ( obj.syncPoolAfterCommit() )
223 str << " syncPoolAfterCommit";
224 if ( obj.rpmInstFlags() )
225 str << " rpmInstFlags{" << str::hexstring(obj.rpmInstFlags()) << "}";
226 return str << " )";
227 }
228
230} // namespace zypp
A sat capability.
Definition Capability.h:63
Interim helper class to collect global options and settings.
Definition ZConfig.h:69
Impl * clone() const
clone for RWCOW_pointer
friend Impl * rwcowClone(const Impl *rhs)
target::rpm::RpmInstFlags _rpmInstFlags
ZYppCommitPolicy & rpmInstFlags(target::rpm::RpmInstFlags newFlags_r)
The default target::rpm::RpmInstFlags.
bool singleTransModeEnabled() const
Whether the single_rpmtrans backend is enabled (or the classic_rpmtrans)
ZYppCommitPolicy & syncPoolAfterCommit(bool yesNo_r)
Kepp pool in sync with the Target databases after commit (default: true)
ZYppCommitPolicy & dryRun(bool yesNo_r)
Set dry run (default: false).
ZYppCommitPolicy & restrictToMedia(unsigned mediaNr_r)
Restrict commit to media 1.
DownloadMode downloadMode() const
target::rpm::RpmInstFlags rpmInstFlags() const
ZYppCommitPolicy & downloadMode(DownloadMode val_r)
Commit download policy to use.
unsigned restrictToMedia() const
RWCOW_pointer< Impl > _pimpl
Pointer to data.
ZYpp::Ptr getZYpp()
Convenience to get the Pointer to the ZYpp instance.
Definition ZYppFactory.h:77
Wrapper class for stat/lstat.
Definition PathInfo.h:226
Container of Solvable providing a Capability (read only).
String related utilities and Regular expression matching.
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like 'readlink'.
Definition PathInfo.cc:929
std::string hexstring(char n, int w=4)
Definition String.h:325
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
Definition String.cc:84
Easy-to use interface to the ZYPP dependency resolver.
bool pendingUsrmerge()
bool isPreUsrmerge(const Pathname &root_r)
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
bool singleTransEnabled()
bool transactionWillUsrmerge()
DownloadMode
Supported commit download policies.
@ DownloadAsNeeded
Alternating download and install.
@ DownloadInAdvance
First download all packages to the local cache.
callback::UserData UserData
typsafe map of userdata
static bool info(const std::string &msg_r, const UserData &userData_r=UserData())
send message text
#define DBG
Definition Logger.h:99
#define WAR
Definition Logger.h:101