From 6adc9abc4a6958741e9b0242cbee22912e128745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 4 Apr 2026 19:43:04 +0200 Subject: [PATCH] imds: convert to the new option parser Cosmetic changes in --help output only. Co-developed-by: Claude Opus 4.6 --- src/imds/imds-tool.c | 121 ++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 70 deletions(-) diff --git a/src/imds/imds-tool.c b/src/imds/imds-tool.c index ff5a9b317a..0d71801aec 100644 --- a/src/imds/imds-tool.c +++ b/src/imds/imds-tool.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include #include #include @@ -26,6 +25,7 @@ #include "json-util.h" #include "log.h" #include "main-func.h" +#include "options.h" #include "parse-argument.h" #include "pcrextend-util.h" #include "pretty-print.h" @@ -51,148 +51,129 @@ STATIC_DESTRUCTOR_REGISTER(arg_key, freep); static int help(void) { _cleanup_free_ char *link = NULL; + _cleanup_(table_unrefp) Table *options = NULL; int r; r = terminal_urlify_man("systemd-imds", "1", &link); if (r < 0) return log_oom(); + r = option_parser_get_help_table(&options); + if (r < 0) + return r; + printf("%s [OPTIONS...] [KEY]\n" - "\n%sIMDS data acquisition.%s\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " -K --well-known=[hostname|region|zone|ipv4-public|ipv6-public|ssh-key|\n" - " userdata|userdata-base|userdata-base64]\n" - " Select well-known key/base\n" - " --refresh=SEC Set minimum freshness time for returned data\n" - " --cache=no Disable cache use\n" - " -u --userdata Dump user data\n" - " --import Import system credentials from IMDS userdata\n" - " and place them in /run/credstore/\n" - "\nSee the %s for details.\n", + "\n%sIMDS data acquisition.%s\n\n", program_invocation_short_name, ansi_highlight(), - ansi_normal(), - link); + ansi_normal()); + r = table_print_or_warn(options); + if (r < 0) + return r; + + printf("\nSee the %s for details.\n", link); return 0; } static int parse_argv(int argc, char *argv[]) { - - enum { - ARG_VERSION = 0x100, - ARG_REFRESH, - ARG_CACHE, - ARG_IMPORT, - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "well-known", required_argument, NULL, 'K' }, - { "refresh", required_argument, NULL, ARG_REFRESH }, - { "cache", required_argument, NULL, ARG_CACHE }, - { "userdata", no_argument, NULL, 'u' }, - { "import", no_argument, NULL, ARG_IMPORT }, - {} - }; - - int c, r; + int r; assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hK:u", options, NULL)) >= 0) { + OptionParser state = { argc, argv }; + const char *arg; + FOREACH_OPTION(&state, c, &arg, /* on_error= */ return c) switch (c) { - case 'h': + OPTION_COMMON_HELP: return help(); - case ARG_VERSION: + OPTION_COMMON_VERSION: return version(); - case 'K': { - if (isempty(optarg)) { + OPTION('K', "well-known", "KEY", + "Select well-known key/base, one of:" + " hostname, region, zone, ipv4-public, ipv6-public, ssh-key," + " userdata, userdata-base, userdata-base64"): { + if (isempty(arg)) { arg_well_known = _IMDS_WELL_KNOWN_INVALID; break; } - if (streq(optarg, "help")) + if (streq(arg, "help")) return DUMP_STRING_TABLE(imds_well_known, ImdsWellKnown, _IMDS_WELL_KNOWN_MAX); - ImdsWellKnown wk = imds_well_known_from_string(optarg); + ImdsWellKnown wk = imds_well_known_from_string(arg); if (wk < 0) - return log_error_errno(wk, "Failed to parse --well-known= argument: %s", optarg); + return log_error_errno(wk, "Failed to parse --well-known= argument: %s", arg); arg_well_known = wk; break; } - case ARG_CACHE: - r = parse_tristate_argument_with_auto("--cache=", optarg, &arg_cache); - if (r < 0) - return r; - - break; - - case ARG_REFRESH: { - if (isempty(optarg)) { + OPTION_LONG("refresh", "SEC", "Set minimum freshness time for returned data"): { + if (isempty(arg)) { arg_refresh_usec_set = false; break; } usec_t t; - r = parse_sec(optarg, &t); + r = parse_sec(arg, &t); if (r < 0) - return log_error_errno(r, "Failed to parse refresh timeout: %s", optarg); + return log_error_errno(r, "Failed to parse refresh timeout: %s", arg); arg_refresh_usec = t; arg_refresh_usec_set = true; break; } - case 'u': + OPTION_LONG("cache", "BOOL", "Control cache use"): + r = parse_tristate_argument_with_auto("--cache=", arg, &arg_cache); + if (r < 0) + return r; + break; + + OPTION('u', "userdata", NULL, "Dump user data"): arg_action = ACTION_USERDATA; break; - case ARG_IMPORT: + OPTION_LONG("import", NULL, + "Import system credentials from IMDS userdata" + " and place them in /run/credstore/"): arg_action = ACTION_IMPORT; break; - - case '?': - return -EINVAL; - - default: - assert_not_reached(); } - } + + char **args = option_parser_get_args(&state); + size_t n_args = option_parser_get_n_args(&state); if (IN_SET(arg_action, ACTION_USERDATA, ACTION_IMPORT)) { - if (argc != optind) + if (n_args != 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No parameters expected."); } else { assert(arg_action < 0); - if (argc > optind + 1) + if (n_args > 1) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "None or one argument expected."); - if (argc == optind && arg_well_known < 0) + if (n_args == 0 && arg_well_known < 0) arg_action = ACTION_SUMMARY; else { if (arg_well_known < 0) arg_well_known = IMDS_BASE; - if (argc > optind) { - if (!imds_key_is_valid(argv[optind])) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Specified IMDS key is not valid, refusing: %s", argv[optind]); + if (n_args > 0) { + if (!imds_key_is_valid(args[0])) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Specified IMDS key is not valid, refusing: %s", args[0]); if (!imds_well_known_can_suffix(arg_well_known)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Well known key '%s' does not take a key suffix, refusing.", imds_well_known_to_string(arg_well_known)); - r = free_and_strdup_warn(&arg_key, argv[optind]); + r = free_and_strdup_warn(&arg_key, args[0]); if (r < 0) return r; }