sysroot: Add concept of deployment "pinning" 📌

Example user story: Jane rebases her OS to a new major version N, and wants to
keep around N-1 even after a few upgrades for a while so she can easily roll
back. I plan to add `rpm-ostree rebase --pin` to opt-in to this for example.

Builds on the new `libostree-transient` group to store pinning state there.

Closes: https://github.com/ostreedev/ostree/issues/1460

Closes: #1464
Approved by: jlebon
This commit is contained in:
Colin Walters authored and Atomic Bot committed 2018-02-26 19:06:59 +00:00
1 parent c40a47e965
commit 7f88fddcd4
15 files changed
+323 -1

No files matched your search

+2
View File
@@ -20,6 +20,8 @@
/* Add new symbols here. Release commits should copy this section into -released.sym. */
LIBOSTREE_2018.3 {
ostree_deployment_origin_remove_transient_state;
ostree_sysroot_deployment_set_pinned;
ostree_deployment_is_pinned;
} LIBOSTREE_2018.2;
/* Stub section for the stable release *after* this development one; don't
+17
View File
@@ -322,3 +322,20 @@ ostree_deployment_get_unlocked (OstreeDeployment *self)
{
return self->unlocked;
}
/**
* ostree_deployment_is_pinned:
* @self: Deployment
*
* See ostree_sysroot_deployment_set_pinned().
*
* Returns: `TRUE` if deployment will not be subject to GC
* Since: 2018.3
*/
gboolean
ostree_deployment_is_pinned (OstreeDeployment *self)
{
if (!self->origin)
return FALSE;
return g_key_file_get_boolean (self->origin, OSTREE_ORIGIN_TRANSIENT_GROUP, "pinned", NULL);
}
+3
View File
@@ -74,6 +74,9 @@ _OSTREE_PUBLIC
GKeyFile *ostree_deployment_get_origin (OstreeDeployment *self);
_OSTREE_PUBLIC
gboolean ostree_deployment_is_pinned (OstreeDeployment *self);
_OSTREE_PUBLIC
void ostree_deployment_set_index (OstreeDeployment *self, int index);
_OSTREE_PUBLIC
+44
View File
@@ -1572,12 +1572,14 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
/* Retain deployment if:
* - we're explicitly asked to, or
* - it's pinned
* - the deployment is for another osname, or
* - we're keeping pending deployments and this is a pending deployment, or
* - this is the merge or boot deployment, or
* - we're keeping rollback deployments and this is a rollback deployment
*/
if (retain
|| ostree_deployment_is_pinned (deployment)
|| !osname_matches
|| (retain_pending && !passed_crossover)
|| (is_booted || is_merge)
@@ -1832,3 +1834,45 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
return TRUE;
}
/**
* ostree_sysroot_deployment_set_pinned:
* @self: Sysroot
* @deployment: A deployment
* @is_pinned: Whether or not deployment will be automatically GC'd
* @error: Error
*
* By default, deployments may be subject to garbage collection. Typical uses of
* libostree only retain at most 2 deployments. If @is_pinned is `TRUE`, a
* metadata bit will be set causing libostree to avoid automatic GC of the
* deployment. However, this is really an "advisory" note; it's still possible
* for e.g. older versions of libostree unaware of pinning to GC the deployment.
*
* This function does nothing and returns successfully if the deployment
* is already in the desired pinning state.
*
* Since: 2018.3
*/
gboolean
ostree_sysroot_deployment_set_pinned (OstreeSysroot *self,
OstreeDeployment *deployment,
gboolean is_pinned,
GError **error)
{
const gboolean current_pin = ostree_deployment_is_pinned (deployment);
if (is_pinned == current_pin)
return TRUE;
g_autoptr(OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment);
GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone);
if (is_pinned)
g_key_file_set_boolean (origin_clone, OSTREE_ORIGIN_TRANSIENT_GROUP, "pinned", TRUE);
else
g_key_file_remove_key (origin_clone, OSTREE_ORIGIN_TRANSIENT_GROUP, "pinned", NULL);
if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone, NULL, error))
return FALSE;
return TRUE;
}
+6
View File
@@ -181,6 +181,12 @@ gboolean ostree_sysroot_deployment_set_mutable (OstreeSysroot *self,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
gboolean ostree_sysroot_deployment_set_pinned (OstreeSysroot *self,
OstreeDeployment *deployment,
gboolean is_pinned,
GError **error);
_OSTREE_PUBLIC
gboolean ostree_sysroot_deployment_unlock (OstreeSysroot *self,
OstreeDeployment *deployment,