mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-09 18:50:10 -04:00
Add flatpak_pull_from_oci helper
This commit is contained in:
@@ -29,5 +29,7 @@ typedef enum {
|
||||
typedef struct FlatpakDir FlatpakDir;
|
||||
typedef struct FlatpakDeploy FlatpakDeploy;
|
||||
typedef struct FlatpakContext FlatpakContext;
|
||||
typedef struct FlatpakOciRegistry FlatpakOciRegistry;
|
||||
typedef struct _FlatpakOciManifest FlatpakOciManifest;
|
||||
|
||||
#endif /* __FLATPAK_COMMON_TYPES_H__ */
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "flatpak-dir.h"
|
||||
#include "flatpak-utils.h"
|
||||
#include "flatpak-oci-registry.h"
|
||||
#include "flatpak-run.h"
|
||||
|
||||
#include "errno.h"
|
||||
|
||||
@@ -33,11 +33,8 @@
|
||||
#define FLATPAK_OCI_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_OCI_REGISTRY, FlatpakOciRegistry))
|
||||
#define FLATPAK_IS_OCI_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_OCI_REGISTRY))
|
||||
|
||||
|
||||
GType flatpak_oci_registry_get_type (void);
|
||||
|
||||
typedef struct FlatpakOciRegistry FlatpakOciRegistry;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakOciRegistry, g_object_unref)
|
||||
|
||||
#define FLATPAK_TYPE_OCI_LAYER_WRITER flatpak_oci_layer_writer_get_type ()
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "lib/flatpak-error.h"
|
||||
#include "flatpak-dir.h"
|
||||
#include "flatpak-portal-error.h"
|
||||
#include "flatpak-oci-registry.h"
|
||||
#include "flatpak-run.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -49,6 +50,18 @@ static const GDBusErrorEntry flatpak_error_entries[] = {
|
||||
{FLATPAK_ERROR_NOT_INSTALLED, "org.freedesktop.Flatpak.Error.NotInstalled"},
|
||||
};
|
||||
|
||||
|
||||
GLNX_DEFINE_CLEANUP_FUNCTION (void *, flatpak_local_free_read_archive, archive_read_free)
|
||||
#define free_read_archive __attribute__((cleanup (flatpak_local_free_read_archive)))
|
||||
|
||||
static void
|
||||
propagate_libarchive_error (GError **error,
|
||||
struct archive *a)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"%s", archive_error_string (a));
|
||||
}
|
||||
|
||||
GQuark
|
||||
flatpak_error_quark (void)
|
||||
{
|
||||
@@ -3981,6 +3994,112 @@ flatpak_pull_from_bundle (OstreeRepo *repo,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
flatpak_pull_from_oci (OstreeRepo *repo,
|
||||
FlatpakOciRegistry *registry,
|
||||
FlatpakOciManifest *manifest,
|
||||
const char *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(OstreeMutableTree) archive_mtree = NULL;
|
||||
g_autoptr(GFile) archive_root = NULL;
|
||||
g_autofree char *commit_checksum = NULL;
|
||||
g_autofree char *dir_uri = NULL;
|
||||
const char *parent = NULL;
|
||||
g_autofree char *subject = NULL;
|
||||
g_autofree char *body = NULL;
|
||||
guint64 timestamp = 0;
|
||||
g_autoptr(GVariant) metadatav = NULL;
|
||||
g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
||||
GHashTable *annotations;
|
||||
int i;
|
||||
|
||||
g_assert (ref != NULL);
|
||||
|
||||
annotations = flatpak_oci_manifest_get_annotations (manifest);
|
||||
if (annotations)
|
||||
flatpak_oci_parse_commit_annotations (annotations, ×tamp,
|
||||
&subject, &body,
|
||||
NULL, NULL, NULL,
|
||||
metadata_builder);
|
||||
|
||||
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
|
||||
return NULL;
|
||||
|
||||
/* There is no way to write a subset of the archive to a mtree, so instead
|
||||
we write all of it and then build a new mtree with the subset */
|
||||
archive_mtree = ostree_mutable_tree_new ();
|
||||
|
||||
for (i = 0; manifest->layers[i] != NULL; i++)
|
||||
{
|
||||
FlatpakOciDescriptor *layer = manifest->layers[i];
|
||||
OstreeRepoImportArchiveOptions opts = { 0, };
|
||||
free_read_archive struct archive *a = NULL;
|
||||
glnx_fd_close int layer_fd = -1;
|
||||
|
||||
opts.autocreate_parents = TRUE;
|
||||
opts.ignore_unsupported_content = TRUE;
|
||||
|
||||
layer_fd = flatpak_oci_registry_download_blob (registry, layer->digest,
|
||||
NULL, NULL,
|
||||
cancellable, error);
|
||||
if (layer_fd == -1)
|
||||
goto error;
|
||||
|
||||
a = archive_read_new ();
|
||||
#ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL
|
||||
archive_read_support_filter_all (a);
|
||||
#else
|
||||
archive_read_support_compression_all (a);
|
||||
#endif
|
||||
archive_read_support_format_all (a);
|
||||
if (archive_read_open_fd (a, layer_fd, 8192) != ARCHIVE_OK)
|
||||
{
|
||||
propagate_libarchive_error (error, a);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!ostree_repo_import_archive_to_mtree (repo, &opts, a, archive_mtree, NULL, cancellable, error))
|
||||
goto error;
|
||||
|
||||
if (archive_read_close (a) != ARCHIVE_OK)
|
||||
{
|
||||
propagate_libarchive_error (error, a);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ostree_repo_write_mtree (repo, archive_mtree, &archive_root, cancellable, error))
|
||||
goto error;
|
||||
|
||||
if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *) archive_root, error))
|
||||
goto error;
|
||||
|
||||
if (!ostree_repo_write_commit_with_time (repo,
|
||||
parent,
|
||||
subject,
|
||||
body,
|
||||
metadatav,
|
||||
OSTREE_REPO_FILE (archive_root),
|
||||
timestamp,
|
||||
&commit_checksum,
|
||||
cancellable, error))
|
||||
goto error;
|
||||
|
||||
ostree_repo_transaction_set_ref (repo, NULL, ref, commit_checksum);
|
||||
|
||||
if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
|
||||
return NULL;
|
||||
|
||||
return g_steal_pointer (&commit_checksum);
|
||||
|
||||
error:
|
||||
|
||||
ostree_repo_abort_transaction (repo, cancellable, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This allocates and locks a subdir of the tmp dir, using an existing
|
||||
* one with the same prefix if it is not in use already. */
|
||||
gboolean
|
||||
|
||||
@@ -294,6 +294,12 @@ gboolean flatpak_pull_from_bundle (OstreeRepo *repo,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
char * flatpak_pull_from_oci (OstreeRepo *repo,
|
||||
FlatpakOciRegistry *registry,
|
||||
FlatpakOciManifest *manifest,
|
||||
const char *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user