common: Add OCI image installation support

This commit is contained in:
Owen W. Taylor
2024-12-18 00:52:27 +01:00
committed by Sebastian Wick
parent dc56bda820
commit 806fc83cd6
6 changed files with 252 additions and 79 deletions

View File

@@ -574,6 +574,7 @@ gboolean flatpak_dir_pull (Fla
const char *opt_rev,
const char **subpaths,
GFile *sideload_repo,
FlatpakImageSource *opt_image_source,
GBytes *require_metadata,
const char *token,
OstreeRepo *repo,
@@ -695,6 +696,7 @@ gboolean flatpak_dir_install (Fla
const char **subpaths,
const char **previous_ids,
GFile *sideload_repo,
FlatpakImageSource *opt_image_source,
GBytes *require_metadata,
const char *token,
FlatpakProgress *progress,
@@ -741,6 +743,7 @@ gboolean flatpak_dir_update (Fla
const char **opt_subpaths,
const char **opt_previous_ids,
GFile *sideload_repo,
FlatpakImageSource *opt_image_source,
GBytes *require_metadata,
const char *token,
FlatpakProgress *progress,

View File

@@ -123,7 +123,7 @@ static gboolean flatpak_dir_mirror_oci (FlatpakDir *self,
FlatpakRemoteState *state,
const char *ref,
const char *opt_rev,
const char *skip_if_current_is,
FlatpakImageSource *opt_image_source,
const char *token,
FlatpakProgress *progress,
GCancellable *cancellable,
@@ -5307,7 +5307,7 @@ flatpak_dir_update_appstream (FlatpakDir *self,
if (child_repo == NULL)
return FALSE;
if (!flatpak_dir_pull (self, state, used_branch, appstream_commit, NULL, appstream_sideload_path, NULL, NULL,
if (!flatpak_dir_pull (self, state, used_branch, appstream_commit, NULL, appstream_sideload_path, NULL, NULL, NULL,
child_repo, FLATPAK_PULL_FLAGS_NONE, 0,
progress, cancellable, error))
{
@@ -5351,7 +5351,7 @@ flatpak_dir_update_appstream (FlatpakDir *self,
}
if (!flatpak_dir_pull (self, state, used_branch, appstream_commit, NULL, appstream_sideload_path, NULL, NULL, NULL,
if (!flatpak_dir_pull (self, state, used_branch, appstream_commit, NULL, appstream_sideload_path, NULL, NULL, NULL, NULL,
FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_NONE, progress,
cancellable, error))
{
@@ -5903,7 +5903,7 @@ flatpak_dir_mirror_oci (FlatpakDir *self,
FlatpakRemoteState *state,
const char *ref,
const char *opt_rev,
const char *skip_if_current_is,
FlatpakImageSource *opt_image_source,
const char *token,
FlatpakProgress *progress,
GCancellable *cancellable,
@@ -5911,40 +5911,42 @@ flatpak_dir_mirror_oci (FlatpakDir *self,
{
g_autoptr(FlatpakImageSource) image_source = NULL;
g_autofree char *oci_digest = NULL;
g_autofree char *latest_rev = NULL;
VarRefInfoRef latest_rev_info;
VarMetadataRef metadata;
const char *oci_repository = NULL;
const char *delta_url = NULL;
const char *rev;
gboolean res;
/* We use the summary so that we can reuse any cached json */
if (!flatpak_remote_state_lookup_ref (state, ref, &latest_rev, NULL, &latest_rev_info, NULL, error))
return FALSE;
if (latest_rev == NULL)
return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
_("Couldn't find latest checksum for ref %s in remote %s"),
ref, state->remote_name);
rev = opt_rev != NULL ? opt_rev : latest_rev;
if (skip_if_current_is != NULL && strcmp (rev, skip_if_current_is) == 0)
if (opt_image_source)
{
return flatpak_fail_error (error, FLATPAK_ERROR_ALREADY_INSTALLED,
_("%s commit %s already installed"),
ref, rev);
image_source = g_object_ref (opt_image_source);
oci_digest = g_strdup (flatpak_image_source_get_digest (image_source));
}
else
{
g_autofree char *latest_rev = NULL;
VarRefInfoRef latest_rev_info;
VarMetadataRef metadata;
const char *oci_repository = NULL;
const char *rev;
metadata = var_ref_info_get_metadata (latest_rev_info);
oci_repository = var_metadata_lookup_string (metadata, "xa.oci-repository", NULL);
delta_url = var_metadata_lookup_string (metadata, "xa.delta-url", NULL);
/* We use the summary so that we can reuse any cached json */
if (!flatpak_remote_state_lookup_ref (state, ref, &latest_rev, NULL, &latest_rev_info, NULL, error))
return FALSE;
if (latest_rev == NULL)
return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
_("Couldn't find latest checksum for ref %s in remote %s"),
ref, state->remote_name);
oci_digest = g_strconcat ("sha256:", rev, NULL);
rev = opt_rev != NULL ? opt_rev : latest_rev;
image_source = flatpak_remote_state_new_image_source (state, oci_repository, oci_digest, token, cancellable, error);
if (image_source == NULL)
return FALSE;
metadata = var_ref_info_get_metadata (latest_rev_info);
oci_repository = var_metadata_lookup_string (metadata, "xa.oci-repository", NULL);
delta_url = var_metadata_lookup_string (metadata, "xa.delta-url", NULL);
oci_digest = g_strconcat ("sha256:", rev, NULL);
image_source = flatpak_remote_state_new_image_source (state, oci_repository, oci_digest, token, cancellable, error);
if (image_source == NULL)
return FALSE;
}
flatpak_progress_start_oci_pull (progress);
@@ -5964,6 +5966,7 @@ flatpak_dir_pull_oci (FlatpakDir *self,
FlatpakRemoteState *state,
const char *ref,
const char *opt_rev,
FlatpakImageSource *opt_image_source,
OstreeRepo *repo,
FlatpakPullFlags flatpak_flags,
OstreeRepoPullFlags flags,
@@ -5974,40 +5977,49 @@ flatpak_dir_pull_oci (FlatpakDir *self,
{
g_autoptr(FlatpakImageSource) image_source = NULL;
FlatpakOciRegistry *registry = NULL;
const char *oci_repository = NULL;
const char *delta_url = NULL;
g_autofree char *oci_digest = NULL;
g_autofree char *checksum = NULL;
VarRefInfoRef latest_rev_info;
g_autofree char *latest_alt_commit = NULL;
VarMetadataRef metadata;
g_autofree char *latest_rev = NULL;
G_GNUC_UNUSED g_autofree char *latest_commit =
flatpak_dir_read_latest (self, state->remote_name, ref, &latest_alt_commit, cancellable, NULL);
g_autofree char *name = NULL;
/* We use the summary so that we can reuse any cached json */
if (!flatpak_remote_state_lookup_ref (state, ref, &latest_rev, NULL, &latest_rev_info, NULL, error))
return FALSE;
if (latest_rev == NULL)
return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
_("Couldn't find latest checksum for ref %s in remote %s"),
ref, state->remote_name);
if (opt_image_source)
{
image_source = g_object_ref (opt_image_source);
oci_digest = g_strdup (flatpak_image_source_get_digest (image_source));
}
else
{
VarMetadataRef metadata;
VarRefInfoRef latest_rev_info;
const char *oci_repository = NULL;
g_autofree char *latest_rev = NULL;
metadata = var_ref_info_get_metadata (latest_rev_info);
oci_repository = var_metadata_lookup_string (metadata, "xa.oci-repository", NULL);
delta_url = var_metadata_lookup_string (metadata, "xa.delta-url", NULL);
/* We use the summary so that we can reuse any cached json */
if (!flatpak_remote_state_lookup_ref (state, ref, &latest_rev, NULL, &latest_rev_info, NULL, error))
return FALSE;
if (latest_rev == NULL)
return flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND,
_("Couldn't find latest checksum for ref %s in remote %s"),
ref, state->remote_name);
oci_digest = g_strconcat ("sha256:", opt_rev != NULL ? opt_rev : latest_rev, NULL);
metadata = var_ref_info_get_metadata (latest_rev_info);
oci_repository = var_metadata_lookup_string (metadata, "xa.oci-repository", NULL);
delta_url = var_metadata_lookup_string (metadata, "xa.delta-url", NULL);
oci_digest = g_strconcat ("sha256:", opt_rev != NULL ? opt_rev : latest_rev, NULL);
image_source = flatpak_remote_state_new_image_source (state, oci_repository, oci_digest, token, cancellable, error);
if (image_source == NULL)
return FALSE;
}
/* Short circuit if we've already got this commit */
if (latest_alt_commit != NULL && strcmp (oci_digest + strlen ("sha256:"), latest_alt_commit) == 0)
return TRUE;
image_source = flatpak_remote_state_new_image_source (state, oci_repository, oci_digest, token, cancellable, error);
if (image_source == NULL)
return FALSE;
if (repo == NULL)
repo = self->repo;
@@ -6046,6 +6058,7 @@ flatpak_dir_pull (FlatpakDir *self,
const char *opt_rev,
const char **subpaths,
GFile *sideload_repo,
FlatpakImageSource *opt_image_source,
GBytes *require_metadata,
const char *token,
OstreeRepo *repo,
@@ -6076,8 +6089,8 @@ flatpak_dir_pull (FlatpakDir *self,
if (repo == NULL && !flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error))
return FALSE;
if (flatpak_dir_get_remote_oci (self, state->remote_name))
return flatpak_dir_pull_oci (self, state, ref, opt_rev, repo, flatpak_flags,
if (opt_image_source || flatpak_dir_get_remote_oci (self, state->remote_name))
return flatpak_dir_pull_oci (self, state, ref, opt_rev, opt_image_source, repo, flatpak_flags,
flags, token, progress, cancellable, error);
if (!ostree_repo_remote_get_url (self->repo,
@@ -9849,6 +9862,7 @@ flatpak_dir_install (FlatpakDir *self,
const char **opt_subpaths,
const char **opt_previous_ids,
GFile *sideload_repo,
FlatpakImageSource *opt_image_source,
GBytes *require_metadata,
const char *token,
FlatpakProgress *progress,
@@ -9913,7 +9927,8 @@ flatpak_dir_install (FlatpakDir *self,
child_repo_path = g_file_get_path (registry_file);
if (!flatpak_dir_mirror_oci (self, registry, state, flatpak_decomposed_get_ref (ref), opt_commit, NULL, token, progress, cancellable, error))
if (!flatpak_dir_mirror_oci (self, registry, state, flatpak_decomposed_get_ref (ref),
opt_commit, opt_image_source, token, progress, cancellable, error))
return FALSE;
}
else if (!gpg_verify_summary || !gpg_verify)
@@ -10007,7 +10022,7 @@ flatpak_dir_install (FlatpakDir *self,
flatpak_flags |= FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;
if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref), opt_commit, subpaths, sideload_repo, require_metadata, token,
if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref), opt_commit, subpaths, sideload_repo, NULL, require_metadata, token,
child_repo,
flatpak_flags,
0,
@@ -10082,7 +10097,8 @@ flatpak_dir_install (FlatpakDir *self,
if (!no_pull)
{
if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref), opt_commit, opt_subpaths, sideload_repo, require_metadata, token, NULL,
if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref), opt_commit, opt_subpaths,
sideload_repo, opt_image_source, require_metadata, token, NULL,
flatpak_flags, OSTREE_REPO_PULL_FLAGS_NONE,
progress, cancellable, error))
return FALSE;
@@ -10529,6 +10545,7 @@ flatpak_dir_update (FlatpakDir *self,
const char **opt_subpaths,
const char **opt_previous_ids,
GFile *sideload_repo,
FlatpakImageSource *opt_image_source,
GBytes *require_metadata,
const char *token,
FlatpakProgress *progress,
@@ -10616,7 +10633,7 @@ flatpak_dir_update (FlatpakDir *self,
child_repo_path = g_file_get_path (registry_file);
if (!flatpak_dir_mirror_oci (self, registry, state, flatpak_decomposed_get_ref (ref),
commit, NULL, token, progress, cancellable, error))
commit, opt_image_source, token, progress, cancellable, error))
return FALSE;
}
else if (!gpg_verify_summary || !gpg_verify)
@@ -10696,7 +10713,7 @@ flatpak_dir_update (FlatpakDir *self,
flatpak_flags |= FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;
if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref),
commit, subpaths, sideload_repo, require_metadata, token,
commit, subpaths, sideload_repo, NULL, require_metadata, token,
child_repo,
flatpak_flags, 0,
progress, cancellable, error))
@@ -10762,7 +10779,7 @@ flatpak_dir_update (FlatpakDir *self,
if (!no_pull)
{
if (!flatpak_dir_pull (self, state, flatpak_decomposed_get_ref (ref),
commit, subpaths, sideload_repo, require_metadata, token,
commit, subpaths, sideload_repo, opt_image_source, require_metadata, token,
NULL, flatpak_flags, OSTREE_REPO_PULL_FLAGS_NONE,
progress, cancellable, error))
return FALSE;

View File

@@ -1930,7 +1930,7 @@ flatpak_installation_install_full (FlatpakInstallation *self,
(flags & FLATPAK_INSTALL_FLAGS_NO_DEPLOY) != 0,
(flags & FLATPAK_INSTALL_FLAGS_NO_STATIC_DELTAS) != 0,
FALSE, FALSE, FALSE, state,
ref, NULL, (const char **) subpaths, NULL, NULL, NULL, NULL,
ref, NULL, (const char **) subpaths, NULL, NULL, NULL, NULL, NULL,
progress, cancellable, error))
return NULL;
@@ -2098,7 +2098,7 @@ flatpak_installation_update_full (FlatpakInstallation *self,
(flags & FLATPAK_UPDATE_FLAGS_NO_STATIC_DELTAS) != 0,
FALSE, FALSE, FALSE, state,
ref, target_commit,
(const char **) subpaths, NULL, NULL, NULL, NULL,
(const char **) subpaths, NULL, NULL, NULL, NULL, NULL,
progress, cancellable, error))
return NULL;

View File

@@ -26,7 +26,9 @@
#include "flatpak-auth-private.h"
#include "flatpak-dir-private.h"
#include "flatpak-error.h"
#include "flatpak-image-source-private.h"
#include "flatpak-installation-private.h"
#include "flatpak-oci-registry-private.h"
#include "flatpak-progress-private.h"
#include "flatpak-repo-utils-private.h"
#include "flatpak-transaction-private.h"
@@ -103,6 +105,7 @@ struct _FlatpakTransactionOperation
char **subpaths;
char **previous_ids;
char *commit;
FlatpakImageSource *image_source;
GFile *bundle;
GBytes *external_metadata;
FlatpakTransactionOperationType kind;
@@ -115,6 +118,7 @@ struct _FlatpakTransactionOperation
gboolean resolved;
char *resolved_commit;
GFile *resolved_sideload_path;
FlatpakImageSource *resolved_image_source;
GBytes *resolved_metadata;
GKeyFile *resolved_metakey;
GBytes *resolved_old_metadata;
@@ -144,6 +148,11 @@ typedef struct _BundleData
GBytes *gpg_data;
} BundleData;
typedef struct _ImageData
{
char *image_location;
} ImageData;
typedef struct {
FlatpakTransaction *transaction;
const char *remote;
@@ -168,6 +177,7 @@ typedef struct _FlatpakTransactionPrivate
GList *flatpakrefs; /* GKeyFiles */
GList *bundles; /* BundleData */
GList *images; /* ImageData */
guint next_request_id;
guint active_request_id;
@@ -260,6 +270,23 @@ bundle_data_free (BundleData *data)
g_free (data);
}
static ImageData *
image_data_new (const char *image_location)
{
ImageData *data = g_new0 (ImageData, 1);
data->image_location = g_strdup (image_location);
return data;
}
static void
image_data_free (ImageData *data)
{
g_clear_pointer (&data->image_location, g_free);
g_free (data);
}
static guint progress_signals[LAST_SIGNAL] = { 0 };
/**
@@ -612,6 +639,8 @@ flatpak_transaction_operation_finalize (GObject *object)
g_clear_pointer (&self->run_before_ops, g_list_free);
g_clear_pointer (&self->related_to_ops, g_ptr_array_unref);
g_clear_pointer (&self->summary_metadata, g_variant_unref);
g_clear_object (&self->image_source);
g_clear_object (&self->resolved_image_source);
G_OBJECT_CLASS (flatpak_transaction_operation_parent_class)->finalize (object);
}
@@ -993,6 +1022,7 @@ flatpak_transaction_finalize (GObject *object)
g_free (priv->parent_window);
g_list_free_full (priv->flatpakrefs, (GDestroyNotify) g_key_file_unref);
g_list_free_full (priv->bundles, (GDestroyNotify) bundle_data_free);
g_list_free_full (priv->images, (GDestroyNotify) image_data_free);
g_free (priv->default_arch);
g_hash_table_unref (priv->last_op_for_ref);
g_hash_table_unref (priv->remote_states);
@@ -2603,6 +2633,7 @@ flatpak_transaction_add_ref (FlatpakTransaction *self,
const char *commit,
FlatpakTransactionOperationType kind,
GFile *bundle,
FlatpakImageSource *image_source,
const char *external_metadata,
gboolean pin_on_deploy,
FlatpakTransactionOperation **out_op,
@@ -2730,6 +2761,9 @@ flatpak_transaction_add_ref (FlatpakTransaction *self,
op = flatpak_transaction_add_op (self, remote, ref, subpaths, previous_ids,
commit, bundle, kind, pin_on_deploy);
if (image_source)
op->image_source = g_object_ref (image_source);
if (external_metadata)
op->external_metadata = g_bytes_new (external_metadata, strlen (external_metadata));
@@ -2783,7 +2817,7 @@ flatpak_transaction_add_install (FlatpakTransaction *self,
if (!flatpak_transaction_add_ref (self, remote, decomposed, subpaths, NULL, NULL,
FLATPAK_TRANSACTION_OPERATION_INSTALL,
NULL, NULL, pin_on_deploy, NULL, error))
NULL, NULL, NULL, pin_on_deploy, NULL, error))
return FALSE;
return TRUE;
@@ -2843,7 +2877,7 @@ flatpak_transaction_add_rebase (FlatpakTransaction *self,
if (dir_ref_is_installed (priv->dir, decomposed, &installed_origin, NULL))
remote = installed_origin;
return flatpak_transaction_add_ref (self, remote, decomposed, subpaths, previous_ids, NULL, FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE, NULL, NULL, FALSE, NULL, error);
return flatpak_transaction_add_ref (self, remote, decomposed, subpaths, previous_ids, NULL, FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE, NULL, NULL, NULL, FALSE, NULL, error);
}
/**
@@ -2919,12 +2953,12 @@ flatpak_transaction_add_rebase_and_uninstall (FlatpakTransaction *self,
if (!flatpak_transaction_add_ref (self, remote, new_decomposed, subpaths,
previous_ids, NULL,
FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE,
NULL, NULL, FALSE, &rebase_op, error))
NULL, NULL, NULL, FALSE, &rebase_op, error))
return FALSE;
if (!flatpak_transaction_add_ref (self, NULL, old_decomposed, NULL, NULL, NULL,
FLATPAK_TRANSACTION_OPERATION_UNINSTALL,
NULL, NULL, FALSE, &uninstall_op, &local_error))
NULL, NULL, NULL, FALSE, &uninstall_op, &local_error))
{
/* If the user is trying to install an eol-rebased app from scratch, the
* @old_ref cant be uninstalled because its not installed already.
@@ -2980,6 +3014,36 @@ flatpak_transaction_add_install_bundle (FlatpakTransaction *self,
return TRUE;
}
/**
* flatpak_transaction_add_install_image:
* @self: a #FlatpakTransaction
* @image_location: (nullable): location string to install from.
* @error: return location for a #GError
*
* Install a Flatpak from a container image. The image is specified
*
* If the reference from the image was previously installed, then
* that remote will be used as the remote for the newly installed image. If the
* reference was not previously installed, then a remote will be created for the
* reference.
*
* @image_location is specified in containers-transports(5) form. Only a subset
* of transports are supported: oci: and docker:.
*
* Returns: %TRUE on success; %FALSE with @error set on failure.
*/
gboolean
flatpak_transaction_add_install_image (FlatpakTransaction *self,
const char *image_location,
GError **error)
{
FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
priv->images = g_list_append (priv->images, image_data_new (image_location));
return TRUE;
}
/**
* flatpak_transaction_add_install_flatpakref:
* @self: a #FlatpakTransaction
@@ -3046,7 +3110,7 @@ flatpak_transaction_add_update (FlatpakTransaction *self,
return FALSE;
/* Note: we implement the merge when subpaths == NULL in flatpak_transaction_add_ref() */
return flatpak_transaction_add_ref (self, NULL, decomposed, subpaths, NULL, commit, FLATPAK_TRANSACTION_OPERATION_UPDATE, NULL, NULL, FALSE, NULL, error);
return flatpak_transaction_add_ref (self, NULL, decomposed, subpaths, NULL, commit, FLATPAK_TRANSACTION_OPERATION_UPDATE, NULL, NULL, NULL, FALSE, NULL, error);
}
/**
@@ -3073,7 +3137,7 @@ flatpak_transaction_add_uninstall (FlatpakTransaction *self,
if (decomposed == NULL)
return FALSE;
return flatpak_transaction_add_ref (self, NULL, decomposed, NULL, NULL, NULL, FLATPAK_TRANSACTION_OPERATION_UNINSTALL, NULL, NULL, FALSE, NULL, error);
return flatpak_transaction_add_ref (self, NULL, decomposed, NULL, NULL, NULL, FLATPAK_TRANSACTION_OPERATION_UNINSTALL, NULL, NULL, NULL, FALSE, NULL, error);
}
static gboolean
@@ -3185,7 +3249,7 @@ flatpak_transaction_add_auto_install (FlatpakTransaction *self,
if (!flatpak_transaction_add_ref (self, remote, auto_install_ref, NULL, NULL, NULL,
FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE,
NULL, NULL, FALSE, NULL,
NULL, NULL, NULL, FALSE, NULL,
&local_error))
g_info ("Failed to add auto-install ref %s: %s", flatpak_decomposed_get_ref (auto_install_ref),
local_error->message);
@@ -3283,6 +3347,7 @@ static gboolean
mark_op_resolved (FlatpakTransactionOperation *op,
const char *commit,
GFile *sideload_path,
FlatpakImageSource *image_source,
GBytes *metadata,
GBytes *old_metadata,
GError **error)
@@ -3291,7 +3356,7 @@ mark_op_resolved (FlatpakTransactionOperation *op,
g_assert (op != NULL);
g_assert (commit != NULL);
g_assert (commit != NULL || image_source != NULL);
op->resolved = TRUE;
@@ -3304,6 +3369,9 @@ mark_op_resolved (FlatpakTransactionOperation *op,
if (sideload_path)
op->resolved_sideload_path = g_object_ref (sideload_path);
if (image_source)
op->resolved_image_source = g_object_ref (image_source);
if (metadata)
{
g_autoptr(GKeyFile) metakey = g_key_file_new ();
@@ -3337,13 +3405,14 @@ resolve_op_end (FlatpakTransaction *self,
FlatpakTransactionOperation *op,
const char *checksum,
GFile *sideload_path,
FlatpakImageSource *image_source,
GBytes *metadata_bytes,
GError **error)
{
g_autoptr(GBytes) old_metadata_bytes = NULL;
old_metadata_bytes = load_deployed_metadata (self, op->ref, NULL, NULL);
if (!mark_op_resolved (op, checksum, sideload_path, metadata_bytes, old_metadata_bytes, error))
if (!mark_op_resolved (op, checksum, sideload_path, image_source, metadata_bytes, old_metadata_bytes, error))
return FALSE;
emit_eol_and_maybe_skip (self, op);
return TRUE;
@@ -3394,7 +3463,7 @@ resolve_op_from_commit (FlatpakTransaction *self,
flatpak_decomposed_get_ref (eolr_decomposed));
}
return resolve_op_end (self, op, checksum, sideload_path, metadata_bytes, error);
return resolve_op_end (self, op, checksum, sideload_path, NULL, metadata_bytes, error);
}
/* NOTE: In case of non-available summary this returns FALSE with a
@@ -3459,7 +3528,7 @@ try_resolve_op_from_metadata (FlatpakTransaction *self,
}
}
return resolve_op_end (self, op, checksum, sideload_path, metadata_bytes, error);
return resolve_op_end (self, op, checksum, sideload_path, NULL, metadata_bytes, error);
}
static gboolean
@@ -3502,7 +3571,7 @@ resolve_ops (FlatpakTransaction *self,
* checksum we got was the version already installed.
*/
g_assert (op->resolved_commit != NULL);
if (!mark_op_resolved (op, op->resolved_commit, NULL, NULL, NULL, error))
if (!mark_op_resolved (op, op->resolved_commit, NULL, NULL, NULL, NULL, error))
return FALSE;
continue;
}
@@ -3517,7 +3586,7 @@ resolve_ops (FlatpakTransaction *self,
op->skip = TRUE;
continue;
}
if (!mark_op_resolved (op, checksum, NULL, metadata_bytes, NULL, error))
if (!mark_op_resolved (op, checksum, NULL, NULL, metadata_bytes, NULL, error))
return FALSE;
continue;
}
@@ -3525,7 +3594,7 @@ resolve_ops (FlatpakTransaction *self,
if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE)
{
g_assert (op->commit != NULL);
if (!mark_op_resolved (op, op->commit, NULL, op->external_metadata, NULL, error))
if (!mark_op_resolved (op, op->commit, NULL, NULL, op->external_metadata, NULL, error))
return FALSE;
continue;
}
@@ -3549,8 +3618,13 @@ resolve_ops (FlatpakTransaction *self,
if (state == NULL)
return FALSE;
if (op->image_source)
{
if (!mark_op_resolved (op, NULL, NULL, op->image_source, op->external_metadata, NULL, error))
return FALSE;
}
/* Should we use local state */
if (transaction_is_local_only (self, op->kind))
else if (transaction_is_local_only (self, op->kind))
{
g_autoptr(GVariant) commit_data = flatpak_dir_read_latest_commit (priv->dir, op->remote, op->ref,
&checksum, NULL, error);
@@ -4688,7 +4762,74 @@ flatpak_transaction_resolve_bundles (FlatpakTransaction *self,
if (!flatpak_transaction_add_ref (self, remote, ref, NULL, NULL, commit,
FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE,
data->file, metadata, FALSE, NULL, error))
data->file, NULL, metadata, FALSE, NULL, error))
return FALSE;
}
return TRUE;
}
static gboolean
flatpak_transaction_resolve_images (FlatpakTransaction *self,
GCancellable *cancellable,
GError **error)
{
FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
GList *l;
for (l = priv->images; l != NULL; l = l->next)
{
ImageData *data = l->data;
g_autoptr(FlatpakImageSource) image_source = NULL;
g_autofree char *remote = NULL;
g_autoptr(FlatpakDecomposed) ref = NULL;
const char *ref_label;
const char *metadata_label;
FlatpakTransactionOperation *op;
g_autoptr(GBytes) deploy_data = NULL;
image_source = flatpak_image_source_new_for_location (data->image_location,
cancellable, error);
if (!image_source)
return FALSE;
ref_label = flatpak_image_source_get_ref (image_source);
ref = flatpak_decomposed_new_from_ref (ref_label, error);
if (ref == NULL)
{
g_prefix_error (error, "Cannot parse org.flatpak.ref label: ");
return FALSE;
}
metadata_label = flatpak_image_source_get_metadata (image_source);
if (metadata_label == NULL)
return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
"Image does not have org.flatpak.metadata label");
deploy_data = flatpak_dir_get_deploy_data (priv->dir, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);
if (deploy_data != NULL)
remote = g_strdup (flatpak_deploy_data_get_origin (deploy_data));
if (remote == NULL)
{
gboolean created_remote;
g_autofree char *id = flatpak_decomposed_dup_id (ref);
remote = flatpak_dir_create_origin_remote (priv->dir, NULL /* url */, id,
NULL /* title */, ref_label,
NULL /* gpg_data */, NULL /* collection_id */,
&created_remote,
cancellable, error);
if (!remote)
return FALSE;
if (created_remote)
flatpak_installation_drop_caches (priv->installation, NULL, NULL);
}
if (!flatpak_transaction_add_ref (self, remote, ref, NULL, NULL, NULL,
FLATPAK_TRANSACTION_OPERATION_INSTALL,
NULL, image_source, metadata_label, FALSE, &op, error))
return FALSE;
}
@@ -4747,7 +4888,7 @@ _run_op_kind (FlatpakTransaction *self,
emit_new_op (self, op, progress);
g_assert (op->resolved_commit != NULL); /* We resolved this before */
g_assert (op->resolved_commit != NULL || op->resolved_image_source != NULL); /* We resolved this before */
if (op->resolved_metakey && !flatpak_check_required_version (flatpak_decomposed_get_ref (op->ref),
op->resolved_metakey, &local_error))
@@ -4765,6 +4906,7 @@ _run_op_kind (FlatpakTransaction *self,
(const char **) op->subpaths,
(const char **) op->previous_ids,
op->resolved_sideload_path,
op->resolved_image_source,
op->resolved_metadata,
op->resolved_token,
progress->progress_obj,
@@ -4838,6 +4980,7 @@ _run_op_kind (FlatpakTransaction *self,
(const char **) op->subpaths,
(const char **) op->previous_ids,
op->resolved_sideload_path,
op->resolved_image_source,
op->resolved_metadata,
op->resolved_token,
progress->progress_obj,
@@ -5149,6 +5292,12 @@ flatpak_transaction_real_run (FlatpakTransaction *self,
return FALSE;
}
if (!flatpak_transaction_resolve_images (self, cancellable, error))
{
g_assert (error == NULL || *error != NULL);
return FALSE;
}
/* Resolve initial ops */
if (!resolve_all_ops (self, cancellable, error))
{

View File

@@ -326,6 +326,10 @@ gboolean flatpak_transaction_add_install_bundle (FlatpakTransaction *
GBytes *gpg_data,
GError **error);
FLATPAK_EXTERN
gboolean flatpak_transaction_add_install_image (FlatpakTransaction *self,
const char *image_location,
GError **error);
FLATPAK_EXTERN
gboolean flatpak_transaction_add_install_flatpakref (FlatpakTransaction *self,
GBytes *flatpakref_data,
GError **error);

View File

@@ -640,7 +640,7 @@ handle_deploy (FlatpakSystemHelper *object,
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
if (!flatpak_dir_pull (system, state, arg_ref, NULL, (const char **) arg_subpaths, NULL, NULL, NULL, NULL,
if (!flatpak_dir_pull (system, state, arg_ref, NULL, (const char **) arg_subpaths, NULL, NULL, NULL, NULL, NULL,
FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_UNTRUSTED, NULL,
NULL, &error))
{
@@ -874,11 +874,11 @@ handle_deploy_appstream (FlatpakSystemHelper *object,
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
if (!flatpak_dir_pull (system, state, new_branch, NULL, NULL, NULL, NULL, NULL, NULL,
if (!flatpak_dir_pull (system, state, new_branch, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_UNTRUSTED, NULL,
NULL, &first_error))
{
if (!flatpak_dir_pull (system, state, old_branch, NULL, NULL, NULL, NULL, NULL, NULL,
if (!flatpak_dir_pull (system, state, old_branch, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
FLATPAK_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_UNTRUSTED, NULL,
NULL, &second_error))
{