[packagekit] zypper patches + packages ...
ma at suse.de
Wed May 12 08:33:33 PDT 2010
On Tuesday 11 May 2010 18:33:10 Michael Meeks wrote:
> Riight; well - all that aside, the code I use is (no doubt)
> unbelievably nasty and is here; it's prolly simpler to review as code:
(used by zypp_get_package_updates)
Is it intended to ignore repository priorities as well as solver
policies (like allow vendor change) when looking for an update?
Anyway, there's no need to search through the whole pool in
order to find an appropriate item. There's a proxy for this:
Selectable: sort of container offering all PoolItems with the same
name and kind as item_r. Includes (all) installed versions; all
uninstalled versions in a list ordered by repoprioriy, arch,
edition ('best' candidate first). Also status manipulating methods.
\ \_ installed: PoolItem(glibc-1.0) < rpmdb
\ _ available: PoolItem(glibc-1.1) < repo-update (prio99)
PoolItem(glibc-1.0) < repo-oss (prio99)
PoolItem(glibc-1.0) < DVD (prio99)
PoolItem(glibc-2pm.0) < packman (prio100)
zypp_find_arch_update_item( ..., zypp::PoolItem item_r )
if ( ! item_r )
// Get the Selectable for item.
zypp::ui:Selectable::Ptr sel( zypp::ui:Selectable::get( item ) );
// (as item_r is valid, (sel != 0) is asserted
Now return one of the predefined items, or lookup the one you like best:
a) return sel->updateCandidateObj(); // The best candidate for update,
// if there is one.
b) return sel->highestAvailableVersionObj; // Simply the highest
// available version, ignoring priorities and policies.
c) for_( it, sel->availableBegin(), sel->availableEnd() )
zypp::PoolItem p( *it );
if ( fits_your_needs( p ) )
But maybe you don't need zypp_find_arch_update_item at all...
- Why excluding the(?) patch repo? Admitted that you ususally have one
patch repo on openSUSE, but that's just because others are probably too lazy
to offer patches. It's no problem to have more than one repo offering
patches, and ther's also no rule that would prevent such a repo to ship pure
package updates at the same time.
// Why not some smart ptr, reducing the risk of mem leaks?
std::set<zypp::PoolItem> *pks = new std::set<zypp::PoolItem> ();
// - zypp::ResPool pool = zypp::ResPool::instance ();
// Better use the proxy, so you process each (package) name only
// once. I.e. you iterate Selectables not PoolItems:
zypp::ResPoolProy selPool( ResPool::instance().proxy() );
for_( it, selPool.byKindBegin<Package>(), selPool.byKindEnd<Package>() )
zypp::ui::Selectable::Ptr sel( *it ); // != 0 asserted in ResPoolProy
// now e.g:
zypp::PoolItem candidate( sel->updateCandidateObj() );
// (!candiate) would mean package is not installed or
// there is no 'better' package which does not violate
// any solver policy. There may be higher 'versions'
// available in low prio repos or from different vendor...
if ( candidate && ! candidate.status().isLocked() )
std::set<zypp::PoolItem> *candidates = zypp_get_patches ();
std::set<zypp::PoolItem> *packages = zypp_get_package_updates();
Now you want to exclude all package_updates which are also covered by patches?
(maybe include zypp/IdString.h)
zypp::IdStringSet covered; // collect names of packages updated by patches
for_( it, candidates->begin(), candidates->end() )
zypp::Patch::constPtr patch( it->asKind<zypp::Patch>() );
if ( ! patch )
zypp::Patch::Contents contents( patch->contents() );
for_( c, contents.begin(), contents.end() )
covered.insert( c->ident() );
// Take the packages not updated by a patch
for_( it, packages.begin(), packages.end() )
if ( covered.find( (*it)->ident() ) == covered.end() )
candidates->insert( *it );
Just a note about line 746:
for (pki = patch->contents().begin(); pki != patch->contents().end(); pki++)
You should avoid calling .begin() and .end() on a container returned by value
by some function call in the loop header. The first and the second
patch->contents() return 2 different SolvableSets. What you do is:
Container a = patch->contents();
Container b = patch->contents();
for( pki = a.begin(); pki != b.end(), ++pki )
You're lucky if the container type has a common representation for end()
(a.end() == b.end()). Even if patch->contents() returned a reference, you'd
need to be sure the implementation does not perform any operation which might
invalidate previously retrieved iterators.
> I was slightly interested in the naming of patches (as PackageKit sees
> them), we appear to return a package name:
> based on a zypp::Patch's ->satSolvable() name / ver / etc. details;
> presumably it works well since it's what we did before :-) is there a
> pseudo-package created for a patch ?
If you call the Solvable a pseudo-package - yes.
libzypp in 10 seconds:
A Solvable is an item with name, version, arch, dependencies (simplified).
Thus Packages as well as Patterns, Patches, Products, even Sourcepackages are
A PoolItem is a Solvable + its associated status (or fate; keep, install,
The satsolver knows about all the Solvables, gets a bunch of job requests
(lock this, update that,..) and tries to produce some reasonable result. This
result is then translated into new Solvable fates (PoolItem changes status,
or call it a transaction).
The ResPool is the place where all PoolItems live.
A Selectable finally is the collection of all PoolItems with the same name.
It maintains a single status by combining the individual PoolItem fates.
And it helps translating user requests into solver jobs. If you say 'update
glibc' the Selectable thinks about how to explain it to the resolver without
asking you to be more specific, because there are 6 glibcs for two different
architectures available in 3 repositories....
The ResPoolProxy is the Selectable view to the pool.
Usually faster and more convenient than iterating over the pool and manually
collecting the matching Poolitems.
The rest is a bit repo handling, some comments and debug output. ;)
> Advice much appreciated, I have no
> idea what I'm doing there (as you can probably see by now).
Hmm. Do you feel better or worse now?
Key fingerprint = 2DFA 5D73 18B1 E7EF A862 27AC 3FB8 9E3A 27C6 B0E4
Michael Andres YaST Development ma at novell.com
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg)
Maxfeldstrasse 5, D-90409 Nuernberg, Germany, ++49 (0)911 - 740 53-0
More information about the PackageKit