]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: add simple --discover command 25564/head
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Nov 2022 15:39:06 +0000 (16:39 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 7 Dec 2022 16:57:22 +0000 (17:57 +0100)
man/systemd-dissect.xml
src/dissect/dissect.c
test/units/testsuite-50.sh

index 2eb8972feed4ec248e468549036874bbe0ecfc19..8c6211b601d09ed9e10883108aead5f39f5493ac 100644 (file)
         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>
index 3a882ee12c32a9c4569f68b42ac852637a85f908..e7ea582300d0e76f44165c1638d3c767c2cbb8ab 100644 (file)
@@ -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,
index a5c1eaba268674cf9fcc14ef21a14e93c4b5106c..031803f5b8cf31808cb4e69a557dcebf48fcc239 100755 (executable)
@@ -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