Bug 454556

Summary: rpm transaction continues when it shouldn't
Product: Red Hat Enterprise Linux 5 Reporter: Mustafa Jamil <mustafa_jamil>
Component: rpmAssignee: Panu Matilainen <pmatilai>
Status: CLOSED WONTFIX QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: 5.2   
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2008-10-02 12:55:10 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Mustafa Jamil 2008-07-08 22:04:15 UTC
Description of problem:

Let's say you have two packages, A and A-dependent.  
A-dependent specifies a PreReq dependency on A.  
A has a %pre scriptlet that consistently fails.

This means that A on its own cannot install:

[root@mjamil-dev2 SPECS]# rpm -Uvh A-1-1.x86_64.rpm
Preparing...                ########################################### [100%]
error: %pre(A-1-1.x86_64) scriptlet failed, exit status 1
error:   install: %pre scriptlet failed (2), skipping A-1-1

[root@mjamil-dev2 SPECS]# echo $?
1

This also means that A-dependent on its own cannot install:

[root@mjamil-dev2 SPECS]# rpm -Uvh A-dependent-1-1.x86_64.rpm 
error: Failed dependencies:
        A is needed by A-dependent-1-1.x86_64

[root@mjamil-dev2 SPECS]# echo $?
1

If you try to install both together, neither should install, since A cannot
install and A-dependent requires A to be installed properly before it can install.

But (and here's the bug) rpm allows A-dependent to install anyway (suggesting
that the rpm transaction simply ignores dependency checking at actual
installation time):

[root@mjamil-dev2 SPECS]# rpm -Uvh A-1-1.x86_64.rpm A-dependent-1-1.x86_64.rpm 
Preparing...                ########################################### [100%]
error: %pre(A-1-1.x86_64) scriptlet failed, exit status 1
error:   install: %pre scriptlet failed (2), skipping A-1-1
   1:A-dependent            ########################################### [ 50%]

[root@mjamil-dev2 SPECS]# rpm -q A-dependent
A-dependent-1-1


Version-Release number of selected component (if applicable):
rpm-4.4.2-48

How reproducible:
Always


Here's a simple spec file to generate the A and A-dependent rpms:

-- START --

%define _basename A

Name: %{_basename}
Version: 1
Release: 1
Summary: Package %{_basename}
Group: System/Utilities
License: GPLv2

%description
Hi. I'm package %{_basename}. Package %{_basename}-dependent requires me
to be installed properly before it can be installed.

%files

%pre
exit 1


%package dependent
Version: 1
Release: 1
Summary: Package %{_basename}-dependent
Group: System/Utilities
License: GPLv2
PreReq: %{_basename}

%description dependent
Hi. I'm package %{_basename}-dependent.  I require package %{_basename}
to be installed properly before I can be installed.

%files dependent

-- END --

Comment 1 Mustafa Jamil 2008-07-08 22:08:07 UTC
Panu, when you comment on this bug, can you please explicitly clarify whether
this is a bug in upstream code, or just in the Redhat/Fedora codebase?  I have
co-workers who have given me unconfirmed reports that this happens on SLES 10 SP
2 as well (so it's not just a RedHat bug, I think), but I'm not sure of that.

Comment 2 Mustafa Jamil 2008-07-08 22:50:53 UTC
OK, I confirmed myself that this behaviour is reproducible in SLES 10 SP 2.  So
it's definitely in upstream code.

Comment 3 Panu Matilainen 2008-07-09 07:47:45 UTC
RPM transactions aren't ACID, they're only "best effort" and only guarantees
that there are no known problems before transaction starts. It's impossible to
predict scriptlet failures and it's also impossible to reliably undo the
transaction once started as there's no way to undo scriptlet actions that
might've occurred up to the point of failure within the transaction. And
stopping the transaction on a single package failure is just as (or even more)
dangerous as trying to continue.

This isn't a bug, just ugly reality of the complexities involved.

Comment 4 Mustafa Jamil 2008-07-09 19:00:22 UTC
Panu, this is a classic case of "it's not a bug; it's a feature."  I'm not
trying to be rude, so please don't take my comment that way.  I understand the
limitation that you're pointing out, but there seem to be various ways that it
can be addressed (spec file authors, for example, can be required to provide
arbitrary rollback code for each scriptlet; while that wouldn't guarantee true
ACID rollback, it certainly is a far better attempt at attempting to do the
correct thing rather than the fire-and-forget model rpm currently has).  But
what I'm hearing is that this simply won't get addressed.  Is my understanding
correct?  Is there a better approach to this (or a chance to address it) in
rpm5, at least?

Comment 5 Mustafa Jamil 2008-07-09 19:05:05 UTC
Panu, furthermore, in this specific case, I'd be happy if the dependency
checking was performed once again right before an rpm is installed (even in the
middle of a transaction).  That seems very doable to me.  In the example I
provided, A-dependent set a PreReq dependency on A.  Right before A-dependent is
actually installed, why can't its Requires and PreReq's be checked once again? 
I can see that being performance-unfriendly, so why can't it be added as an
option to rpm (e.g., --recheck-dependencies)?


Comment 6 Panu Matilainen 2008-10-02 12:55:10 UTC
Let me rephrase: intelligently skipping installation of packages whose dependencies failed to install inside the transaction is quite different from aborting (and attempting to roll back) the transaction, and is quite feasible to some extent at least.

Addressing this is beyond the realm of RHEL 5 however -> WONTFIX. This needs to be tracked upstream at rpm.org.