From 80fdc4e0de3fa654364be127dc5c152692f0012a Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 8 Feb 2025 12:58:04 +0000 Subject: [PATCH] oci: Use the archive writer to create the layer Signed-off-by: Michael Tremer --- src/pakfire/archive_writer.c | 52 +++++++++++++++++++++++++++++++++++- src/pakfire/archive_writer.h | 4 +++ src/pakfire/oci.c | 37 +++++++------------------ 3 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/pakfire/archive_writer.c b/src/pakfire/archive_writer.c index 1ac2e3ae..0e7d40fd 100644 --- a/src/pakfire/archive_writer.c +++ b/src/pakfire/archive_writer.c @@ -50,6 +50,7 @@ struct pakfire_archive_writer { // Container enum pakfire_archive_writer_container { PAKFIRE_CONTAINER_PAX, + PAKFIRE_CONTAINER_GNU, } container; // Compression @@ -96,6 +97,18 @@ static int pakfire_archive_writer_setup_format( self->checksums = PAKFIRE_HASH_SHA3_512|PAKFIRE_HASH_BLAKE2B512; break; + // OCI Layer + case PAKFIRE_FORMAT_OCI_LAYER: + // Use the GNU tar format + self->container = PAKFIRE_CONTAINER_GNU; + + // We use Zstandard compression + self->compression = PAKFIRE_COMPRESSION_ZSTD; + + // Use some good compression + self->compression_level = 20; + break; + // Fail on invalid inputs default: ERROR(self->ctx, "Invalid archive format\n"); @@ -118,8 +131,8 @@ static int pakfire_archive_writer_setup_archive(struct pakfire_archive_writer* s // Set the container format switch (self->container) { + // PAX Format case PAKFIRE_CONTAINER_PAX: - // Use the PAX format r = archive_write_set_format_pax(self->archive); if (r) { ERROR(self->ctx, "Could not set format to PAX: %s\n", @@ -135,6 +148,16 @@ static int pakfire_archive_writer_setup_archive(struct pakfire_archive_writer* s return -ENOTSUP; } break; + + // GNU Tar Format + case PAKFIRE_CONTAINER_GNU: + r = archive_write_set_format_gnutar(self->archive); + if (r) { + ERROR(self->ctx, "Could not set format to GNU tar: %s\n", + archive_error_string(self->archive)); + return -ENOTSUP; + } + break; } // Set the compression @@ -523,6 +546,33 @@ ERROR: return r; } +int pakfire_archive_writer_write_everything( + struct pakfire_archive_writer* self, const char* root) { + struct pakfire_filelist* files = NULL; + int r; + + // Create a new filelist + r = pakfire_filelist_create(&files, self->pakfire); + if (r < 0) + goto ERROR; + + // Scan for all files + r = pakfire_filelist_scan(files, root, NULL, NULL, 0); + if (r < 0) + goto ERROR; + + // Write all files + r = pakfire_archive_writer_write_files(self, files); + if (r < 0) + goto ERROR; + +ERROR: + if (files) + pakfire_filelist_unref(files); + + return r; +} + /* * Creates a new file and writes it to the archive. */ diff --git a/src/pakfire/archive_writer.h b/src/pakfire/archive_writer.h index 92289684..3a356e3c 100644 --- a/src/pakfire/archive_writer.h +++ b/src/pakfire/archive_writer.h @@ -30,6 +30,7 @@ struct pakfire_archive_writer; typedef enum pakfire_archive_writer_formats { PAKFIRE_FORMAT_ARCHIVE, + PAKFIRE_FORMAT_OCI_LAYER, } pakfire_archive_writer_format; int pakfire_archive_writer_create(struct pakfire_archive_writer** writer, @@ -44,6 +45,9 @@ int pakfire_archive_writer_set_title(struct pakfire_archive_writer* self, int pakfire_archive_writer_write_files( struct pakfire_archive_writer* self, struct pakfire_filelist* files); +int pakfire_archive_writer_write_everything( + struct pakfire_archive_writer* self, const char* root); + int pakfire_archive_writer_create_file(struct pakfire_archive_writer* self, const char* filename, mode_t mode, const char* payload, const size_t length); diff --git a/src/pakfire/oci.c b/src/pakfire/oci.c index 70811a1f..1d5b74b6 100644 --- a/src/pakfire/oci.c +++ b/src/pakfire/oci.c @@ -22,54 +22,37 @@ #include #include -#include -#include +#include #include #include #include #include int pakfire_oci_mkimage(struct pakfire* pakfire, FILE* f) { - struct pakfire_filelist* filelist = NULL; - struct archive* archive = NULL; + struct pakfire_archive_writer* writer = NULL; int r; // Fetch the pakfire root const char* root = pakfire_get_path(pakfire); - // Create a new filelist - r = pakfire_filelist_create(&filelist, pakfire); + // Make a new archive writer + r = pakfire_archive_writer_create(&writer, pakfire, PAKFIRE_FORMAT_OCI_LAYER, f); if (r < 0) goto ERROR; - // Scan for all files - r = pakfire_filelist_scan(filelist, root, NULL, NULL, 0); + // Set the title + r = pakfire_archive_writer_set_title(writer, "%s", _("Writing Layer")); if (r < 0) goto ERROR; - // Create a new archive - r = pakfire_compress_create_archive(pakfire, &archive, f, PAKFIRE_COMPRESS_GZIP, 9); + // Write all files + r = pakfire_archive_writer_write_everything(writer, root); if (r < 0) goto ERROR; - // Write all files to the image - r = pakfire_compress(pakfire, archive, filelist, - _("Creating Image"), PAKFIRE_COMPRESS_SHOW_THROUGHPUT, 0); - if (r < 0) - goto ERROR; - - // Close archive - r = archive_write_close(archive); - if (r) { - //ERROR(pakfire, "Could not close archive: %s\n", archive_error_string(archive)); - goto ERROR; - } - ERROR: - if (filelist) - pakfire_filelist_unref(filelist); - if (archive) - archive_free(archive); + if (writer) + pakfire_archive_writer_unref(writer); return r; } -- 2.39.5