]> git.ipfire.org Git - pakfire.git/commitdiff
repo: Unify code to import packages
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 09:54:12 +0000 (09:54 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 10:04:31 +0000 (10:04 +0000)
This now supports the flat layout that we use for the @local build
repository as well as the UUID layout that we use to publish packages.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/repo.c

index f40c64db79ddbcd3d24fb3d98cc1969728270316..51c6be0ff0ec72cded4b7cd58096adeecb4822dd 100644 (file)
@@ -76,6 +76,12 @@ struct pakfire_repo_appdata {
        char mirrorlist_url[PATH_MAX];
        char mirrorlist[PATH_MAX];
 
+       // Filesystem Layout
+       enum pakfire_repo_filesystem_layout {
+               PAKFIRE_REPO_UUID = (1 << 0),
+               PAKFIRE_REPO_FLAT = (1 << 1),
+       } fs_layout;
+
        // Markers
        int ready:1;
 };
@@ -223,6 +229,13 @@ static int __pakfire_repo_path(struct pakfire_repo* repo,
        return __pakfire_cache_path(repo->pakfire, path, length, "%s/%s", name, buffer);
 }
 
+static const char* pakfire_repo_relpath(struct pakfire_repo* self, const char* path) {
+       // Fetch the repo's base path
+       const char* basepath = pakfire_repo_get_path(self);
+
+       return pakfire_path_relpath(basepath, path);
+}
+
 static int pakfire_repo_xfer_create(struct pakfire_xfer** xfer, struct pakfire_repo* repo,
        const char* url, ...) __attribute__((format(printf, 3, 4)));
 
@@ -412,30 +425,65 @@ int pakfire_repo_add_archive(struct pakfire_repo* repo,
 
 int pakfire_repo_import_archive(struct pakfire_repo* self, struct pakfire_archive* archive) {
        struct pakfire_package* pkg = NULL;
+       const char* uuid = NULL;
        char path[PATH_MAX];
        int r;
 
-       // Fetch the package
-       r = pakfire_archive_make_package(archive, NULL, &pkg);
+       // This repository must be local
+       if (!pakfire_repo_is_local(self))
+               return -ENOTSUP;
+
+       // Add the metadata
+       r = pakfire_archive_make_package(archive, self, &pkg);
        if (r < 0)
                goto ERROR;
 
+       // Fetch NEVRA
+       const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA);
+       if (!nevra)
+               return -EINVAL;
+
        // Fetch the filename this package should have
        const char* filename = pakfire_package_get_filename(pkg);
        if (!filename)
                return -EINVAL;
 
        // Compose the destination path
-       r = pakfire_repo_path(self, path, "%s", filename);
-       if (r < 0)
-               goto ERROR;
+       switch (self->appdata->fs_layout) {
+               case PAKFIRE_REPO_FLAT:
+                       r = pakfire_repo_path(self, path, "%s", filename);
+                       if (r < 0)
+                               goto ERROR;
+                       break;
+
+               case PAKFIRE_REPO_UUID:
+                       // Fetch the UUID
+                       uuid = pakfire_package_get_string(pkg, PAKFIRE_PKG_UUID);
+                       if (!uuid) {
+                               ERROR(self->ctx, "%s does not have a UUID\n", nevra);
+                               r = -EINVAL;
+                               goto ERROR;
+                       }
+
+                       r = pakfire_repo_path(self, path, "%s/%s", uuid, filename);
+                       if (r < 0)
+                               goto ERROR;
+                       break;
+       }
 
        // Copy (or link) the archive
        r = pakfire_archive_link_or_copy(archive, path);
        if (r < 0)
                goto ERROR;
 
+       // Reset the path
+       r = pakfire_package_set_string(pkg, PAKFIRE_PKG_PATH, pakfire_repo_relpath(self, path));
+       if (r < 0)
+               goto ERROR;
+
 ERROR:
+       // XXX REMOVE THE PACKAGE METDATA FROM THIS REPOSITORY
+
        if (pkg)
                pakfire_package_unref(pkg);
 
@@ -790,6 +838,13 @@ static int pakfire_repo_setup_appdata(struct pakfire_repo* self) {
        // Refresh Interval: Set to invalid
        appdata->refresh = -1;
 
+       // The local build repository will have a flat layout, but all other
+       // local repositories will be using the UUID layout.
+       if (pakfire_string_equals(self->repo->name, PAKFIRE_REPO_LOCAL))
+               appdata->fs_layout = PAKFIRE_REPO_FLAT;
+       else
+               appdata->fs_layout = PAKFIRE_REPO_UUID;
+
        // Store the pointer
        self->appdata = self->repo->appdata = appdata;
 
@@ -1979,6 +2034,7 @@ ERROR:
 
 int pakfire_repo_compose(struct pakfire* pakfire, const char* path,
                struct pakfire_key* key, const char** files) {
+       struct pakfire_archive* archive = NULL;
        struct pakfire_repo* repo = NULL;
        char realpath[PATH_MAX];
        char baseurl[PATH_MAX];
@@ -2037,13 +2093,6 @@ int pakfire_repo_compose(struct pakfire* pakfire, const char* path,
                goto ERROR;
        }
 
-       struct pakfire_archive* archive = NULL;
-       struct pakfire_package* package = NULL;
-       const char* uuid = NULL;
-       const char* filename = NULL;
-       char destination_path[PATH_MAX];
-       char repo_path[PATH_MAX];
-
        DEBUG(ctx, "Adding %zu file(s) to the repository\n", num_files);
 
        // Add more files
@@ -2058,58 +2107,18 @@ int pakfire_repo_compose(struct pakfire* pakfire, const char* path,
                                goto OUT;
                        }
 
-                       // Add package metadata
-                       r = pakfire_repo_add_archive(repo, archive, &package);
-                       if (r) {
-                               ERROR(ctx, "Could not add %s to the repository: %m\n", *file);
+                       // Import the archive
+                       r = pakfire_repo_import_archive(repo, archive);
+                       if (r < 0) {
+                               ERROR(ctx, "Could not import %s: %s\n", *file, strerror(-r));
                                goto OUT;
                        }
 
-                       // Fetch the UUID
-                       uuid = pakfire_package_get_string(package, PAKFIRE_PKG_UUID);
-                       if (!uuid) {
-                               ERROR(ctx, "Could not retrieve the UUID of %s: %m\n", *file);
-                               r = -EINVAL;
-                               goto OUT;
-                       }
-
-                       // Fetch the filename
-                       filename = pakfire_package_get_string(package, PAKFIRE_PKG_FILENAME);
-                       if (!filename) {
-                               ERROR(ctx, "Could not retrieve filename of %s: %m\n", *file);
-                               r = -EINVAL;
-                               goto OUT;
-                       }
-
-                       // Make new path where the archive is being stored
-                       r = pakfire_string_format(repo_path, "%s/%s", uuid, filename);
-                       if (r)
-                               goto OUT;
-
-                       // Make the path absolute
-                       r = pakfire_path_append(destination_path, realpath, repo_path);
-                       if (r)
-                               goto OUT;
-
-                       // Copying archive to destination
-                       r = pakfire_archive_link_or_copy(archive, destination_path);
-                       if (r) {
-                               ERROR(ctx, "Could not copy archive to %s: %m\n", destination_path);
-                               goto OUT;
-                       }
-
-                       // Reset the path
-                       pakfire_package_set_string(package, PAKFIRE_PKG_PATH, repo_path);
-
 OUT:
                        if (archive) {
                                pakfire_archive_unref(archive);
                                archive = NULL;
                        }
-                       if (package) {
-                               pakfire_package_unref(package);
-                               package = NULL;
-                       }
 
                        if (r)
                                goto ERROR;