2 // g++ -Wall zypp-install.cc -l zypp -o zypp-install
4 // A small (and simple) demo which walks through zypp, initializing
5 // and refreshing the repos, selecting packages ('zypper dup'),
6 // resolving dependencies and finally comitting/installing the
7 // result (in dry-run mode).
9 // No callbacks, questions or fancy output during commit, but it will
10 // do a 'zypper dup' if you'd remove the DryRun and DownloadOnly flag.
12 // So be careful if running it as root.
16 #define TEST_DEBUGLOG 0
19 #include <zypp/base/LogControl.h>
21 #include <zypp/ZYppFactory.h>
22 #include <zypp/RepoManager.h>
23 #include <zypp/ResPool.h>
31 ////////////////////////////////////////////////////////////////////////////////
32 int main( int argc, char * argv[] )
37 #warning debug log is on
38 base::LogControl::instance().logfile( "/tmp/zypp-install.log" );
41 Pathname sysRoot( "/" );
42 ZYpp::Ptr zypp = getZYpp(); // acquire initial zypp lock
44 ////////////////////////////////////////////////////////////////////////////////
47 cout << "Initialize target at " << sysRoot << endl;
48 zypp->initializeTarget( sysRoot ); // initialize target
49 cout << "Loading target resolvables" << endl;
50 zypp->getTarget()->load(); // load installed packages to pool
53 ////////////////////////////////////////////////////////////////////////////////
56 RepoManager repoManager( sysRoot );
58 // sync the current repo set
59 for ( RepoInfo & nrepo : repoManager.knownRepositories() )
61 if ( ! nrepo.enabled() )
64 // Often volatile media are sipped in automated environments
65 // to avoid media chagne requests:
66 if ( nrepo.url().schemeIsVolatile() )
69 bool refreshNeeded = false;
70 if ( nrepo.autorefresh() ) // test whether to autorefresh repo metadata
72 for ( const Url & url : nrepo.baseUrls() )
76 if ( repoManager.checkIfToRefreshMetadata( nrepo, url ) == RepoManager::REFRESH_NEEDED )
78 cout << "Need to autorefresh repo " << nrepo.alias() << endl;
81 break; // exit after first successful checkIfToRefreshMetadata
83 catch ( const Exception & exp )
84 {} // Url failed, try next one...
86 // If all urls failed we can leave it to the code below to
87 // fail if access is actually needed and still failing.
88 // (missing metadata, package download, ...)
91 // initial metadata download or cache refresh
92 if ( ! repoManager.isCached( nrepo ) || refreshNeeded )
94 cout << "Refreshing repo " << nrepo << endl;
95 if ( repoManager.isCached( nrepo ) )
97 repoManager.cleanCache( nrepo );
99 repoManager.refreshMetadata( nrepo );
100 repoManager.buildCache( nrepo );
106 cout << "Loading resolvables from " << nrepo.alias() << endl;
107 repoManager.loadFromCache( nrepo );// load available packages to pool
109 catch ( const Exception & exp )
111 // cachefile has old fomat (or is corrupted): try yo rebuild it
112 repoManager.cleanCache( nrepo );
113 repoManager.buildCache( nrepo );
114 repoManager.loadFromCache( nrepo );
119 cout << zypp->pool() << endl;
120 cout << "=====[pool ready]==============================" << endl;
122 ////////////////////////////////////////////////////////////////////////////////
124 ////////////////////////////////////////////////////////////////////////////////
126 ////////////////////////////////////////////////////////////////////////////////
127 // Select package to install...
128 // For demo purpose do 'zypper dup'
129 // otherwise select manually whatever you need...
130 zypp->resolver()->doUpgrade();
133 ////////////////////////////////////////////////////////////////////////////////
134 // solve selection...
136 cout << "Solving dependencies..." << endl;
138 unsigned attempt = 0;
139 while ( ! zypp->resolver()->resolvePool() )
142 cout << "Solving dependencies: " << attempt << ". attempt failed" << endl;
143 const ResolverProblemList & problems( zypp->resolver()->problems() );
144 cout << problems.size() << " problems found..." << endl;
146 // ==============================
147 // kdepim3-3.5.10-29.1.4.x86_64 requires libsasl2.so.2()(64bit), but this requirement
148 // cannot be provided deleted providers: cyrus-sasl-2.1.25-28.1.2.x86_64
149 // ------------------------------
151 // keep obsolete cyrus-sasl-2.1.25-28.1.2.x86_64
153 // remove lock to allow removal of kdepim3-3.5.10-29.1.4.x86_64
155 // remove lock to allow removal of kdepim3-3.5.10-29.1.4.x86_64
157 // break kdepim3-3.5.10-29.1.4.x86_64 by ignoring some of its dependencies
159 ProblemSolutionList totry; // only needed if you (interactively) resolve problems...
162 for ( const auto & probPtr : problems )
164 cout << "Problem " << ++probNo << ": " << probPtr->description() << endl;
166 const ProblemSolutionList & solutions = probPtr->solutions();
168 for ( const auto & solPtr : solutions )
170 cout << " Solution " << ++solNo << ": " << solPtr->description() << endl;
173 // if you (interactively) resolve problems pick 1 solution per problem
174 // and store it int the totry list. After having applied the selected
175 // start a new attempt.
177 // It's not necessary to process all problems. You can pick a solution
178 // for the first problem and retry immediately. Often one solution actually
179 // resolves more than one reported problem.
181 // totry.push_back( solPtr );
185 if ( ! totry.empty() )
187 cout << "Apply selected solutions..." << endl;
188 zypp->resolver()->applySolutions( totry );
189 cout << "Solving dependencies..." << endl;
193 throw "Solving dependencies failed: Giving up!";
195 cout << "Dependencies solved" << endl;
198 ////////////////////////////////////////////////////////////////////////////////
199 // printing some stats...
202 cout << "PoolItem summary (individual packages):" << endl;
203 for ( const PoolItem & pi : zypp->pool() )
205 if ( pi.status().transacts() )
206 cout << " " << pi << endl;
211 cout << "Selectable summary (grouped by name):" << endl;
212 for ( const ui::Selectable_Ptr & sel : zypp->pool().proxy() )
214 if ( sel->toModify() )
215 cout << " " << sel << endl;
219 ////////////////////////////////////////////////////////////////////////////////
222 cout << "Going to commit..." << endl;
223 // dryRun and DownloadOnly will cause commit to skip
224 // transaction steps, so you want to check for 'noError'
225 // rather than 'allDone'.
226 bool dryRunEtc = false;
228 ZYppCommitPolicy policy;
231 policy.dryRun( true );
236 policy.downloadMode( DownloadOnly );
242 ZYppCommitResult result = zypp->commit( policy ); // go....
243 if ( ! ( result.allDone() || ( dryRunEtc && result.noError() ) ) )
245 throw "Incomplete commit!";
246 // ZYppCommitResult offers access to the TransactionStepList
247 // where you can see which packages have been processed and
250 cout << "Commit succeeded" << endl;
252 catch ( const Exception & exp )
254 cout << "Commit aborted with exception:" << endl;
258 cout << "[bye]: " << endl;
261 catch ( const Exception & exp )
262 { cerr << exp << endl << exp.historyAsString(); exit( 91 ); }
263 catch ( const std::exception & exp )
264 { cerr << exp.what() << endl; exit( 92 ); }
265 catch ( const char * exp )
266 { cerr << (exp?exp:"Oops!") << endl; exit( 93 ); }
268 { cerr << "Oops!" << endl; exit( 94 ); }