#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"
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);
break;
case ACTION_INSPECT:
- assert(!c->version);
- assert(!c->initrds);
verb = "add|remove";
break;
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();
+
+ 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);
+
+ 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("%sUsing plugins:%s\n", ansi_underline(), ansi_normal());
- strv_print_full(c->plugins, " ");
- puts("");
+ table_set_ersatz_string(t, TABLE_ERSATZ_UNSET);
- printf("%sPlugin environment:%s\n", ansi_underline(), ansi_normal());
- strv_print_full(c->envp, " ");
- puts("");
+ for (size_t row = 1; row < table_get_rows(t); row++) {
+ _cleanup_free_ char *name = NULL;
- printf("%sPlugin arguments:%s\n", ansi_underline(), ansi_normal());
- joined = strv_join(strv_skip(c->argv, 1), " ");
- printf(" %s\n", strna(joined));
+ name = strdup(table_get_at(t, row, 0));
+ if (!name)
+ return log_oom();
- return 0;
+ 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) {
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"
" 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"
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' },
{ "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;
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;
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 = {
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