summaryrefslogtreecommitdiff
path: root/src/ostree/ot-admin-kargs-builtin-edit-in-place.c
blob: f7125e2cf48a5c4a9f7391a3666727381cf11a35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
 * 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_autofree char *new_options = ostree_kernel_args_to_string (kargs);

      if (!ostree_sysroot_deployment_set_kargs_in_place (sysroot, deployment, new_options,
                                                         cancellable, error))
        return FALSE;

    }

  return TRUE;
}