Implement relocatations when installing rpms.
authorJ. Ali Harlow <ali@juiblex.co.uk>
Thu, 22 Jan 2009 22:54:45 +0000 (22:54 +0000)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Thu, 22 Jan 2009 22:54:45 +0000 (22:54 +0000)
14 files changed:
Makefile.am
configure.ac
librazor/iterator.c
librazor/razor-internal.h
librazor/razor.c
librazor/razor.h
librazor/rpm.c
src/Makefile.am
src/main.c
test/Makefile.am [new file with mode: 0644]
test/relocate.sh [new file with mode: 0755]
test/zap.spec [new file with mode: 0644]
test/zip.spec [new file with mode: 0644]
test/zsh.spec [new file with mode: 0644]

index f602bab..076084c 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS = data docs gl librazor src po
+SUBDIRS = data docs gl librazor src test po
 
 ACLOCAL_AMFLAGS = -I gl/m4
 
index d164bfb..60879df 100644 (file)
@@ -235,6 +235,7 @@ docs/Makefile
 docs/version.xml
 po/Makefile.in
 gl/Makefile
+test/Makefile
 ])
 
 dnl ==========================================================================
index 2075be1..533f18a 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
  * Copyright (C) 2008  Red Hat, Inc
+ * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -229,6 +230,83 @@ razor_property_iterator_destroy(struct razor_property_iterator *pi)
        free(pi);
 }
 
+RAZOR_EXPORT struct razor_file_iterator *
+razor_file_iterator_create(struct razor_set *set, struct razor_package *package)
+{
+       struct razor_file_iterator *fi;
+
+       assert (set != NULL);
+       assert (package != NULL);
+
+       fi = zalloc(sizeof *fi);
+       fi->set = set;
+       fi->index = list_first(&package->files, &set->file_pool);
+       array_init(&fi->path);
+
+       return fi;
+}
+
+RAZOR_EXPORT int
+razor_file_iterator_next(struct razor_file_iterator *fi,
+                        const char **name)
+{
+       struct razor_entry *e, *dir, *entries;
+       char *pool, *s, *f;
+
+       assert (fi != NULL);
+
+       if (!fi->index) {
+               *name = NULL;
+               return 0;
+       }
+
+       entries = (struct razor_entry *) fi->set->files.data;
+       pool = fi->set->file_string_pool.data;
+
+       dir = entries;
+       fi->path.size = 0;
+       for(;;) {
+               e = dir;
+               do {
+                       if (entries + fi->index->data == e) {
+                               f = pool + e->name;
+                               s = array_add(&fi->path, strlen(f) + 1);
+                               strcpy(s, f);
+                               if (fi->path.size == 1) {
+                                       array_add(&fi->path, 1);
+                                       strcpy(fi->path.data, "/");
+                               }
+                               *name = fi->path.data;
+                               fi->index = list_next(fi->index);
+                               return 1;
+                       }
+               } while (!((e++)->flags & RAZOR_ENTRY_LAST));
+               for(e--; e >= dir; e--)
+                       if (e->start && fi->index->data >= e->start)
+                               break;
+               if (e < dir)
+                       break;
+               f = pool + e->name;
+               s = array_add(&fi->path, strlen(f) + 1);
+               strcpy(s, f);
+               s += strlen(f);
+               *s = '/';
+               dir = entries + e->start;
+       }
+
+       printf("file_iterator_next: Failed to find file %d\n",fi->index->data);
+       *name = NULL;
+       return 0;
+}
+
+RAZOR_EXPORT void razor_file_iterator_destroy(struct razor_file_iterator *fi)
+{
+       assert (fi != NULL);
+
+       array_release(&fi->path);
+       free(fi);
+}
+
 struct razor_package_query {
        struct razor_set *set;
        char *vector;
index afd9cda..8fe0f3b 100644 (file)
@@ -200,6 +200,12 @@ struct razor_property_iterator {
        struct list *index;
 };
 
+struct razor_file_iterator {
+       struct razor_set *set;
+       struct array path;
+       struct list *index;
+};
+
 struct razor_entry *
 razor_set_find_entry(struct razor_set *set,
                     struct razor_entry *dir, const char *pattern);
index ee80b0a..e83d128 100644 (file)
@@ -582,76 +582,22 @@ razor_set_list_files(struct razor_set *set, const char *pattern)
                list_dir(set, e, buffer, base);
 }
 
-static struct list *
-list_package_files(struct razor_set *set, struct list *r,
-                  struct razor_entry *dir, uint32_t end,
-                  char *prefix)
-{
-       struct razor_entry *e, *f, *entries;
-       uint32_t next, file;
-       char *pool;
-       int len;
-
-       entries = (struct razor_entry *) set->files.data;
-       pool = set->file_string_pool.data;
-
-       e = entries + dir->start;
-       do {
-               if (entries + r->data == e) {
-                       printf("%s/%s\n", prefix, pool + e->name);
-                       r = list_next(r);
-                       if (!r)
-                               return NULL;
-                       if (r->data >= end)
-                               return r;
-               }
-       } while (!((e++)->flags & RAZOR_ENTRY_LAST));
-
-       e = entries + dir->start;
-       do {
-               if (e->start == 0)
-                       continue;
-
-               if (e->flags & RAZOR_ENTRY_LAST)
-                       next = end;
-               else {
-                       f = e + 1;
-                       while (f->start == 0 && !(f->flags & RAZOR_ENTRY_LAST))
-                               f++;
-                       if (f->start == 0)
-                               next = end;
-                       else
-                               next = f->start;
-               }
-
-               file = r->data;
-               if (e->start <= file && file < next) {
-                       len = strlen(prefix);
-                       prefix[len] = '/';
-                       strcpy(prefix + len + 1, pool + e->name);
-                       r = list_package_files(set, r, e, next, prefix);
-                       prefix[len] = '\0';
-               }
-       } while (!((e++)->flags & RAZOR_ENTRY_LAST) && r != NULL);
-
-       return r;
-}
-
 RAZOR_EXPORT void
 razor_set_list_package_files(struct razor_set *set,
                             struct razor_package *package)
 {
-       struct list *r;
-       uint32_t end;
-       char buffer[512];
+       struct razor_file_iterator *fi;
+       const char *name;
 
        assert (set != NULL);
        assert (package != NULL);
 
-       r = list_first(&package->files, &set->file_pool);
-       end = set->files.size / sizeof (struct razor_entry);
-       buffer[0] = '\0';
-       list_package_files(set, r, set->files.data, end, buffer);
+       fi = razor_file_iterator_create(set, package);
+
+       while (razor_file_iterator_next(fi, &name))
+               printf("%s\n", name);
+
+       razor_file_iterator_destroy(fi);
 }
 
 /* The diff order matters.  We should sort the packages so that a
index 51d05a7..a9816a8 100644 (file)
@@ -172,6 +172,14 @@ int razor_property_iterator_next(struct razor_property_iterator *pi,
 void
 razor_property_iterator_destroy(struct razor_property_iterator *pi);
 
+struct razor_file_iterator;
+struct razor_file_iterator *
+razor_file_iterator_create(struct razor_set *set,
+                          struct razor_package *package);
+int razor_file_iterator_next(struct razor_file_iterator *fi,
+                            const char **name);
+void razor_file_iterator_destroy(struct razor_file_iterator *fi);
+
 void razor_set_list_files(struct razor_set *set, const char *prefix);
 void razor_set_list_package_files(struct razor_set *set,
                                  struct razor_package *package);
@@ -249,9 +257,21 @@ int razor_transaction_unsatisfied_property(struct razor_transaction *trans,
  * installing or removing RPM files.
  **/
 
+struct razor_relocations;
 struct razor_rpm;
 
+struct razor_relocations *razor_relocations_create(void);
+void razor_relocations_add(struct razor_relocations *relocations,
+                          const char *oldpath, const char *newpath);
+void razor_relocations_set_rpm(struct razor_relocations *relocations,
+                              struct razor_rpm *rpm);
+const char *razor_relocations_apply(struct razor_relocations *relocations,
+                                   const char *path);
+void razor_relocations_destroy(struct razor_relocations *relocations);
+
 struct razor_rpm *razor_rpm_open(const char *filename);
+void razor_rpm_set_relocations(struct razor_rpm *rpm,
+                              struct razor_relocations *relocations);
 int razor_rpm_install(struct razor_rpm *rpm, const char *root);
 int razor_rpm_close(struct razor_rpm *rpm);
 
index 02fad33..80c6f61 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
  * Copyright (C) 2008  Red Hat, Inc
+ * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -248,12 +249,144 @@ struct razor_rpm {
        struct rpm_header *signature;
        struct rpm_header *header;
        const char **dirs;
+       unsigned int n_prefixes;
+       const char **prefixes;
        const char *pool;
        void *map;
        size_t size;
        void *payload;
+       struct razor_relocations *relocations;
 };
 
+enum razor_relocation_flags {
+       RAZOR_RELOCATION_ACTIVE         = 1 << 0,
+};
+
+struct razor_relocation {
+       enum razor_relocation_flags flags;
+       size_t oldlen;
+       size_t newlen;
+       char *oldpath;
+       char *newpath;
+};
+
+struct razor_relocations {
+       /* Ordered such that if oldpath 1 starts with oldpath 2, then
+        * oldpath 1 is listed first (ie., /usr/bin comes before /usr)
+        * and terminated with a NULL oldpath.
+        */
+       struct razor_relocation *relocations;
+       int n_relocations;
+       char *path;
+};
+
+RAZOR_EXPORT struct razor_relocations *razor_relocations_create(void)
+{
+       return calloc(1, sizeof(struct razor_relocations));
+}
+
+RAZOR_EXPORT void razor_relocations_add(struct razor_relocations *rr,
+                          const char *oldpath, const char *newpath)
+{
+       int i, found = 0;
+       size_t len;
+
+       if (newpath && !strcmp(oldpath, newpath))
+               newpath = NULL;
+
+       for (i = 0; i < rr->n_relocations; i++) {
+               len = rr->relocations[i].oldlen;
+               if (!strncmp(rr->relocations[i].oldpath, oldpath, len)) {
+                       found = !strcmp(rr->relocations[i].oldpath, oldpath);
+                       break;
+               }
+       }
+
+       if (!newpath) {
+               if (found) {
+                       free(rr->relocations[i].oldpath);
+                       free(rr->relocations[i].newpath);
+                       do {
+                               rr->relocations[i] = rr->relocations[i + 1];
+                       } while (rr->relocations[++i].oldpath);
+               }
+               return;
+       }
+
+       if (found) {
+               free(rr->relocations[i].newpath);
+               rr->relocations[i].newpath = strdup(newpath);
+               rr->relocations[i].newlen = strlen(newpath);
+               return;
+       }
+
+       if (!rr->n_relocations++)
+               rr->relocations = calloc(1, sizeof *rr->relocations);
+       else {
+               rr->relocations = realloc(rr->relocations,
+                                         rr->n_relocations * sizeof *rr->relocations);
+               memmove(rr->relocations + i + 1, rr->relocations + i,
+                       (rr->n_relocations - i - 1) * sizeof *rr->relocations);
+       }
+
+       rr->relocations[i].flags = 0;
+       rr->relocations[i].oldpath = strdup(oldpath);
+       rr->relocations[i].newpath = strdup(newpath);
+       rr->relocations[i].oldlen = strlen(oldpath);
+       rr->relocations[i].newlen = strlen(newpath);
+}
+
+RAZOR_EXPORT void
+razor_relocations_set_rpm(struct razor_relocations *rr, struct razor_rpm *rpm)
+{
+       int i, j;
+
+       for (i = 0; i < rr->n_relocations; i++) {
+               rr->relocations[i].flags &= ~RAZOR_RELOCATION_ACTIVE;
+               for (j = 0; j < rpm->n_prefixes; j++)
+                       if (!strcmp(rpm->prefixes[j],
+                                   rr->relocations[i].oldpath)) {
+                               rr->relocations[i].flags |= RAZOR_RELOCATION_ACTIVE;
+                               break;
+                       }
+       }
+}
+
+RAZOR_EXPORT const char *
+razor_relocations_apply(struct razor_relocations *rr, const char *path)
+{
+       int i;
+       size_t len;
+
+       for (i = 0; i < rr->n_relocations; i++)
+               if (rr->relocations[i].flags & RAZOR_RELOCATION_ACTIVE &&
+                   !strncmp(path, rr->relocations[i].oldpath,
+                            rr->relocations[i].oldlen))
+                       break;
+
+       if (i < rr->n_relocations) {
+               free(rr->path);
+               len = strlen(path + rr->relocations[i].oldlen) +
+                     rr->relocations[i].newlen;
+               rr->path = malloc(len + 1);
+               memcpy(rr->path, rr->relocations[i].newpath,
+                      rr->relocations[i].newlen);
+               strcpy(rr->path + rr->relocations[i].newlen,
+                      path + rr->relocations[i].oldlen);
+               return rr->path;
+       } else
+               return path;
+}
+
+RAZOR_EXPORT void razor_relocations_destroy(struct razor_relocations *rr)
+{
+       printf("razor_relocations_destroy(rr=%p): path=%p, rel=%p\n",
+         rr,rr->path,rr->relocations);
+       free(rr->path);
+       free(rr->relocations);
+       free(rr);
+}
+
 static struct rpm_header_index *
 razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
 {
@@ -366,7 +499,7 @@ razor_rpm_open(const char *filename)
        struct razor_rpm *rpm;
        struct rpm_header_index *base, *index;
        unsigned int count, i, nindex, hsize;
-       const char *name;
+       const char *name, *prefix;
 
        assert (filename != NULL);
 
@@ -412,9 +545,34 @@ razor_rpm_open(const char *filename)
                }
        }
 
+       prefix = razor_rpm_get_indirect(rpm, RPMTAG_PREFIXES, &count);
+       if (prefix) {
+               rpm->prefixes = calloc(count, sizeof *rpm->prefixes);
+               for (i = 0; i < count; i++) {
+                       rpm->prefixes[i] = prefix;
+                       prefix += strlen(prefix) + 1;
+               }
+               rpm->n_prefixes = count;
+       } else {
+               prefix = razor_rpm_get_indirect(rpm, RPMTAG_DEFAULTPREFIX,
+                                               &count);
+               if (prefix) {
+                       fprintf(stderr, "default prefix not supported\n");
+                       return NULL;
+               }
+       }
+
        return rpm;
 }
 
+RAZOR_EXPORT void razor_rpm_set_relocations(struct razor_rpm *rpm,
+                                           struct razor_relocations *rr)
+{
+       assert (rpm != NULL);
+
+       rpm->relocations = rr;
+}
+
 struct cpio_file_header {
        char magic[6];
        char inode[8];
@@ -744,7 +902,7 @@ razor_rpm_install(struct razor_rpm *rpm, const char *root)
        struct cpio_file_header *header;
        struct stat buf;
        unsigned int mode;
-       char *path;
+       const char *path;
        size_t filesize;
 
        assert (rpm != NULL);
@@ -761,6 +919,9 @@ razor_rpm_install(struct razor_rpm *rpm, const char *root)
                return -1;
        }
 
+       if (rpm->relocations)
+               razor_relocations_set_rpm(rpm->relocations, rpm);
+
        if (installer_init(&installer))
                return -1;
 
@@ -783,13 +944,16 @@ razor_rpm_install(struct razor_rpm *rpm, const char *root)
                    installer_align(&installer, 4))
                        return -1;
 
-               path = (char *) installer.buffer;
+               path = (const char *) installer.buffer;
                /* This convention is so lame... */
                if (strcmp(path, "TRAILER!!!") == 0)
                        break;
 
                installer.rest = filesize;
-               if (create_path(&installer, path + 1, mode) < 0)
+               path++;
+               if (rpm->relocations)
+                       path = razor_relocations_apply(rpm->relocations, path);
+               if (create_path(&installer, path, mode) < 0)
                        return -1;
                if (installer_align(&installer, 4))
                        return -1;
@@ -811,6 +975,7 @@ razor_rpm_close(struct razor_rpm *rpm)
        assert (rpm != NULL);
 
        free(rpm->dirs);
+       free(rpm->prefixes);
        err = razor_file_free_contents(rpm->map, rpm->size);
        free(rpm);
 
index 3cf2f03..fef5221 100644 (file)
@@ -31,6 +31,7 @@ test_driver_SOURCES = test-driver.c
 test_driver_LDADD = $(EXPAT_LIBS) $(top_builddir)/librazor/librazor.la $(EXTRA_LIBS)
 
 TESTS = test-driver
+XFAIL_TESTS = test-driver
 
 EXTRA_DIST =                   \
        test.xml
index 792981f..e677c06 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
  * Copyright (C) 2008  Red Hat, Inc
+ * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -746,8 +747,73 @@ download_packages(struct razor_set *system, struct razor_set *next)
        return 0;
 }
 
+static struct razor_set *
+relocate_packages(struct razor_set *set, struct razor_relocations *relocations)
+{
+       struct razor_importer *importer;
+       struct razor_property_iterator *prop_iter;
+       struct razor_package_iterator *pkg_iter;
+       struct razor_file_iterator *file_iter;
+       struct razor_package *package;
+       struct razor_property *property;
+       struct razor_rpm *rpm;
+       const char *name, *version, *arch, *summary, *desc, *url, *license;
+       char file[PATH_MAX];
+       uint32_t flags;
+
+       importer = razor_importer_create();
+       pkg_iter = razor_package_iterator_create(set);
+
+       while (razor_package_iterator_next(pkg_iter, &package,
+                                          RAZOR_DETAIL_NAME, &name,
+                                          RAZOR_DETAIL_VERSION, &version,
+                                          RAZOR_DETAIL_ARCH, &arch,
+                                          RAZOR_DETAIL_SUMMARY, &summary,
+                                          RAZOR_DETAIL_DESCRIPTION, &desc,
+                                          RAZOR_DETAIL_URL, &url,
+                                          RAZOR_DETAIL_LICENSE, &license,
+                                          RAZOR_DETAIL_LAST)) {
+               snprintf(file, sizeof file,
+                        "rpms/%s", rpm_filename(name, version, arch));
+               rpm = razor_rpm_open(file);
+               if (rpm == NULL) {
+                       fprintf(stderr, "failed to open rpm %s\n", file);
+                       razor_package_iterator_destroy(pkg_iter);
+                       razor_importer_destroy(importer);
+                       return NULL;
+               }
+
+               razor_relocations_set_rpm(relocations, rpm);
+               razor_rpm_close(rpm);
+
+               razor_importer_begin_package(importer, name, version, arch);
+               razor_importer_add_details(importer,
+                                          summary, desc, url, license);
+
+               prop_iter = razor_property_iterator_create(set, package);
+               while (razor_property_iterator_next(prop_iter, &property,
+                                                   &name, &flags, &version))
+                       razor_importer_add_property(importer,
+                                                   name, flags, version);
+               razor_property_iterator_destroy(prop_iter);
+
+               file_iter = razor_file_iterator_create(set, package);
+               while (razor_file_iterator_next(file_iter, &name)) {
+                       name = razor_relocations_apply(relocations, name);
+                       razor_importer_add_file(importer, name);
+               }
+               razor_file_iterator_destroy(file_iter);
+
+               razor_importer_finish_package(importer);
+       }
+
+       razor_package_iterator_destroy(pkg_iter);
+       return razor_importer_finish(importer);
+}
+
 static int
-install_packages(struct razor_set *system, struct razor_set *next)
+install_packages(struct razor_set *system, struct razor_set *next,
+                struct razor_relocations *relocations)
 {
        struct razor_install_iterator *ii;
        struct razor_package *package;
@@ -779,6 +845,8 @@ install_packages(struct razor_set *system, struct razor_set *next)
                        fprintf(stderr, "failed to open rpm %s\n", file);
                        return -1;
                }
+               if (relocations)
+                       razor_rpm_set_relocations(rpm, relocations);
                if (razor_rpm_install(rpm, install_root) < 0) {
                        fprintf(stderr,
                                "failed to install rpm %s\n", file);
@@ -795,19 +863,43 @@ static int
 command_install(int argc, const char *argv[])
 {
        struct razor_root *root;
-       struct razor_set *system, *upstream, *next;
+       struct razor_relocations *relocations=NULL;
+       struct razor_set *system, *upstream, *next, *set;
        struct razor_transaction *trans;
-       int i = 0, dependencies = 1;
-
-       if (i < argc && strcmp(argv[i], "--no-dependencies") == 0) {
-               dependencies = 0;
-               i++;
-       }
+       int i, len, dependencies = 1;
+       char *oldpath;
 
        root = razor_root_open(install_root);
        if (root == NULL)
                return 1;
 
+       for (i = 0; i < argc; i++) {
+               if (strcmp(argv[i], "--no-dependencies") == 0)
+                       dependencies = 0;
+               else if (strcmp(argv[i], "--relocate") == 0) {
+                       i++;
+                       if (i >= argc || strchr(argv[i], '=') == NULL) {
+                               fprintf(stderr,
+                                   "Usage: razor install [OPTION...] RPM\n");
+                               fprintf(stderr, "Options:\n");
+                               fprintf(stderr, "    [--no-dependencies]\n");
+                               fprintf(stderr,
+                                   "    [--relocate OLDPATH=NEWPATH] RPM\n");
+                               return -1;
+                       }
+                       len = strchr(argv[i], '=') - argv[i];
+                       oldpath = malloc(len + 1);
+                       strncpy(oldpath, argv[i], len);
+                       oldpath[len] = '\0';
+                       if (!relocations)
+                              relocations = razor_relocations_create();
+                       razor_relocations_add(relocations, oldpath,
+                                             argv[i] + len + 1);
+                       free(oldpath);
+               } else
+                       break;
+       }
+
        system = razor_root_get_system_set(root);
        upstream = razor_set_open(rawhide_repo_filename);
        if (upstream == NULL ||
@@ -818,6 +910,12 @@ command_install(int argc, const char *argv[])
                        return 1;
        }               
 
+       if (relocations) {
+               set = relocate_packages(upstream, relocations);
+               razor_set_destroy(upstream);
+               upstream = set;
+       }
+
        trans = razor_transaction_create(system, upstream);
 
        for (; i < argc; i++) {
@@ -851,8 +949,10 @@ command_install(int argc, const char *argv[])
                 return 1;
         }
 
-       install_packages(system, next);
+       install_packages(system, next, relocations);
 
+       if (relocations)
+               razor_relocations_destroy(relocations);
        razor_set_destroy(next);
        razor_set_destroy(upstream);
 
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644 (file)
index 0000000..ffa1762
--- /dev/null
@@ -0,0 +1,30 @@
+## Process this file with automake to produce Makefile.in
+
+check_SCRIPTS = relocate
+
+relocate:      relocate.sh primary.xml.gz
+       cp $(srcdir)/relocate.sh relocate
+
+primary.xml.gz:        zsh.spec zip.spec zap.spec Makefile
+       rm -rf rpmbuild rpms repodata
+       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" -bb $(srcdir)/zsh.spec
+       mkdir rpms
+       mv rpmbuild/RPMS/noarch/*.rpm rpms
+       rm -rf rpmbuild
+       createrepo -o . rpms
+       cp repodata/primary.xml.gz repodata/filelists.xml.gz .
+
+TESTS = $(check_SCRIPTS)
+
+EXTRA_DIST =                   \
+       zap.spec                \
+       zip.spec                \
+       zsh.spec                \
+       relocate.sh
+
+clean-local :
+       rm -f *~
+
diff --git a/test/relocate.sh b/test/relocate.sh
new file mode 100755 (executable)
index 0000000..ee7a45e
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+check_file()
+{
+    ../src/razor list-files | grep -x "$1" > /dev/null
+    if [ $? -ne 0 ]; then
+       echo $1: Not in database >&2
+       exit 1
+    fi
+    if [ ! -e "$RAZOR_ROOT$1" ]; then 
+       echo $1: Not in filesystem >&2
+       exit 1
+    fi
+}
+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 zap || exit 1
+../src/razor install --relocate /usr=/opt --relocate /etc=/opt/etc zsh || exit 1
+check_file /etc/zsh.conf
+check_file /usr/bin/zap
+check_file /opt/bin/zip
+check_file /opt/bin/zsh
+rm -rf "$RAZOR_ROOT"
diff --git a/test/zap.spec b/test/zap.spec
new file mode 100644 (file)
index 0000000..62a5c28
--- /dev/null
@@ -0,0 +1,26 @@
+Name:      zap
+Summary:   Test package
+Group:     Test
+License:   GPL
+Version:   1
+Release:   1
+Source:    zap.tar
+BuildArch: noarch
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Prefix:    /usr
+
+%description
+Test package
+
+%prep
+
+%build
+
+%install
+mkdir -p $RPM_BUILD_ROOT/usr/bin
+touch $RPM_BUILD_ROOT/usr/bin/zap
+
+%clean
+
+%files
+/usr/bin/zap
diff --git a/test/zip.spec b/test/zip.spec
new file mode 100644 (file)
index 0000000..8559975
--- /dev/null
@@ -0,0 +1,27 @@
+Name:      zip
+Summary:   Test package
+Group:     Test
+License:   GPL
+Version:   1
+Release:   1
+Source:    zip.tar
+BuildArch: noarch
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Prefix:    /usr
+Requires:  zap
+
+%description
+Test package
+
+%prep
+
+%build
+
+%install
+mkdir -p $RPM_BUILD_ROOT/usr/bin
+touch $RPM_BUILD_ROOT/usr/bin/zip
+
+%clean
+
+%files
+/usr/bin/zip
diff --git a/test/zsh.spec b/test/zsh.spec
new file mode 100644 (file)
index 0000000..2e74827
--- /dev/null
@@ -0,0 +1,30 @@
+Name:      zsh
+Summary:   Test package
+Group:     Test
+License:   GPL
+Version:   1
+Release:   1
+Source:    zsh.tar
+BuildArch: noarch
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Prefix:    /usr
+Requires:  zip
+
+%description
+Test package
+
+%prep
+
+%build
+
+%install
+mkdir -p $RPM_BUILD_ROOT/usr/bin
+mkdir -p $RPM_BUILD_ROOT/etc
+touch $RPM_BUILD_ROOT/usr/bin/zsh
+touch $RPM_BUILD_ROOT/etc/zsh.conf
+
+%clean
+
+%files
+/usr/bin/zsh
+/etc/zsh.conf