Make %pretrans failure fail the install (RhBug:736960)
authorPanu Matilainen <pmatilai@redhat.com>
Tue, 22 Nov 2011 09:24:22 +0000 (11:24 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Tue, 22 Nov 2011 09:38:13 +0000 (11:38 +0200)
- %pre and %preun scriptlets cause the package install/erase to fail,
  whereas %pretrans return has simply been ignored ever since its
  introduction somewhere in rpm <= 4.4.x. This is just inconsistent,
  make %pretrans more like the other %pre-scriptlets. %posttrans
  exit code is still essentially ignored, just like %post and %postun etc.
- This can obviously affect installability of existing packages: if
  they have been careless about their %pretrans exit code or outright
  relying on the "yes it spits errors in some situations but who cares"
  behavior, they will now fail to install at all. The way to write
  "portable" %pretrans scriptlets is ensuring non-error exit.

lib/psm.c
lib/transaction.c

index 7b1111b..4f43772 100644 (file)
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -411,6 +411,7 @@ static rpmRC runScript(rpmpsm psm, ARGV_const_t prefixes,
     rpmTagVal stag = rpmScriptTag(script);
     int warn_only = (stag != RPMTAG_PREIN &&
                     stag != RPMTAG_PREUN &&
+                    stag != RPMTAG_PRETRANS &&
                     stag != RPMTAG_VERIFYSCRIPT);
     int selinux = !(rpmtsFlags(psm->ts) & RPMTRANS_FLAG_NOCONTEXTS);
 
index bf2e480..efecfd3 100644 (file)
@@ -1088,13 +1088,14 @@ static rpmps checkProblems(rpmts ts)
  */
 static int runTransScripts(rpmts ts, pkgGoal goal) 
 {
+    int rc = 0;
     rpmte p;
     rpmtsi pi = rpmtsiInit(ts);
     while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
-       rpmteProcess(p, goal);
+       rc += rpmteProcess(p, goal);
     }
     rpmtsiFree(pi);
-    return 0; /* what to do about failures? */
+    return rc;
 }
 
 static int rpmtsSetupCollections(rpmts ts)
@@ -1431,7 +1432,8 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
     if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_NOPRE))
          || (rpmpsNumProblems(tsprobs)))) {
        rpmlog(RPMLOG_DEBUG, "running pre-transaction scripts\n");
-       runTransScripts(ts, PKG_PRETRANS);
+       if (runTransScripts(ts, PKG_PRETRANS))
+           goto exit;
     }
     tsprobs = rpmpsFree(tsprobs);