Skip to content

Commit

Permalink
deploy: Keep last deployment version during stage
Browse files Browse the repository at this point in the history
Fixes #1905

Signed-off-by: Rafael Fonseca <[email protected]>
  • Loading branch information
r4f4 committed Apr 21, 2021
1 parent 37bc7b3 commit 1e897e6
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 7 deletions.
16 changes: 11 additions & 5 deletions src/libostree/ostree-sysroot-deploy.c
Original file line number Diff line number Diff line change
Expand Up @@ -3120,6 +3120,11 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self,
g_variant_builder_add (builder, "{sv}", "overlay-initrds",
g_variant_new_strv ((const char *const*)opts->overlay_initrds, -1));

/* Proxy across any flags */
if (opts && opts->flags)
g_variant_builder_add (builder, "{sv}", "write-deployment-flags",
g_variant_new_uint32 ((guint32)opts->flags));

const char *parent = dirname (strdupa (_OSTREE_SYSROOT_RUNSTATE_STAGED));
if (!glnx_shutil_mkdir_p_at (AT_FDCWD, parent, 0755, cancellable, error))
return FALSE;
Expand Down Expand Up @@ -3239,14 +3244,15 @@ _ostree_sysroot_finalize_staged (OstreeSysroot *self,
staged->staged = FALSE;
g_ptr_array_remove_index (self->deployments, 0);

/* TODO: Proxy across flags too?
*
* But note that we always use NO_CLEAN to avoid adding more latency at
OstreeSysrootSimpleWriteDeploymentFlags flags = 0;
g_variant_lookup (self->staged_deployment_data, "write-deployment-flags", "u", &flags);
/*
* Note that we always use NO_CLEAN to avoid adding more latency at
* shutdown, and also because e.g. rpm-ostree wants to own the cleanup
* process.
*/
OstreeSysrootSimpleWriteDeploymentFlags flags =
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN;
flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN;

if (!ostree_sysroot_simple_write_deployment (self, ostree_deployment_get_osname (staged),
staged, merge_deployment, flags,
cancellable, error))
Expand Down
42 changes: 42 additions & 0 deletions src/libostree/ostree-sysroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,9 @@ ostree_sysroot_init_osname (OstreeSysroot *self,
* specified, then no cleanup will be performed after adding the
* deployment. Make sure to call ostree_sysroot_cleanup() sometime
* later, instead.
*
* If %OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PREVIOUS_VERSION is
* specified, then the previous version will not be garbage collected.
*/
gboolean
ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
Expand All @@ -1862,6 +1865,8 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
(flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING) > 0;
const gboolean retain_rollback =
(flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK) > 0;
const gboolean retain_previous =
(flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PREVIOUS_VERSION) > 0;
gboolean retain =
(flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN) > 0;

Expand All @@ -1884,6 +1889,27 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
if (!booted_deployment && !merge_deployment && (retain_pending || retain_rollback))
retain = TRUE;

/* tracks current versioned deployment */
OstreeRepo *repo = ostree_sysroot_repo (sysroot);
const gchar *new_version =
_ostree_deployment_get_version (new_deployment, repo, error);

gboolean retained_previous_version = FALSE;
if (booted_deployment)
{
const gchar *booted_version =
_ostree_deployment_get_version (booted_deployment, repo, error);
retained_previous_version = (g_strcmp0 (booted_version, new_version) != 0);
}

if (!retained_previous_version && merge_deployment &&
!ostree_deployment_equal (merge_deployment, booted_deployment))
{
const gchar *merge_version =
_ostree_deployment_get_version (merge_deployment, repo, error);
retained_previous_version = (g_strcmp0 (merge_version, new_version) != 0);
}

/* tracks when we come across the booted deployment */
gboolean before_booted = TRUE;
gboolean before_merge = TRUE;
Expand All @@ -1904,6 +1930,13 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
* deployments, fall back on merge deployment */
const gboolean passed_crossover = booted_deployment ? !before_booted : !before_merge;

gboolean is_previous_version = FALSE;
if (passed_crossover && osname_matches && !retained_previous_version)
{
const gchar *version = _ostree_deployment_get_version (deployment, repo, error);
is_previous_version = (g_strcmp0 (version, new_version) != 0);
}

/* Retain deployment if:
* - we're explicitly asked to, or
* - it's pinned
Expand All @@ -1919,6 +1952,15 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
|| (is_booted || is_merge)
|| (retain_rollback && passed_crossover))
g_ptr_array_add (new_deployments, g_object_ref (deployment));
/*
* - we're keeping the previous version deployment
*/
else if (retain_previous && !retained_previous_version && is_previous_version)
{
g_ptr_array_add (new_deployments, g_object_ref (deployment));
/* Just keep one previous version */
retained_previous_version = TRUE;
}

/* add right after booted/merge deployment */
if (!added_new && passed_crossover)
Expand Down
5 changes: 3 additions & 2 deletions src/libostree/ostree-sysroot.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ gboolean ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self,

typedef struct {
gboolean unused_bools[8];
int unused_ints[8];
int unused_ints[7];
int flags;
char **override_kernel_argv;
char **overlay_initrds;
gpointer unused_ptrs[6];
Expand Down Expand Up @@ -248,7 +249,6 @@ gboolean ostree_sysroot_stage_tree_with_options (OstreeSysroot *self,
GCancellable *cancellable,
GError **error);


_OSTREE_PUBLIC
gboolean ostree_sysroot_deployment_set_mutable (OstreeSysroot *self,
OstreeDeployment *deployment,
Expand Down Expand Up @@ -291,6 +291,7 @@ typedef enum {
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN = (1 << 2),
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING = (1 << 3),
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK = (1 << 4),
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PREVIOUS_VERSION = (1 << 5),
} OstreeSysrootSimpleWriteDeploymentFlags;

_OSTREE_PUBLIC
Expand Down

0 comments on commit 1e897e6

Please sign in to comment.