summaryrefslogtreecommitdiff
path: root/src/libostree
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2018-02-23 12:46:32 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-02-26 19:06:59 +0000
commit7f88fddcd41f0fb12333eba145c99d2499b7767f (patch)
treee7d94073c4356c4cff20c4919883f4b197777362 /src/libostree
parentc40a47e965d139cf6e72192bd582098a635b72f4 (diff)
downloadostree-7f88fddcd41f0fb12333eba145c99d2499b7767f.tar.gz
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
Diffstat (limited to 'src/libostree')
-rw-r--r--src/libostree/libostree-devel.sym2
-rw-r--r--src/libostree/ostree-deployment.c17
-rw-r--r--src/libostree/ostree-deployment.h3
-rw-r--r--src/libostree/ostree-sysroot.c44
-rw-r--r--src/libostree/ostree-sysroot.h6
5 files changed, 72 insertions, 0 deletions
diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym
index 123627a4..285ba5f5 100644
--- a/src/libostree/libostree-devel.sym
+++ b/src/libostree/libostree-devel.sym
@@ -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
diff --git a/src/libostree/ostree-deployment.c b/src/libostree/ostree-deployment.c
index 2c479fdb..75a5bd1d 100644
--- a/src/libostree/ostree-deployment.c
+++ b/src/libostree/ostree-deployment.c
@@ -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);
+}
diff --git a/src/libostree/ostree-deployment.h b/src/libostree/ostree-deployment.h
index 985c8133..612222a2 100644
--- a/src/libostree/ostree-deployment.h
+++ b/src/libostree/ostree-deployment.h
@@ -75,6 +75,9 @@ 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
void ostree_deployment_set_bootserial (OstreeDeployment *self, int index);
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index 34799444..2c12b78b 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -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;
+}
diff --git a/src/libostree/ostree-sysroot.h b/src/libostree/ostree-sysroot.h
index 830ed272..e4763d37 100644
--- a/src/libostree/ostree-sysroot.h
+++ b/src/libostree/ostree-sysroot.h
@@ -182,6 +182,12 @@ gboolean ostree_sysroot_deployment_set_mutable (OstreeSysroot *self,
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,
OstreeDeploymentUnlockedState unlocked_state,