summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuijing Hei <hhei@redhat.com>2022-06-02 15:30:20 +0800
committerHuijing Hei <hhei@redhat.com>2022-06-23 22:31:39 +0800
commit3bc59a52068ed52e063d99ebe2492eae6f6f92c0 (patch)
treeac35f74101d25faddb3eab5675f73d49874a1f8c
parentb04c436bb9b718198c2bf0d891ae0b6e1184daf2 (diff)
downloadostree-3bc59a52068ed52e063d99ebe2492eae6f6f92c0.tar.gz
RFE: Add a hidden option to `ostree admin kargs edit-in-place` to
update all existing deployments in place Example: $ sudo ostree admin kargs edit-in-place --append-if-missing=rw See https://github.com/ostreedev/ostree/issues/2617 This will not add duplicate key, if there is `TESTARG=VAL1` in the kernel arguments, `--append-if-missing=TESTARG=VAL2` will be ignored.
-rw-r--r--Makefile-libostree.am3
-rw-r--r--Makefile-ostree.am3
-rw-r--r--Makefile-tests.am1
-rw-r--r--apidoc/ostree-sections.txt1
-rw-r--r--src/libostree/libostree-devel.sym4
-rw-r--r--src/libostree/ostree-kernel-args.c25
-rw-r--r--src/libostree/ostree-kernel-args.h4
-rw-r--r--src/ostree/ot-admin-builtin-kargs.c134
-rw-r--r--src/ostree/ot-admin-builtins.h1
-rw-r--r--src/ostree/ot-admin-kargs-builtin-edit-in-place.c80
-rw-r--r--src/ostree/ot-admin-kargs-builtins.h35
-rw-r--r--src/ostree/ot-builtin-admin.c3
-rwxr-xr-xtests/test-admin-kargs.sh44
13 files changed, 338 insertions, 0 deletions
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index f93f712a..dd7ed8df 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -174,6 +174,9 @@ symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym
#if BUILDOPT_IS_DEVEL_BUILD
#symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym
#endif
+if BUILDOPT_IS_DEVEL_BUILD
+symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym
+endif
# http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html
wl_versionscript_arg = -Wl,--version-script=
diff --git a/Makefile-ostree.am b/Makefile-ostree.am
index 0fe2c5f8..fb377075 100644
--- a/Makefile-ostree.am
+++ b/Makefile-ostree.am
@@ -73,6 +73,7 @@ ostree_SOURCES += \
src/ostree/ot-admin-builtin-boot-complete.c \
src/ostree/ot-admin-builtin-undeploy.c \
src/ostree/ot-admin-builtin-instutil.c \
+ src/ostree/ot-admin-builtin-kargs.c \
src/ostree/ot-admin-builtin-cleanup.c \
src/ostree/ot-admin-builtin-os-init.c \
src/ostree/ot-admin-builtin-set-origin.c \
@@ -88,6 +89,8 @@ ostree_SOURCES += \
src/ostree/ot-admin-instutil-builtins.h \
src/ostree/ot-admin-functions.h \
src/ostree/ot-admin-functions.c \
+ src/ostree/ot-admin-kargs-builtins.h \
+ src/ostree/ot-admin-kargs-builtin-edit-in-place.c \
$(NULL)
# Remote subcommand
diff --git a/Makefile-tests.am b/Makefile-tests.am
index 29de6c7a..c87893ee 100644
--- a/Makefile-tests.am
+++ b/Makefile-tests.am
@@ -114,6 +114,7 @@ _installed_or_uninstalled_test_scripts = \
tests/test-admin-pull-deploy-split.sh \
tests/test-admin-locking.sh \
tests/test-admin-deploy-clean.sh \
+ tests/test-admin-kargs.sh \
tests/test-reset-nonlinear.sh \
tests/test-oldstyle-partial.sh \
tests/test-delta.sh \
diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt
index adf52557..5af8e687 100644
--- a/apidoc/ostree-sections.txt
+++ b/apidoc/ostree-sections.txt
@@ -727,6 +727,7 @@ ostree_kernel_args_replace_argv
ostree_kernel_args_append
ostree_kernel_args_append_argv
ostree_kernel_args_append_argv_filtered
+ostree_kernel_args_append_if_missing
ostree_kernel_args_new_replace
ostree_kernel_args_delete
ostree_kernel_args_delete_key_entry
diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym
index eef5cba0..54945eca 100644
--- a/src/libostree/libostree-devel.sym
+++ b/src/libostree/libostree-devel.sym
@@ -20,6 +20,10 @@
- uncomment the include in Makefile-libostree.am
*/
+LIBOSTREE_2022.5 {
+global:
+ ostree_kernel_args_append_if_missing;
+} LIBOSTREE_2022.4;
/* Stub section for the stable release *after* this development one; don't
* edit this other than to update the year. This is just a copy/paste
diff --git a/src/libostree/ostree-kernel-args.c b/src/libostree/ostree-kernel-args.c
index 40f11e99..08dcf992 100644
--- a/src/libostree/ostree-kernel-args.c
+++ b/src/libostree/ostree-kernel-args.c
@@ -804,3 +804,28 @@ ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key)
const OstreeKernelArgsEntry *e = entries->pdata[entries->len-1];
return _ostree_kernel_args_entry_get_value (e);
}
+
+/**
+ * ostree_kernel_args_append_if_missing:
+ * @kargs: a OstreeKernelArgs instance
+ * @arg: key or key/value pair to be added
+ *
+ * Appends @arg which is in the form of key=value pair to the hash table kargs->table
+ * (appends to the value list if key is not in the hash table)
+ * and appends key to kargs->order if it is not in the hash table.
+ *
+ * Since: 2022.5
+ **/
+void
+ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs,
+ const char *arg)
+{
+ g_autofree char *key = g_strdup (arg);
+ split_keyeq (key);
+
+ // Don't insert a duplicate key.
+ if (g_hash_table_contains (kargs->table, key))
+ return;
+
+ ostree_kernel_args_append (kargs, arg);
+}
diff --git a/src/libostree/ostree-kernel-args.h b/src/libostree/ostree-kernel-args.h
index dde0312f..2e1b249a 100644
--- a/src/libostree/ostree-kernel-args.h
+++ b/src/libostree/ostree-kernel-args.h
@@ -130,4 +130,8 @@ char **ostree_kernel_args_to_strv (OstreeKernelArgs *kargs);
_OSTREE_PUBLIC
char *ostree_kernel_args_to_string (OstreeKernelArgs *kargs);
+_OSTREE_PUBLIC
+void ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs,
+ const char *arg);
+
G_END_DECLS
diff --git a/src/ostree/ot-admin-builtin-kargs.c b/src/ostree/ot-admin-builtin-kargs.c
new file mode 100644
index 00000000..4afef294
--- /dev/null
+++ b/src/ostree/ot-admin-builtin-kargs.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 Colin Walters <walters@verbum.org>
+ * Copyright (C) 2022 Huijing Hei <hhei@redhat.com>
+ *
+ * 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 "ot-main.h"
+#include "ot-admin-builtins.h"
+#include "ot-admin-functions.h"
+#include "ot-admin-kargs-builtins.h"
+#include "otutil.h"
+
+#include <glib/gi18n.h>
+
+static OstreeCommand admin_kargs_subcommands[] = {
+ { "edit-in-place", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN,
+ ot_admin_kargs_builtin_edit_in_place,
+ "Set new kernel command line arguments in place (applies to all deployments by default)" },
+ { NULL, 0, NULL, NULL }
+};
+
+static GOptionContext *
+ostree_admin_kargs_option_context_new_with_commands (void)
+{
+ OstreeCommand *command = admin_kargs_subcommands;
+ GOptionContext *context = g_option_context_new ("COMMAND");
+
+ g_autoptr(GString) summary = g_string_new ("Builtin \"admin kargs\" Commands:");
+
+ while (command->name != NULL)
+ {
+ if ((command->flags & OSTREE_BUILTIN_FLAG_HIDDEN) == 0)
+ {
+ g_string_append_printf (summary, "\n %-24s", command->name);
+ if (command->description != NULL)
+ g_string_append_printf (summary, "%s", command->description);
+ }
+
+ command++;
+ }
+
+ g_option_context_set_summary (context, summary->str);
+
+ return context;
+}
+
+gboolean
+ot_admin_builtin_kargs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
+{
+ const char *subcommand_name = NULL;
+ int in, out;
+ for (in = 1, out = 1; in < argc; in++, out++)
+ {
+ /* The non-option is the command, take it out of the arguments */
+ if (argv[in][0] != '-')
+ {
+ if (subcommand_name == NULL)
+ {
+ subcommand_name = argv[in];
+ out--;
+ continue;
+ }
+ }
+
+ else if (g_str_equal (argv[in], "--"))
+ {
+ break;
+ }
+
+ argv[out] = argv[in];
+ }
+
+ argc = out;
+
+ OstreeCommand *subcommand = admin_kargs_subcommands;
+ while (subcommand->name)
+ {
+ if (g_strcmp0 (subcommand_name, subcommand->name) == 0)
+ break;
+ subcommand++;
+ }
+
+ if (!subcommand->name)
+ {
+ g_autoptr(GOptionContext) context =
+ ostree_admin_kargs_option_context_new_with_commands ();
+
+ /* This will not return for some options (e.g. --version). */
+ if (ostree_admin_option_context_parse (context, NULL, &argc, &argv,
+ OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT,
+ invocation, NULL, cancellable, error))
+ {
+ if (subcommand_name == NULL)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No \"admin kargs\" subcommand specified");
+ }
+ else
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Unknown \"admin kargs\" subcommand '%s'", subcommand_name);
+ }
+ }
+
+ g_autofree char *help = g_option_context_get_help (context, FALSE, NULL);
+ g_printerr ("%s", help);
+ return FALSE;
+ }
+
+ g_autofree char *prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name);
+ g_set_prgname (prgname);
+
+ OstreeCommandInvocation sub_invocation = { .command = subcommand };
+ if (!subcommand->fn (argc, argv, &sub_invocation, cancellable, error))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/ostree/ot-admin-builtins.h b/src/ostree/ot-admin-builtins.h
index 8d9451be..8bac1c56 100644
--- a/src/ostree/ot-admin-builtins.h
+++ b/src/ostree/ot-admin-builtins.h
@@ -46,6 +46,7 @@ BUILTINPROTO(set_origin);
BUILTINPROTO(diff);
BUILTINPROTO(switch);
BUILTINPROTO(upgrade);
+BUILTINPROTO(kargs);
#undef BUILTINPROTO
diff --git a/src/ostree/ot-admin-kargs-builtin-edit-in-place.c b/src/ostree/ot-admin-kargs-builtin-edit-in-place.c
new file mode 100644
index 00000000..40ada02f
--- /dev/null
+++ b/src/ostree/ot-admin-kargs-builtin-edit-in-place.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Colin Walters <walters@verbum.org>
+ * Copyright (C) 2022 Huijing Hei <hhei@redhat.com>
+ *
+ * This program 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 licence 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 "ot-main.h"
+#include "ot-admin-kargs-builtins.h"
+
+#include "ostree.h"
+#include "otutil.h"
+
+static char **opt_kargs_edit_in_place_append;
+
+static GOptionEntry options[] = {
+ { "append-if-missing", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kargs_edit_in_place_append, "Append kernel arguments if they do not exist", "NAME=VALUE" },
+ { NULL }
+};
+
+gboolean
+ot_admin_kargs_builtin_edit_in_place (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
+{
+ g_autoptr(OstreeSysroot) sysroot = NULL;
+
+ g_autoptr(GOptionContext) context = g_option_context_new ("ARGS");
+
+ if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
+ OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
+ invocation, &sysroot, cancellable, error))
+ return FALSE;
+
+ g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot);
+ if (deployments->len == 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Unable to find a deployment in sysroot");
+ return FALSE;
+ }
+
+ // set kargs for each deployment
+ for (guint i = 0; i < deployments->len; i++)
+ {
+ OstreeDeployment *deployment = deployments->pdata[i];
+ OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment);
+ g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_from_string (ostree_bootconfig_parser_get (bootconfig, "options"));
+
+ if (opt_kargs_edit_in_place_append)
+ {
+ for (char **strviter = opt_kargs_edit_in_place_append; strviter && *strviter; strviter++)
+ {
+ const char *arg = *strviter;
+ ostree_kernel_args_append_if_missing (kargs, arg);
+ }
+ }
+
+ g_auto(GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs);
+
+ if (!ostree_sysroot_deployment_set_kargs (sysroot, deployment,
+ kargs_strv,
+ cancellable, error))
+ return FALSE;
+
+ }
+
+ return TRUE;
+}
diff --git a/src/ostree/ot-admin-kargs-builtins.h b/src/ostree/ot-admin-kargs-builtins.h
new file mode 100644
index 00000000..f3837c34
--- /dev/null
+++ b/src/ostree/ot-admin-kargs-builtins.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Colin Walters <walters@verbum.org>
+ * Copyright (C) 2022 Huijing Hei <hhei@redhat.com>
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#include <ostree.h>
+
+G_BEGIN_DECLS
+
+#define BUILTINPROTO(name) gboolean ot_admin_kargs_builtin_ ## name (int argc, char **argv, \
+ OstreeCommandInvocation *invocation, \
+ GCancellable *cancellable, GError **error)
+
+BUILTINPROTO(edit_in_place);
+
+#undef BUILTINPROTO
+
+G_END_DECLS
diff --git a/src/ostree/ot-builtin-admin.c b/src/ostree/ot-builtin-admin.c
index af09a614..503fb9a7 100644
--- a/src/ostree/ot-builtin-admin.c
+++ b/src/ostree/ot-builtin-admin.c
@@ -76,6 +76,9 @@ static OstreeCommand admin_subcommands[] = {
{ "upgrade", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_upgrade,
"Construct new tree from current origin and deploy it, if it changed" },
+ { "kargs", OSTREE_BUILTIN_FLAG_NO_REPO,
+ ot_admin_builtin_kargs,
+ "Change kernel arguments" },
{ NULL, 0, NULL, NULL }
};
diff --git a/tests/test-admin-kargs.sh b/tests/test-admin-kargs.sh
new file mode 100755
index 00000000..afcfc05a
--- /dev/null
+++ b/tests/test-admin-kargs.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+#
+# Copyright (C) 2011 Colin Walters <walters@verbum.org>
+# Copyright (C) 2022 Huijing Hei <hhei@redhat.com>
+#
+# 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/>.
+
+set -euo pipefail
+
+. $(dirname $0)/libtest.sh
+
+# Exports OSTREE_SYSROOT so --sysroot not needed.
+setup_os_repository "archive" "syslinux"
+
+echo "1..2"
+
+${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime
+${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmain/x86_64-runtime
+${CMD_PREFIX} ostree admin kargs edit-in-place --append-if-missing=TESTARG=TESTVALUE --append-if-missing=ARGWITHOUTKEY testos:testos/buildmain/x86_64-runtime
+
+assert_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'options.*TESTARG=TESTVALUE .*ARGWITHOUTKEY'
+
+echo "ok kargs edit-in-place (basic)"
+
+${CMD_PREFIX} ostree admin kargs edit-in-place --append-if-missing=quiet testos:testos/buildmain/x86_64-runtime
+assert_not_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'quiet$'
+
+${CMD_PREFIX} ostree admin kargs edit-in-place --append-if-missing=TESTARG=TESTVALUE testos:testos/buildmain/x86_64-runtime
+assert_not_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'TESTARG=TESTVALUE$'
+
+echo "ok kargs edit-in-place (duplicate)"