libzypp  17.37.5
ZYppCommitPolicy.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #include <iostream>
14 
15 #include <zypp-core/base/String.h>
16 #include <zypp-core/base/StringV.h>
17 
18 #include <zypp/ZConfig.h>
19 #include <zypp-core/APIConfig.h>
20 #include <zypp/ZYppCommitPolicy.h>
22 #include <zypp-core/TriBool.h>
23 #include <zypp/PathInfo.h>
24 #include <zypp/ZYppCallbacks.h>
25 #include <zypp/ZYppFactory.h>
26 
28 namespace 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
67 
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 
134  : _pimpl( new Impl )
135  {}
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  {
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 
186 
188  { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_REPLACEFILES, yesNo_r ); return *this; }
189 
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
bool strToFalse(const C_Str &str)
Return false if str is 0, false, no, off, never.
Definition: String.cc:84
DownloadMode downloadMode() const
Container of Solvable providing a Capability (read only).
Definition: WhatProvides.h:87
Alternating download and install.
Definition: DownloadMode.h:34
First download all packages to the local cache.
Definition: DownloadMode.h:29
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like &#39;readlink&#39;.
Definition: PathInfo.cc:929
ZYppCommitPolicy & rpmInstFlags(target::rpm::RpmInstFlags newFlags_r)
The default target::rpm::RpmInstFlags.
ZYppCommitPolicy & dryRun(bool yesNo_r)
Set dry run (default: false).
String related utilities and Regular expression matching.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Definition: SerialNumber.cc:52
bool singleTransEnabled()
target::rpm::RpmInstFlags rpmInstFlags() const
bool transactionWillUsrmerge()
Options and policies for ZYpp::commit.
ZYppCommitPolicy & downloadMode(DownloadMode val_r)
Commit download policy to use.
Interim helper class to collect global options and settings.
Definition: ZConfig.h:68
#define WAR
Definition: Logger.h:101
ZYppCommitPolicy & syncPoolAfterCommit(bool yesNo_r)
Kepp pool in sync with the Target databases after commit (default: true)
bool pendingUsrmerge()
ZYppCommitPolicy & restrictToMedia(unsigned mediaNr_r)
Restrict commit to media 1.
Impl * clone() const
clone for RWCOW_pointer
RWCOW_pointer< Impl > _pimpl
Pointer to data.
A sat capability.
Definition: Capability.h:62
bool isPreUsrmerge(const Pathname &root_r)
Typesafe passing of user data via callbacks.
Definition: UserData.h:39
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:225
bool singleTransModeEnabled() const
Whether the single_rpmtrans backend is enabled (or the classic_rpmtrans)
static bool info(const std::string &msg_r, const UserData &userData_r=UserData())
send message text
bool syncPoolAfterCommit() const
target::rpm::RpmInstFlags _rpmInstFlags
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
std::string hexstring(char n, int w=4)
Definition: String.h:325
unsigned restrictToMedia() const
#define DBG
Definition: Logger.h:99
DownloadMode
Supported commit download policies.
Definition: DownloadMode.h:24