mirror of
https://github.com/flatpak/flatpak.git
synced 2026-05-06 23:18:40 -04:00
run: Support running a runtime directly
This means you can do: flatpak run org.freedesktop.Sdk to get a shell in a sandbox with that runtime, but with an empty /app. You can also specify a particular runtime branch and command like so: flatpak run --command=ls org.gnome.Platform//3.22 /
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "flatpak-builtins.h"
|
||||
#include "flatpak-utils.h"
|
||||
#include "flatpak-error.h"
|
||||
#include "flatpak-dbus.h"
|
||||
#include "flatpak-run.h"
|
||||
|
||||
@@ -63,6 +64,7 @@ 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;
|
||||
const char *pref;
|
||||
int i;
|
||||
int rest_argv_start, rest_argc;
|
||||
@@ -71,6 +73,7 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
|
||||
g_autofree char *arch = NULL;
|
||||
g_autofree char *branch = NULL;
|
||||
FlatpakKinds kinds;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
context = g_option_context_new (_("APP [args...] - Run an app"));
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
@@ -99,7 +102,8 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
|
||||
|
||||
pref = argv[rest_argv_start];
|
||||
|
||||
if (!flatpak_split_partial_ref_arg (pref, FLATPAK_KINDS_APP, opt_arch, opt_branch,
|
||||
if (!flatpak_split_partial_ref_arg (pref, FLATPAK_KINDS_APP | FLATPAK_KINDS_RUNTIME,
|
||||
opt_arch, opt_branch,
|
||||
&kinds, &id, &arch, &branch, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -126,18 +130,46 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
|
||||
}
|
||||
}
|
||||
|
||||
if (app_ref == NULL)
|
||||
if ((kinds & FLATPAK_KINDS_APP) != 0)
|
||||
{
|
||||
app_ref = flatpak_compose_ref (TRUE, id, branch, arch, error);
|
||||
app_ref = flatpak_compose_ref (TRUE, id, branch, arch, &local_error);
|
||||
if (app_ref == NULL)
|
||||
return FALSE;
|
||||
|
||||
app_deploy = flatpak_find_deploy_for_ref (app_ref, cancellable, &local_error);
|
||||
if (app_deploy == NULL &&
|
||||
(!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED) ||
|
||||
(kinds & FLATPAK_KINDS_RUNTIME) == 0))
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
return FALSE;
|
||||
}
|
||||
/* On error, local_error is set after this point so we can reuse
|
||||
this error rather than later errors, as the app-kind error
|
||||
is more likely interesting. */
|
||||
}
|
||||
|
||||
app_deploy = flatpak_find_deploy_for_ref (app_ref, cancellable, error);
|
||||
if (app_deploy == NULL)
|
||||
return FALSE;
|
||||
{
|
||||
g_autoptr(FlatpakDeploy) runtime_deploy = NULL;
|
||||
|
||||
if (!flatpak_run_app (app_ref, app_deploy,
|
||||
runtime_ref = flatpak_compose_ref (FALSE, id, branch, arch, error);
|
||||
if (runtime_ref == NULL)
|
||||
return FALSE;
|
||||
|
||||
runtime_deploy = flatpak_find_deploy_for_ref (runtime_ref, cancellable, NULL);
|
||||
if (runtime_deploy == NULL)
|
||||
{
|
||||
/* Report old app-kind error, as its more likely right */
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
return FALSE;
|
||||
}
|
||||
/* Clear app-kind error */
|
||||
g_clear_error (&local_error);
|
||||
}
|
||||
|
||||
if (!flatpak_run_app (app_deploy ? app_ref : runtime_ref,
|
||||
app_deploy,
|
||||
arg_context,
|
||||
opt_runtime,
|
||||
opt_runtime_version,
|
||||
|
||||
@@ -2580,7 +2580,8 @@ compute_permissions (GKeyFile *app_metadata,
|
||||
if (!flatpak_context_load_metadata (app_context, runtime_metadata, error))
|
||||
return NULL;
|
||||
|
||||
if (!flatpak_context_load_metadata (app_context, app_metadata, error))
|
||||
if (app_metadata != NULL &&
|
||||
!flatpak_context_load_metadata (app_context, app_metadata, error))
|
||||
return NULL;
|
||||
|
||||
return g_steal_pointer (&app_context);
|
||||
@@ -2601,10 +2602,10 @@ flatpak_run_add_app_info_args (GPtrArray *argv_array,
|
||||
g_autofree char *tmp_path = NULL;
|
||||
int fd;
|
||||
g_autoptr(GKeyFile) keyfile = NULL;
|
||||
g_autofree char *app_path = NULL;
|
||||
g_autofree char *runtime_path = NULL;
|
||||
g_autofree char *fd_str = NULL;
|
||||
g_autofree char *old_dest = g_strdup_printf ("/run/user/%d/flatpak-info", getuid ());
|
||||
const char *group;
|
||||
|
||||
fd = g_file_open_tmp ("flatpak-context-XXXXXX", &tmp_path, NULL);
|
||||
if (fd < 0)
|
||||
@@ -2619,11 +2620,19 @@ flatpak_run_add_app_info_args (GPtrArray *argv_array,
|
||||
|
||||
keyfile = g_key_file_new ();
|
||||
|
||||
g_key_file_set_string (keyfile, "Application", "name", app_id);
|
||||
g_key_file_set_string (keyfile, "Application", "runtime", runtime_ref);
|
||||
if (app_files)
|
||||
group = "Application";
|
||||
else
|
||||
group = "Runtime";
|
||||
|
||||
app_path = g_file_get_path (app_files);
|
||||
g_key_file_set_string (keyfile, "Instance", "app-path", app_path);
|
||||
g_key_file_set_string (keyfile, group, "name", app_id);
|
||||
g_key_file_set_string (keyfile, group, "runtime", runtime_ref);
|
||||
|
||||
if (app_files)
|
||||
{
|
||||
g_autofree char *app_path = g_file_get_path (app_files);
|
||||
g_key_file_set_string (keyfile, "Instance", "app-path", app_path);
|
||||
}
|
||||
runtime_path = g_file_get_path (runtime_files);
|
||||
g_key_file_set_string (keyfile, "Instance", "runtime-path", runtime_path);
|
||||
if (app_branch != NULL)
|
||||
@@ -3449,8 +3458,6 @@ flatpak_run_app (const char *app_ref,
|
||||
if (app_ref_parts == NULL)
|
||||
return FALSE;
|
||||
|
||||
metakey = flatpak_deploy_get_metadata (app_deploy);
|
||||
|
||||
argv_array = g_ptr_array_new_with_free_func (g_free);
|
||||
fd_array = g_array_new (FALSE, TRUE, sizeof (int));
|
||||
g_array_set_clear_func (fd_array, clear_fd);
|
||||
@@ -3458,13 +3465,22 @@ flatpak_run_app (const char *app_ref,
|
||||
session_bus_proxy_argv = g_ptr_array_new_with_free_func (g_free);
|
||||
system_bus_proxy_argv = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
default_runtime = g_key_file_get_string (metakey, "Application",
|
||||
(flags & FLATPAK_RUN_FLAG_DEVEL) != 0 ? "sdk" : "runtime",
|
||||
&my_error);
|
||||
if (my_error)
|
||||
if (app_deploy == NULL)
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&my_error));
|
||||
return FALSE;
|
||||
g_assert (g_str_has_prefix (app_ref, "runtime/"));
|
||||
default_runtime = g_strdup (app_ref + strlen ("runtime/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
metakey = flatpak_deploy_get_metadata (app_deploy);
|
||||
default_runtime = g_key_file_get_string (metakey, "Application",
|
||||
(flags & FLATPAK_RUN_FLAG_DEVEL) != 0 ? "sdk" : "runtime",
|
||||
&my_error);
|
||||
if (my_error)
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&my_error));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
runtime_parts = g_strsplit (default_runtime, "/", 0);
|
||||
@@ -3509,30 +3525,44 @@ flatpak_run_app (const char *app_ref,
|
||||
if (app_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
overrides = flatpak_deploy_get_overrides (app_deploy);
|
||||
flatpak_context_merge (app_context, overrides);
|
||||
if (app_deploy != NULL)
|
||||
{
|
||||
overrides = flatpak_deploy_get_overrides (app_deploy);
|
||||
flatpak_context_merge (app_context, overrides);
|
||||
}
|
||||
|
||||
if (extra_context)
|
||||
flatpak_context_merge (app_context, extra_context);
|
||||
|
||||
runtime_files = flatpak_deploy_get_files (runtime_deploy);
|
||||
app_files = flatpak_deploy_get_files (app_deploy);
|
||||
|
||||
if ((app_id_dir = flatpak_ensure_data_dir (app_ref_parts[1], cancellable, error)) == NULL)
|
||||
return FALSE;
|
||||
if (app_deploy != NULL)
|
||||
{
|
||||
app_files = flatpak_deploy_get_files (app_deploy);
|
||||
if ((app_id_dir = flatpak_ensure_data_dir (app_ref_parts[1], cancellable, error)) == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
envp = g_get_environ ();
|
||||
envp = flatpak_run_apply_env_default (envp);
|
||||
envp = flatpak_run_apply_env_vars (envp, app_context);
|
||||
envp = flatpak_run_apply_env_appid (envp, app_id_dir);
|
||||
if (app_id_dir != NULL)
|
||||
envp = flatpak_run_apply_env_appid (envp, app_id_dir);
|
||||
|
||||
add_args (argv_array,
|
||||
"--ro-bind", flatpak_file_get_path_cached (runtime_files), "/usr",
|
||||
"--lock-file", "/usr/.ref",
|
||||
"--ro-bind", flatpak_file_get_path_cached (app_files), "/app",
|
||||
"--lock-file", "/app/.ref",
|
||||
NULL);
|
||||
|
||||
if (app_files != NULL)
|
||||
add_args (argv_array,
|
||||
"--ro-bind", flatpak_file_get_path_cached (app_files), "/app",
|
||||
"--lock-file", "/app/.ref",
|
||||
NULL);
|
||||
else
|
||||
add_args (argv_array,
|
||||
"--dir", "/app",
|
||||
NULL);
|
||||
|
||||
if (app_context->features & FLATPAK_CONTEXT_FEATURE_DEVEL)
|
||||
flags |= FLATPAK_RUN_FLAG_DEVEL;
|
||||
|
||||
@@ -3546,7 +3576,8 @@ flatpak_run_app (const char *app_ref,
|
||||
runtime_ref, app_context, &app_info_path, error))
|
||||
return FALSE;
|
||||
|
||||
if (!flatpak_run_add_extension_args (argv_array, metakey, app_ref, cancellable, error))
|
||||
if (metakey != NULL &&
|
||||
!flatpak_run_add_extension_args (argv_array, metakey, app_ref, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!flatpak_run_add_extension_args (argv_array, runtime_metakey, runtime_ref, cancellable, error))
|
||||
@@ -3592,7 +3623,7 @@ flatpak_run_app (const char *app_ref,
|
||||
{
|
||||
command = custom_command;
|
||||
}
|
||||
else
|
||||
else if (metakey)
|
||||
{
|
||||
default_command = g_key_file_get_string (metakey, "Application", "command", &my_error);
|
||||
if (my_error)
|
||||
@@ -3600,7 +3631,6 @@ flatpak_run_app (const char *app_ref,
|
||||
g_propagate_error (error, g_steal_pointer (&my_error));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
command = default_command;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user