diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-11-29 16:39:06 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-12-07 17:57:22 +0100 |
commit | 0305cf6e9d208067d249898f1d7bf638f27020fb (patch) | |
tree | c35ef3e348d9dec2384e2e5b0a8b32e1e4512c2b | |
parent | discover-image: store image class in Image object too, if known (diff) | |
download | systemd-0305cf6e9d208067d249898f1d7bf638f27020fb.tar.xz systemd-0305cf6e9d208067d249898f1d7bf638f27020fb.zip |
dissect: add simple --discover command
-rw-r--r-- | man/systemd-dissect.xml | 11 | ||||
-rw-r--r-- | src/dissect/dissect.c | 66 | ||||
-rwxr-xr-x | test/units/testsuite-50.sh | 9 |
3 files changed, 86 insertions, 0 deletions
diff --git a/man/systemd-dissect.xml b/man/systemd-dissect.xml index 2eb8972fee..8c6211b601 100644 --- a/man/systemd-dissect.xml +++ b/man/systemd-dissect.xml @@ -230,6 +230,17 @@ operation begins.</para></listitem> </varlistentry> + <varlistentry> + <term><option>--discover</option></term> + + <listitem><para>Show a list of DDIs in well known directories. This will show machine, portable + service and system extension disk images in the usual directories + <filename>/usr/lib/machines/</filename>, <filename>/usr/lib/portables/</filename>, + <filename>/usr/lib/extensions/</filename>, <filename>/var/lib/machines/</filename>, + <filename>/var/lib/portables/</filename>, <filename>/var/lib/extensions/</filename> and so + on.</para></listitem> + </varlistentry> + <xi:include href="standard-options.xml" xpointer="help" /> <xi:include href="standard-options.xml" xpointer="version" /> </variablelist> diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 3a882ee12c..e7ea582300 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -17,6 +17,7 @@ #include "copy.h" #include "device-util.h" #include "devnum-util.h" +#include "discover-image.h" #include "dissect-image.h" #include "env-util.h" #include "escape.h" @@ -56,6 +57,7 @@ static enum { ACTION_WITH, ACTION_COPY_FROM, ACTION_COPY_TO, + ACTION_DISCOVER, } arg_action = ACTION_DISSECT; static const char *arg_image = NULL; static const char *arg_path = NULL; @@ -128,6 +130,7 @@ static int help(void) { " --with Mount, run command, unmount\n" " -x --copy-from Copy files from image to host\n" " -a --copy-to Copy files from host to image\n" + " --discover Discover DDIs in well known directories\n" "\nSee the %2$s for details.\n", program_invocation_short_name, link, @@ -199,6 +202,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_RMDIR, ARG_JSON, ARG_MTREE, + ARG_DISCOVER, }; static const struct option options[] = { @@ -223,6 +227,7 @@ static int parse_argv(int argc, char *argv[]) { { "copy-from", no_argument, NULL, 'x' }, { "copy-to", no_argument, NULL, 'a' }, { "json", required_argument, NULL, ARG_JSON }, + { "discover", no_argument, NULL, ARG_DISCOVER }, {} }; @@ -400,6 +405,10 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_DISCOVER: + arg_action = ACTION_DISCOVER; + break; + case '?': return -EINVAL; @@ -491,6 +500,13 @@ static int parse_argv(int argc, char *argv[]) { break; + case ACTION_DISCOVER: + if (optind != argc) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Expected no argument."); + + break; + default: assert_not_reached(); } @@ -1325,6 +1341,54 @@ static int action_with(DissectedImage *m, LoopDevice *d) { return rcode; } +static int action_discover(void) { + _cleanup_(hashmap_freep) Hashmap *images = NULL; + _cleanup_(table_unrefp) Table *t = NULL; + Image *img; + int r; + + images = hashmap_new(&image_hash_ops); + if (!images) + return log_oom(); + + for (ImageClass cl = 0; cl < _IMAGE_CLASS_MAX; cl++) { + r = image_discover(cl, NULL, images); + if (r < 0) + return log_error_errno(r, "Failed to discover images: %m"); + } + + if ((arg_json_format_flags & JSON_FORMAT_OFF) && hashmap_isempty(images)) { + log_info("No images found."); + return 0; + } + + t = table_new("name", "type", "class", "ro", "path", "time", "usage"); + if (!t) + return log_oom(); + + HASHMAP_FOREACH(img, images) { + + if (!IN_SET(img->type, IMAGE_RAW, IMAGE_BLOCK)) + continue; + + r = table_add_many( + t, + TABLE_STRING, img->name, + TABLE_STRING, image_type_to_string(img->type), + TABLE_STRING, image_class_to_string(img->class), + TABLE_BOOLEAN, img->read_only, + TABLE_PATH, img->path, + TABLE_TIMESTAMP, img->mtime != 0 ? img->mtime : img->crtime, + TABLE_SIZE, img->usage); + if (r < 0) + return table_log_add_error(r); + } + + (void) table_set_sort(t, (size_t) 0); + + return table_print_with_pager(t, arg_json_format_flags, arg_pager_flags, arg_legend); +} + static int run(int argc, char *argv[]) { _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; _cleanup_(loop_device_unrefp) LoopDevice *d = NULL; @@ -1338,6 +1402,8 @@ static int run(int argc, char *argv[]) { if (arg_action == ACTION_UMOUNT) return action_umount(arg_path); + if (arg_action == ACTION_DISCOVER) + return action_discover(); r = verity_settings_load( &arg_verity_settings, diff --git a/test/units/testsuite-50.sh b/test/units/testsuite-50.sh index a5c1eaba26..031803f5b8 100755 --- a/test/units/testsuite-50.sh +++ b/test/units/testsuite-50.sh @@ -409,6 +409,15 @@ systemd-sysext unmerge rmdir /etc/extensions/app-nodistro rm /var/lib/extensions/app-nodistro.raw +mkdir -p /run/machines /run/portables /run/extensions +touch /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw + +systemd-dissect --discover --json=short > /tmp/discover.json +grep -q -F '{"name":"a","type":"raw","class":"machine","ro":false,"path":"/run/machines/a.raw"' /tmp/discover.json +grep -q -F '{"name":"b","type":"raw","class":"portable","ro":false,"path":"/run/portables/b.raw"' /tmp/discover.json +grep -q -F '{"name":"c","type":"raw","class":"extension","ro":false,"path":"/run/extensions/c.raw"' /tmp/discover.json +rm /tmp/discover.json /run/machines/a.raw /run/portables/b.raw /run/extensions/c.raw + echo OK >/testok exit 0 |