Skip to content

Commit

Permalink
RFE: Add a hidden option to ostree admin kargs edit-in-place to
Browse files Browse the repository at this point in the history
update all existing deployments in place

Example:
$ sudo ostree admin kargs edit-in-place --append-if-missing=rw
See ostreedev#2617

This will not add duplicate key, if there is `TESTARG=VAL1` in the
kernel arguments, `--append-if-missing=TESTARG=VAL2` will be ignored.
  • Loading branch information
HuijingHei committed Jun 23, 2022
1 parent b04c436 commit 3bc59a5
Show file tree
Hide file tree
Showing 13 changed files with 338 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Makefile-libostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
3 changes: 3 additions & 0 deletions Makefile-ostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions Makefile-tests.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions apidoc/ostree-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/libostree/libostree-devel.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 25 additions & 0 deletions src/libostree/ostree-kernel-args.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
4 changes: 4 additions & 0 deletions src/libostree/ostree-kernel-args.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
134 changes: 134 additions & 0 deletions src/ostree/ot-admin-builtin-kargs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright (C) 2015 Colin Walters <[email protected]>
* Copyright (C) 2022 Huijing Hei <[email protected]>
*
* 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;
}
1 change: 1 addition & 0 deletions src/ostree/ot-admin-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ BUILTINPROTO(set_origin);
BUILTINPROTO(diff);
BUILTINPROTO(switch);
BUILTINPROTO(upgrade);
BUILTINPROTO(kargs);

#undef BUILTINPROTO

Expand Down
80 changes: 80 additions & 0 deletions src/ostree/ot-admin-kargs-builtin-edit-in-place.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (C) 2014 Colin Walters <[email protected]>
* Copyright (C) 2022 Huijing Hei <[email protected]>
*
* 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;
}
35 changes: 35 additions & 0 deletions src/ostree/ot-admin-kargs-builtins.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2014 Colin Walters <[email protected]>
* Copyright (C) 2022 Huijing Hei <[email protected]>
*
* 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
3 changes: 3 additions & 0 deletions src/ostree/ot-builtin-admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
};

Expand Down
Loading

0 comments on commit 3bc59a5

Please sign in to comment.