update/install: Handle deploy using the system service

tingping/wmclass
Alexander Larsson 2016-04-22 15:32:23 +02:00
parent 6af6d629a2
commit b2b05e1175
7 changed files with 209 additions and 9 deletions

View File

@ -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;
}

View File

@ -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))

View File

@ -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);

View File

@ -84,7 +84,11 @@
<interface name='org.freedesktop.XdgApp.SystemHelper'>
<method name="Deploy">
<arg type='ay' name='path' direction='in'/>
<arg type='ay' name='repo_path' direction='in'/>
<arg type='u' name='flags' direction='in'/>
<arg type='s' name='ref' direction='in'/>
<arg type='s' name='origin' direction='in'/>
<arg type='as' name='subpaths' direction='in'/>
</method>
</interface>

View File

@ -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;
}

View File

@ -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)

View File

@ -26,13 +26,115 @@
#include <gio/gio.h>
#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