From 3d79c339bc7a54683f80c6ab1624f6fa65f64820 Mon Sep 17 00:00:00 2001 From: Simon McVittie <smcv@collabora.com> Date: Tue, 9 Jun 2020 20:22:43 +0100 Subject: [PATCH] wrap: Add an --only-prepare mode This is primarily useful for testing and development: it lets us generate the temporary sysroot and inspect its contents, even if we are in a container (such as Docker or Flatpak) that does not give us the necessary privileges to run bubblewrap and create a new user namespace. In particular, this will make it more straightforward for us to check some of our assumptions when running on a non-Debian-derived host system. Signed-off-by: Simon McVittie <smcv@collabora.com> --- src/runtime.c | 27 +++++++++++++++++++++++++-- src/wrap.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/runtime.c b/src/runtime.c index c940e3ea1..592e2a1d2 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -273,13 +273,36 @@ pv_runtime_set_property (GObject *object, path = g_value_get_string (value); if (path != NULL) - self->mutable_parent = flatpak_canonicalize_filename (path); + { + self->mutable_parent = realpath (path, NULL); + + if (self->mutable_parent == NULL) + { + /* It doesn't exist. Keep the non-canonical path so we + * can warn about it later */ + self->mutable_parent = g_strdup (path); + } + } + break; case PROP_SOURCE_FILES: /* Construct-only */ g_return_if_fail (self->source_files == NULL); - self->source_files = g_value_dup_string (value); + path = g_value_get_string (value); + + if (path != NULL) + { + self->source_files = realpath (path, NULL); + + if (self->source_files == NULL) + { + /* It doesn't exist. Keep the non-canonical path so we + * can warn about it later */ + self->source_files = g_strdup (path); + } + } + break; case PROP_TOOLS_DIRECTORY: diff --git a/src/wrap.c b/src/wrap.c index 8b6a7f0aa..386a14b02 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -100,7 +100,8 @@ find_bwrap (const char *tools_dir) } static gchar * -check_bwrap (const char *tools_dir) +check_bwrap (const char *tools_dir, + gboolean only_prepare) { g_autoptr(GError) local_error = NULL; GError **error = &local_error; @@ -119,6 +120,14 @@ check_bwrap (const char *tools_dir) { g_warning ("Cannot find bwrap"); } + else if (only_prepare) + { + /* With --only-prepare we don't necessarily expect to be able to run + * it anyway (we are probably in a Docker container that doesn't allow + * creation of nested user namespaces), so just assume that it's the + * right one. */ + return g_steal_pointer (&bwrap_executable); + } else { int wait_status; @@ -325,6 +334,7 @@ static gboolean opt_generate_locales = TRUE; static char *opt_home = NULL; static gboolean opt_host_fallback = FALSE; static gboolean opt_host_graphics = TRUE; +static gboolean opt_only_prepare = FALSE; static gboolean opt_remove_game_overlay = FALSE; static PvShell opt_shell = PV_SHELL_NONE; static GPtrArray *opt_ld_preload = NULL; @@ -632,6 +642,9 @@ static GOptionEntry options[] = { "test", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_test, "Smoke test pressure-vessel-wrap and exit.", NULL }, + { "only-prepare", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_only_prepare, + "Prepare runtime, but do not actually run anything.", NULL }, { NULL } }; @@ -803,7 +816,7 @@ main (int argc, goto out; } - if (argc < 2 && !opt_test) + if (argc < 2 && !opt_test && !opt_only_prepare) { g_printerr ("%s: An executable to run is required\n", g_get_prgname ()); @@ -888,6 +901,13 @@ main (int argc, } } + if (opt_only_prepare && opt_test) + { + g_printerr ("%s: --only-prepare and --test are mutually exclusive", + g_get_prgname ()); + goto out; + } + /* Finished parsing arguments, so any subsequent failures will make * us exit 1. */ ret = 1; @@ -1006,7 +1026,7 @@ main (int argc, flatpak_bwrap_append_argsv (wrapped_command, &argv[1], argc - 1); g_debug ("Checking for bwrap..."); - bwrap_executable = check_bwrap (tools_dir); + bwrap_executable = check_bwrap (tools_dir, opt_only_prepare); if (opt_test) { @@ -1322,7 +1342,11 @@ main (int argc, pv_runtime_cleanup (runtime); flatpak_bwrap_finish (bwrap); - pv_bwrap_execve (bwrap, error); + + if (opt_only_prepare) + ret = 0; + else + pv_bwrap_execve (bwrap, error); out: if (local_error != NULL) -- GitLab