Add `admin set-default`
authorColin Walters <walters@verbum.org>
Wed, 2 Aug 2023 15:25:58 +0000 (11:25 -0400)
committerColin Walters <walters@verbum.org>
Thu, 3 Aug 2023 19:09:57 +0000 (15:09 -0400)
A core underlying primitive in the C library is the ability
to arbitrarily reorder bootloader entries.

Let's expose the basic functionality here with the ability to pick
an arbitrarily deployment for the next boot.

Closes: https://github.com/ostreedev/ostree/issues/2965
Makefile-man.am
Makefile-ostree.am
man/ostree-admin-set-default.xml [new file with mode: 0644]
src/ostree/ot-admin-builtin-set-default.c [new file with mode: 0644]
src/ostree/ot-admin-builtins.h
src/ostree/ot-builtin-admin.c
tests/admin-test.sh

index 5df392cacaff2bf226203e4490a3d8f406a472ca..03f16edc0c721aa6313842349b2e962f25540d82 100644 (file)
@@ -29,7 +29,7 @@ ostree-admin-config-diff.1 ostree-admin-deploy.1                      \
 ostree-admin-init-fs.1 ostree-admin-instutil.1 ostree-admin-os-init.1  \
 ostree-admin-status.1 ostree-admin-set-origin.1 ostree-admin-switch.1  \
 ostree-admin-undeploy.1 ostree-admin-upgrade.1 ostree-admin-unlock.1   \
-ostree-admin-pin.1 \
+ostree-admin-pin.1 ostree-admin-set-default.1 \
 ostree-admin.1 ostree-cat.1 ostree-checkout.1 ostree-checksum.1                \
 ostree-commit.1 ostree-create-usb.1 ostree-export.1 \
 ostree-config.1 ostree-diff.1 ostree-find-remotes.1 ostree-fsck.1 \
index 118db281c74b7ede4956907f45883c751c11ec4d..16bb04d02b42904c1e123ae5f4464ecb77e02a99 100644 (file)
@@ -72,6 +72,7 @@ ostree_SOURCES += \
        src/ostree/ot-admin-builtin-finalize-staged.c \
        src/ostree/ot-admin-builtin-boot-complete.c \
        src/ostree/ot-admin-builtin-undeploy.c \
+       src/ostree/ot-admin-builtin-set-default.c \
        src/ostree/ot-admin-builtin-instutil.c \
        src/ostree/ot-admin-builtin-kargs.c \
        src/ostree/ot-admin-builtin-cleanup.c \
diff --git a/man/ostree-admin-set-default.xml b/man/ostree-admin-set-default.xml
new file mode 100644 (file)
index 0000000..7d362fe
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+    "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+SPDX-License-Identifier: LGPL-2.0+
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<refentry id="ostree">
+
+    <refentryinfo>
+        <title>ostree admin set-default</title>
+        <productname>OSTree</productname>
+
+        <authorgroup>
+            <author>
+                <contrib>Developer</contrib>
+                <firstname>Colin</firstname>
+                <surname>Walters</surname>
+                <email>walters@verbum.org</email>
+            </author>
+        </authorgroup>
+    </refentryinfo>
+
+    <refmeta>
+        <refentrytitle>ostree admin set-default</refentrytitle>
+        <manvolnum>1</manvolnum>
+    </refmeta>
+
+    <refnamediv>
+        <refname>ostree-admin-set-default</refname>
+        <refpurpose>Make deployment at a given index the default for the next boot</refpurpose>
+    </refnamediv>
+
+    <refsynopsisdiv>
+            <cmdsynopsis>
+                <command>ostree admin set-default</command> <arg choice="req">INDEX</arg>
+            </cmdsynopsis>
+    </refsynopsisdiv>
+
+    <refsect1>
+        <title>Description</title>
+
+        <para>
+            Make the deployment at INDEX the default for the next boot.
+        </para>
+    </refsect1>
+
+    <refsect1>
+        <title>Example</title>
+        <para><command>$ ostree admin status</command></para>
+<programlisting>
+        * exampleos 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
+            origin refspec: exampleos/buildmain/x86_64-runtime
+          exampleos ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0
+            origin refspec: exampleos/buildmain/x86_64-runtime
+</programlisting>
+<para><command>$ ostree admin set-default 1</command></para>
+<programlisting>
+        Transaction complete; bootconfig swap: deployment count change: 0
+</programlisting>
+<para><command>$ ostree admin status</command></para>
+          exampleos ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0
+            origin refspec: exampleos/buildmain/x86_64-runtime
+        * exampleos 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
+            origin refspec: exampleos/buildmain/x86_64-runtime
+<programlisting>
+</programlisting>
+    </refsect1>
+</refentry>
diff --git a/src/ostree/ot-admin-builtin-set-default.c b/src/ostree/ot-admin-builtin-set-default.c
new file mode 100644 (file)
index 0000000..89e6754
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "ostree.h"
+#include "ot-admin-builtins.h"
+#include "ot-admin-functions.h"
+#include "ot-main.h"
+#include "otutil.h"
+
+static GOptionEntry options[] = { { NULL } };
+
+gboolean
+ot_admin_builtin_set_default (int argc, char **argv, OstreeCommandInvocation *invocation,
+                              GCancellable *cancellable, GError **error)
+{
+  g_autoptr (GOptionContext) context = g_option_context_new ("INDEX");
+
+  g_autoptr (OstreeSysroot) sysroot = NULL;
+  if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
+                                          OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot,
+                                          cancellable, error))
+    return FALSE;
+
+  if (argc < 2)
+    {
+      ot_util_usage_error (context, "INDEX must be specified", error);
+      return FALSE;
+    }
+
+  g_autoptr (GPtrArray) current_deployments = ostree_sysroot_get_deployments (sysroot);
+
+  const char *deploy_index_str = argv[1];
+  int deploy_index = atoi (deploy_index_str);
+
+  g_autoptr (OstreeDeployment) target_deployment
+      = ot_admin_get_indexed_deployment (sysroot, deploy_index, error);
+  if (!target_deployment)
+    return FALSE;
+
+  g_ptr_array_remove_index (current_deployments, deploy_index);
+  g_ptr_array_insert (current_deployments, 0, g_object_ref (target_deployment));
+
+  if (!ostree_sysroot_write_deployments (sysroot, current_deployments, cancellable, error))
+    return FALSE;
+
+  if (!ostree_sysroot_cleanup (sysroot, cancellable, error))
+    return glnx_prefix_error (error, "Performing final cleanup");
+
+  return TRUE;
+}
index d2ad836c8d63b5621454687a83fe188bd175cbc0..0464a81860ee9e30dd7e5f42a24910768d8d84bb 100644 (file)
@@ -35,6 +35,7 @@ BUILTINPROTO (install);
 BUILTINPROTO (instutil);
 BUILTINPROTO (init_fs);
 BUILTINPROTO (undeploy);
+BUILTINPROTO (set_default);
 BUILTINPROTO (deploy);
 BUILTINPROTO (cleanup);
 BUILTINPROTO (pin);
index 4d3c33648d30540fd7ceae5aea5b0e3545140858..14f776c02e8bddeb49a321595114128b347a47cd 100644 (file)
@@ -55,6 +55,8 @@ static OstreeCommand admin_subcommands[] = {
   { "switch", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_switch,
     "Construct new tree from REFSPEC and deploy it" },
   { "undeploy", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_undeploy, "Delete deployment INDEX" },
+  { "set-default", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_set_default,
+    "Make deployment INDEX the default" },
   { "unlock", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_unlock,
     "Make the current deployment mutable (as a hotfix or development)" },
   { "upgrade", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_upgrade,
index 366dece1f18e01272597d0087252e3bb48c3bbaa..9962e2edb2555cc42e3517395d041a3ae8de8a1b 100644 (file)
@@ -19,7 +19,7 @@
 
 set -euo pipefail
 
-echo "1..$((28 + ${extra_admin_tests:-0}))"
+echo "1..$((29 + ${extra_admin_tests:-0}))"
 
 mkdir sysrootmin
 ${CMD_PREFIX} ostree admin init-fs --modern sysrootmin
@@ -208,6 +208,16 @@ validate_bootloader
 
 echo "ok deploy --retain-rollback"
 
+
+${CMD_PREFIX} ostree admin status
+assert_file_has_content sysroot/boot/loader/entries/ostree-3-otheros.conf "^title.*TestOS 42 1.0.10"
+${CMD_PREFIX} ostree admin set-default 1
+assert_file_has_content sysroot/boot/loader/entries/ostree-3-testos.conf "^title.*TestOS 42 1.0.10"
+${CMD_PREFIX} ostree admin set-default 1
+assert_file_has_content sysroot/boot/loader/entries/ostree-3-otheros.conf "^title.*TestOS 42 1.0.10"
+
+echo "ok set-default"
+
 os_repository_new_commit
 ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime
 newrev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos:testos/buildmain/x86_64-runtime)