From 409fa1eafc6fd8608f37ffd839cdfe90d569425a Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 9 Nov 2020 12:13:04 +0100 Subject: [PATCH] decomposed: Use FlatpakDecomposed in flatpak_run_* --- app/flatpak-builtins-build.c | 30 ++-- app/flatpak-builtins-run.c | 13 +- common/flatpak-installation.c | 2 +- common/flatpak-run-private.h | 106 +++++++------- common/flatpak-run.c | 250 +++++++++++++++++----------------- 5 files changed, 200 insertions(+), 201 deletions(-) diff --git a/app/flatpak-builtins-build.c b/app/flatpak-builtins-build.c index 8da0de81..b8c129ac 100644 --- a/app/flatpak-builtins-build.c +++ b/app/flatpak-builtins-build.c @@ -167,8 +167,8 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError g_autoptr(GFile) runtime_files = NULL; g_autoptr(GFile) metadata = NULL; g_autofree char *metadata_contents = NULL; - g_autofree char *runtime = NULL; - g_autofree char *runtime_ref = NULL; + g_autofree char *runtime_pref = NULL; + g_autoptr(FlatpakDecomposed) runtime_ref = NULL; g_autofree char *extensionof_ref = NULL; g_autofree char *extensionof_tag = NULL; g_autofree char *extension_point = NULL; @@ -186,7 +186,6 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError g_autoptr(FlatpakContext) arg_context = NULL; g_autoptr(FlatpakContext) app_context = NULL; gboolean custom_usr; - g_auto(GStrv) runtime_ref_parts = NULL; FlatpakRunFlags run_flags; const char *group = NULL; const char *runtime_key = NULL; @@ -194,6 +193,7 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError gboolean is_app = FALSE; gboolean is_extension = FALSE; gboolean is_app_extension = FALSE; + g_autofree char *arch = NULL; g_autofree char *app_info_path = NULL; g_autofree char *app_extensions = NULL; g_autofree char *runtime_extensions = NULL; @@ -280,16 +280,16 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError else runtime_key = FLATPAK_METADATA_KEY_SDK; - runtime = g_key_file_get_string (metakey, group, runtime_key, error); - if (runtime == NULL) + runtime_pref = g_key_file_get_string (metakey, group, runtime_key, error); + if (runtime_pref == NULL) return FALSE; - runtime_ref = g_build_filename ("runtime", runtime, NULL); - - runtime_ref_parts = flatpak_decompose_ref (runtime_ref, error); - if (runtime_ref_parts == NULL) + runtime_ref = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, runtime_pref, error); + if (runtime_ref == NULL) return FALSE; + arch = flatpak_decomposed_dup_arch (runtime_ref); + custom_usr = FALSE; usr = g_file_get_child (res_deploy, opt_sdk_dir ? opt_sdk_dir : "usr"); if (g_file_query_exists (usr, cancellable)) @@ -299,7 +299,7 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError } else { - runtime_deploy = flatpak_find_deploy_for_ref (runtime_ref, NULL, cancellable, error); + runtime_deploy = flatpak_find_deploy_for_ref (flatpak_decomposed_get_ref (runtime_ref), NULL, cancellable, error); if (runtime_deploy == NULL) return FALSE; @@ -455,7 +455,7 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError /* Never set up an a11y bus for builds */ run_flags |= FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY; - if (!flatpak_run_setup_base_argv (bwrap, runtime_files, app_id_dir, runtime_ref_parts[2], + if (!flatpak_run_setup_base_argv (bwrap, runtime_files, app_id_dir, arch, run_flags, error)) return FALSE; @@ -494,7 +494,7 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError flatpak_bwrap_add_args (bwrap, "--setenv", "FLATPAK_DEST", dest, "--setenv", "FLATPAK_ID", id, - "--setenv", "FLATPAK_ARCH", runtime_ref_parts[2], + "--setenv", "FLATPAK_ARCH", arch, NULL); /* Persist some stuff in /var. We can't persist everything because that breaks /var things @@ -515,8 +515,10 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError { /* We don't actually know the final branchname yet, so use "nobranch" as fallback to avoid unexpected matches. This means any extension point used at build time must have explicit versions to work. */ - g_autofree char *fake_ref = g_strdup_printf ("app/%s/%s/nobranch", id, runtime_ref_parts[2]); - if (!flatpak_run_add_extension_args (bwrap, metakey, fake_ref, FALSE, &app_extensions, cancellable, error)) + g_autoptr(FlatpakDecomposed) fake_ref = + flatpak_decomposed_new_from_parts (FLATPAK_KINDS_APP, id, arch, "nobranch", NULL); + if (fake_ref != NULL && + !flatpak_run_add_extension_args (bwrap, metakey, fake_ref, FALSE, &app_extensions, cancellable, error)) return FALSE; } diff --git a/app/flatpak-builtins-run.c b/app/flatpak-builtins-run.c index aeeec24a..eb5c1497 100644 --- a/app/flatpak-builtins-run.c +++ b/app/flatpak-builtins-run.c @@ -91,8 +91,8 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** { g_autoptr(GOptionContext) context = NULL; g_autoptr(FlatpakDeploy) app_deploy = NULL; - g_autofree char *app_ref = NULL; - g_autofree char *runtime_ref = NULL; + g_autoptr(FlatpakDecomposed) app_ref = NULL; + g_autoptr(FlatpakDecomposed) runtime_ref = NULL; const char *pref; int i; int rest_argv_start, rest_argc; @@ -170,11 +170,10 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** if ((kinds & FLATPAK_KINDS_APP) != 0) { - app_ref = flatpak_compose_ref (TRUE, id, branch, arch, &local_error); - if (app_ref == NULL) - return FALSE; + app_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_APP, id, arch, branch, &local_error); + if (app_ref != NULL) + app_deploy = flatpak_find_deploy_for_ref_in (dirs, flatpak_decomposed_get_ref (app_ref), opt_commit, cancellable, &local_error); - app_deploy = flatpak_find_deploy_for_ref_in (dirs, app_ref, opt_commit, cancellable, &local_error); if (app_deploy == NULL && (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED) || (kinds & FLATPAK_KINDS_RUNTIME) == 0)) @@ -257,7 +256,7 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** return FALSE; } - runtime_ref = flatpak_decomposed_dup_ref (chosen_pair->ref); + runtime_ref = flatpak_decomposed_ref (chosen_pair->ref); /* Clear app-kind error */ g_clear_error (&local_error); diff --git a/common/flatpak-installation.c b/common/flatpak-installation.c index 79d1454f..c413f1ca 100644 --- a/common/flatpak-installation.c +++ b/common/flatpak-installation.c @@ -698,7 +698,7 @@ flatpak_installation_launch_full (FlatpakInstallation *self, if (flags & FLATPAK_LAUNCH_FLAGS_DO_NOT_REAP) run_flags |= FLATPAK_RUN_FLAG_DO_NOT_REAP; - if (!flatpak_run_app (flatpak_decomposed_get_ref (app_ref), + if (!flatpak_run_app (app_ref, app_deploy, NULL, NULL, NULL, NULL, diff --git a/common/flatpak-run-private.h b/common/flatpak-run-private.h index d9c94360..04c22b3d 100644 --- a/common/flatpak-run-private.h +++ b/common/flatpak-run-private.h @@ -108,23 +108,23 @@ gboolean flatpak_run_in_transient_unit (const char *app_id, #define FLATPAK_METADATA_KEY_DCONF_PATHS "paths" #define FLATPAK_METADATA_KEY_DCONF_MIGRATE_PATH "migrate-path" -gboolean flatpak_run_add_extension_args (FlatpakBwrap *bwrap, - GKeyFile *metakey, - const char *full_ref, - gboolean use_ld_so_cache, - char **extensions_out, - GCancellable *cancellable, - GError **error); -gboolean flatpak_run_add_environment_args (FlatpakBwrap *bwrap, - const char *app_info_path, - FlatpakRunFlags flags, - const char *app_id, - FlatpakContext *context, - GFile *app_id_dir, - GPtrArray *previous_app_id_dirs, - FlatpakExports **exports_out, - GCancellable *cancellable, - GError **error); +gboolean flatpak_run_add_extension_args (FlatpakBwrap *bwrap, + GKeyFile *metakey, + FlatpakDecomposed *ref, + gboolean use_ld_so_cache, + char **extensions_out, + GCancellable *cancellable, + GError **error); +gboolean flatpak_run_add_environment_args (FlatpakBwrap *bwrap, + const char *app_info_path, + FlatpakRunFlags flags, + const char *app_id, + FlatpakContext *context, + GFile *app_id_dir, + GPtrArray *previous_app_id_dirs, + FlatpakExports **exports_out, + GCancellable *cancellable, + GError **error); char ** flatpak_run_get_minimal_env (gboolean devel, gboolean use_ld_so_cache); void flatpak_run_apply_env_default (FlatpakBwrap *bwrap, @@ -147,43 +147,43 @@ gboolean flatpak_run_setup_base_argv (FlatpakBwrap *bwrap, const char *arch, FlatpakRunFlags flags, GError **error); -gboolean flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, - GFile *app_files, - GBytes *app_deploy_data, - const char *app_extensions, - GFile *runtime_files, - GBytes *runtime_deploy_data, - const char *runtime_extensions, - const char *app_id, - const char *app_branch, - const char *runtime_ref, - GFile *app_id_dir, - FlatpakContext *final_app_context, - FlatpakContext *cmdline_context, - gboolean sandbox, - gboolean build, - gboolean devel, - char **app_info_path_out, - int instance_id_fd, - char **host_instance_id_host_dir_out, - GError **error); +gboolean flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, + GFile *app_files, + GBytes *app_deploy_data, + const char *app_extensions, + GFile *runtime_files, + GBytes *runtime_deploy_data, + const char *runtime_extensions, + const char *app_id, + const char *app_branch, + FlatpakDecomposed *runtime_ref, + GFile *app_id_dir, + FlatpakContext *final_app_context, + FlatpakContext *cmdline_context, + gboolean sandbox, + gboolean build, + gboolean devel, + char **app_info_path_out, + int instance_id_fd, + char **host_instance_id_host_dir_out, + GError **error); -gboolean flatpak_run_app (const char *app_ref, - FlatpakDeploy *app_deploy, - FlatpakContext *extra_context, - const char *custom_runtime, - const char *custom_runtime_version, - const char *custom_runtime_commit, - int parent_pid, - FlatpakRunFlags flags, - const char *cwd, - const char *custom_command, - char *args[], - int n_args, - int instance_id_fd, - char **instance_dir_out, - GCancellable *cancellable, - GError **error); +gboolean flatpak_run_app (FlatpakDecomposed *app_ref, + FlatpakDeploy *app_deploy, + FlatpakContext *extra_context, + const char *custom_runtime, + const char *custom_runtime_version, + const char *custom_runtime_commit, + int parent_pid, + FlatpakRunFlags flags, + const char *cwd, + const char *custom_command, + char *args[], + int n_args, + int instance_id_fd, + char **instance_dir_out, + GCancellable *cancellable, + GError **error); extern const char * const *flatpak_abs_usrmerged_dirs; diff --git a/common/flatpak-run.c b/common/flatpak-run.c index d45c32cd..190ad11e 100644 --- a/common/flatpak-run.c +++ b/common/flatpak-run.c @@ -1013,17 +1013,15 @@ flatpak_extension_compare_by_path (gconstpointer _a, } gboolean -flatpak_run_add_extension_args (FlatpakBwrap *bwrap, - GKeyFile *metakey, - const char *full_ref, - gboolean use_ld_so_cache, - char **extensions_out, - GCancellable *cancellable, - GError **error) +flatpak_run_add_extension_args (FlatpakBwrap *bwrap, + GKeyFile *metakey, + FlatpakDecomposed *ref, + gboolean use_ld_so_cache, + char **extensions_out, + GCancellable *cancellable, + GError **error) { - g_auto(GStrv) parts = NULL; g_autoptr(GString) used_extensions = g_string_new (""); - gboolean is_app; GList *extensions, *path_sorted_extensions, *l; g_autoptr(GString) ld_library_path = g_string_new (""); int count = 0; @@ -1031,15 +1029,11 @@ flatpak_run_add_extension_args (FlatpakBwrap *bwrap, g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_autoptr(GHashTable) created_symlink = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_autofree char *arch = flatpak_decomposed_dup_arch (ref); + const char *branch = flatpak_decomposed_get_branch (ref); + gboolean is_app = flatpak_decomposed_is_app (ref); - parts = g_strsplit (full_ref, "/", 0); - if (g_strv_length (parts) != 4) - return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Failed to determine parts from ref: %s"), full_ref); - - is_app = strcmp (parts[0], "app") == 0; - - extensions = flatpak_list_extensions (metakey, - parts[2], parts[3]); + extensions = flatpak_list_extensions (metakey, arch, branch); /* First we apply all the bindings, they are sorted alphabetically in order for parent directory to be mounted before child directories */ @@ -1051,7 +1045,7 @@ flatpak_run_add_extension_args (FlatpakBwrap *bwrap, FlatpakExtension *ext = l->data; g_autofree char *directory = g_build_filename (is_app ? "/app" : "/usr", ext->directory, NULL); g_autofree char *full_directory = g_build_filename (directory, ext->subdir_suffix, NULL); - g_autofree char *ref = g_build_filename (full_directory, ".ref", NULL); + g_autofree char *ref_file = g_build_filename (full_directory, ".ref", NULL); g_autofree char *real_ref = g_build_filename (ext->files_path, ext->directory, ".ref", NULL); if (ext->needs_tmpfs) @@ -1073,7 +1067,7 @@ flatpak_run_add_extension_args (FlatpakBwrap *bwrap, if (g_file_test (real_ref, G_FILE_TEST_EXISTS)) flatpak_bwrap_add_args (bwrap, - "--lock-file", ref, + "--lock-file", ref_file, NULL); } @@ -1105,7 +1099,7 @@ flatpak_run_add_extension_args (FlatpakBwrap *bwrap, { g_autofree char *contents = g_strconcat (ld_path, "\n", NULL); /* We prepend app or runtime and a counter in order to get the include order correct for the conf files */ - g_autofree char *ld_so_conf_file = g_strdup_printf ("%s-%03d-%s.conf", parts[0], ++count, ext->installed_id); + g_autofree char *ld_so_conf_file = g_strdup_printf ("%s-%03d-%s.conf", flatpak_decomposed_get_kind_str (ref), ++count, ext->installed_id); g_autofree char *ld_so_conf_file_path = g_build_filename ("/run/flatpak/ld.so.conf.d", ld_so_conf_file, NULL); if (!flatpak_bwrap_add_args_data (bwrap, "ld-so-conf", @@ -2185,26 +2179,26 @@ flatpak_run_add_dconf_args (FlatpakBwrap *bwrap, } gboolean -flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, - GFile *app_files, - GBytes *app_deploy_data, - const char *app_extensions, - GFile *runtime_files, - GBytes *runtime_deploy_data, - const char *runtime_extensions, - const char *app_id, - const char *app_branch, - const char *runtime_ref, - GFile *app_id_dir, - FlatpakContext *final_app_context, - FlatpakContext *cmdline_context, - gboolean sandbox, - gboolean build, - gboolean devel, - char **app_info_path_out, - int instance_id_fd, - char **instance_id_host_dir_out, - GError **error) +flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, + GFile *app_files, + GBytes *app_deploy_data, + const char *app_extensions, + GFile *runtime_files, + GBytes *runtime_deploy_data, + const char *runtime_extensions, + const char *app_id, + const char *app_branch, + FlatpakDecomposed *runtime_ref, + GFile *app_id_dir, + FlatpakContext *final_app_context, + FlatpakContext *cmdline_context, + gboolean sandbox, + gboolean build, + gboolean devel, + char **app_info_path_out, + int instance_id_fd, + char **instance_id_host_dir_out, + GError **error) { g_autofree char *info_path = NULL; g_autofree char *bwrapinfo_path = NULL; @@ -2212,7 +2206,6 @@ flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, g_autoptr(GKeyFile) keyfile = NULL; g_autofree char *runtime_path = NULL; g_autofree char *old_dest = g_strdup_printf ("/run/user/%d/flatpak-info", getuid ()); - g_auto(GStrv) runtime_ref_parts = g_strsplit (runtime_ref, "/", 0); const char *group; g_autofree char *instance_id = NULL; glnx_autofd int lock_fd = -1; @@ -2220,6 +2213,7 @@ flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, g_autofree char *instance_id_sandbox_dir = NULL; g_autofree char *instance_id_lock_file = NULL; g_autofree char *user_runtime_dir = flatpak_get_real_xdg_runtime_dir (); + g_autofree char *arch = flatpak_decomposed_dup_arch (runtime_ref); instance_id = flatpak_run_allocate_id (&lock_fd); if (instance_id == NULL) @@ -2250,7 +2244,7 @@ flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_NAME, app_id); g_key_file_set_string (keyfile, group, FLATPAK_METADATA_KEY_RUNTIME, - runtime_ref); + flatpak_decomposed_get_ref (runtime_ref)); g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_INSTANCE_ID, instance_id); @@ -2286,7 +2280,7 @@ flatpak_run_add_app_info_args (FlatpakBwrap *bwrap, g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_BRANCH, app_branch); g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE, - FLATPAK_METADATA_KEY_ARCH, runtime_ref_parts[2]); + FLATPAK_METADATA_KEY_ARCH, arch); g_key_file_set_string (keyfile, FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_FLATPAK_VERSION, PACKAGE_VERSION); @@ -3399,13 +3393,12 @@ regenerate_ld_cache (GPtrArray *base_argv_array, /* Check that this user is actually allowed to run this app. When running * from the gnome-initial-setup session, an app filter might not be available. */ static gboolean -check_parental_controls (const char *app_ref, - FlatpakDeploy *deploy, - GCancellable *cancellable, - GError **error) +check_parental_controls (FlatpakDecomposed *app_ref, + FlatpakDeploy *deploy, + GCancellable *cancellable, + GError **error) { #ifdef HAVE_LIBMALCONTENT - g_auto(GStrv) app_ref_parts = NULL; g_autoptr(MctManager) manager = NULL; g_autoptr(MctAppFilter) app_filter = NULL; g_autoptr(GAsyncResult) app_filter_result = NULL; @@ -3414,10 +3407,6 @@ check_parental_controls (const char *app_ref, g_autoptr(GDesktopAppInfo) app_info = NULL; gboolean allowed = FALSE; - app_ref_parts = flatpak_decompose_ref (app_ref, error); - if (app_ref_parts == NULL) - return FALSE; - system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); if (system_bus == NULL) return FALSE; @@ -3429,14 +3418,14 @@ check_parental_controls (const char *app_ref, if (g_error_matches (local_error, MCT_APP_FILTER_ERROR, MCT_APP_FILTER_ERROR_DISABLED)) { g_debug ("Skipping parental controls check for %s since parental " - "controls are disabled globally", app_ref); + "controls are disabled globally", flatpak_decomposed_get_ref (app_ref)); return TRUE; } else if (g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) || g_error_matches (local_error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER)) { g_debug ("Skipping parental controls check for %s since a required " - "service was not found", app_ref); + "service was not found", flatpak_decomposed_get_ref (app_ref)); return TRUE; } else if (local_error != NULL) @@ -3451,7 +3440,7 @@ check_parental_controls (const char *app_ref, * multiple .desktop files, we use the main one. The app ID check is * always done, as the binary executed by `flatpak run` isn’t necessarily * extracted from a .desktop file. */ - allowed = mct_app_filter_is_flatpak_ref_allowed (app_filter, app_ref); + allowed = mct_app_filter_is_flatpak_ref_allowed (app_filter, flatpak_decomposed_get_ref (app_ref)); /* Look up the app’s main .desktop file. */ if (deploy != NULL && allowed) @@ -3460,11 +3449,12 @@ check_parental_controls (const char *app_ref, const char *deploy_path; g_autofree char *desktop_file_name = NULL; g_autofree char *desktop_file_path = NULL; + g_autofree char *app_id = flatpak_decomposed_dup_id (app_ref); deploy_dir = flatpak_deploy_get_dir (deploy); deploy_path = flatpak_file_get_path_cached (deploy_dir); - desktop_file_name = g_strconcat (app_ref_parts[1], ".desktop", NULL); + desktop_file_name = g_strconcat (app_id, ".desktop", NULL); desktop_file_path = g_build_path (G_DIR_SEPARATOR_S, deploy_path, "export", @@ -3483,7 +3473,7 @@ check_parental_controls (const char *app_ref, return flatpak_fail_error (error, FLATPAK_ERROR_PERMISSION_DENIED, /* Translators: The placeholder is for an app ref. */ _("Running %s is not allowed by the policy set by your administrator"), - app_ref); + flatpak_decomposed_get_ref (app_ref)); #endif /* HAVE_LIBMALCONTENT */ return TRUE; @@ -3530,22 +3520,22 @@ check_sudo (GError **error) } gboolean -flatpak_run_app (const char *app_ref, - FlatpakDeploy *app_deploy, - FlatpakContext *extra_context, - const char *custom_runtime, - const char *custom_runtime_version, - const char *custom_runtime_commit, - int parent_pid, - FlatpakRunFlags flags, - const char *cwd, - const char *custom_command, - char *args[], - int n_args, - int instance_id_fd, - char **instance_dir_out, - GCancellable *cancellable, - GError **error) +flatpak_run_app (FlatpakDecomposed *app_ref, + FlatpakDeploy *app_deploy, + FlatpakContext *extra_context, + const char *custom_runtime, + const char *custom_runtime_version, + const char *custom_runtime_commit, + int parent_pid, + FlatpakRunFlags flags, + const char *cwd, + const char *custom_command, + char *args[], + int n_args, + int instance_id_fd, + char **instance_dir_out, + GCancellable *cancellable, + GError **error) { g_autoptr(FlatpakDeploy) runtime_deploy = NULL; g_autoptr(GBytes) runtime_deploy_data = NULL; @@ -3555,23 +3545,24 @@ flatpak_run_app (const char *app_ref, g_autoptr(GFile) bin_ldconfig = NULL; g_autoptr(GFile) app_id_dir = NULL; g_autoptr(GFile) real_app_id_dir = NULL; - g_autofree char *default_runtime = NULL; + g_autofree char *default_runtime_pref = NULL; + g_autoptr(FlatpakDecomposed) default_runtime = NULL; g_autofree char *default_command = NULL; - g_autofree char *runtime_ref = NULL; g_autoptr(GKeyFile) metakey = NULL; g_autoptr(GKeyFile) runtime_metakey = NULL; g_autoptr(FlatpakBwrap) bwrap = NULL; const char *command = "/bin/sh"; g_autoptr(GError) my_error = NULL; - g_auto(GStrv) runtime_parts = NULL; + g_autoptr(FlatpakDecomposed) runtime_ref = NULL; int i; g_autoptr(GPtrArray) previous_app_id_dirs = NULL; + g_autofree char *app_id = NULL; + g_autofree char *app_arch = NULL; g_autofree char *app_info_path = NULL; g_autofree char *instance_id_host_dir = NULL; g_autoptr(FlatpakContext) app_context = NULL; g_autoptr(FlatpakContext) overrides = NULL; g_autoptr(FlatpakExports) exports = NULL; - g_auto(GStrv) app_ref_parts = NULL; g_autofree char *commandline = NULL; g_autofree char *doc_mount_path = NULL; g_autofree char *app_extensions = NULL; @@ -3589,9 +3580,8 @@ flatpak_run_app (const char *app_ref, if (!check_sudo (error)) return FALSE; - app_ref_parts = flatpak_decompose_ref (app_ref, error); - if (app_ref_parts == NULL) - return FALSE; + app_id = flatpak_decomposed_dup_id (app_ref); + app_arch = flatpak_decomposed_dup_id (app_ref); /* Check the user is allowed to run this flatpak. */ if (!check_parental_controls (app_ref, app_deploy, cancellable, error)) @@ -3603,8 +3593,8 @@ flatpak_run_app (const char *app_ref, if (app_deploy == NULL) { - g_assert (g_str_has_prefix (app_ref, "runtime/")); - default_runtime = g_strdup (app_ref + strlen ("runtime/")); + g_assert (flatpak_decomposed_is_runtime (app_ref)); + default_runtime_pref = flatpak_decomposed_dup_pref (app_ref); } else { @@ -3620,9 +3610,9 @@ flatpak_run_app (const char *app_ref, key = FLATPAK_METADATA_KEY_RUNTIME; metakey = flatpak_deploy_get_metadata (app_deploy); - default_runtime = g_key_file_get_string (metakey, - FLATPAK_METADATA_GROUP_APPLICATION, - key, &my_error); + default_runtime_pref = g_key_file_get_string (metakey, + FLATPAK_METADATA_GROUP_APPLICATION, + key, &my_error); if (my_error) { g_propagate_error (error, g_steal_pointer (&my_error)); @@ -3630,39 +3620,47 @@ flatpak_run_app (const char *app_ref, } } - runtime_parts = g_strsplit (default_runtime, "/", 0); - if (g_strv_length (runtime_parts) != 3) - return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Wrong number of components in runtime %s"), default_runtime); - - if (custom_runtime) - { - g_auto(GStrv) custom_runtime_parts = g_strsplit (custom_runtime, "/", 0); - - for (i = 0; i < 3 && custom_runtime_parts[i] != NULL; i++) - { - if (strlen (custom_runtime_parts[i]) > 0) - { - g_free (runtime_parts[i]); - runtime_parts[i] = g_steal_pointer (&custom_runtime_parts[i]); - } - } - } - - if (custom_runtime_version) - { - g_free (runtime_parts[2]); - runtime_parts[2] = g_strdup (custom_runtime_version); - } - - runtime_ref = flatpak_compose_ref (FALSE, - runtime_parts[0], - runtime_parts[2], - runtime_parts[1], - error); - if (runtime_ref == NULL) + default_runtime = flatpak_decomposed_new_from_pref (FLATPAK_KINDS_RUNTIME, default_runtime_pref, error); + if (default_runtime == NULL) return FALSE; - runtime_deploy = flatpak_find_deploy_for_ref (runtime_ref, custom_runtime_commit, cancellable, error); + if (custom_runtime != NULL || custom_runtime_version != NULL) + { + g_auto(GStrv) custom_runtime_parts = NULL; + const char *custom_runtime_id = NULL; + const char *custom_runtime_arch = NULL; + + if (custom_runtime) + { + custom_runtime_parts = g_strsplit (custom_runtime, "/", 0); + for (i = 0; i < 3 && custom_runtime_parts[i] != NULL; i++) + { + if (strlen (custom_runtime_parts[i]) > 0) + { + if (i == 0) + custom_runtime_id = custom_runtime_parts[i]; + if (i == 1) + custom_runtime_arch = custom_runtime_parts[i]; + + if (i == 2 && custom_runtime_version == NULL) + custom_runtime_version = custom_runtime_parts[i]; + } + } + } + + runtime_ref = flatpak_decomposed_new_from_decomposed (default_runtime, + FLATPAK_KINDS_RUNTIME, + custom_runtime_id, + custom_runtime_arch, + custom_runtime_version, + error); + if (runtime_ref == NULL) + return FALSE; + } + else + runtime_ref = flatpak_decomposed_ref (default_runtime); + + runtime_deploy = flatpak_find_deploy_for_ref (flatpak_decomposed_get_ref (runtime_ref), custom_runtime_commit, cancellable, error); if (runtime_deploy == NULL) return FALSE; @@ -3699,7 +3697,7 @@ flatpak_run_app (const char *app_ref, gsize len = 0; gboolean do_migrate; - real_app_id_dir = flatpak_get_data_dir (app_ref_parts[1]); + real_app_id_dir = flatpak_get_data_dir (app_id); app_files = flatpak_deploy_get_files (app_deploy); previous_app_id_dirs = g_ptr_array_new_with_free_func (g_object_unref); @@ -3755,13 +3753,13 @@ flatpak_run_app (const char *app_ref, if (!flatpak_file_rename (previous_app_id_dir, real_app_id_dir, cancellable, &local_error)) { g_warning (_("Failed to migrate old app data directory %s to new name %s: %s"), - flatpak_file_get_path_cached (previous_app_id_dir), app_ref_parts[1], + flatpak_file_get_path_cached (previous_app_id_dir), app_id, local_error->message); } else { /* Leave a symlink in place of the old data dir */ - if (!g_file_make_symbolic_link (previous_app_id_dir, app_ref_parts[1], cancellable, &local_error)) + if (!g_file_make_symbolic_link (previous_app_id_dir, app_id, cancellable, &local_error)) { g_warning (_("Failed to create symlink while migrating %s: %s"), flatpak_file_get_path_cached (previous_app_id_dir), @@ -3783,7 +3781,7 @@ flatpak_run_app (const char *app_ref, flatpak_run_apply_env_default (bwrap, use_ld_so_cache); flatpak_run_apply_env_vars (bwrap, app_context); - flatpak_run_apply_env_prompt (bwrap, app_ref_parts[1]); + flatpak_run_apply_env_prompt (bwrap, app_id); if (real_app_id_dir) { @@ -3837,7 +3835,7 @@ flatpak_run_app (const char *app_ref, flags |= flatpak_context_get_run_flags (app_context); - if (!flatpak_run_setup_base_argv (bwrap, runtime_files, app_id_dir, app_ref_parts[2], flags, error)) + if (!flatpak_run_setup_base_argv (bwrap, runtime_files, app_id_dir, app_arch, flags, error)) return FALSE; if (generate_ld_so_conf) @@ -3857,21 +3855,21 @@ flatpak_run_app (const char *app_ref, if (!flatpak_run_add_app_info_args (bwrap, app_files, app_deploy_data, app_extensions, runtime_files, runtime_deploy_data, runtime_extensions, - app_ref_parts[1], app_ref_parts[3], + app_id, flatpak_decomposed_get_branch (app_ref), runtime_ref, app_id_dir, app_context, extra_context, sandboxed, FALSE, flags & FLATPAK_RUN_FLAG_DEVEL, &app_info_path, instance_id_fd, &instance_id_host_dir, error)) return FALSE; - if (!flatpak_run_add_dconf_args (bwrap, app_ref_parts[1], metakey, error)) + if (!flatpak_run_add_dconf_args (bwrap, app_id, metakey, error)) return FALSE; if (!sandboxed && !(flags & FLATPAK_RUN_FLAG_NO_DOCUMENTS_PORTAL)) - add_document_portal_args (bwrap, app_ref_parts[1], &doc_mount_path); + add_document_portal_args (bwrap, app_id, &doc_mount_path); if (!flatpak_run_add_environment_args (bwrap, app_info_path, flags, - app_ref_parts[1], app_context, app_id_dir, previous_app_id_dirs, + app_id, app_context, app_id_dir, previous_app_id_dirs, &exports, cancellable, error)) return FALSE; @@ -3940,7 +3938,7 @@ flatpak_run_app (const char *app_ref, flatpak_bwrap_add_arg (bwrap, command); - if (!add_rest_args (bwrap, app_ref_parts[1], + if (!add_rest_args (bwrap, app_id, exports, (flags & FLATPAK_RUN_FLAG_FILE_FORWARDING) != 0, doc_mount_path, args, n_args, error))