diff options
author | Alexander Larsson <alexl@redhat.com> | 2016-02-25 11:17:46 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2016-02-25 11:31:22 +0100 |
commit | eadb10cba76f5906fb9690131eb88ad7b7a4512d (patch) | |
tree | eec46391dc941e10af0ced18930ecfc986659e1e /app | |
parent | e66e7e3f15586750d1dbf635ce1a65cf3cca3903 (diff) | |
download | xdg-app-eadb10cba76f5906fb9690131eb88ad7b7a4512d.tar.gz |
common: Move part of bundle install to helper functions
Diffstat (limited to 'app')
-rw-r--r-- | app/xdg-app-builtins-install.c | 202 |
1 files changed, 35 insertions, 167 deletions
diff --git a/app/xdg-app-builtins-install.c b/app/xdg-app-builtins-install.c index 46df46f..12c51ee 100644 --- a/app/xdg-app-builtins-install.c +++ b/app/xdg-app-builtins-install.c @@ -110,27 +110,20 @@ install_bundle (XdgAppDir *dir, gboolean ret = FALSE; g_autoptr(GFile) deploy_base = NULL; g_autoptr(GFile) file = NULL; - g_autoptr(GFile) gpg_tmp_file = NULL; const char *filename; g_autofree char *ref = NULL; g_autofree char *origin = NULL; - g_autofree char *metadata_contents = NULL; gboolean created_deploy_base = FALSE; gboolean added_remote = FALSE; g_autofree char *to_checksum = NULL; g_auto(GStrv) parts = NULL; - g_autoptr(GFile) root = NULL; - g_autoptr(GFile) metadata_file = NULL; g_autoptr(GBytes) gpg_data = NULL; - g_autoptr(GInputStream) in = NULL; g_autofree char *remote = NULL; OstreeRepo *repo; - g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL; - g_autoptr(GError) my_error = NULL; g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT; g_autoptr(GVariant) metadata = NULL; g_autoptr(GVariant) gpg_value = NULL; - gboolean metadata_valid; + g_autofree char *basename = NULL; if (argc < 2) return usage_error (context, "bundle filename must be specified", error); @@ -142,23 +135,19 @@ install_bundle (XdgAppDir *dir, if (!xdg_app_supports_bundles (repo)) return xdg_app_fail (error, "Your version of ostree is too old to support single-file bundles"); - if (!xdg_app_dir_lock (dir, &lock, - cancellable, error)) - goto out; - file = g_file_new_for_commandline_arg (filename); - metadata = xdg_app_bundle_load (file, &to_checksum, error); - if (metadata == NULL) - goto out; + return FALSE; + + if (!xdg_app_dir_lock (dir, &lock, + cancellable, error)) + return FALSE; if (!g_variant_lookup (metadata, "ref", "s", &ref)) return xdg_app_fail (error, "Invalid bundle, no ref in metadata"); - g_variant_lookup (metadata, "metadata", "s", &metadata_contents); - if (!g_variant_lookup (metadata, "origin", "s", &origin)) origin = NULL; @@ -171,14 +160,6 @@ install_bundle (XdgAppDir *dir, gpg_data = g_bytes_new (data, n_elements); } - parts = xdg_app_decompose_ref (ref, error); - if (parts == NULL) - return FALSE; - - deploy_base = xdg_app_dir_get_deploy_dir (dir, ref); - if (g_file_query_exists (deploy_base, cancellable)) - return xdg_app_fail (error, "%s branch %s already installed", parts[1], parts[3]); - if (opt_gpg_file != NULL) { /* Override gpg_data from file */ @@ -187,159 +168,46 @@ install_bundle (XdgAppDir *dir, return FALSE; } - /* Add a remote for later updates */ - if (origin != NULL) - { - g_auto(GStrv) remotes = ostree_repo_remote_list (repo, NULL); - int version = 0; - - do - { - g_autofree char *name = NULL; - if (version == 0) - name = g_strdup_printf ("%s-origin", parts[1]); - else - name = g_strdup_printf ("%s-%d-origin", parts[1], version); - version++; - - if (remotes == NULL || - !g_strv_contains ((const char * const *) remotes, name)) - remote = g_steal_pointer (&name); - } - while (remote == NULL); - } - - if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) - return FALSE; - - ostree_repo_transaction_set_ref (repo, remote, ref, to_checksum); - - if (!ostree_repo_static_delta_execute_offline (repo, - file, - FALSE, - cancellable, - error)) + parts = xdg_app_decompose_ref (ref, error); + if (parts == NULL) return FALSE; - if (gpg_data) - { - g_autoptr(GFileIOStream) stream; - GOutputStream *o; - - gpg_tmp_file = g_file_new_tmp (".xdg-app-XXXXXX", &stream, error); - if (gpg_tmp_file == NULL) - return FALSE; - o = g_io_stream_get_output_stream (G_IO_STREAM (stream)); - if (!g_output_stream_write_all (o, g_bytes_get_data (gpg_data, NULL), g_bytes_get_size (gpg_data), NULL, cancellable, error)) - return FALSE; - } - - gpg_result = ostree_repo_verify_commit_ext (repo, - to_checksum, - NULL, gpg_tmp_file, cancellable, &my_error); - - if (gpg_tmp_file) - g_file_delete (gpg_tmp_file, cancellable, NULL); - - if (gpg_result == NULL) - { - /* NOT_FOUND means no gpg signature, we ignore this *if* there - * is no gpg key specified in the bundle or by the user */ - if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) && - gpg_data == NULL) - g_clear_error (&my_error); - else - { - g_propagate_error (error, g_steal_pointer (&my_error)); - return FALSE; - } - } - else - { - /* If there is no valid gpg signature we fail, unless there is no gpg - key specified (on the command line or in the file) because then we - trust the source bundle. */ - if (ostree_gpg_verify_result_count_valid (gpg_result) == 0 && - gpg_data != NULL) - return xdg_app_fail (error, "GPG signatures found, but none are in trusted keyring"); - } + deploy_base = xdg_app_dir_get_deploy_dir (dir, ref); - if (!ostree_repo_read_commit (repo, to_checksum, &root, NULL, NULL, error)) - return FALSE; + if (g_file_query_exists (deploy_base, cancellable)) + return xdg_app_fail (error, "%s branch %s already installed", parts[1], parts[3]); - if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error)) + /* Add a remote for later updates */ + basename = g_file_get_basename (file); + remote = xdg_app_dir_create_origin_remote (dir, + origin, + parts[1], + basename, + gpg_data, + cancellable, + error); + if (remote == NULL) return FALSE; - /* We ensure that the actual installed metadata matches the one in the - header, because you may have made decisions on wheter to install it or not - based on that data. */ - metadata_file = g_file_resolve_relative_path (root, "metadata"); - in = (GInputStream*)g_file_read (metadata_file, cancellable, NULL); - if (in != NULL) - { - g_autoptr(GMemoryOutputStream) data_stream = (GMemoryOutputStream*)g_memory_output_stream_new_resizable (); - - if (g_output_stream_splice (G_OUTPUT_STREAM (data_stream), in, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - cancellable, error) < 0) - return FALSE; - - /* Null terminate */ - g_output_stream_write (G_OUTPUT_STREAM (data_stream), "\0", 1, NULL, NULL); - - metadata_valid = strcmp (metadata_contents, g_memory_output_stream_get_data (data_stream)) == 0; - } - else - metadata_valid = (metadata_contents == NULL); - - if (!metadata_valid) - { - /* Immediately remove this broken commit */ - ostree_repo_set_ref_immediate (repo, remote, ref, NULL, cancellable, error); - return xdg_app_fail (error, "Metadata in header and app are inconsistent"); - } + /* From here we need to goto out on error, to clean up */ + added_remote = TRUE; + + if (!xdg_app_dir_pull_from_bundle (dir, + file, + remote, + ref, + gpg_data != NULL, + cancellable, + error)) + goto out; if (!g_file_make_directory_with_parents (deploy_base, cancellable, error)) - return FALSE; + goto out; - /* From here we need to goto out on error, to clean up */ created_deploy_base = TRUE; - if (remote) - { - g_autoptr(GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); - g_autofree char *basename = g_file_get_basename (file); - - g_variant_builder_add (optbuilder, "{s@v}", - "xa.title", - g_variant_new_variant (g_variant_new_string (basename))); - - g_variant_builder_add (optbuilder, "{s@v}", - "xa.noenumerate", - g_variant_new_variant (g_variant_new_boolean (TRUE))); - - g_variant_builder_add (optbuilder, "{s@v}", - "xa.prio", - g_variant_new_variant (g_variant_new_string ("0"))); - - if (!ostree_repo_remote_add (repo, - remote, origin, g_variant_builder_end (optbuilder), cancellable, error)) - goto out; - - added_remote = TRUE; - - if (gpg_data) - { - g_autoptr(GInputStream) gpg_data_as_stream = g_memory_input_stream_new_from_bytes (gpg_data); - - if (!ostree_repo_remote_gpg_import (repo, remote, gpg_data_as_stream, - NULL, NULL, cancellable, error)) - goto out; - } - - if (!xdg_app_dir_set_origin (dir, ref, remote, cancellable, error)) - goto out; - } + if (!xdg_app_dir_set_origin (dir, ref, remote, cancellable, error)) + goto out; if (!xdg_app_dir_deploy (dir, ref, to_checksum, cancellable, error)) goto out; |