forked from Mirrors/flatpak-builder
update/install: Handle deploy using the system service
parent
6af6d629a2
commit
b2b05e1175
|
@ -106,7 +106,7 @@ do_update (XdgAppDir* dir,
|
||||||
|
|
||||||
if (!opt_no_deploy)
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ enum {
|
||||||
PROP_PATH
|
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," \
|
#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")
|
"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_autoptr(GError) local_error = NULL;
|
||||||
g_auto(GStrv) ref_parts = g_strsplit (ref, "/", -1);
|
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,
|
if (!xdg_app_dir_lock (self, &lock,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2603,6 +2640,7 @@ xdg_app_dir_deploy_install (XdgAppDir *self,
|
||||||
gboolean
|
gboolean
|
||||||
xdg_app_dir_deploy_update (XdgAppDir *self,
|
xdg_app_dir_deploy_update (XdgAppDir *self,
|
||||||
const char *ref,
|
const char *ref,
|
||||||
|
const char *remote_name,
|
||||||
const char *checksum_or_latest,
|
const char *checksum_or_latest,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
|
@ -2611,6 +2649,54 @@ xdg_app_dir_deploy_update (XdgAppDir *self,
|
||||||
g_autoptr(GError) my_error = NULL;
|
g_autoptr(GError) my_error = NULL;
|
||||||
g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;
|
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,
|
if (!xdg_app_dir_lock (self, &lock,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -3189,7 +3275,7 @@ xdg_app_dir_find_remote_ref (XdgAppDir *self,
|
||||||
return NULL;
|
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);
|
refs = g_variant_get_child_value (summary, 0);
|
||||||
|
|
||||||
if (app_ref && xdg_app_summary_lookup_ref (summary, app_ref, NULL))
|
if (app_ref && xdg_app_summary_lookup_ref (summary, app_ref, NULL))
|
||||||
|
|
|
@ -48,6 +48,13 @@ typedef enum {
|
||||||
XDG_APP_DIR_ERROR_NOT_DEPLOYED,
|
XDG_APP_DIR_ERROR_NOT_DEPLOYED,
|
||||||
} XdgAppDirErrorEnum;
|
} 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);
|
GQuark xdg_app_dir_error_quark (void);
|
||||||
|
|
||||||
GFile * xdg_app_get_system_base_dir_location (void);
|
GFile * xdg_app_get_system_base_dir_location (void);
|
||||||
|
@ -220,6 +227,7 @@ gboolean xdg_app_dir_deploy (XdgAppDir *self,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean xdg_app_dir_deploy_update (XdgAppDir *self,
|
gboolean xdg_app_dir_deploy_update (XdgAppDir *self,
|
||||||
const char *ref,
|
const char *ref,
|
||||||
|
const char *origin,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
|
@ -84,7 +84,11 @@
|
||||||
|
|
||||||
<interface name='org.freedesktop.XdgApp.SystemHelper'>
|
<interface name='org.freedesktop.XdgApp.SystemHelper'>
|
||||||
<method name="Deploy">
|
<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>
|
</method>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
|
|
|
@ -1061,7 +1061,7 @@ xdg_app_installation_update (XdgAppInstallation *self,
|
||||||
|
|
||||||
if ((flags & XDG_APP_UPDATE_FLAGS_NO_DEPLOY) == 0)
|
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))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,5 +30,5 @@ xdg_app_system_helper_SOURCES = \
|
||||||
system-helper/xdg-app-resources.c \
|
system-helper/xdg-app-resources.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
xdg_app_system_helper_LDADD = $(BASE_LIBS) libxdgapp-common.la
|
xdg_app_system_helper_LDADD = $(BASE_LIBS) $(OSTREE_LIBS) libxdgapp-common.la
|
||||||
xdg_app_system_helper_CFLAGS = $(BASE_CFLAGS)
|
xdg_app_system_helper_CFLAGS = $(BASE_CFLAGS) $(OSTREE_CFLAGS)
|
||||||
|
|
|
@ -26,13 +26,115 @@
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include "xdg-app-dbus.h"
|
#include "xdg-app-dbus.h"
|
||||||
|
#include "xdg-app-dir.h"
|
||||||
|
|
||||||
static GDBusNodeInfo *introspection_data = NULL;
|
static GDBusNodeInfo *introspection_data = NULL;
|
||||||
|
|
||||||
void
|
static gboolean
|
||||||
handle_deploy (void)
|
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
|
static void
|
||||||
|
|
Loading…
Reference in New Issue