[gnome-builder/wip/gtk4-port: 1592/1774] plugins/flatpak: port flatpak runtime to use run context




commit f6c6fb4a7b0519fd89498ec6ed5f58360a3a8570
Author: Christian Hergert <chergert redhat com>
Date:   Tue Jun 21 21:49:16 2022 -0700

    plugins/flatpak: port flatpak runtime to use run context
    
    This makes the run manager able to run flatpak projects again. We still
    have some work to do on the handlers of course.

 src/plugins/flatpak/gbp-flatpak-runtime.c | 157 ++++++++++++++++++++++++++++++
 1 file changed, 157 insertions(+)
---
diff --git a/src/plugins/flatpak/gbp-flatpak-runtime.c b/src/plugins/flatpak/gbp-flatpak-runtime.c
index f7be43c1d..7035e83da 100644
--- a/src/plugins/flatpak/gbp-flatpak-runtime.c
+++ b/src/plugins/flatpak/gbp-flatpak-runtime.c
@@ -20,10 +20,17 @@
 
 #define G_LOG_DOMAIN "gbp-flatpak-runtime"
 
+#include "config.h"
+
+#include <unistd.h>
+
 #include <glib/gi18n.h>
+
 #include <json-glib/json-glib.h>
+
 #include <libide-vcs.h>
 
+#include "gbp-flatpak-aux.h"
 #include "gbp-flatpak-manifest.h"
 #include "gbp-flatpak-runner.h"
 #include "gbp-flatpak-runtime.h"
@@ -308,6 +315,155 @@ gbp_flatpak_runtime_create_runner (IdeRuntime     *runtime,
   return runner;
 }
 
+static gboolean
+can_pass_through_finish_arg (const char *arg)
+{
+  if (arg == NULL)
+    return FALSE;
+
+  return g_str_has_prefix (arg, "--allow") ||
+         g_str_has_prefix (arg, "--share") ||
+         g_str_has_prefix (arg, "--socket") ||
+         g_str_has_prefix (arg, "--filesystem") ||
+         g_str_has_prefix (arg, "--device") ||
+         g_str_has_prefix (arg, "--env") ||
+         g_str_has_prefix (arg, "--system-talk") ||
+         g_str_has_prefix (arg, "--own-name") ||
+         g_str_has_prefix (arg, "--talk-name") ||
+         g_str_has_prefix (arg, "--add-policy");
+}
+
+static gboolean
+gbp_flatpak_runtime_handle_run_context_cb (IdeRunContext       *run_context,
+                                           const char * const  *argv,
+                                           const char * const  *env,
+                                           const char          *cwd,
+                                           IdeUnixFDMap        *unix_fd_map,
+                                           gpointer             user_data,
+                                           GError             **error)
+{
+  GbpFlatpakRuntime *self = user_data;
+  IdeConfigManager *config_manager;
+  g_autofree char *project_build_dir_arg = NULL;
+  g_autofree char *project_build_dir = NULL;
+  g_autofree char *doc_portal_arg = NULL;
+  g_autofree char *staging_dir = NULL;
+  IdeBuildManager *build_manager;
+  IdePipeline *pipeline;
+  const char *app_id;
+  IdeContext *context;
+  IdeConfig *config;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_FLATPAK_RUNTIME (self));
+  g_assert (IDE_IS_RUN_CONTEXT (run_context));
+  g_assert (IDE_IS_UNIX_FD_MAP (unix_fd_map));
+
+  /* TODO: need way to specify to run on host */
+
+  /* Pass through the FD mappings */
+  if (!ide_run_context_merge_unix_fd_map (run_context, unix_fd_map, error))
+    return FALSE;
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+
+  /* Get the the staging directory for "flatpak build" to use */
+  build_manager = ide_build_manager_from_context (context);
+  pipeline = ide_build_manager_get_pipeline (build_manager);
+  staging_dir = gbp_flatpak_get_staging_dir (pipeline);
+
+  /* Get the app-id and access to config for finish-args */
+  config_manager = ide_config_manager_from_context (context);
+  config = ide_config_manager_get_current (config_manager);
+  app_id = ide_config_get_app_id (config);
+
+  /* Make sure our worker has access to our Builder-specific Flatpak repository */
+  ide_run_context_setenv (run_context, "FLATPAK_CONFIG_DIR", gbp_flatpak_get_config_dir ());
+
+  /* We can pass the CWD directory down just fine */
+  ide_run_context_set_cwd (run_context, cwd);
+
+  /* Now setup our basic arguments for the application */
+  ide_run_context_append_argv (run_context, "flatpak");
+  ide_run_context_append_argv (run_context, "build");
+  ide_run_context_append_argv (run_context, "--with-appdir");
+  ide_run_context_append_argv (run_context, "--allow=devel");
+
+  /* Make sure we have access to the document portal */
+  doc_portal_arg = g_strdup_printf ("--bind-mount=/run/user/%u/doc=/run/user/%u/doc/by-app/%s",
+                                    getuid (), getuid (), app_id);
+  ide_run_context_append_argv (run_context, doc_portal_arg);
+
+  /* Make sure we have access to fonts and such */
+  gbp_flatpak_aux_append_to_run_context (run_context);
+
+  /* Make sure we have access to the build directory */
+  project_build_dir = ide_context_cache_filename (context, NULL, NULL);
+  project_build_dir_arg = g_strdup_printf ("--filesystem=%s", project_build_dir);
+  ide_run_context_append_argv (run_context, project_build_dir_arg);
+
+  /* Concvert environment from upper level into --env=FOO=BAR */
+  if (env != NULL)
+    {
+      for (guint i = 0; env[i]; i++)
+        {
+          g_autofree char *arg = g_strconcat ("--env=", env[i], NULL);
+          ide_run_context_append_argv (run_context, arg);
+        }
+    }
+
+  /* Make sure all of our finish arguments for the manifest are included */
+  if (GBP_IS_FLATPAK_MANIFEST (config))
+    {
+      const gchar * const *finish_args = gbp_flatpak_manifest_get_finish_args (GBP_FLATPAK_MANIFEST 
(config));
+
+      if (finish_args != NULL)
+        {
+          for (guint i = 0; finish_args[i]; i++)
+            {
+              if (can_pass_through_finish_arg (finish_args[i]))
+                ide_run_context_append_argv (run_context, finish_args[i]);
+            }
+        }
+    }
+  else
+    {
+      ide_run_context_append_argv (run_context, "--share=ipc");
+      ide_run_context_append_argv (run_context, "--share=network");
+      ide_run_context_append_argv (run_context, "--socket=x11");
+      ide_run_context_append_argv (run_context, "--socket=wayland");
+    }
+
+  ide_run_context_append_argv (run_context, "--talk-name=org.freedesktop.portal.*");
+  ide_run_context_append_argv (run_context, "--talk-name=org.a11y.Bus");
+
+  /* And last, before our child command, is the staging directory */
+  ide_run_context_append_argv (run_context, staging_dir);
+
+  /* And now the upper layer's command arguments */
+  ide_run_context_append_args (run_context, argv);
+
+  IDE_RETURN (TRUE);
+}
+
+static void
+gbp_flatpak_runtime_prepare_run_context (IdeRuntime    *runtime,
+                                         IdeRunContext *run_context)
+{
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_FLATPAK_RUNTIME (runtime));
+  g_assert (IDE_IS_RUN_CONTEXT (run_context));
+
+  ide_run_context_push (run_context,
+                        gbp_flatpak_runtime_handle_run_context_cb,
+                        g_object_ref (runtime),
+                        g_object_unref);
+
+  IDE_EXIT;
+}
+
 static void
 gbp_flatpak_runtime_prepare_configuration (IdeRuntime *runtime,
                                            IdeConfig  *config)
@@ -687,6 +843,7 @@ gbp_flatpak_runtime_class_init (GbpFlatpakRuntimeClass *klass)
   runtime_class->create_runner = gbp_flatpak_runtime_create_runner;
   runtime_class->contains_program_in_path = gbp_flatpak_runtime_contains_program_in_path;
   runtime_class->prepare_configuration = gbp_flatpak_runtime_prepare_configuration;
+  runtime_class->prepare_run_context = gbp_flatpak_runtime_prepare_run_context;
   runtime_class->translate_file = gbp_flatpak_runtime_translate_file;
   runtime_class->get_system_include_dirs = gbp_flatpak_runtime_get_system_include_dirs;
   runtime_class->get_triplet = gbp_flatpak_runtime_real_get_triplet;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]