libzypp  17.36.3
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/ZYppCommitPolicy.h>
21 #include <zypp-core/TriBool.h>
22 #include <zypp/PathInfo.h>
23 #include <zypp/ZYppCallbacks.h>
24 #include <zypp/ZYppFactory.h>
25 
27 namespace zypp
28 {
29 
30  inline bool ImZYPPER()
31  {
32  static bool ret = filesystem::readlink( "/proc/self/exe" ).basename() == "zypper";
33  return ret;
34  }
35 
36  inline bool singleTransInEnv()
37  {
38  const char *val = ::getenv("ZYPP_SINGLE_RPMTRANS");
39  return ( val && std::string_view( val ) == "1" );
40  }
41 
42  inline bool singleTransEnabled()
43  {
44 #ifdef SINGLE_RPMTRANS_AS_DEFAULT_FOR_ZYPPER
45  return ImZYPPER();
46 #else // SINGLE_RPMTRANS_AS_DEFAULT_FOR_ZYPPER
47  return ImZYPPER() && singleTransInEnv();
48 #endif // SINGLE_RPMTRANS_AS_DEFAULT_FOR_ZYPPER
49  }
50 
51 
52  inline bool isPreUsrmerge( const Pathname & root_r )
53  {
54  // If systems /lib is a directory and not a symlink.
55  return PathInfo( root_r / "lib", PathInfo::LSTAT ).isDir();
56  }
57 
59  {
60  // A package providing "may-perform-usrmerge" is going to be installed.
61  const sat::WhatProvides q { Capability("may-perform-usrmerge") };
62  for ( const auto & pi : q.poolItem() ) {
63  if ( pi.status().isToBeInstalled() )
64  return true;
65  }
66  return false;
67  }
68 
69  inline bool pendingUsrmerge()
70  {
71  // NOTE: Bug 1189788 - UsrMerge: filesystem package breaks system when
72  // upgraded in a single rpm transaction. Target::Commit must amend this
73  // request depending on whether a UsrMerge may be performed by the
74  // transaction.
75  Target_Ptr target { getZYpp()->getTarget() };
76  bool ret = target && isPreUsrmerge( target->root() ) && transactionWillUsrmerge();
77  return ret;
78  }
79 
81  //
82  // CLASS NAME : ZYppCommitPolicy::Impl
83  //
85 
87  {
88  public:
89  Impl()
90  : _restrictToMedia ( 0 )
91  , _downloadMode ( ZConfig::instance().commit_downloadMode() )
92  , _rpmInstFlags ( ZConfig::instance().rpmInstallFlags() )
93  , _syncPoolAfterCommit ( true )
95  {}
96 
97  public:
98  unsigned _restrictToMedia;
100  target::rpm::RpmInstFlags _rpmInstFlags;
102  mutable bool _singleTransMode; // mutable: [bsc#1189788] pending usrmerge must disable singletrans
103 
104  private:
105  friend Impl * rwcowClone<Impl>( const Impl * rhs );
107  Impl * clone() const { return new Impl( *this ); }
108  };
109 
111  //
112  // CLASS NAME : ZYppCommitPolicy
113  //
115 
117  : _pimpl( new Impl )
118  {}
119 
120 
122  { _pimpl->_restrictToMedia = ( mediaNr_r == 1 ) ? 1 : 0; return *this; }
123 
125  { return _pimpl->_restrictToMedia; }
126 
127 
129  { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_TEST, yesNo_r ); return *this; }
130 
132  { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_TEST );}
133 
135  { _pimpl->_downloadMode = val_r; return *this; }
136 
138  {
140  DBG << _pimpl->_downloadMode << " is not compatible with singleTransMode, falling back to " << DownloadInAdvance << std::endl;
141  return DownloadInAdvance;
142  }
143  return _pimpl->_downloadMode;
144  }
145 
146  ZYppCommitPolicy & ZYppCommitPolicy::rpmInstFlags( target::rpm::RpmInstFlags newFlags_r )
147  { _pimpl->_rpmInstFlags = newFlags_r; return *this; }
148 
150  { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_NOSIGNATURE, yesNo_r ); return *this; }
151 
153  { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_EXCLUDEDOCS, yesNo_r ); return *this; }
154 
155  target::rpm::RpmInstFlags ZYppCommitPolicy::rpmInstFlags() const
156  { return _pimpl->_rpmInstFlags; }
157 
159  { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_NOSIGNATURE ); }
160 
162  { return _pimpl->_rpmInstFlags.testFlag( target::rpm::RPMINST_EXCLUDEDOCS ); }
163 
165  { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_ALLOWDOWNGRADE, yesNo_r ); return *this; }
166 
169 
171  { _pimpl->_rpmInstFlags.setFlag( target::rpm::RPMINST_REPLACEFILES, yesNo_r ); return *this; }
172 
175 
177  { _pimpl->_syncPoolAfterCommit = yesNo_r; return *this; }
178 
180  { return _pimpl->_syncPoolAfterCommit; }
181 
183  {
184  if ( _pimpl->_singleTransMode and pendingUsrmerge() ) {
185  WAR << "Ignore $ZYPP_SINGLE_RPMTRANS=1: Bug 1189788 - UsrMerge: filesystem package breaks system when upgraded in a single rpm transaction" << std::endl;
187  "[bsc#1189788] The filesystem package seems to be unable to perform the pending\n"
188  " UsrMerge reliably in a single transaction. The single_rpmtrans\n"
189  " backend will therefore be IGNORED and the transaction is performed\n"
190  " by the classic_rpmtrans backend."
191  , JobReport::UserData( "cmdout", "[bsc#1189788]" ) );
192  _pimpl->_singleTransMode = false;
193  }
194  return _pimpl->_singleTransMode;
195  }
196 
197  std::ostream & operator<<( std::ostream & str, const ZYppCommitPolicy & obj )
198  {
199  str << "CommitPolicy(";
200  if ( obj.restrictToMedia() )
201  str << " restrictToMedia:" << obj.restrictToMedia();
202  if ( obj.dryRun() )
203  str << " dryRun";
204  str << " " << obj.downloadMode();
205  if ( obj.syncPoolAfterCommit() )
206  str << " syncPoolAfterCommit";
207  if ( obj.rpmInstFlags() )
208  str << " rpmInstFlags{" << str::hexstring(obj.rpmInstFlags()) << "}";
209  return str << " )";
210  }
211 
213 } // namespace zypp
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()
bool ImZYPPER()
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 singleTransInEnv()
bool singleTransModeEnabled() const
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:324
unsigned restrictToMedia() const
#define DBG
Definition: Logger.h:99
DownloadMode
Supported commit download policies.
Definition: DownloadMode.h:24