mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
kernel-install: Add --json option for inspect verb
In mkosi, we can't use kernel-install directly but we do want to mimick its behavior as much as possible. Let's make that easier by making it easy to fetch data from kernel-install as JSON. To get all the necessary data, we extend the inspect verb to also allow passing in a kernel version and initrds, to mimick the "add" verb. The kernel version is used to determine the "Entry Directory", and in absence of auto-detection of kernel version in kernel-install we have to allow users to pass it. We also add --no-pager while we're at it.
This commit is contained in:
parent
ad6216cbc7
commit
bdd36c003d
@ -40,7 +40,9 @@
|
||||
<command>kernel-install</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">inspect</arg>
|
||||
<arg choice="opt"><replaceable>KERNEL-VERSION</replaceable></arg>
|
||||
<arg choice="opt"><replaceable>KERNEL-IMAGE</replaceable></arg>
|
||||
<arg choice="opt" rep="repeat"><replaceable>INITRD-FILE</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -176,11 +178,14 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>inspect [<replaceable>KERNEL-IMAGE</replaceable>]</command></term>
|
||||
<term>
|
||||
<command>inspect [[<replaceable>KERNEL-VERSION</replaceable>] <replaceable>KERNEL-IMAGE</replaceable>] [<replaceable>INITRD-FILE</replaceable> ...]</command>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Shows the various paths and parameters configured or auto-detected. In particular shows the
|
||||
values of the various <varname>$KERNEL_INSTALL_*</varname> environment variables listed
|
||||
below.</para>
|
||||
below. The <option>--json</option> option can be used to get the output of this verb as a JSON
|
||||
object.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v251"/>
|
||||
</listitem>
|
||||
@ -298,6 +303,8 @@
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
<xi:include href="standard-options.xml" xpointer="no-pager"/>
|
||||
<xi:include href="standard-options.xml" xpointer="json" />
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "find-esp.h"
|
||||
#include "format-table.h"
|
||||
#include "id128-util.h"
|
||||
#include "kernel-image.h"
|
||||
#include "main-func.h"
|
||||
@ -32,6 +33,8 @@ static bool arg_verbose = false;
|
||||
static char *arg_esp_path = NULL;
|
||||
static char *arg_xbootldr_path = NULL;
|
||||
static int arg_make_entry_directory = -1; /* tristate */
|
||||
static PagerFlags arg_pager_flags = 0;
|
||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
|
||||
@ -860,8 +863,6 @@ static int context_build_arguments(Context *c) {
|
||||
break;
|
||||
|
||||
case ACTION_INSPECT:
|
||||
assert(!c->version);
|
||||
assert(!c->initrds);
|
||||
verb = "add|remove";
|
||||
break;
|
||||
|
||||
@ -1081,39 +1082,92 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
|
||||
|
||||
static int verb_inspect(int argc, char *argv[], void *userdata) {
|
||||
Context *c = ASSERT_PTR(userdata);
|
||||
_cleanup_free_ char *joined = NULL;
|
||||
_cleanup_(table_unrefp) Table *t = NULL;
|
||||
int r;
|
||||
|
||||
c->action = ACTION_INSPECT;
|
||||
|
||||
if (argc >= 2) {
|
||||
if (argc == 2) {
|
||||
r = context_set_kernel(c, argv[1]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (argc >= 3) {
|
||||
r = context_set_version(c, argv[1]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = context_set_kernel(c, argv[2]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = context_set_initrds(c, strv_skip(argv, 3));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = context_prepare_execution(c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%sBoot Loader Entries:%s\n", ansi_underline(), ansi_normal());
|
||||
printf(" $BOOT: %s\n", c->boot_root);
|
||||
printf(" Token: %s\n", c->entry_token);
|
||||
puts("");
|
||||
t = table_new_vertical();
|
||||
if (!t)
|
||||
return log_oom();
|
||||
|
||||
printf("%sUsing plugins:%s\n", ansi_underline(), ansi_normal());
|
||||
strv_print_full(c->plugins, " ");
|
||||
puts("");
|
||||
r = table_add_many(t,
|
||||
TABLE_FIELD, "Machine ID",
|
||||
TABLE_ID128, c->machine_id,
|
||||
TABLE_FIELD, "Kernel Image Type",
|
||||
TABLE_STRING, kernel_image_type_to_string(c->kernel_image_type),
|
||||
TABLE_FIELD, "Layout",
|
||||
TABLE_STRING, context_get_layout(c),
|
||||
TABLE_FIELD, "Boot Root",
|
||||
TABLE_STRING, c->boot_root,
|
||||
TABLE_FIELD, "Entry Token Type",
|
||||
TABLE_STRING, boot_entry_token_type_to_string(c->entry_token_type),
|
||||
TABLE_FIELD, "Entry Token",
|
||||
TABLE_STRING, c->entry_token,
|
||||
TABLE_FIELD, "Entry Directory",
|
||||
TABLE_STRING, c->entry_dir,
|
||||
TABLE_FIELD, "Kernel Version",
|
||||
TABLE_STRING, c->version,
|
||||
TABLE_FIELD, "Kernel",
|
||||
TABLE_STRING, c->kernel,
|
||||
TABLE_FIELD, "Initrds",
|
||||
TABLE_STRV, c->initrds,
|
||||
TABLE_FIELD, "Initrd Generator",
|
||||
TABLE_STRING, c->initrd_generator,
|
||||
TABLE_FIELD, "UKI Generator",
|
||||
TABLE_STRING, c->uki_generator,
|
||||
TABLE_FIELD, "Plugins",
|
||||
TABLE_STRV, c->plugins,
|
||||
TABLE_FIELD, "Plugin Environment",
|
||||
TABLE_STRV, c->envp);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
printf("%sPlugin environment:%s\n", ansi_underline(), ansi_normal());
|
||||
strv_print_full(c->envp, " ");
|
||||
puts("");
|
||||
if (arg_json_format_flags & JSON_FORMAT_OFF) {
|
||||
r = table_add_many(t,
|
||||
TABLE_FIELD, "Plugin Arguments",
|
||||
TABLE_STRV, strv_skip(c->argv, 1));
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
printf("%sPlugin arguments:%s\n", ansi_underline(), ansi_normal());
|
||||
joined = strv_join(strv_skip(c->argv, 1), " ");
|
||||
printf(" %s\n", strna(joined));
|
||||
table_set_ersatz_string(t, TABLE_ERSATZ_UNSET);
|
||||
|
||||
return 0;
|
||||
for (size_t row = 1; row < table_get_rows(t); row++) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
|
||||
name = strdup(table_get_at(t, row, 0));
|
||||
if (!name)
|
||||
return log_oom();
|
||||
|
||||
r = table_set_json_field_name(t, row - 1, delete_chars(name, " "));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set JSON field name: %m");
|
||||
}
|
||||
|
||||
return table_print_with_pager(t, arg_json_format_flags, arg_pager_flags, /* show_header= */ false);
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
@ -1127,9 +1181,9 @@ static int help(void) {
|
||||
printf("%1$s [OPTIONS...] COMMAND ...\n\n"
|
||||
"%2$sAdd and remove kernel and initrd images to and from /boot%3$s\n"
|
||||
"\nUsage:\n"
|
||||
" kernel-install [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE...]\n"
|
||||
" kernel-install [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD ...]\n"
|
||||
" kernel-install [OPTIONS...] remove KERNEL-VERSION\n"
|
||||
" kernel-install [OPTIONS...] inspect [KERNEL-IMAGE]\n"
|
||||
" kernel-install [OPTIONS...] inspect [KERNEL-VERSION] KERNEL-IMAGE [INITRD ...]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -h --help Show this help\n"
|
||||
@ -1141,6 +1195,9 @@ static int help(void) {
|
||||
" Create $BOOT/ENTRY-TOKEN/ directory\n"
|
||||
" --entry-token=machine-id|os-id|os-image-id|auto|literal:…\n"
|
||||
" Entry token to use for this installation\n"
|
||||
" --no-pager Do not pipe inspect output into a pager\n"
|
||||
" --json=pretty|short|off\n"
|
||||
" Generate JSON output\n"
|
||||
"\n"
|
||||
"This program may also be invoked as 'installkernel':\n"
|
||||
" installkernel [OPTIONS...] VERSION VMLINUZ [MAP] [INSTALLATION-DIR]\n"
|
||||
@ -1162,6 +1219,8 @@ static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
ARG_BOOT_PATH,
|
||||
ARG_MAKE_ENTRY_DIRECTORY,
|
||||
ARG_ENTRY_TOKEN,
|
||||
ARG_NO_PAGER,
|
||||
ARG_JSON,
|
||||
};
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
@ -1171,6 +1230,8 @@ static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
{ "boot-path", required_argument, NULL, ARG_BOOT_PATH },
|
||||
{ "make-entry-directory", required_argument, NULL, ARG_MAKE_ENTRY_DIRECTORY },
|
||||
{ "entry-token", required_argument, NULL, ARG_ENTRY_TOKEN },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{}
|
||||
};
|
||||
int t, r;
|
||||
@ -1222,6 +1283,16 @@ static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
return r;
|
||||
break;
|
||||
|
||||
case ARG_NO_PAGER:
|
||||
arg_pager_flags |= PAGER_DISABLE;
|
||||
break;
|
||||
|
||||
case ARG_JSON:
|
||||
r = parse_json_argument(optarg, &arg_json_format_flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -1236,7 +1307,7 @@ static int run(int argc, char* argv[]) {
|
||||
static const Verb verbs[] = {
|
||||
{ "add", 3, VERB_ANY, 0, verb_add },
|
||||
{ "remove", 2, VERB_ANY, 0, verb_remove },
|
||||
{ "inspect", 1, 2, VERB_DEFAULT, verb_inspect },
|
||||
{ "inspect", 1, VERB_ANY, VERB_DEFAULT, verb_inspect },
|
||||
{}
|
||||
};
|
||||
_cleanup_(context_done) Context c = {
|
||||
|
@ -269,3 +269,40 @@ test -d "$BOOT_ROOT/hoge/1.1.1"
|
||||
test ! -e "$BOOT_ROOT/hoge/1.1.1"
|
||||
test -d "$BOOT_ROOT/hoge"
|
||||
rmdir "$BOOT_ROOT/hoge"
|
||||
|
||||
###########################################
|
||||
# tests for --json=
|
||||
###########################################
|
||||
output="$("$kernel_install" -v --json=pretty inspect 1.1.1 "$D/sources/linux")"
|
||||
|
||||
diff -u <(echo "$output") - <<EOF
|
||||
{
|
||||
"MachineID" : "3e0484f3634a418b8e6a39e8828b03e3",
|
||||
"KernelImageType" : "unknown",
|
||||
"Layout" : "other",
|
||||
"BootRoot" : "$BOOT_ROOT",
|
||||
"EntryTokenType" : "literal",
|
||||
"EntryToken" : "the-token",
|
||||
"EntryDirectory" : "$BOOT_ROOT/the-token/1.1.1",
|
||||
"KernelVersion" : "1.1.1",
|
||||
"Kernel" : "$D/sources/linux",
|
||||
"Initrds" : null,
|
||||
"InitrdGenerator" : "none",
|
||||
"UKIGenerator" : null,
|
||||
"Plugins" : [
|
||||
"$D/00-skip.install"
|
||||
],
|
||||
"PluginEnvironment" : [
|
||||
"LC_COLLATE=C.UTF-8",
|
||||
"KERNEL_INSTALL_VERBOSE=1",
|
||||
"KERNEL_INSTALL_IMAGE_TYPE=unknown",
|
||||
"KERNEL_INSTALL_MACHINE_ID=3e0484f3634a418b8e6a39e8828b03e3",
|
||||
"KERNEL_INSTALL_ENTRY_TOKEN=the-token",
|
||||
"KERNEL_INSTALL_BOOT_ROOT=$BOOT_ROOT",
|
||||
"KERNEL_INSTALL_LAYOUT=other",
|
||||
"KERNEL_INSTALL_INITRD_GENERATOR=none",
|
||||
"KERNEL_INSTALL_UKI_GENERATOR=",
|
||||
"KERNEL_INSTALL_STAGING_AREA=/tmp/kernel-install.staging.XXXXXX"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
Loading…
Reference in New Issue
Block a user