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 Sep 19, 2024
1 parent 2a2c355 commit 6e4b112
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/libostree/ostree-sysroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,9 @@ ostree_sysroot_init_osname (OstreeSysroot *self, const char *osname, GCancellabl
* 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, const char *osname,
Expand All @@ -1920,6 +1923,8 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, const char *osna
= (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;

g_autoptr (GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot);
Expand All @@ -1941,6 +1946,34 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, const char *osna
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);

gboolean retained_previous_version = FALSE;

/* we never prune booted and merge deployments, so if they exist and are of a
* different version from `new_version`, they already fulfill the criteria of
* retaining the previous version */
if (booted_deployment)
{
const gchar *booted_version =
_ostree_deployment_get_version (booted_deployment, repo);
retained_previous_version = (g_strcmp0 (booted_version, new_version) != 0);
}

/* checking also that booted and merge are not the same although that's not a
* big deal since we cache the version now (though this will still work in
* the NULL case)
*/
if (!retained_previous_version && merge_deployment &&
!ostree_deployment_equal (merge_deployment, booted_deployment))
{
const gchar *merge_version =
_ostree_deployment_get_version (merge_deployment, repo);
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 @@ -1962,6 +1995,13 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, const char *osna
* 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);
is_previous_version = (g_strcmp0 (version, new_version) != 0);
}

/* Retain deployment if:
* - we're explicitly asked to, or
* - it's pinned
Expand All @@ -1974,6 +2014,15 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, const char *osna
|| (retain_pending && !passed_crossover) || (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
1 change: 1 addition & 0 deletions src/libostree/ostree-sysroot.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,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 6e4b112

Please sign in to comment.