RPM Community Forums

Mailing List Message of <rpm-users>

Re: 'Obsolotes' and 'Requires'

From: Jeff Johnson <n3npq@mac.com>
Date: Tue 02 Jun 2009 - 00:32:09 CEST
Message-id: <12BDF7E9-C606-461C-87AC-C109DFD5A768@mac.com>

On Jun 1, 2009, at 5:37 PM, Anshuman Kanetkar wrote:

> Jeff,
>    Thanks for asking :).
> Here is what I want to accomplish:
> - Consider a system, with the state of its  package database and
> installed packages at some state S0.
> - Now, there is a sequence of available upgrades U1 and U2  already
> published for this system, that take it to
> states S1 and S2 respectively.
> - Each upgrade is a set of one or more RPMs.
> - Each upgrade can perform only one state transition - i.e. the  
> shortest one.
> e.g. U1 takes the system from S0 to S1
>       U2 from S1 to S2, and so on.
> - Now, can the package creator construct an upgrade U3, such that it
> can upgrade a system from state S0 to a state S3, by forcing
> transitions from S0 through S2 using package-level dependencies? (Just
> so that Yum can sequence the updates, rather than the package creator
> having to write her upgrade packages to explicitly check for
> dependencies)
> As part of this, some scenarios would be:
> - If a  package  requires a previous version of the same package as a
> prerequisite, can this be expressed in the RPM spec? (Does this work?
> I am guessing it does.)
> - Now some packages from U3 could only depend on side-effects of
> packages in U1/U2. As long as erasing those packages does not undo
> those side-effects, I would want to preserve the side-effects, but
> erase the packages.
> I figured one way to achieve this would be obsolescence. So, can a
> package 'a.rpm' require 'b.rpm', but also obsolete it? Is the
> 'requires' relation only a pre-installation check (i.e. it doesn't
> matter if b is removed later during the transaction), or does it imply
> a & b *must* co-exist? What would be the sequence of actions in this
> case?
> And of course, is there a different, better way to achieve the same  
> result?

OK, I think I see what you want.

Let me try to describe what rpm does while upgrading.

First of all, during a single upgrade transaction, RPM
distinguishes between the "installed" and "added" package sets.

What you appear to miss (my guess from what you asked for)
is that Obsoletes: is a directive applied to the "installed"
set at the time the package that has the Obsoletes: is
included in the "added" set. So Obsoletes: by itself will
only cause an already "installed" package to be removed at
one instance in time. There is no persistence, nor is Obsoletes:
applied to the "added" set.

What that likely means for your S0 -> S1 -> S2 -> S3
state transitions induced by U1, U2, U3 carrier packages is
that the N+1 U package must Obsolete: members that were
installed at level N. I believe you wanted U at level N
to have the Obsoletes:, and the Obsoletes: must be at level N+1 instead,
because Obsoletes: is honored only at a single instance
in time, and applied only against "installed", packages,
and that's at the point where the N+1 transaction is being assembled.

The other detail that you may be missing (its hard to tell whether
you want a strict "sequence" through the intermediate Sn stages or
an optimized "sequence" that just jumps from S0 -> S3) is how
RPM upgrades "newer" packages. For packages with identical
names, RPM will eliminate all older versions, even multiple instances
with different versions, when upgrading to a "newer" package with the  
same name.

There's one other detail that must be mentioned as well. Any single  
can have only a single package with a given name. If multiple versions  
of an
identical package are requested in a single name, then the "newest"  
will be used, older versions will be silently dropped from the  
and replaced with the "newest" version.

So within the restriction of identically named packages, the  
transition from
S0 -> S3 using a U3 carrier (i.e. with Requires:) will usually do an
optimized transition, replacing all possible older versions with the
identically named "newer" version. That's basically what I called
an "optimized sequence". If you want a strict "sequence" then the  
_MUST_ go through U1 -> U2 to get to installing U3 because, in general,
there will be multiple versions of identically named packages  
involved, and
so multiple transactions must be constructed for strict sequencing.

There are details with package re-naming that can be handled by  
expressing the
Obsoletes: differently. At least @rpm5.org,
	Obsoletes: /path/to/file
	Obsoletes: virtualprovide = E:V-R
will erase the package that "contains" whatever matches, and so one can
work around package renaming with Obsoletes: directives on contents if  
But I suggest trying to keep the packages identically named if at all
possible, its a nightmare to debug upgrades when the namespace is in  
constant flux.

I think you've got the usage case of Un having Requires: on the  
elements in
the set of packages that constitutes a Sn-1 -> Sn transition. All  
are pre-requisites, not co-requisites, unless there are loops, in  
which case
the Requires: will be assertion checked, but the Requires: will be  
while ordering packages.

Does this answer your questions? If not, try again, and I will try
to be as specific and literal as possible.

73 de Jeff
Received on Tue Jun 2 00:32:34 2009
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.