forked from Mirrors/flatpak-builder
During undeploy, keep files around if they are in use
We check for a lock on the .ref file to detect if anything is using a partilular checkout before we remove it.tingping/wmclass
parent
f1091127c5
commit
6ea2391583
|
@ -12,10 +12,12 @@
|
|||
|
||||
static char *opt_arch;
|
||||
static gboolean opt_keep_ref;
|
||||
static gboolean opt_force_remove;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, "Arch to uninstall", "ARCH" },
|
||||
{ "keep-ref", 0, 0, G_OPTION_ARG_NONE, &opt_keep_ref, "Keep ref in local repository", NULL },
|
||||
{ "force-remove", 0, 0, G_OPTION_ARG_NONE, &opt_force_remove, "Remove files even if running", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -115,7 +117,7 @@ xdg_app_builtin_uninstall_runtime (int argc, char **argv, GCancellable *cancella
|
|||
for (i = 0; deployed[i] != NULL; i++)
|
||||
{
|
||||
g_debug ("undeploying %s", deployed[i]);
|
||||
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], cancellable, error))
|
||||
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], opt_force_remove, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -229,7 +231,7 @@ xdg_app_builtin_uninstall_app (int argc, char **argv, GCancellable *cancellable,
|
|||
for (i = 0; deployed[i] != NULL; i++)
|
||||
{
|
||||
g_debug ("undeploying %s", deployed[i]);
|
||||
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], cancellable, error))
|
||||
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], opt_force_remove, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,12 @@
|
|||
|
||||
static char *opt_arch;
|
||||
static char *opt_commit;
|
||||
static gboolean opt_force_remove;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, "Arch to update for", "ARCH" },
|
||||
{ "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, "Commit to deploy", "COMMIT" },
|
||||
{ "force-remove", 0, 0, G_OPTION_ARG_NONE, &opt_force_remove, "Remove old files even if running", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -83,6 +85,7 @@ xdg_app_builtin_update_runtime (int argc, char **argv, GCancellable *cancellable
|
|||
if (previous_deployment != NULL)
|
||||
{
|
||||
if (!xdg_app_dir_undeploy (dir, ref, previous_deployment,
|
||||
opt_force_remove,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
@ -161,6 +164,7 @@ xdg_app_builtin_update_app (int argc, char **argv, GCancellable *cancellable, GE
|
|||
if (previous_deployment != NULL)
|
||||
{
|
||||
if (!xdg_app_dir_undeploy (dir, ref, previous_deployment,
|
||||
opt_force_remove,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -158,7 +158,13 @@ xdg_app_dir_get_deploy_dir (XdgAppDir *self,
|
|||
GFile *
|
||||
xdg_app_dir_get_exports_dir (XdgAppDir *self)
|
||||
{
|
||||
return g_file_resolve_relative_path (self->basedir, "exports");
|
||||
return g_file_get_child (self->basedir, "exports");
|
||||
}
|
||||
|
||||
GFile *
|
||||
xdg_app_dir_get_removed_dir (XdgAppDir *self)
|
||||
{
|
||||
return g_file_get_child (self->basedir, ".removed");
|
||||
}
|
||||
|
||||
GFile *
|
||||
|
@ -990,17 +996,43 @@ xdg_app_dir_list_deployed (XdgAppDir *self,
|
|||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dir_is_locked (GFile *dir)
|
||||
{
|
||||
gs_fd_close int ref_fd = -1;
|
||||
struct flock lock = {0};
|
||||
gs_unref_object GFile *reffile = NULL;
|
||||
|
||||
reffile = g_file_resolve_relative_path (dir, "files/.ref");
|
||||
|
||||
ref_fd = open (gs_file_get_path_cached (reffile), O_RDWR | O_CLOEXEC);
|
||||
if (ref_fd != -1)
|
||||
{
|
||||
lock.l_type = F_WRLCK;
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
|
||||
if (fcntl (ref_fd, F_GETLK, &lock) == 0)
|
||||
return lock.l_type != F_UNLCK;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xdg_app_dir_undeploy (XdgAppDir *self,
|
||||
const char *ref,
|
||||
const char *checksum,
|
||||
gboolean force_remove,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFile *deploy_base = NULL;
|
||||
gs_unref_object GFile *checkoutdir = NULL;
|
||||
gs_unref_object GFile *removeddir = NULL;
|
||||
gs_unref_object GFile *removed_subdir = NULL;
|
||||
gs_unref_object GFile *removed_dir = NULL;
|
||||
gs_free char *tmpname = NULL;
|
||||
gs_free char *active = NULL;
|
||||
gboolean is_app;
|
||||
|
@ -1051,18 +1083,23 @@ xdg_app_dir_undeploy (XdgAppDir *self,
|
|||
goto out;
|
||||
}
|
||||
|
||||
tmpname = gs_fileutil_gen_tmp_name (".removed-", checksum);
|
||||
removed_dir = xdg_app_dir_get_removed_dir (self);
|
||||
if (!gs_file_ensure_directory (removed_dir, TRUE, cancellable, error))
|
||||
goto out;
|
||||
|
||||
checkoutdir = g_file_get_child (deploy_base, checksum);
|
||||
removeddir = g_file_get_child (deploy_base, tmpname);
|
||||
tmpname = gs_fileutil_gen_tmp_name ("", checksum);
|
||||
removed_subdir = g_file_get_child (removed_dir, tmpname);
|
||||
|
||||
if (!gs_file_rename (checkoutdir,
|
||||
removeddir,
|
||||
removed_subdir,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!gs_shutil_rm_rf (removeddir, cancellable, error))
|
||||
goto out;
|
||||
if (force_remove || !dir_is_locked (removed_subdir))
|
||||
{
|
||||
if (!gs_shutil_rm_rf (removed_subdir, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
is_app = g_str_has_prefix (ref, "app");
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ GFile * xdg_app_dir_get_path (XdgAppDir *self);
|
|||
GFile * xdg_app_dir_get_deploy_dir (XdgAppDir *self,
|
||||
const char *ref);
|
||||
GFile * xdg_app_dir_get_exports_dir (XdgAppDir *self);
|
||||
GFile * xdg_app_dir_get_removed_dir (XdgAppDir *self);
|
||||
GFile * xdg_app_dir_get_if_deployed (XdgAppDir *self,
|
||||
const char *ref,
|
||||
const char *checksum,
|
||||
|
@ -72,6 +73,7 @@ gboolean xdg_app_dir_deploy (XdgAppDir *self,
|
|||
gboolean xdg_app_dir_undeploy (XdgAppDir *self,
|
||||
const char *ref,
|
||||
const char *checksum,
|
||||
gboolean force_remove,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean xdg_app_dir_prune (XdgAppDir *self,
|
||||
|
|
Loading…
Reference in New Issue