Description of problem: Trying to update a broken RPM, I see: Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Updating : gawk 1/2 Error unpacking rpm package gawk-3.1.6-3.fc11.x86_64 error: unpacking of archive failed on file /bin/pgawk-3.1.6a;4951e4ed: cpio: link =============================== Leaving rpm code =============================== Updated: gawk.x86_64 0:3.1.6-3.fc11 Complete! # rpm -q gawk gawk-3.1.6-2.fc11.x86_64 Version-Release number of selected component (if applicable): yum-3.2.20-8.fc11.noarch How reproducible: Steps to Reproduce: 1. 2. 3. Actual results: Expected results: Additional info: Probably a dup, but I couldn't find it in bugzilla...
Created attachment 329237 [details] Report failed packages in transaction summary Yum reporting success on failure is a yum bug. Yum gets told about the error (see below, the first one comes from yum and the second from librpm) but it doesn't record which package failed and goes on to claim everything went fine. > Error unpacking rpm package gawk-3.1.6-3.fc11.x86_64 > error: unpacking of archive failed on file /bin/pgawk-3.1.6a;4951e4ed: cpio: > link Yum actually exits with an error code here, and there's even a warning emitted by yum in this case, BUT it's not visible in the default verbosity-level (try the above with -d5 to see it), I'd suggest giving it a higher than debug priority: errstring = _('Warning: scriptlet or other non-fatal errors occurred during transaction.') self.verbose_logger.debug(errstring) As for the reporting: yum has access to its transaction members during the callback, this is easy to fix. The attached patch records cpio and unpack errors and reports them in the transaction summary, eg: ------ ... Running Transaction Installing : telnet 1/2 Installing : failtest 2/2 Error unpacking rpm package failtest-1.0-1.noarch error: unpacking of archive failed on file /boot/failtest;4970cbf7: cpio: link =============================== Leaving rpm code =============================== Installed: telnet.x86_64 1:0.17-42.fc9 Failed: failtest.noarch 0:1.0-1 Complete! ------ Didn't commit it as I dont know if you want to use txmbr.output_state for recording failures but you'll get the idea. For added bonus, check for rpm.RPMCALLBACK_SCRIPT_ERROR in the callback too, with that you can report each and every scriptlet warning/failure and which script it was in the post-transaction summary if you want.
*** Bug 452804 has been marked as a duplicate of this bug. ***
Created attachment 329240 [details] Record scriptlet failures While at it, here's the other half (on top of the previous patch) to additionally collect scriptlet errors. This is mostly for demonstration purposes, tweak messages etc to your liking (reporting the errors from yum seems redundant when you already get the error messages from rpm), "installed with warnings" status in the transaction summary might not be a bad idea.
So, do the above patches handle 'partial' failures or is it considering each te atomic? Since a te isn't independent of the rest of the transaction it seems like our failure options are: 1. fatal - everything in the ts is in question and/or could not be run 2. non-fatal - everything in the ts is okay 3. no failure
The above patches are only about recording individual package status, on the three levels you list above, according to how rpm saw it: 1. Fatal - the package didn't get installed (not on filesystem and not in rpmdb). These are the cases which the above patches mark with TS_FAILED (TE_FAILED would be more descriptive). 2. Non-fatal - the package got installed but non-pre scriptlet failure(s) occurred. The above patches don't specifically record this but would be easy, just add another state "installed with warnings". 3. No failure. What the outcome of the entire transaction should be is a whole other question, but knowing what happened on individual package level you're in better position to do so. One straightforward possibility would be to use the worst package status in the transaction as the result of the entire transaction, ie "fatal" would mean "there was at least one fatal error" etc. Oh and yes, there's a lot that rpm could do better in this area, improvements will be coming eventually but reasonably correct per-package level result can be achieved already. And *that* is what I wanted to fix here: giving the users a more realistic summary of what happened in the transaction
okay, I just tested the following situation on a rawhide kvm instance. I setup a transaction in yum. It passes the test transaction with enough disk space free. Right before the transaction begins I fill up the disk entirely. The transaction (a single pkg localinstall) fails with a cpio error unpacking the archive. Now in yum currently (for rpm 4.4) we have code which says: if the transaction returns None, then everything succeeded if the transaction returns an empty list then you had scriptlet or other non-fatal failures if the transaction returns a list then you had fatal failures. the above always returns an empty list. Did I get some piece of what it is supposed to do wrong? I'll add in the scriptlet error check shortly but I want to make sure I'm not going to leave a problem out for rpm 4.4
Hum, lets see... With rpm 4.4: a) ts.run() returns None if no errors were present b) ts.run() returning empty list means there were errors, but the transaction ran to the finish line. For cpio/unpack errors you get callbacks, but for failing scriptlets you dont. In 4.4 all scriptlet errors are "fatal" in that either a) the package doesn't install at all or b) the package got installed but with errors, and in case of updates it leaves the old package around. You'd have to look into rpmdb to see what got done and what didn't to put all the pieces together correctly. c) ts.run() exiting with a non-empty list means the transaction didn't even start (due to dependency, disk space or file conflict issues basically) With rpm 4.6: a) and c) are same as above b) differs in that not all scriptlet errors are considered fatal, and ts.run() error code (the empty list) is only triggered by fatal errors, but every scriptlet failure issues a callback with fatal/non-fatal status. Lovely isn't it ;) Bottom line: cpio and unpack errors can be relied on everywhere, with scriptlets its helluva lot more fuzzy.
I did some cpio and scriptlet error tests with your patches and it came out well. I've applied them. Thanks.