Basic support for update
authorJ. Ali Harlow <ali@juiblex.co.uk>
Thu, 13 Aug 2009 06:14:51 +0000 (07:14 +0100)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Thu, 13 Aug 2009 06:14:51 +0000 (07:14 +0100)
librazor/razor.c
librazor/razor.h
src/main.c
test/Makefile.am
test/update.sh [new file with mode: 0755]
test/zip.spec

index bbd5f6c..ae968a3 100644 (file)
@@ -469,7 +469,8 @@ razor_package_get_details(struct razor_set *set, struct razor_package *package,
 
 /**
  * razor_package_remove:
- * @set: a %razor_set
+ * @prev: The %razor_set before the current transaction
+ * @next: The %razor_set after the current transaction is applied
  * @package: a %razor_package
  * @root: the root into which the package is currently installed
  * @install_count: the value to pass to uninstall scripts
@@ -477,8 +478,9 @@ razor_package_get_details(struct razor_set *set, struct razor_package *package,
  * Removes an installed package.
  **/
 RAZOR_EXPORT int
-razor_package_remove(struct razor_set *set, struct razor_package *package,
-                    const char *root, int install_count)
+razor_package_remove(struct razor_set *prev, struct razor_set *next,
+                    struct razor_package *package, const char *root,
+                    int install_count)
 {
        struct razor_file_iterator *fi;
        struct razor_package_iterator *pi;
@@ -491,16 +493,16 @@ razor_package_remove(struct razor_set *set, struct razor_package *package,
        const char *prefix;
 
        environment_init(&env);
-       link = list_first(&package->install_prefixes, &set->prefix_pool);
+       link = list_first(&package->install_prefixes, &prev->prefix_pool);
        for (i = 0; link; i++) {
-               prefix = (const char *)set->string_pool.data + link->data;
+               prefix = (const char *)prev->string_pool.data + link->data;
                sprintf(buffer, "RPM_INSTALL_PREFIX%d", i);
                environment_add_variable(&env, buffer, prefix);
                link = list_next(link);
        }
        environment_set(&env);
 
-       razor_package_get_details(set, package,
+       razor_package_get_details(prev, package,
                                  RAZOR_DETAIL_PREUNPROG, &program,
                                  RAZOR_DETAIL_PREUN, &script,
                                  RAZOR_DETAIL_LAST);
@@ -508,15 +510,15 @@ razor_package_remove(struct razor_set *set, struct razor_package *package,
        retval = razor_run_script(root, RAZOR_PROPERTY_PREUN, program, script,
                                  install_count);
 
-       fi = razor_file_iterator_create(set, package, 1);
+       fi = razor_file_iterator_create(prev, package, 1);
 
        while (razor_file_iterator_next(fi, &name)) {
-               pi = razor_package_iterator_create_for_file(set, name);
+               pi = razor_package_iterator_create_for_file(next, name);
                count = 0;
                while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST))
                        count++;
                razor_package_iterator_destroy(pi);
-               if (count <= 1) {
+               if (count <= 0) {
                        snprintf(buffer, sizeof buffer, "%s%s", root, name);
                        if (razor_remove(buffer) && errno != ENOENT) {
                                perror(name);
@@ -527,7 +529,7 @@ razor_package_remove(struct razor_set *set, struct razor_package *package,
 
        razor_file_iterator_destroy(fi);
 
-       razor_package_get_details(set, package,
+       razor_package_get_details(prev, package,
                                  RAZOR_DETAIL_POSTUNPROG, &program,
                                  RAZOR_DETAIL_POSTUN, &script,
                                  RAZOR_DETAIL_LAST);
@@ -878,29 +880,38 @@ razor_set_create_install_iterator(struct razor_set *set,
 
 RAZOR_EXPORT int
 razor_install_iterator_next(struct razor_install_iterator *ii,
-                           struct razor_set **set,
                            struct razor_package **package,
                            enum razor_install_action *action,
                            int *count)
 {
        struct install_action *a;
+       struct razor_package_iterator *pi;
+       struct razor_package *pkg;
+       const char *removing, *name;
+
        if (deque_empty(ii->order))
                return 0;
 
        a = (struct install_action *)ii->actions.data + deque_pop(ii->order);
-       switch (a->action) {
-       case RAZOR_INSTALL_ACTION_ADD:
-               *set = ii->next;
-               break;
-       case RAZOR_INSTALL_ACTION_REMOVE:
-               *set = ii->set;
-               break;
-       }
-
        *package = a->package;
        *action = a->action;
        *count = 0;
 
+       if (a->action == RAZOR_INSTALL_ACTION_REMOVE) {
+               razor_package_get_details(ii->set, a->package,
+                                         RAZOR_DETAIL_NAME, &removing,
+                                         RAZOR_DETAIL_LAST);
+
+               pi = razor_package_iterator_create(ii->next);
+               while (razor_package_iterator_next(pi, &pkg,
+                                                  RAZOR_DETAIL_NAME, &name,
+                                                  RAZOR_DETAIL_LAST)) {
+                       if (!strcmp(name, removing))
+                               (*count)++;
+               }
+               razor_package_iterator_destroy(pi);
+       }
+
        return 1;
 }
 
index 82682e0..49a24b0 100644 (file)
@@ -109,9 +109,9 @@ void
 razor_package_get_details(struct razor_set *set,
                          struct razor_package *package, ...);
 int
-razor_package_remove(struct razor_set *set, struct razor_package *package,
-                    const char *root, int install_count);
-
+razor_package_remove(struct razor_set *prev, struct razor_set *next,
+                    struct razor_package *package, const char *root,
+                    int install_count);
 
 /**
  * SECTION:iterator
@@ -226,7 +226,6 @@ razor_set_create_install_iterator(struct razor_set *set,
                                  struct razor_set *next);
 
 int razor_install_iterator_next(struct razor_install_iterator *ii,
-                               struct razor_set **set,
                                struct razor_package **package,
                                enum razor_install_action *action,
                                int *count);
index a4e00fb..46d7704 100644 (file)
@@ -42,7 +42,6 @@
 static const char system_repo_filename[] = "system.rzdb";
 static const char next_repo_filename[] = "system-next.rzdb";
 static const char rawhide_repo_filename[] = "rawhide.rzdb";
-static const char updated_repo_filename[] = "system-updated.rzdb";
 static const char *install_root = "";
 static const char *repo_filename = system_repo_filename;
 static const char *yum_url;
@@ -549,50 +548,6 @@ mark_packages_for_removal(struct razor_transaction *trans,
 }
 
 static int
-command_update(int argc, const char *argv[])
-{
-       struct razor_set *set, *upstream;
-       struct razor_transaction *trans;
-       int i, errors;
-
-       set = razor_root_open_read_only(install_root);
-       if (set == NULL)
-               return 1;
-
-       upstream = razor_set_open(rawhide_repo_filename);
-       if (upstream == NULL)
-               return 1;
-
-       trans = razor_transaction_create(set, upstream);
-       if (argc == 0)
-               razor_transaction_update_all(trans);
-       for (i = 0; i < argc; i++) {
-               if (mark_packages_for_update(trans, set, argv[i]) == 0) {
-                       fprintf(stderr, "no match for %s\n", argv[i]);
-                       razor_transaction_destroy(trans);
-                       return 1;
-               }
-       }
-
-       razor_transaction_resolve(trans);
-       errors = razor_transaction_describe(trans);
-       if (errors) {
-               fprintf(stderr, "unresolved dependencies\n");
-               razor_transaction_destroy(trans);
-               return 1;
-       }
-
-       set = razor_transaction_commit(trans);
-       razor_set_write(set, updated_repo_filename, RAZOR_SECTION_ALL);
-       razor_transaction_destroy(trans);
-       razor_set_destroy(set);
-       razor_set_destroy(upstream);
-       printf("wrote system-updated.rzdb\n");
-
-       return 0;
-}
-
-static int
 command_remove(int argc, const char *argv[])
 {
        struct razor_root *root;
@@ -659,7 +614,7 @@ command_diff(int argc, const char *argv[])
        struct razor_set *set, *updated;
 
        set = razor_root_open_read_only(install_root);
-       updated = razor_set_open(updated_repo_filename);
+       updated = razor_set_open(rawhide_repo_filename);
        if (set == NULL || updated == NULL)
                return 1;
 
@@ -756,19 +711,17 @@ download_packages(struct razor_set *system, struct razor_set *next)
 {
        struct razor_install_iterator *ii;
        struct razor_package *package;
-       struct razor_set *set;
        enum razor_install_action action;
        const char *name, *version, *arch;
        char file[PATH_MAX], url[256];
        int errors = 0, count;
 
        ii = razor_set_create_install_iterator(system, next);
-       while (razor_install_iterator_next(ii, &set, &package,
-                                          &action, &count)) {
+       while (razor_install_iterator_next(ii, &package, &action, &count)) {
                if (action == RAZOR_INSTALL_ACTION_REMOVE)
                        continue;
 
-               razor_package_get_details(set, package,
+               razor_package_get_details(next, package,
                                          RAZOR_DETAIL_NAME, &name,
                                          RAZOR_DETAIL_VERSION, &version,
                                          RAZOR_DETAIL_ARCH, &arch,
@@ -920,19 +873,18 @@ update_packages(struct razor_transaction *trans, struct razor_set *system,
 {
        struct razor_install_iterator *ii;
        struct razor_package *package;
-       struct razor_set *set;
        enum razor_install_action action;
        int retval = 0, count;
 
        ii = razor_set_create_install_iterator(system, next);
-       while (!retval && razor_install_iterator_next(ii, &set, &package,
+       while (!retval && razor_install_iterator_next(ii, &package,
                                                      &action, &count)) {
                if (action == RAZOR_INSTALL_ACTION_ADD)
-                       retval = install_package(trans, set, package,
+                       retval = install_package(trans, next, package,
                                                 relocations);
                else if (action == RAZOR_INSTALL_ACTION_REMOVE)
-                       retval = razor_package_remove(set, package,
-                                                     install_root, 0);
+                       retval = razor_package_remove(system, next, package,
+                                                     install_root, count);
        }
        razor_install_iterator_destroy(ii);
 
@@ -940,7 +892,7 @@ update_packages(struct razor_transaction *trans, struct razor_set *system,
 }
 
 static int
-command_install(int argc, const char *argv[])
+command_install_or_update(int argc, const char *argv[], int do_update)
 {
        struct razor_root *root;
        struct razor_relocations *relocations=NULL;
@@ -960,7 +912,8 @@ command_install(int argc, const char *argv[])
                        i++;
                        if (i >= argc || strchr(argv[i], '=') == NULL) {
                                fprintf(stderr,
-                                   "Usage: razor install [OPTION...] RPM\n");
+                                   "Usage: razor %s [OPTION...] RPM\n",
+                                   do_update ? "update" : "install");
                                fprintf(stderr, "Options:\n");
                                fprintf(stderr, "    [--no-dependencies]\n");
                                fprintf(stderr,
@@ -983,10 +936,9 @@ command_install(int argc, const char *argv[])
        system = razor_root_get_system_set(root);
        upstream = razor_set_open(rawhide_repo_filename);
        if (upstream == NULL) {
-               fprintf(stderr, "couldn't open rawhide repo\n");
                razor_root_close(root);
                return 1;
-       }               
+       }
 
        if (relocations) {
                set = relocate_packages(upstream, relocations);
@@ -996,10 +948,13 @@ command_install(int argc, const char *argv[])
 
        trans = razor_transaction_create(system, upstream);
 
+       if (i == argc && do_update)
+               razor_transaction_update_all(trans);
        for (; i < argc; i++) {
                if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
                        fprintf(stderr, "no package matched %s\n", argv[i]);
                        razor_transaction_destroy(trans);
+                       razor_set_destroy(upstream);
                        razor_root_close(root);
                        return 1;
                }
@@ -1009,22 +964,26 @@ command_install(int argc, const char *argv[])
                razor_transaction_resolve(trans);
                if (razor_transaction_describe(trans) > 0) {
                        razor_transaction_destroy(trans);
+                       razor_set_destroy(upstream);
                        razor_root_close(root);
                        return 1;
                }
        }
 
-       next = razor_transaction_commit(trans);
-
        if (mkdir("rpms", 0777) && errno != EEXIST) {
                fprintf(stderr, "failed to create rpms directory.\n");
                razor_transaction_destroy(trans);
+               razor_set_destroy(upstream);
                razor_root_close(root);
                return 1;
        }
 
+       next = razor_transaction_commit(trans);
+
        if (download_packages(system, next) < 0) {
+               razor_set_destroy(next);
                razor_transaction_destroy(trans);
+               razor_set_destroy(upstream);
                razor_root_close(root);
                 return 1;
         }
@@ -1043,6 +1002,18 @@ command_install(int argc, const char *argv[])
 }
 
 static int
+command_update(int argc, const char *argv[])
+{
+       return command_install_or_update(argc, argv, 1);
+}
+
+static int
+command_install(int argc, const char *argv[])
+{
+       return command_install_or_update(argc, argv, 0);
+}
+
+static int
 command_init(int argc, const char *argv[])
 {
        return razor_root_create(install_root);
index 032e80f..c724914 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-check_SCRIPTS = relocate named-root remove
+check_SCRIPTS = relocate named-root remove update
 if HAVE_LUA
   check_SCRIPTS += lua
 endif
@@ -15,25 +15,44 @@ named-root: named-root.sh primary.xml.gz
 remove:        remove.sh primary.xml.gz
        cp $(srcdir)/remove.sh remove
 
+update:        update.sh base/repodata/primary.xml.gz updates/repodata/primary.xml.gz
+       cp $(srcdir)/update.sh update
+
 order: order.sh primary.xml.gz
        cp $(srcdir)/order.sh order
 
 lua:   lua.sh primary.xml.gz
        cp $(srcdir)/lua.sh lua
 
-primary.xml.gz:        zsh.spec zsh2.spec zip.spec zap.spec filesystem.spec Makefile
-       rm -rf rpmbuild rpms repodata
+base/repodata/primary.xml.gz:  zsh.spec zsh2.spec zip.spec zap.spec \
+               filesystem.spec Makefile
+       rm -rf rpmbuild base
        mkdir -p rpmbuild/BUILD rpmbuild/RPMS
        rpmbuild --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zap.spec
-       rpmbuild --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zip.spec
+       rpmbuild --define "_topdir `pwd`/rpmbuild" --define "_version 1" \
+         -bb $(srcdir)/zip.spec
        rpmbuild --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zsh.spec
        rpmbuild --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zsh2.spec
        rpmbuild --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/filesystem.spec
-       mkdir rpms
-       mv rpmbuild/RPMS/noarch/*.rpm rpms
+       mkdir -p base/rpms
+       mv rpmbuild/RPMS/noarch/*.rpm base/rpms
+       rm -rf rpmbuild
+       createrepo -o base base/rpms
+
+updates/repodata/primary.xml.gz:       zip.spec Makefile
+       rm -rf rpmbuild updates
+       mkdir -p rpmbuild/BUILD rpmbuild/RPMS
+       rpmbuild --define "_topdir `pwd`/rpmbuild" --define "_version 2" \
+         -bb $(srcdir)/zip.spec
+       mkdir -p updates/rpms
+       mv rpmbuild/RPMS/noarch/*.rpm updates/rpms
        rm -rf rpmbuild
-       createrepo -o . rpms
-       cp repodata/primary.xml.gz repodata/filelists.xml.gz .
+       createrepo -o updates updates/rpms
+
+primary.xml.gz:        base/repodata/primary.xml.gz
+       cp base/repodata/primary.xml.gz base/repodata/filelists.xml.gz .
+       rm -rf rpms
+       ln -s base/rpms .
 
 TESTS = $(check_SCRIPTS)
 
@@ -46,6 +65,7 @@ EXTRA_DIST =                  \
        order.sh                \
        lua.sh                  \
        remove.sh               \
+       update.sh               \
        named-root.sh           \
        relocate.sh
 
@@ -57,5 +77,4 @@ MOSTLYCLEANFILES =            \
 
 clean-local :
        rm -f *~
-       rm -rf repodata rpms
-
+       rm -rf repodata rpms base updates
diff --git a/test/update.sh b/test/update.sh
new file mode 100755 (executable)
index 0000000..80725db
--- /dev/null
@@ -0,0 +1,89 @@
+#!/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
+}
+set_repository()
+{
+    cp $1/repodata/primary.xml.gz $1/repodata/filelists.xml.gz .
+    rm -rf rpms
+    ln -s $1/rpms .
+}
+export RAZOR_ROOT=`mktemp -dt` || exit 1
+../src/razor init || exit 1
+export YUM_URL="file://localhost/`pwd`"
+set_repository base
+../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
+trap "set_repository base" 0
+set_repository updates
+../src/razor import-yum || exit 1
+../src/razor update --relocate /usr=/opt || exit 1
+check_file /opt/bin/zip
+fs_check_file_contents /opt/bin/zip zip-2-1
+fs_check_file /opt/var/lib/zip/data.zap
+../src/razor remove zip || exit 1
+fs_check_no_file /opt/var/lib/zip/data.zap
+rm -rf "$RAZOR_ROOT"
index 25ca630..2694449 100644 (file)
@@ -2,7 +2,7 @@ Name:      zip
 Summary:   Test package
 Group:     Test
 License:   GPL
-Version:   1
+Version:   %{_version}
 Release:   1
 Source:    zip.tar
 BuildArch: noarch
@@ -19,7 +19,7 @@ Test package
 
 %install
 mkdir -p $RPM_BUILD_ROOT/usr/bin
-touch $RPM_BUILD_ROOT/usr/bin/zip
+echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/zip
 
 %clean