diff --git a/app/xdg-app-builtins-update.c b/app/xdg-app-builtins-update.c
index a5aa0d85..42802878 100644
--- a/app/xdg-app-builtins-update.c
+++ b/app/xdg-app-builtins-update.c
@@ -106,7 +106,7 @@ do_update (XdgAppDir* dir,
if (!opt_no_deploy)
{
- if (!xdg_app_dir_deploy_update (dir, ref, opt_commit, cancellable, error))
+ if (!xdg_app_dir_deploy_update (dir, ref, repository, opt_commit, cancellable, error))
return FALSE;
}
diff --git a/common/xdg-app-dir.c b/common/xdg-app-dir.c
index cedeb8cf..a2bf8b3c 100644
--- a/common/xdg-app-dir.c
+++ b/common/xdg-app-dir.c
@@ -79,6 +79,8 @@ enum {
PROP_PATH
};
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppSystemHelper, g_object_unref)
+
#define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \
"unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev")
@@ -2541,6 +2543,41 @@ xdg_app_dir_deploy_install (XdgAppDir *self,
g_autoptr(GError) local_error = NULL;
g_auto(GStrv) ref_parts = g_strsplit (ref, "/", -1);
+ if (self->child_repo)
+ {
+ char *empty_subpaths[] = {NULL};
+ g_autoptr(XdgAppSystemHelper) helper = NULL;
+
+ helper = xdg_app_system_helper_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ "org.freedesktop.XdgApp.SystemHelper",
+ "/org/freedesktop/XdgApp/SystemHelper",
+ cancellable,
+ error);
+ if (helper == NULL)
+ return FALSE;
+
+ if (!xdg_app_system_helper_call_deploy_sync (helper,
+ gs_file_get_path_cached (ostree_repo_get_path (self->child_repo)),
+ XDG_APP_HELPER_DEPLOY_FLAGS_NONE,
+ ref,
+ origin,
+ (const char *const *)(subpaths ? subpaths : empty_subpaths),
+ cancellable,
+ error))
+ return FALSE;
+
+ (void) glnx_shutil_rm_rf_at (AT_FDCWD,
+ gs_file_get_path_cached (ostree_repo_get_path (self->child_repo)),
+ NULL, NULL);
+
+ g_clear_object (&self->child_repo);
+ glnx_release_lock_file (&self->child_repo_lock);
+
+ return TRUE;
+ }
+
if (!xdg_app_dir_lock (self, &lock,
cancellable, error))
goto out;
@@ -2603,6 +2640,7 @@ xdg_app_dir_deploy_install (XdgAppDir *self,
gboolean
xdg_app_dir_deploy_update (XdgAppDir *self,
const char *ref,
+ const char *remote_name,
const char *checksum_or_latest,
GCancellable *cancellable,
GError **error)
@@ -2611,6 +2649,54 @@ xdg_app_dir_deploy_update (XdgAppDir *self,
g_autoptr(GError) my_error = NULL;
g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;
+ if (self->child_repo)
+ {
+ char *empty_subpaths[] = {NULL};
+ g_autofree char *pulled_checksum = NULL;
+ g_autofree char *active_checksum = NULL;
+ g_autofree char *remote_and_ref = NULL;
+ g_autoptr(XdgAppSystemHelper) helper = NULL;
+
+ if (checksum_or_latest != NULL)
+ return xdg_app_fail (error, "Can't update to a specific commit without root permissions");
+
+ if (!ostree_repo_resolve_rev (self->child_repo, ref, FALSE, &pulled_checksum, error))
+ return FALSE;
+
+ active_checksum = xdg_app_dir_read_active (self, ref, NULL);
+ if (active_checksum == NULL || strcmp (active_checksum, pulled_checksum) != 0)
+ {
+ helper = xdg_app_system_helper_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ "org.freedesktop.XdgApp.SystemHelper",
+ "/org/freedesktop/XdgApp/SystemHelper",
+ cancellable,
+ error);
+ if (helper == NULL)
+ return FALSE;
+
+ if (!xdg_app_system_helper_call_deploy_sync (helper,
+ gs_file_get_path_cached (ostree_repo_get_path (self->child_repo)),
+ XDG_APP_HELPER_DEPLOY_FLAGS_UPDATE,
+ ref,
+ remote_name,
+ (const char *const *)empty_subpaths,
+ cancellable,
+ error))
+ return FALSE;
+ }
+
+ (void) glnx_shutil_rm_rf_at (AT_FDCWD,
+ gs_file_get_path_cached (ostree_repo_get_path (self->child_repo)),
+ NULL, NULL);
+
+ g_clear_object (&self->child_repo);
+ glnx_release_lock_file (&self->child_repo_lock);
+
+ return TRUE;
+ }
+
if (!xdg_app_dir_lock (self, &lock,
cancellable, error))
return FALSE;
@@ -3189,7 +3275,7 @@ xdg_app_dir_find_remote_ref (XdgAppDir *self,
return NULL;
}
- summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE);
+ summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE));
refs = g_variant_get_child_value (summary, 0);
if (app_ref && xdg_app_summary_lookup_ref (summary, app_ref, NULL))
diff --git a/common/xdg-app-dir.h b/common/xdg-app-dir.h
index f94f59fa..9a6bd473 100644
--- a/common/xdg-app-dir.h
+++ b/common/xdg-app-dir.h
@@ -48,6 +48,13 @@ typedef enum {
XDG_APP_DIR_ERROR_NOT_DEPLOYED,
} XdgAppDirErrorEnum;
+typedef enum {
+ XDG_APP_HELPER_DEPLOY_FLAGS_NONE = 0,
+ XDG_APP_HELPER_DEPLOY_FLAGS_UPDATE = 1<<0,
+} XdgAppHelperDeployFlags;
+
+#define XDG_APP_HELPER_DEPLOY_FLAGS_ALL (XDG_APP_HELPER_DEPLOY_FLAGS_UPDATE)
+
GQuark xdg_app_dir_error_quark (void);
GFile * xdg_app_get_system_base_dir_location (void);
@@ -220,6 +227,7 @@ gboolean xdg_app_dir_deploy (XdgAppDir *self,
GError **error);
gboolean xdg_app_dir_deploy_update (XdgAppDir *self,
const char *ref,
+ const char *origin,
const char *checksum,
GCancellable *cancellable,
GError **error);
diff --git a/data/org.freedesktop.XdgApp.xml b/data/org.freedesktop.XdgApp.xml
index 6f77efc6..d90a6e0a 100644
--- a/data/org.freedesktop.XdgApp.xml
+++ b/data/org.freedesktop.XdgApp.xml
@@ -84,7 +84,11 @@
-
+
+
+
+
+
diff --git a/lib/xdg-app-installation.c b/lib/xdg-app-installation.c
index d642b4a6..3da464f4 100644
--- a/lib/xdg-app-installation.c
+++ b/lib/xdg-app-installation.c
@@ -1061,7 +1061,7 @@ xdg_app_installation_update (XdgAppInstallation *self,
if ((flags & XDG_APP_UPDATE_FLAGS_NO_DEPLOY) == 0)
{
- if (!xdg_app_dir_deploy_update (dir_clone, ref, NULL,
+ if (!xdg_app_dir_deploy_update (dir_clone, ref, remote_name, NULL,
cancellable, error))
goto out;
}
diff --git a/system-helper/Makefile.am.inc b/system-helper/Makefile.am.inc
index 0bd2c6c5..b14822a0 100644
--- a/system-helper/Makefile.am.inc
+++ b/system-helper/Makefile.am.inc
@@ -30,5 +30,5 @@ xdg_app_system_helper_SOURCES = \
system-helper/xdg-app-resources.c \
$(NULL)
-xdg_app_system_helper_LDADD = $(BASE_LIBS) libxdgapp-common.la
-xdg_app_system_helper_CFLAGS = $(BASE_CFLAGS)
+xdg_app_system_helper_LDADD = $(BASE_LIBS) $(OSTREE_LIBS) libxdgapp-common.la
+xdg_app_system_helper_CFLAGS = $(BASE_CFLAGS) $(OSTREE_CFLAGS)
diff --git a/system-helper/xdg-app-system-helper.c b/system-helper/xdg-app-system-helper.c
index 8f17a49d..67321d3e 100644
--- a/system-helper/xdg-app-system-helper.c
+++ b/system-helper/xdg-app-system-helper.c
@@ -26,13 +26,115 @@
#include
#include "xdg-app-dbus.h"
+#include "xdg-app-dir.h"
static GDBusNodeInfo *introspection_data = NULL;
-void
-handle_deploy (void)
+static gboolean
+handle_deploy (XdgAppSystemHelper *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *arg_repo_path,
+ guint32 arg_flags,
+ const gchar *arg_ref,
+ const gchar *arg_origin,
+ const gchar *const *arg_subpaths)
{
- g_print ("deploy!");
+ g_autoptr(XdgAppDir) system = xdg_app_dir_get_system ();
+ g_autoptr(GFile) path = g_file_new_for_path (arg_repo_path);
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GFile) deploy_dir = NULL;
+ gboolean is_update;
+
+ is_update = (arg_flags & XDG_APP_HELPER_DEPLOY_FLAGS_UPDATE) != 0;
+
+ if ((arg_flags & ~XDG_APP_HELPER_DEPLOY_FLAGS_ALL) != 0)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Unsupported flags enabled: 0x%x", (arg_flags & ~XDG_APP_HELPER_DEPLOY_FLAGS_ALL));
+ }
+
+ if (!g_file_query_exists (path, NULL))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Path does not exist");
+ return TRUE;
+ }
+
+ deploy_dir = xdg_app_dir_get_if_deployed (system, arg_ref,
+ NULL, NULL);
+
+ if (deploy_dir)
+ {
+ g_autofree char *real_origin = NULL;
+ if (!is_update)
+ {
+ /* Can't install already installed app */
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "%s is already installed", arg_ref);
+ return TRUE;
+ }
+
+ real_origin = xdg_app_dir_get_origin (system, arg_ref, NULL, NULL);
+ if (real_origin == NULL || strcmp (real_origin, arg_origin) != 0)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Wrong origin %s for update", arg_origin);
+ return TRUE;
+ }
+ }
+ else if (!deploy_dir && is_update)
+ {
+ /* Can't update not installed app */
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "%s is not installed", arg_ref);
+ return TRUE;
+ }
+
+ if (!xdg_app_dir_ensure_repo (system, NULL, &error))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Can't open system repo %s", error->message);
+ return TRUE;
+ }
+
+ if (!xdg_app_dir_pull_untrusted_local (system, arg_repo_path,
+ arg_origin,
+ arg_ref,
+ (char **)arg_subpaths,
+ NULL,
+ NULL, &error))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Error pulling from repo: %s", error->message);
+ return TRUE;
+ }
+
+ if (is_update)
+ {
+ /* TODO: This doesn't support a custom subpath */
+ if (!xdg_app_dir_deploy_update (system, arg_ref, arg_origin,
+ NULL,
+ NULL, &error))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Error deploying: %s", error->message);
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (!xdg_app_dir_deploy_install (system, arg_ref, arg_origin,
+ (char **)arg_subpaths,
+ NULL, &error))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Error deploying: %s", error->message);
+ return TRUE;
+ }
+ }
+
+ xdg_app_system_helper_complete_deploy (object, invocation);
+
+ return TRUE;
}
static void