mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-08 20:58:20 +03:00
Merge pull request #25302 from poettering/dissect-with
dissect: add new --with command for excuting commands with a DDI mounted
This commit is contained in:
commit
0b24845d1f
@ -34,6 +34,9 @@
|
||||
<cmdsynopsis>
|
||||
<command>systemd-dissect <arg choice="opt" rep="repeat">OPTIONS</arg> <option>--list</option> <arg choice="plain"><replaceable>IMAGE</replaceable></arg></command>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-dissect <arg choice="opt" rep="repeat">OPTIONS</arg> <option>--with</option> <arg choice="plain"><replaceable>IMAGE</replaceable></arg> <arg choice="opt" rep="repeat"><replaceable>COMMAND</replaceable></arg></command>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-dissect <arg choice="opt" rep="repeat">OPTIONS</arg> <option>--copy-from</option> <arg choice="plain"><replaceable>IMAGE</replaceable></arg> <arg choice="plain"><replaceable>PATH</replaceable></arg> <arg choice="opt"><replaceable>TARGET</replaceable></arg></command>
|
||||
</cmdsynopsis>
|
||||
@ -160,6 +163,19 @@
|
||||
standard output.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--with</option></term>
|
||||
|
||||
<listitem><para>Runs the specified command with the specified OS image mounted. This will mount the
|
||||
image to a temporary directory, switch the current working directory to it, and invoke the specified
|
||||
command line as child process. Once the process ends it will unmount the image again, and remove the
|
||||
temporary directory. If no command is specified a shell is invoked. The image is mounted writable,
|
||||
use <option>--read-only</option> to switch to read-only operation. The invoked process will have the
|
||||
<varname>$SYSTEMD_DISSECT_ROOT</varname> environment variable set, containing the absolute path name
|
||||
of the temporary mount point, i.e. the same directory that is set as the current working
|
||||
directory.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--copy-from</option></term>
|
||||
<term><option>-x</option></term>
|
||||
@ -294,14 +310,24 @@
|
||||
<xi:include href="standard-options.xml" xpointer="no-legend" />
|
||||
<xi:include href="standard-options.xml" xpointer="json" />
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Exit status</title>
|
||||
|
||||
<para>On success, 0 is returned, a non-zero failure code
|
||||
otherwise.</para>
|
||||
<para>On success, 0 is returned, a non-zero failure code otherwise. If the <option>--with</option>
|
||||
command is used the exit status of the invoked command is propagated.</para>
|
||||
</refsect1>
|
||||
|
||||
|
||||
<refsect1>
|
||||
<title>Examples</title>
|
||||
|
||||
<example>
|
||||
<title>Generate a tarball from an OS disk image</title>
|
||||
|
||||
<programlisting>$ systemd-dissect --with foo.raw tar cz . > foo.tar.gz</programlisting>
|
||||
</example>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "recurse-dir.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
@ -49,6 +50,7 @@ static enum {
|
||||
ACTION_MOUNT,
|
||||
ACTION_UMOUNT,
|
||||
ACTION_LIST,
|
||||
ACTION_WITH,
|
||||
ACTION_COPY_FROM,
|
||||
ACTION_COPY_TO,
|
||||
} arg_action = ACTION_DISSECT;
|
||||
@ -68,8 +70,10 @@ static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||
static PagerFlags arg_pager_flags = 0;
|
||||
static bool arg_legend = true;
|
||||
static bool arg_rmdir = false;
|
||||
static char **arg_argv = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_verity_settings, verity_settings_done);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_argv, strv_freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
@ -83,6 +87,7 @@ static int help(void) {
|
||||
"%1$s [OPTIONS...] --mount IMAGE PATH\n"
|
||||
"%1$s [OPTIONS...] --umount PATH\n"
|
||||
"%1$s [OPTIONS...] --list IMAGE\n"
|
||||
"%1$s [OPTIONS...] --with IMAGE [COMMAND…]\n"
|
||||
"%1$s [OPTIONS...] --copy-from IMAGE PATH [TARGET]\n"
|
||||
"%1$s [OPTIONS...] --copy-to IMAGE [SOURCE] PATH\n\n"
|
||||
"%5$sDissect a Discoverable Disk Image (DDI).%6$s\n\n"
|
||||
@ -113,6 +118,7 @@ static int help(void) {
|
||||
" -U Shortcut for --umount --rmdir\n"
|
||||
" -l --list List all the files and directories of the specified\n"
|
||||
" OS image\n"
|
||||
" --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"
|
||||
"\nSee the %2$s for details.\n",
|
||||
@ -126,12 +132,56 @@ static int help(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int patch_argv(int *argc, char ***argv, char ***buf) {
|
||||
_cleanup_free_ char **l = NULL;
|
||||
char **e;
|
||||
|
||||
assert(argc);
|
||||
assert(*argc >= 0);
|
||||
assert(argv);
|
||||
assert(*argv);
|
||||
assert(buf);
|
||||
|
||||
/* Ugly hack: if --with is included in command line, also insert "--" immediately after it, to make
|
||||
* getopt_long() stop processing switches */
|
||||
|
||||
for (e = *argv + 1; e < *argv + *argc; e++) {
|
||||
assert(*e);
|
||||
|
||||
if (streq(*e, "--with"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (e >= *argv + *argc || streq_ptr(e[1], "--")) {
|
||||
/* No --with used? Or already followed by "--"? Then don't do anything */
|
||||
*buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Insert the extra "--" right after the --with */
|
||||
l = new(char*, *argc + 2);
|
||||
if (!l)
|
||||
return log_oom();
|
||||
|
||||
size_t idx = e - *argv + 1;
|
||||
memcpy(l, *argv, sizeof(char*) * idx); /* copy everything up to and including the --with */
|
||||
l[idx] = (char*) "--"; /* insert "--" */
|
||||
memcpy(l + idx + 1, e + 1, sizeof(char*) * (*argc - idx + 1)); /* copy the rest, including trailing NULL entry */
|
||||
|
||||
(*argc)++;
|
||||
(*argv) = l;
|
||||
|
||||
*buf = TAKE_PTR(l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_NO_PAGER,
|
||||
ARG_NO_LEGEND,
|
||||
ARG_WITH,
|
||||
ARG_DISCARD,
|
||||
ARG_FSCK,
|
||||
ARG_GROWFS,
|
||||
@ -150,6 +200,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND },
|
||||
{ "mount", no_argument, NULL, 'm' },
|
||||
{ "umount", no_argument, NULL, 'u' },
|
||||
{ "with", no_argument, NULL, ARG_WITH },
|
||||
{ "read-only", no_argument, NULL, 'r' },
|
||||
{ "discard", required_argument, NULL, ARG_DISCARD },
|
||||
{ "fsck", required_argument, NULL, ARG_FSCK },
|
||||
@ -166,11 +217,16 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{}
|
||||
};
|
||||
|
||||
_cleanup_free_ char **buf = NULL; /* we use free(), not strv_free() here, as we don't copy the strings here */
|
||||
int c, r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
r = patch_argv(&argc, &argv, &buf);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "hmurMUlxa", options, NULL)) >= 0) {
|
||||
|
||||
switch (c) {
|
||||
@ -222,6 +278,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_flags |= DISSECT_IMAGE_READ_ONLY;
|
||||
break;
|
||||
|
||||
case ARG_WITH:
|
||||
arg_action = ACTION_WITH;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
arg_action = ACTION_COPY_FROM;
|
||||
arg_flags |= DISSECT_IMAGE_READ_ONLY;
|
||||
@ -332,7 +392,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch (arg_action) {
|
||||
@ -403,6 +462,20 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
|
||||
break;
|
||||
|
||||
case ACTION_WITH:
|
||||
if (optind >= argc)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Expected an image file path and an optional command line.");
|
||||
|
||||
arg_image = argv[optind];
|
||||
if (argc > optind + 1) {
|
||||
arg_argv = strv_copy(argv + optind + 1);
|
||||
if (!arg_argv)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
@ -518,6 +591,8 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
"Mach. Info:");
|
||||
strv_pair_print(m->os_release,
|
||||
"OS Release:");
|
||||
strv_pair_print(m->initrd_release,
|
||||
"initrd R.:");
|
||||
strv_pair_print(m->extension_release,
|
||||
" Ext. Rel.:");
|
||||
|
||||
@ -525,6 +600,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
!sd_id128_is_null(m->machine_id) ||
|
||||
!strv_isempty(m->machine_info) ||
|
||||
!strv_isempty(m->os_release) ||
|
||||
!strv_isempty(m->initrd_release) ||
|
||||
!strv_isempty(m->extension_release))
|
||||
putc('\n', stdout);
|
||||
|
||||
@ -535,6 +611,8 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
|
||||
printf(" %s portable service\n",
|
||||
COLOR_MARK_BOOL(strv_env_pairs_get(m->os_release, "PORTABLE_PREFIXES")));
|
||||
printf(" %s initrd\n",
|
||||
COLOR_MARK_BOOL(!strv_isempty(m->initrd_release)));
|
||||
|
||||
r = get_sysext_scopes(m, &sysext_scopes);
|
||||
if (r < 0)
|
||||
@ -549,7 +627,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
|
||||
putc('\n', stdout);
|
||||
} else {
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *mi = NULL, *osr = NULL, *exr = NULL;
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *mi = NULL, *osr = NULL, *irdr = NULL, *exr = NULL;
|
||||
_cleanup_strv_free_ char **sysext_scopes = NULL;
|
||||
|
||||
if (!strv_isempty(m->machine_info)) {
|
||||
@ -564,6 +642,12 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (!strv_isempty(m->initrd_release)) {
|
||||
r = strv_pair_to_json(m->initrd_release, &irdr);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (!strv_isempty(m->extension_release)) {
|
||||
r = strv_pair_to_json(m->extension_release, &exr);
|
||||
if (r < 0)
|
||||
@ -581,9 +665,11 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->machine_id), "machineId", JSON_BUILD_ID128(m->machine_id)),
|
||||
JSON_BUILD_PAIR_CONDITION(mi, "machineInfo", JSON_BUILD_VARIANT(mi)),
|
||||
JSON_BUILD_PAIR_CONDITION(osr, "osRelease", JSON_BUILD_VARIANT(osr)),
|
||||
JSON_BUILD_PAIR_CONDITION(osr, "initrdRelease", JSON_BUILD_VARIANT(irdr)),
|
||||
JSON_BUILD_PAIR_CONDITION(exr, "extensionRelease", JSON_BUILD_VARIANT(exr)),
|
||||
JSON_BUILD_PAIR("useBootableUefi", JSON_BUILD_BOOLEAN(m->partitions[PARTITION_ESP].found)),
|
||||
JSON_BUILD_PAIR_CONDITION(m->has_init_system >= 0, "useBootableContainer", JSON_BUILD_BOOLEAN(m->has_init_system)),
|
||||
JSON_BUILD_PAIR("useInitrd", JSON_BUILD_BOOLEAN(!strv_isempty(m->initrd_release))),
|
||||
JSON_BUILD_PAIR("usePortableService", JSON_BUILD_BOOLEAN(strv_env_pairs_get(m->os_release, "PORTABLE_MATCHES"))),
|
||||
JSON_BUILD_PAIR("useSystemExtension", JSON_BUILD_BOOLEAN(strv_contains(sysext_scopes, "system"))),
|
||||
JSON_BUILD_PAIR("useInitRDExtension", JSON_BUILD_BOOLEAN(strv_contains(sysext_scopes, "initrd"))),
|
||||
@ -958,6 +1044,97 @@ static int action_umount(const char *path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_with(DissectedImage *m, LoopDevice *d) {
|
||||
_cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
|
||||
_cleanup_(rmdir_and_freep) char *created_dir = NULL;
|
||||
_cleanup_free_ char *temp = NULL;
|
||||
int r, rcode;
|
||||
|
||||
r = dissected_image_decrypt_interactively(
|
||||
m, NULL,
|
||||
&arg_verity_settings,
|
||||
arg_flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = tempfn_random_child(NULL, program_invocation_short_name, &temp);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate temporary mount directory: %m");
|
||||
|
||||
r = mkdir_p(temp, 0700);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create mount point: %m");
|
||||
|
||||
created_dir = TAKE_PTR(temp);
|
||||
|
||||
r = dissected_image_mount_and_warn(m, created_dir, UID_INVALID, UID_INVALID, arg_flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
mounted_dir = TAKE_PTR(created_dir);
|
||||
|
||||
r = dissected_image_relinquish(m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to relinquish DM and loopback block devices: %m");
|
||||
|
||||
r = loop_device_flock(d, LOCK_UN);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to unlock loopback block device: %m");
|
||||
|
||||
rcode = safe_fork("(with)", FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, NULL);
|
||||
if (rcode == 0) {
|
||||
/* Child */
|
||||
|
||||
if (chdir(mounted_dir) < 0) {
|
||||
log_error_errno(errno, "Failed to change to '%s' directory: %m", mounted_dir);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (setenv("SYSTEMD_DISSECT_ROOT", mounted_dir, /* overwrite= */ true) < 0) {
|
||||
log_error_errno(errno, "Failed to set $SYSTEMD_DISSECT_ROOT: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strv_isempty(arg_argv)) {
|
||||
const char *sh;
|
||||
|
||||
sh = secure_getenv("SHELL");
|
||||
if (sh) {
|
||||
execvp(sh, STRV_MAKE(sh));
|
||||
log_warning_errno(errno, "Failed to execute $SHELL, falling back to /bin/sh: %m");
|
||||
}
|
||||
|
||||
execl("/bin/sh", "sh", NULL);
|
||||
log_error_errno(errno, "Failed to invoke /bin/sh: %m");
|
||||
} else {
|
||||
execvp(arg_argv[0], arg_argv);
|
||||
log_error_errno(errno, "Failed to execute '%s': %m", arg_argv[0]);
|
||||
}
|
||||
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Let's manually detach everything, to make things synchronous */
|
||||
r = loop_device_flock(d, LOCK_SH);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to lock loopback block device, ignoring: %m");
|
||||
|
||||
r = umount_recursive(mounted_dir, 0);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to unmount '%s', ignoring: %m", mounted_dir);
|
||||
else
|
||||
loop_device_unrelinquish(d); /* Let's try to destroy the loopback device */
|
||||
|
||||
created_dir = TAKE_PTR(mounted_dir);
|
||||
|
||||
if (rmdir(created_dir) < 0)
|
||||
log_warning_errno(r, "Failed to remove directory '%s', ignoring: %m", created_dir);
|
||||
|
||||
temp = TAKE_PTR(created_dir);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
|
||||
_cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
|
||||
@ -1026,6 +1203,10 @@ static int run(int argc, char *argv[]) {
|
||||
r = action_list_or_copy(m, d);
|
||||
break;
|
||||
|
||||
case ACTION_WITH:
|
||||
r = action_with(m, d);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
@ -1296,6 +1296,7 @@ DissectedImage* dissected_image_unref(DissectedImage *m) {
|
||||
free(m->hostname);
|
||||
strv_free(m->machine_info);
|
||||
strv_free(m->os_release);
|
||||
strv_free(m->initrd_release);
|
||||
strv_free(m->extension_release);
|
||||
|
||||
return mfree(m);
|
||||
@ -2771,6 +2772,7 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
|
||||
META_MACHINE_ID,
|
||||
META_MACHINE_INFO,
|
||||
META_OS_RELEASE,
|
||||
META_INITRD_RELEASE,
|
||||
META_EXTENSION_RELEASE,
|
||||
META_HAS_INIT_SYSTEM,
|
||||
_META_MAX,
|
||||
@ -2782,11 +2784,13 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
|
||||
[META_MACHINE_INFO] = "/etc/machine-info\0",
|
||||
[META_OS_RELEASE] = ("/etc/os-release\0"
|
||||
"/usr/lib/os-release\0"),
|
||||
[META_INITRD_RELEASE] = ("/etc/initrd-release\0"
|
||||
"/usr/lib/initrd-release\0"),
|
||||
[META_EXTENSION_RELEASE] = "extension-release\0", /* Used only for logging. */
|
||||
[META_HAS_INIT_SYSTEM] = "has-init-system\0", /* ditto */
|
||||
};
|
||||
|
||||
_cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **extension_release = NULL;
|
||||
_cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **initrd_release = NULL, **extension_release = NULL;
|
||||
_cleanup_close_pair_ int error_pipe[2] = { -1, -1 };
|
||||
_cleanup_(rmdir_and_freep) char *t = NULL;
|
||||
_cleanup_(sigkill_waitp) pid_t child = 0;
|
||||
@ -2982,6 +2986,13 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
|
||||
|
||||
break;
|
||||
|
||||
case META_INITRD_RELEASE:
|
||||
r = load_env_file_pairs(f, "initrd-release", &initrd_release);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to read initrd release file of image: %m");
|
||||
|
||||
break;
|
||||
|
||||
case META_EXTENSION_RELEASE:
|
||||
r = load_env_file_pairs(f, "extension-release", &extension_release);
|
||||
if (r < 0)
|
||||
@ -3024,6 +3035,7 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
|
||||
m->machine_id = machine_id;
|
||||
strv_free_and_replace(m->machine_info, machine_info);
|
||||
strv_free_and_replace(m->os_release, os_release);
|
||||
strv_free_and_replace(m->initrd_release, initrd_release);
|
||||
strv_free_and_replace(m->extension_release, extension_release);
|
||||
m->has_init_system = has_init_system;
|
||||
|
||||
|
@ -233,6 +233,7 @@ struct DissectedImage {
|
||||
sd_id128_t machine_id;
|
||||
char **machine_info;
|
||||
char **os_release;
|
||||
char **initrd_release;
|
||||
char **extension_release;
|
||||
int has_init_system;
|
||||
};
|
||||
|
@ -12,7 +12,6 @@ TEST_INSTALL_VERITY_MINIMAL=1
|
||||
# shellcheck source=test/test-functions
|
||||
. "${TEST_BASE_DIR:?}/test-functions"
|
||||
|
||||
|
||||
command -v mksquashfs >/dev/null 2>&1 || exit 0
|
||||
command -v veritysetup >/dev/null 2>&1 || exit 0
|
||||
command -v sfdisk >/dev/null 2>&1 || exit 0
|
||||
@ -27,6 +26,7 @@ test_append_files() {
|
||||
install_dmevent
|
||||
generate_module_dependencies
|
||||
inst_binary wc
|
||||
inst_binary sha256sum
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
inst_binary openssl
|
||||
fi
|
||||
|
@ -41,6 +41,14 @@ systemd-dissect --json=short "${image}.raw" | grep -q -F '{"rw":"ro","designator
|
||||
systemd-dissect "${image}.raw" | grep -q -F "MARKER=1"
|
||||
systemd-dissect "${image}.raw" | grep -q -F -f <(sed 's/"//g' "$os_release")
|
||||
|
||||
systemd-dissect --list "${image}.raw" | grep -q '^etc/os-release$'
|
||||
|
||||
read -r SHA256SUM1 _ < <(systemd-dissect --copy-from "${image}.raw" etc/os-release | sha256sum)
|
||||
test "$SHA256SUM1" != ""
|
||||
read -r SHA256SUM2 _ < <(systemd-dissect --read-only --with "${image}.raw" sha256sum etc/os-release)
|
||||
test "$SHA256SUM2" != ""
|
||||
test "$SHA256SUM1" = "$SHA256SUM2"
|
||||
|
||||
mv "${image}.verity" "${image}.fooverity"
|
||||
mv "${image}.roothash" "${image}.foohash"
|
||||
systemd-dissect --json=short "${image}.raw" --root-hash="${roothash}" --verity-data="${image}.fooverity" | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
|
||||
|
Loading…
x
Reference in New Issue
Block a user