[gnome-builder/wip/chergert/gnome-builder-flatpak: 7/9] flatpak: start on gnome-builder-flatpak daemon
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/gnome-builder-flatpak: 7/9] flatpak: start on gnome-builder-flatpak daemon
- Date: Thu, 11 Apr 2019 04:48:44 +0000 (UTC)
commit 4b6a67a8bfa2649e84a196013159a036f9839a05
Author: Christian Hergert <chergert redhat com>
Date: Wed Apr 10 14:48:18 2019 -0700
flatpak: start on gnome-builder-flatpak daemon
This starts on a deamon that will provide the ultimate goal of us moving
our libflatpak integration out of process. Doing so provides us some
resilience as well as a simplified plugin implementation that can focus
more on bridging the two systems than the mechanics of tracking changes.
src/plugins/flatpak/daemon/gnome-builder-flatpak.c | 115 +++++++
.../flatpak/daemon/ipc-flatpak-service-impl.c | 365 +++++++++++++++++++++
.../flatpak/daemon/ipc-flatpak-service-impl.h | 33 ++
src/plugins/flatpak/daemon/ipc-flatpak-util.h | 42 +++
src/plugins/flatpak/daemon/meson.build | 33 ++
.../daemon/org.gnome.Builder.Flatpak.Service.xml | 50 +++
src/plugins/flatpak/daemon/test-flatpak.c | 155 +++++++++
src/plugins/flatpak/meson.build | 2 +
8 files changed, 795 insertions(+)
---
diff --git a/src/plugins/flatpak/daemon/gnome-builder-flatpak.c
b/src/plugins/flatpak/daemon/gnome-builder-flatpak.c
new file mode 100644
index 000000000..2edd5af26
--- /dev/null
+++ b/src/plugins/flatpak/daemon/gnome-builder-flatpak.c
@@ -0,0 +1,115 @@
+/* gnome-builder-flatpak.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <glib-unix.h>
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+#include <flatpak/flatpak.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#include "ipc-flatpak-service.h"
+#include "ipc-flatpak-service-impl.h"
+
+static GDBusConnection *
+create_connection (GIOStream *stream,
+ GMainLoop *main_loop,
+ GError **error)
+{
+ GDBusConnection *ret;
+
+ g_assert (G_IS_IO_STREAM (stream));
+ g_assert (main_loop != NULL);
+ g_assert (error != NULL);
+
+ if ((ret = g_dbus_connection_new_sync (stream, NULL,
+ G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
+ NULL, NULL, error)))
+ {
+ g_dbus_connection_set_exit_on_close (ret, FALSE);
+ g_signal_connect_swapped (ret, "closed", G_CALLBACK (g_main_loop_quit), main_loop);
+ }
+
+ return ret;
+}
+
+static void
+log_func (const gchar *log_domain,
+ GLogLevelFlags flags,
+ const gchar *message,
+ gpointer user_data)
+{
+ g_printerr ("gnome-builder-flatpak: %s\n", message);
+}
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ g_autoptr(GDBusConnection) connection = NULL;
+ g_autoptr(IpcFlatpakService) service = NULL;
+ g_autoptr(GOutputStream) stdout_stream = NULL;
+ g_autoptr(GInputStream) stdin_stream = NULL;
+ g_autoptr(GIOStream) stream = NULL;
+ g_autoptr(GMainLoop) main_loop = NULL;
+ g_autoptr(GError) error = NULL;
+
+ g_set_prgname ("gnome-builder-flatpak");
+ g_set_application_name ("gnome-builder-flatpak");
+
+ prctl (PR_SET_PDEATHSIG, SIGTERM);
+
+ signal (SIGPIPE, SIG_IGN);
+
+ g_log_set_handler (NULL, G_LOG_LEVEL_MASK, log_func, NULL);
+
+ if (!g_unix_set_fd_nonblocking (STDIN_FILENO, TRUE, &error) ||
+ !g_unix_set_fd_nonblocking (STDOUT_FILENO, TRUE, &error))
+ goto error;
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+ stdin_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
+ stdout_stream = g_unix_output_stream_new (STDOUT_FILENO, FALSE);
+ stream = g_simple_io_stream_new (stdin_stream, stdout_stream);
+
+ if (!(connection = create_connection (stream, main_loop, &error)))
+ goto error;
+
+ service = ipc_flatpak_service_impl_new ();
+
+ if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service),
+ connection,
+ "/org/gnome/Builder/Flatpak",
+ &error))
+ goto error;
+
+ g_dbus_connection_start_message_processing (connection);
+ g_main_loop_run (main_loop);
+
+ return EXIT_SUCCESS;
+
+error:
+ if (error != NULL)
+ g_error ("%s", error->message);
+
+ return EXIT_FAILURE;
+}
diff --git a/src/plugins/flatpak/daemon/ipc-flatpak-service-impl.c
b/src/plugins/flatpak/daemon/ipc-flatpak-service-impl.c
new file mode 100644
index 000000000..fd24d11e8
--- /dev/null
+++ b/src/plugins/flatpak/daemon/ipc-flatpak-service-impl.c
@@ -0,0 +1,365 @@
+/* ipc-flatpak-service-impl.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ipc-flatpak-service-impl"
+
+#include "config.h"
+
+#include <flatpak/flatpak.h>
+
+#include "ipc-flatpak-service-impl.h"
+#include "ipc-flatpak-util.h"
+
+typedef struct
+{
+ FlatpakInstallation *installation;
+ gchar *name;
+ gchar *arch;
+ gchar *branch;
+ gchar *sdk_name;
+ gchar *sdk_branch;
+ gboolean sdk_extension : 1;
+} Runtime;
+
+typedef struct
+{
+ FlatpakInstallation *installation;
+ GFileMonitor *monitor;
+} Install;
+
+struct _IpcFlatpakServiceImpl
+{
+ IpcFlatpakServiceSkeleton parent;
+ GHashTable *installs;
+ GPtrArray *runtimes;
+};
+
+static void ipc_flatpak_service_impl_install_changed_cb (IpcFlatpakServiceImpl *self,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event,
+ GFileMonitor *monitor);
+static gboolean ipc_flatpak_service_impl_add_installation (IpcFlatpakService *service,
+ GDBusMethodInvocation *invocation,
+ const gchar *path,
+ gboolean is_user);
+static void add_runtime (IpcFlatpakServiceImpl *service,
+ Runtime *runtime);
+static Install *install_new (IpcFlatpakServiceImpl *self,
+ FlatpakInstallation *installation,
+ GError **error);
+static void install_free (Install *install);
+static void install_reload (IpcFlatpakServiceImpl *self,
+ Install *install);
+static GVariant *runtime_to_variant (const Runtime *runtime);
+static void runtime_free (Runtime *runtime);
+static gboolean runtime_equal (const Runtime *a,
+ const Runtime *b);
+
+static void
+add_runtime (IpcFlatpakServiceImpl *self,
+ Runtime *runtime)
+{
+ g_autoptr(GVariant) variant = NULL;
+
+ g_assert (IPC_IS_FLATPAK_SERVICE_IMPL (self));
+ g_assert (runtime != NULL);
+
+ for (guint i = 0; i < self->runtimes->len; i++)
+ {
+ const Runtime *other = g_ptr_array_index (self->runtimes, i);
+
+ /* Ignore if we know about it already */
+ if (runtime_equal (other, runtime))
+ return;
+ }
+
+ variant = runtime_to_variant (runtime);
+ g_ptr_array_add (self->runtimes, g_steal_pointer (&runtime));
+
+ ipc_flatpak_service_emit_runtime_added (IPC_FLATPAK_SERVICE (self), variant);
+}
+
+static void
+runtime_free (Runtime *runtime)
+{
+ g_clear_pointer (&runtime->name, g_free);
+ g_clear_pointer (&runtime->arch, g_free);
+ g_clear_pointer (&runtime->branch, g_free);
+ g_clear_pointer (&runtime->sdk_name, g_free);
+ g_clear_pointer (&runtime->sdk_branch, g_free);
+ g_slice_free (Runtime, runtime);
+}
+
+static gboolean
+runtime_equal (const Runtime *a,
+ const Runtime *b)
+{
+ return g_str_equal (a->name, b->name) &&
+ g_str_equal (a->arch, b->arch) &&
+ g_str_equal (a->branch, b->branch);
+}
+
+static GVariant *
+runtime_to_variant (const Runtime *runtime)
+{
+ return g_variant_take_ref (g_variant_new ("(sssssb)",
+ runtime->name,
+ runtime->arch,
+ runtime->branch,
+ runtime->sdk_name,
+ runtime->sdk_branch,
+ runtime->sdk_extension));
+}
+
+static Install *
+install_new (IpcFlatpakServiceImpl *self,
+ FlatpakInstallation *installation,
+ GError **error)
+{
+ g_autoptr(GFileMonitor) monitor = NULL;
+ Install *ret;
+
+ if (!(monitor = flatpak_installation_create_monitor (installation, NULL, error)))
+ return NULL;
+
+ ret = g_slice_new0 (Install);
+ ret->installation = g_object_ref (installation);
+ ret->monitor = g_steal_pointer (&monitor);
+
+ g_signal_connect_object (ret->monitor,
+ "changed",
+ G_CALLBACK (ipc_flatpak_service_impl_install_changed_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
+ return g_steal_pointer (&ret);
+}
+
+static void
+install_free (Install *install)
+{
+ g_clear_object (&install->installation);
+ g_clear_object (&install->monitor);
+ g_slice_free (Install, install);
+}
+
+static void
+install_reload (IpcFlatpakServiceImpl *self,
+ Install *install)
+{
+ g_autoptr(GPtrArray) refs = NULL;
+
+ g_assert (IPC_IS_FLATPAK_SERVICE_IMPL (self));
+ g_assert (install != NULL);
+
+ if (!(refs = flatpak_installation_list_installed_refs_by_kind (install->installation,
+ FLATPAK_REF_KIND_RUNTIME,
+ NULL, NULL)))
+ return;
+
+ for (guint i = 0; i < refs->len; i++)
+ {
+ FlatpakInstalledRef *ref = g_ptr_array_index (refs, i);
+ g_autoptr(FlatpakRef) sdk_ref = NULL;
+ g_autoptr(GBytes) bytes = NULL;
+ g_autoptr(GKeyFile) keyfile = g_key_file_new ();
+ g_autofree gchar *sdk_full_ref = NULL;
+ g_autofree gchar *name = NULL;
+ g_autofree gchar *runtime = NULL;
+ g_autofree gchar *sdk = NULL;
+ g_autofree gchar *exten_of = NULL;
+ Runtime *state;
+
+ if (!(bytes = flatpak_installed_ref_load_metadata (ref, NULL, NULL)) ||
+ !g_key_file_load_from_bytes (keyfile, bytes, G_KEY_FILE_NONE, NULL))
+ continue;
+
+ if (!(name = g_key_file_get_string (keyfile, "Runtime", "name", NULL)) ||
+ !(runtime = g_key_file_get_string (keyfile, "Runtime", "runtime", NULL)) ||
+ !(sdk = g_key_file_get_string (keyfile, "Runtime", "sdk", NULL)))
+ continue;
+
+ if (g_key_file_has_group (keyfile, "ExtensionOf"))
+ {
+ /* Skip if this item is an extension, but not an SDK extension */
+ if (!g_key_file_has_key (keyfile, "ExtensionOf", "ref", NULL) ||
+ strstr (name, ".Extension.") == NULL)
+ continue;
+
+ exten_of = g_key_file_get_string (keyfile, "ExtensionOf", "ref", NULL);
+ }
+
+ if (!g_str_has_prefix (sdk, "runtime/"))
+ sdk_full_ref = g_strdup_printf ("runtime/%s", sdk);
+ else
+ sdk_full_ref = g_strdup (sdk);
+
+ /* Make sure we can parse the SDK reference */
+ if (!(sdk_ref = flatpak_ref_parse (sdk_full_ref, NULL)))
+ continue;
+
+ state = g_slice_new0 (Runtime);
+ state->installation = g_object_ref (install->installation);
+ state->name = g_strdup (flatpak_ref_get_name (FLATPAK_REF (ref)));
+ state->arch = g_strdup (flatpak_ref_get_arch (FLATPAK_REF (ref)));
+ state->branch = g_strdup (flatpak_ref_get_branch (FLATPAK_REF (ref)));
+ state->sdk_name = g_strdup (flatpak_ref_get_name (sdk_ref));
+ state->sdk_branch = g_strdup (flatpak_ref_get_branch (sdk_ref));
+ state->sdk_extension = exten_of != NULL;
+
+ add_runtime (self, g_steal_pointer (&state));
+ }
+}
+
+static gboolean
+ipc_flatpak_service_impl_add_installation (IpcFlatpakService *service,
+ GDBusMethodInvocation *invocation,
+ const gchar *path,
+ gboolean is_user)
+{
+ IpcFlatpakServiceImpl *self = (IpcFlatpakServiceImpl *)service;
+ g_autoptr(FlatpakInstallation) installation = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GFile) file = NULL;
+
+ g_assert (IPC_IS_FLATPAK_SERVICE_IMPL (self));
+ g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+ g_assert (path != NULL);
+
+ file = g_file_new_for_path (path);
+
+ if (!g_hash_table_contains (self->installs, file))
+ {
+ Install *install;
+
+ if (!(installation = flatpak_installation_new_for_path (file, is_user, NULL, &error)) ||
+ !(install = install_new (self, installation, &error)))
+ return complete_wrapped_error (invocation, error);
+
+ install_reload (self, install);
+
+ g_hash_table_insert (self->installs,
+ g_steal_pointer (&file),
+ g_steal_pointer (&install));
+ }
+
+ ipc_flatpak_service_complete_add_installation (service, invocation);
+
+ return TRUE;
+}
+
+static gboolean
+ipc_flatpak_service_impl_list_runtimes (IpcFlatpakService *service,
+ GDBusMethodInvocation *invocation)
+{
+ IpcFlatpakServiceImpl *self = (IpcFlatpakServiceImpl *)service;
+ g_autoptr(GError) error = NULL;
+ GVariantBuilder builder;
+
+ g_assert (IPC_IS_FLATPAK_SERVICE_IMPL (self));
+ g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssssb)"));
+
+ for (guint i = 0; i < self->runtimes->len; i++)
+ {
+ const Runtime *runtime = g_ptr_array_index (self->runtimes, i);
+ g_autoptr(GVariant) item = runtime_to_variant (runtime);
+ g_variant_builder_add_value (&builder, item);
+ }
+
+ ipc_flatpak_service_complete_list_runtimes (service,
+ invocation,
+ g_variant_builder_end (&builder));
+
+ return TRUE;
+}
+
+static void
+ipc_flatpak_service_impl_install_changed_cb (IpcFlatpakServiceImpl *self,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event,
+ GFileMonitor *monitor)
+{
+ GHashTableIter iter;
+ Install *install;
+
+ g_assert (IPC_IS_FLATPAK_SERVICE_IMPL (self));
+ g_assert (G_IS_FILE (file));
+ g_assert (!other_file || G_IS_FILE (other_file));
+ g_assert (G_IS_FILE_MONITOR (monitor));
+
+ g_hash_table_iter_init (&iter, self->installs);
+
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&install))
+ {
+ if (install->monitor == monitor)
+ {
+ install_reload (self, install);
+ break;
+ }
+ }
+}
+
+static void
+service_iface_init (IpcFlatpakServiceIface *iface)
+{
+ iface->handle_add_installation = ipc_flatpak_service_impl_add_installation;
+ iface->handle_list_runtimes = ipc_flatpak_service_impl_list_runtimes;
+}
+
+G_DEFINE_TYPE_WITH_CODE (IpcFlatpakServiceImpl, ipc_flatpak_service_impl, IPC_TYPE_FLATPAK_SERVICE_SKELETON,
+ G_IMPLEMENT_INTERFACE (IPC_TYPE_FLATPAK_SERVICE, service_iface_init))
+
+static void
+ipc_flatpak_service_impl_finalize (GObject *object)
+{
+ IpcFlatpakServiceImpl *self = (IpcFlatpakServiceImpl *)object;
+
+ g_clear_pointer (&self->installs, g_hash_table_unref);
+
+ G_OBJECT_CLASS (ipc_flatpak_service_impl_parent_class)->finalize (object);
+}
+
+static void
+ipc_flatpak_service_impl_class_init (IpcFlatpakServiceImplClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ipc_flatpak_service_impl_finalize;
+}
+
+static void
+ipc_flatpak_service_impl_init (IpcFlatpakServiceImpl *self)
+{
+ self->installs = g_hash_table_new_full (g_file_hash,
+ (GEqualFunc) g_file_equal,
+ g_object_unref,
+ (GDestroyNotify) install_free);
+ self->runtimes = g_ptr_array_new_with_free_func ((GDestroyNotify) runtime_free);
+}
+
+IpcFlatpakService *
+ipc_flatpak_service_impl_new (void)
+{
+ return g_object_new (IPC_TYPE_FLATPAK_SERVICE_IMPL, NULL);
+}
diff --git a/src/plugins/flatpak/daemon/ipc-flatpak-service-impl.h
b/src/plugins/flatpak/daemon/ipc-flatpak-service-impl.h
new file mode 100644
index 000000000..0ab95b9d8
--- /dev/null
+++ b/src/plugins/flatpak/daemon/ipc-flatpak-service-impl.h
@@ -0,0 +1,33 @@
+/* ipc-flatpak-service-impl.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "ipc-flatpak-service.h"
+
+G_BEGIN_DECLS
+
+#define IPC_TYPE_FLATPAK_SERVICE_IMPL (ipc_flatpak_service_impl_get_type())
+
+G_DECLARE_FINAL_TYPE (IpcFlatpakServiceImpl, ipc_flatpak_service_impl, IPC, FLATPAK_SERVICE_IMPL,
IpcFlatpakServiceSkeleton)
+
+IpcFlatpakService *ipc_flatpak_service_impl_new (void);
+
+G_END_DECLS
diff --git a/src/plugins/flatpak/daemon/ipc-flatpak-util.h b/src/plugins/flatpak/daemon/ipc-flatpak-util.h
new file mode 100644
index 000000000..d09099f75
--- /dev/null
+++ b/src/plugins/flatpak/daemon/ipc-flatpak-util.h
@@ -0,0 +1,42 @@
+/* ipc-flatpak-util.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+static inline gboolean
+complete_wrapped_error (GDBusMethodInvocation *invocation,
+ const GError *error)
+{
+ g_autoptr(GError) wrapped = NULL;
+
+ wrapped = g_error_new (G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "The operation failed. The original error was \"%s\"",
+ error->message);
+ g_dbus_method_invocation_return_gerror (invocation, wrapped);
+
+ return TRUE;
+}
+
+G_END_DECLS
diff --git a/src/plugins/flatpak/daemon/meson.build b/src/plugins/flatpak/daemon/meson.build
new file mode 100644
index 000000000..508ba7065
--- /dev/null
+++ b/src/plugins/flatpak/daemon/meson.build
@@ -0,0 +1,33 @@
+gnome_builder_flatpak_deps = [
+ libgiounix_dep,
+ dependency('flatpak', version: '>= 1.0.0'),
+ dependency('ostree-1'),
+ dependency('libsoup-2.4', version: '>= 2.52.0'),
+]
+
+ipc_flatpak_service_src = gnome.gdbus_codegen('ipc-flatpak-service',
+ sources: 'org.gnome.Builder.Flatpak.Service.xml',
+ interface_prefix: 'org.gnome.Builder.',
+ namespace: 'Ipc',
+)
+
+gnome_builder_flatpak_sources = [
+ 'gnome-builder-flatpak.c',
+ 'ipc-flatpak-service-impl.c',
+ ipc_flatpak_service_src,
+]
+
+gnome_builder_flatpak = executable('gnome-builder-flatpak', gnome_builder_flatpak_sources,
+ install: true,
+ install_dir: get_option('libexecdir'),
+ dependencies: gnome_builder_flatpak_deps,
+)
+
+test_flatpak_sources = [
+ 'test-flatpak.c',
+ ipc_flatpak_service_src,
+]
+
+test_flatpak = executable('test-flatpak', 'test-flatpak.c', test_flatpak_sources,
+ dependencies: [ libgiounix_dep ],
+)
diff --git a/src/plugins/flatpak/daemon/org.gnome.Builder.Flatpak.Service.xml
b/src/plugins/flatpak/daemon/org.gnome.Builder.Flatpak.Service.xml
new file mode 100644
index 000000000..7d2acd42f
--- /dev/null
+++ b/src/plugins/flatpak/daemon/org.gnome.Builder.Flatpak.Service.xml
@@ -0,0 +1,50 @@
+<!DOCTYPE node PUBLIC
+ "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" >
+<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+ <!--
+ Copyright 2019 Christian Hergert <chergert redhat com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ -->
+ <interface name="org.gnome.Builder.Flatpak.Service">
+ <signal name="RuntimeAdded">
+ <!--
+ Param is (name, arch, branch, sdk_name, sdk_branch, is_sdk_extension)
+ -->
+ <arg name="runtime" direction="in" type="(sssssb)"/>
+ </signal>
+ <!--
+ AddInstallation:
+ @path: the path of the installation
+ @is_user: if the installation is a user installation
+
+ Adds an installation to the list of monitored installations.
+ -->
+ <method name="AddInstallation">
+ <arg name="path" direction="in" type="ay"/>
+ <arg name="is_user" direction="in" type="b"/>
+ </method>
+ <!--
+ ListRuntimes:
+
+ Lists the available runtimes for use as development.
+ -->
+ <method name="ListRuntimes">
+ <arg name="runtimes" direction="out" type="a(sssssb)"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/plugins/flatpak/daemon/test-flatpak.c b/src/plugins/flatpak/daemon/test-flatpak.c
new file mode 100644
index 000000000..927ecef49
--- /dev/null
+++ b/src/plugins/flatpak/daemon/test-flatpak.c
@@ -0,0 +1,155 @@
+/* test-flatpak.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <glib-unix.h>
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "ipc-flatpak-service.h"
+
+static void
+on_runtime_added_cb (IpcFlatpakService *service,
+ GVariant *info)
+{
+ const gchar *name;
+ const gchar *arch;
+ const gchar *branch;
+ const gchar *sdk_name;
+ const gchar *sdk_branch;
+ gboolean sdk_extension;
+
+ g_assert (IPC_IS_FLATPAK_SERVICE (service));
+ g_assert (info != NULL);
+ g_assert (g_variant_is_of_type (info, G_VARIANT_TYPE ("(sssssb)")));
+
+ g_variant_get (info, "(&s&s&s&s&sb)",
+ &name, &arch, &branch, &sdk_name, &sdk_branch, &sdk_extension);
+
+ if (!sdk_extension)
+ g_message ("Runtime Added: %s/%s/%s with SDK %s//%s",
+ name, arch, branch, sdk_name, sdk_branch);
+ else
+ g_message ("SDK Extension Added: %s/%s/%s with SDK %s//%s",
+ name, arch, branch, sdk_name, sdk_branch);
+}
+
+static void
+add_install_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IpcFlatpakService *service = (IpcFlatpakService *)object;
+ g_autoptr(GMainLoop) main_loop = user_data;
+ g_autoptr(GVariant) runtimes = NULL;
+ g_autoptr(GError) error = NULL;
+ GVariantIter iter;
+ gboolean ret;
+
+ ret = ipc_flatpak_service_call_add_installation_finish (service, result, &error);
+ g_assert_no_error (error);
+ g_assert_true (ret);
+ g_message ("Installation added");
+
+ g_message ("Listing runtimes");
+ ret = ipc_flatpak_service_call_list_runtimes_sync (service, &runtimes, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (ret);
+
+ if (g_variant_iter_init (&iter, runtimes))
+ {
+ const gchar *name;
+ const gchar *arch;
+ const gchar *branch;
+ const gchar *sdk_name;
+ const gchar *sdk_branch;
+ gboolean sdk_extension;
+
+ while (g_variant_iter_next (&iter, "(&s&s&s&s&sb)",
+ &name, &arch, &branch, &sdk_name, &sdk_branch, &sdk_extension))
+ g_message (" %s/%s/%s with SDK %s//%s (Extension: %d)",
+ name, arch, branch, sdk_name, sdk_branch, sdk_extension);
+ }
+
+
+ g_main_loop_quit (main_loop);
+}
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ g_autofree gchar *home_install = g_build_filename (g_get_home_dir (), ".local", "share", "flatpak", NULL);
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GIOStream) stream = NULL;
+ g_autoptr(GInputStream) stdout_stream = NULL;
+ g_autoptr(GOutputStream) stdin_stream = NULL;
+ g_autoptr(GDBusConnection) connection = NULL;
+ g_autoptr(GSubprocess) subprocess = NULL;
+ g_autoptr(GSubprocessLauncher) launcher = NULL;
+ g_autoptr(IpcFlatpakService) service = NULL;
+ GMainLoop *main_loop;
+
+ launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE);
+ subprocess = g_subprocess_launcher_spawn (launcher, &error, "./gnome-builder-flatpak", NULL);
+
+ if (subprocess == NULL)
+ g_error ("%s", error->message);
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+ stdin_stream = g_subprocess_get_stdin_pipe (subprocess);
+ stdout_stream = g_subprocess_get_stdout_pipe (subprocess);
+ stream = g_simple_io_stream_new (stdout_stream, stdin_stream);
+ connection = g_dbus_connection_new_sync (stream,
+ NULL,
+ G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING,
+ NULL,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert_true (G_IS_DBUS_CONNECTION (connection));
+
+ g_dbus_connection_set_exit_on_close (connection, FALSE);
+ g_dbus_connection_start_message_processing (connection);
+
+ g_message ("Creating flatpak service proxy");
+ service = ipc_flatpak_service_proxy_new_sync (connection, 0, NULL, "/org/gnome/Builder/Flatpak", NULL,
&error);
+ g_assert_no_error (error);
+ g_assert_true (IPC_IS_FLATPAK_SERVICE (service));
+
+ g_signal_connect (service,
+ "runtime-added",
+ G_CALLBACK (on_runtime_added_cb),
+ NULL);
+
+ g_message ("Adding user installation to daemon");
+ ipc_flatpak_service_call_add_installation (service,
+ home_install,
+ TRUE,
+ NULL,
+ add_install_cb,
+ g_main_loop_ref (main_loop));
+
+ g_main_loop_run (main_loop);
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/plugins/flatpak/meson.build b/src/plugins/flatpak/meson.build
index 6fab01c1e..5b84734fd 100644
--- a/src/plugins/flatpak/meson.build
+++ b/src/plugins/flatpak/meson.build
@@ -4,6 +4,8 @@ if not get_option('plugin_git')
error('-Dplugin_git=true is required for flatpak')
endif
+subdir('daemon')
+
plugins_sources += files([
'flatpak-plugin.c',
'gbp-flatpak-application-addin.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]