Fix bug causing multiple installs to abort
authorJ. Ali Harlow <ali@juiblex.co.uk>
Tue, 29 Sep 2009 18:31:16 +0000 (19:31 +0100)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Thu, 1 Oct 2009 18:54:03 +0000 (19:54 +0100)
librazor/razor.c
test/Makefile.am
test/mult-install.sh [new file with mode: 0755]

index d29dead..cdbb693 100644 (file)
@@ -704,6 +704,32 @@ razor_set_list_package_files(struct razor_set *set,
        razor_file_iterator_destroy(fi);
 }
 
+/*
+ * Package data can potentially come from two places. The so-called
+ * metadata (eg., from comps.xml) and from an RPM file. We consider
+ * a package which has additional data from an RPM file as "fixed".
+ * If a package needs fixing, then razor_transaction_fixup_package()
+ * will do so. When considering what packages to add and to remove
+ * we need to take this into account since we always want to add
+ * unfixed packages (otherwise we have a potential conflict between
+ * the existing package data and that present in the RPM).
+ */
+static int
+razor_package_is_fixed(struct razor_set *set, struct razor_package *p)
+{
+       const char *preunprog, *preun, *postunprog, *postun;
+
+       if (!p)
+               return 0;
+       razor_package_get_details(set, p,
+                                 RAZOR_DETAIL_PREUNPROG, &preunprog,
+                                 RAZOR_DETAIL_PREUN, &preun,
+                                 RAZOR_DETAIL_POSTUNPROG, &postunprog,
+                                 RAZOR_DETAIL_POSTUN, &postun,
+                                 RAZOR_DETAIL_LAST);
+       return *preunprog || *preun || *postunprog || *postun;
+}
+
 RAZOR_EXPORT void
 razor_set_diff(struct razor_set *set, struct razor_set *upstream,
               razor_diff_callback_t callback, void *data)
@@ -711,7 +737,7 @@ razor_set_diff(struct razor_set *set, struct razor_set *upstream,
        struct razor_package_iterator *pi1, *pi2;
        struct razor_package *p1, *p2;
        const char *name1, *name2, *version1, *version2, *arch1, *arch2;
-       int res;
+       int res, is_fixed1, is_fixed2;
 
        assert (set != NULL);
        assert (upstream != NULL);
@@ -724,17 +750,21 @@ razor_set_diff(struct razor_set *set, struct razor_set *upstream,
                                    RAZOR_DETAIL_VERSION, &version1,
                                    RAZOR_DETAIL_ARCH, &arch1,
                                    RAZOR_DETAIL_LAST);
+       is_fixed1 = razor_package_is_fixed(set, p1);
        razor_package_iterator_next(pi2, &p2,
                                    RAZOR_DETAIL_NAME, &name2,
                                    RAZOR_DETAIL_VERSION, &version2,
                                    RAZOR_DETAIL_ARCH, &arch2,
                                    RAZOR_DETAIL_LAST);
+       is_fixed2 = razor_package_is_fixed(upstream, p2);
 
        while (p1 || p2) {
                if (p1 && p2) {
                        res = strcmp(name1, name2);
                        if (res == 0)
                                res = razor_versioncmp(version1, version2);
+                       if (res == 0)
+                               res = is_fixed1 - is_fixed2;
                } else {
                        res = 0;
                }
@@ -746,18 +776,22 @@ razor_set_diff(struct razor_set *set, struct razor_set *upstream,
                        callback(RAZOR_DIFF_ACTION_ADD,
                                 p2, name2, version2, arch2, data);
 
-               if (p1 != NULL && res <= 0)
+               if (p1 != NULL && res <= 0) {
                        razor_package_iterator_next(pi1, &p1,
                                                    RAZOR_DETAIL_NAME, &name1,
                                                    RAZOR_DETAIL_VERSION, &version1,
                                                    RAZOR_DETAIL_ARCH, &arch1,
                                                    RAZOR_DETAIL_LAST);
-               if (p2 != NULL && res >= 0)
+                       is_fixed1 = razor_package_is_fixed(set, p1);
+               }
+               if (p2 != NULL && res >= 0) {
                        razor_package_iterator_next(pi2, &p2,
                                                    RAZOR_DETAIL_NAME, &name2,
                                                    RAZOR_DETAIL_VERSION, &version2,
                                                    RAZOR_DETAIL_ARCH, &arch2,
                                                    RAZOR_DETAIL_LAST);
+                       is_fixed2 = razor_package_is_fixed(upstream, p2);
+               }
        }
 
        razor_package_iterator_destroy(pi1);
index c724914..0ca2b17 100644 (file)
@@ -2,7 +2,7 @@
 
 check_SCRIPTS = relocate named-root remove update
 if HAVE_LUA
-  check_SCRIPTS += lua
+  check_SCRIPTS += lua mult-install
 endif
 check_SCRIPTS += order
 
@@ -24,6 +24,9 @@ order:        order.sh primary.xml.gz
 lua:   lua.sh primary.xml.gz
        cp $(srcdir)/lua.sh lua
 
+mult-install:  mult-install.sh primary.xml.gz
+       cp $(srcdir)/mult-install.sh mult-install
+
 base/repodata/primary.xml.gz:  zsh.spec zsh2.spec zip.spec zap.spec \
                filesystem.spec Makefile
        rm -rf rpmbuild base
@@ -63,6 +66,7 @@ EXTRA_DIST =                  \
        zsh2.spec               \
        filesystem.spec         \
        order.sh                \
+       mult-install.sh         \
        lua.sh                  \
        remove.sh               \
        update.sh               \
diff --git a/test/mult-install.sh b/test/mult-install.sh
new file mode 100755 (executable)
index 0000000..a6e635c
--- /dev/null
@@ -0,0 +1,75 @@
+#!/bin/sh
+fs_check_file()
+{
+    if [ ! -e "$RAZOR_ROOT$1" ]; then 
+       echo $1: Not in filesystem >&2
+       ls -R "$RAZOR_ROOT" >&2
+       exit 1
+    fi
+}
+fs_check_file_contents()
+{
+    fs_check_file "$1"
+    if [ `cat "$RAZOR_ROOT$1"` != "$2" ]; then
+       echo $1: Unexpected contents >&2
+       cat "$RAZOR_ROOT$1" >&2
+       exit 1
+    fi
+}
+fs_check_no_file()
+{
+    if [ -e "$RAZOR_ROOT$1" ]; then 
+       echo $1: Still in filesystem >&2
+       exit 1
+    fi
+}
+check_file()
+{
+    ../src/razor list-files | grep -x "$1" > /dev/null
+    if [ $? -ne 0 ]; then
+       echo $1: Not in database >&2
+       ../src/razor list-files >&2
+       exit 1
+    fi
+    ../src/razor list-files "$1" | grep -x "$1" > /dev/null
+    if [ $? -ne 0 ]; then
+       echo $1: Not seen by patterned list >&2
+       ../src/razor list-files "$1" >&2
+       exit 1
+    fi
+    pkgs=`../src/razor list-file-packages "$1"`
+    if [ -z "$pkgs" ]; then
+       echo $1: Not owned by any package >&2
+       ../src/razor list-file-packages "$1"
+       exit 1
+    fi
+    for nevra in "$pkgs"; do
+       name=`echo $nevra | sed 's/\-.*$//'`
+       ../src/razor list-package-files "$name" | grep -x "$1" > /dev/null
+       if [ $? -ne 0 ]; then
+           echo $1: Not in database for package $name >&2
+           ../src/razor list-package-files "$name"
+           exit 1
+       fi
+    done
+    fs_check_file $1
+}
+check_no_file()
+{
+    ../src/razor list-files | grep -x "$1" > /dev/null
+    if [ $? -eq 0 ]; then
+       echo $1: Still in database >&2
+       exit 1
+    fi
+    fs_check_no_file $1
+}
+export RAZOR_ROOT=`mktemp -dt` || exit 1
+../src/razor init || exit 1
+export YUM_URL="file://localhost/`pwd`"
+../src/razor import-yum || exit 1
+../src/razor install --relocate /usr=/opt zip || exit 1
+fs_check_file_contents /opt/bin/zip zip-1-1
+fs_check_file /opt/var/lib/zip/data.zap
+../src/razor install --relocate /usr=/opt zip || exit 1
+../src/razor install --relocate /usr=/opt zip || exit 1
+rm -rf "$RAZOR_ROOT"