upgrade: Stabilize deployment staging
authorColin Walters <walters@verbum.org>
Thu, 2 Sep 2021 20:59:15 +0000 (16:59 -0400)
committerColin Walters <walters@verbum.org>
Tue, 7 Sep 2021 20:12:43 +0000 (16:12 -0400)
We're waaay overdue for this, it's been the default
in rpm-ostree for years, and solves several important bugs
around not capturing `/etc` while things are running.

Also, `ostree admin upgrade --stage` (should) become idempotent.

Closes: https://github.com/ostreedev/ostree/issues/2389
man/ostree-admin-upgrade.xml
src/libostree/ostree-sysroot-upgrader.c
src/libostree/ostree-sysroot-upgrader.h
src/ostree/ot-admin-builtin-upgrade.c
tests/kolainst/destructive/staged-deploy.sh

index 8d0cb438b3ad0255ecbebe47930258b5abe84b13..002a217032ce95b6d852353644760a954f060a92 100644 (file)
@@ -96,6 +96,16 @@ Boston, MA 02111-1307, USA.
                 and is ready to deploy them.</para></listitem>
             </varlistentry>
 
+            <varlistentry>
+                <term><option>--stage</option></term>
+
+                <listitem><para>
+                    Perform deployment finalization at shutdown time.  Recommended,
+                    and will likely become the default in the future.
+                </para></listitem>
+            </varlistentry>
+            
+
             <varlistentry>
                 <term><option>--reboot</option>,<option>-r</option></term>
 
index 85e6734033c41f88cb2aeaaf3c5350b2618e9a6e..eefeda6e1c12bcf3f0a0df3a69b1b764006a5ca7 100644 (file)
@@ -646,7 +646,8 @@ ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader  *self,
   g_autoptr(OstreeDeployment) new_deployment = NULL;
 
   /* Experimental flag to enable staging */
-  if (getenv ("OSTREE_EX_STAGE_DEPLOYMENTS"))
+  gboolean stage = (self->flags & OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE) > 0 || getenv ("OSTREE_EX_STAGE_DEPLOYMENTS") != NULL;
+  if (stage)
     {
       if (!ostree_sysroot_stage_tree (self->sysroot, self->osname,
                                       self->new_revision,
@@ -688,6 +689,7 @@ ostree_sysroot_upgrader_flags_get_type (void)
     {
       static const GFlagsValue values[] = {
         { OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED, "OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED", "ignore-unconfigured" },
+        { OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE, "OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE", "stage" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
index c9bf8a127a036a58245d0698591a2050e47eddeb..10a463c5f2cac1c498eaac19e8ccf38cde972e7b 100644 (file)
@@ -35,12 +35,15 @@ G_BEGIN_DECLS
  * OstreeSysrootUpgraderFlags:
  * @OSTREE_SYSROOT_UPGRADER_FLAGS_NONE: No options
  * @OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED: Do not error if the origin has an unconfigured-state key
+ * @OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE: Enable "staging" (finalization at shutdown); recommended
+ *    (Since: 2021.4)
  *
  * Flags controlling operation of an #OstreeSysrootUpgrader.
  */
 typedef enum {
   OSTREE_SYSROOT_UPGRADER_FLAGS_NONE = (1 << 0),
   OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED = (1 << 1),
+  OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE = (1 << 2),
 } OstreeSysrootUpgraderFlags;
 
 _OSTREE_PUBLIC
index eafe8bceb79ed6d5c54a83d159d3ed03137e4642..2c0149c13f9746e459693badc4c14ce2e3b04f4b 100644 (file)
@@ -37,6 +37,7 @@ static gboolean opt_reboot;
 static gboolean opt_allow_downgrade;
 static gboolean opt_pull_only;
 static gboolean opt_deploy_only;
+static gboolean opt_stage;
 static char *opt_osname;
 static char *opt_override_commit;
 
@@ -47,6 +48,7 @@ static GOptionEntry options[] = {
   { "override-commit", 0, 0, G_OPTION_ARG_STRING, &opt_override_commit, "Deploy CHECKSUM instead of the latest tree", "CHECKSUM" },
   { "pull-only", 0, 0, G_OPTION_ARG_NONE, &opt_pull_only, "Do not create a deployment, just download", NULL },
   { "deploy-only", 0, 0, G_OPTION_ARG_NONE, &opt_deploy_only, "Do not pull, only deploy", NULL },
+  { "stage", 0, 0, G_OPTION_ARG_NONE, &opt_stage, "Enable staging (finalization at reboot time)", NULL },
   { NULL }
 };
 
@@ -74,9 +76,13 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeCommandInvocation *invoca
       return FALSE;
     }
 
+  OstreeSysrootUpgraderFlags flags = 0;
+  if (opt_stage)
+    flags |= OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE;
+
   g_autoptr(OstreeSysrootUpgrader) upgrader =
-    ostree_sysroot_upgrader_new_for_os (sysroot, opt_osname,
-                                        cancellable, error);
+    ostree_sysroot_upgrader_new_for_os_with_flags (sysroot, opt_osname, flags,
+                                                   cancellable, error);
   if (!upgrader)
     return FALSE;
 
index b5d0b31961f58a7ec910631043a1ef03aff84fb7..f55bb2c8c1848235332cf98dd4514c1399d190a9 100755 (executable)
@@ -19,9 +19,6 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in
     commit=${host_commit}
   # Test the deploy --stage functionality; first, we stage a deployment
   # reboot, and validate that it worked.
-  # for now, until the preset propagates down
-  # Start up path unit
-    systemctl enable --now ostree-finalize-staged.path
   # Write staged-deploy commit
     cd /ostree/repo/tmp
     # https://github.com/ostreedev/ostree/issues/1569
@@ -70,7 +67,7 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in
     ostree checkout -H "${origcommit}" t
     ostree commit --no-bindings --parent="${origcommit}" -b staged-deploy -I --consume t
     newcommit=$(ostree rev-parse staged-deploy)
-    env OSTREE_EX_STAGE_DEPLOYMENTS=1 ostree admin upgrade >out.txt
+    ostree admin upgrade --stage >out.txt
     test -f /run/ostree/staged-deployment
     # Debating bouncing back out to Ansible for this
     firstdeploycommit=$(rpm-ostree status |grep 'Commit:' |head -1|sed -e 's,^ *Commit: *,,')