From ca99d5be58d77c18ee177bb4431ba783ee7eb1fd Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 15 Nov 2016 11:11:00 +0100 Subject: [PATCH] build-init: Give error if initializing with a partial dependency If you're building a runtime and have a base runtime with expected extensions, fail to build if the actually installed extension is partial (i.e. if it has a subdir specified). Fixes https://github.com/flatpak/flatpak/issues/390 --- app/flatpak-builtins-build-init.c | 19 ++++++++++++ common/flatpak-utils.c | 50 +++++++++++++++++++++++-------- common/flatpak-utils.h | 5 ++++ 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/app/flatpak-builtins-build-init.c b/app/flatpak-builtins-build-init.c index 5973360b..102c1fe7 100644 --- a/app/flatpak-builtins-build-init.c +++ b/app/flatpak-builtins-build-init.c @@ -84,6 +84,25 @@ copy_extensions (FlatpakDeploy *src_deploy, const char *default_branch, g_autoptr(GFile) target_parent = g_file_get_parent (target); g_autoptr(GFile) ext_deploy_files = g_file_new_for_path (ext->files_path); + if (!ext->is_unmaintained) + { + g_autoptr(FlatpakDir) src_dir = NULL; + g_autoptr(GFile) deploy = NULL; + g_autoptr(GVariant) deploy_data = NULL; + const char **subpaths; + + deploy = flatpak_find_deploy_dir_for_ref (ext->ref, &src_dir, cancellable, error); + if (deploy == NULL) + return FALSE; + deploy_data = flatpak_dir_get_deploy_data (src_dir, ext->ref, cancellable, error); + if (deploy_data == NULL) + return FALSE; + + subpaths = flatpak_deploy_data_get_subpaths (deploy_data); + if (subpaths[0] != NULL) + return flatpak_fail (error, _("Requested extension %s is only partially installed"), ext->installed_id); + } + if (!flatpak_mkdir_p (target_parent, cancellable, error)) return FALSE; diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c index c88292b1..8e61e7a3 100644 --- a/common/flatpak-utils.c +++ b/common/flatpak-utils.c @@ -999,26 +999,49 @@ out: } GFile * -flatpak_find_files_dir_for_ref (const char *ref, - GCancellable *cancellable, - GError **error) +flatpak_find_deploy_dir_for_ref (const char *ref, + FlatpakDir **dir_out, + GCancellable *cancellable, + GError **error) { g_autoptr(FlatpakDir) user_dir = NULL; g_autoptr(FlatpakDir) system_dir = NULL; + FlatpakDir *dir = NULL; g_autoptr(GFile) deploy = NULL; user_dir = flatpak_dir_get_user (); system_dir = flatpak_dir_get_system (); - deploy = flatpak_dir_get_if_deployed (user_dir, ref, NULL, cancellable); + dir = user_dir; + deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable); if (deploy == NULL) - deploy = flatpak_dir_get_if_deployed (system_dir, ref, NULL, cancellable); + { + dir = system_dir; + deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable); + } + if (deploy == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("%s not installed"), ref); return NULL; } + if (dir_out) + *dir_out = g_object_ref (dir); + return g_steal_pointer (&deploy); +} + +GFile * +flatpak_find_files_dir_for_ref (const char *ref, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GFile) deploy = NULL; + + deploy = flatpak_find_deploy_dir_for_ref (ref, NULL, cancellable, error); + if (deploy == NULL) + return NULL; + return g_file_get_child (deploy, "files"); } @@ -3329,7 +3352,8 @@ flatpak_extension_new (const char *id, const char *extension, const char *ref, const char *directory, - GFile *files) + GFile *files, + gboolean is_unmaintained) { FlatpakExtension *ext = g_new0 (FlatpakExtension, 1); @@ -3338,6 +3362,7 @@ flatpak_extension_new (const char *id, ext->ref = g_strdup (ref); ext->directory = g_strdup (directory); ext->files_path = g_file_get_path (files); + ext->is_unmaintained = is_unmaintained; return ext; } @@ -3368,6 +3393,7 @@ flatpak_list_extensions (GKeyFile *metakey, g_autofree char *version = g_key_file_get_string (metakey, groups[i], "version", NULL); g_autofree char *ref = NULL; const char *branch; + gboolean is_unmaintained = FALSE; g_autoptr(GFile) files = NULL; if (directory == NULL) @@ -3383,14 +3409,14 @@ flatpak_list_extensions (GKeyFile *metakey, files = flatpak_find_unmaintained_extension_dir_if_exists (extension, arch, branch, NULL); if (files == NULL) - { - files = flatpak_find_files_dir_for_ref (ref, NULL, NULL); - } + files = flatpak_find_files_dir_for_ref (ref, NULL, NULL); + else + is_unmaintained = TRUE; /* Prefer a full extension (org.freedesktop.Locale) over subdirectory ones (org.freedesktop.Locale.sv) */ if (files != NULL) { - ext = flatpak_extension_new (extension, extension, ref, directory, files); + ext = flatpak_extension_new (extension, extension, ref, directory, files, is_unmaintained); res = g_list_prepend (res, ext); } else if (g_key_file_get_boolean (metakey, groups[i], @@ -3412,7 +3438,7 @@ flatpak_list_extensions (GKeyFile *metakey, if (subdir_files) { - ext = flatpak_extension_new (extension, refs[j], dir_ref, extended_dir, subdir_files); + ext = flatpak_extension_new (extension, refs[j], dir_ref, extended_dir, subdir_files, FALSE); ext->needs_tmpfs = needs_tmpfs; needs_tmpfs = FALSE; /* Only first subdir needs a tmpfs */ res = g_list_prepend (res, ext); @@ -3429,7 +3455,7 @@ flatpak_list_extensions (GKeyFile *metakey, if (subdir_files) { - ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref, extended_dir, subdir_files); + ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref, extended_dir, subdir_files, TRUE); ext->needs_tmpfs = needs_tmpfs; needs_tmpfs = FALSE; /* Only first subdir needs a tmpfs */ res = g_list_prepend (res, ext); diff --git a/common/flatpak-utils.h b/common/flatpak-utils.h index e12aa8ba..1147a619 100644 --- a/common/flatpak-utils.h +++ b/common/flatpak-utils.h @@ -127,6 +127,10 @@ char * flatpak_build_runtime_ref (const char *runtime, char * flatpak_build_app_ref (const char *app, const char *branch, const char *arch); +GFile *flatpak_find_deploy_dir_for_ref (const char *ref, + FlatpakDir **dir_out, + GCancellable *cancellable, + GError **error); GFile * flatpak_find_files_dir_for_ref (const char *ref, GCancellable *cancellable, GError **error); @@ -298,6 +302,7 @@ typedef struct char *directory; char *files_path; gboolean needs_tmpfs; + gboolean is_unmaintained; } FlatpakExtension; void flatpak_extension_free (FlatpakExtension *extension);