Merge pull request #25261 from poettering/dissec-uuid
systemd-dissect: show image UUID in output
This commit is contained in:
@@ -85,6 +85,12 @@ All tools:
|
||||
* `$SYSTEMD_MEMPOOL=0` — if set, the internal memory caching logic employed by
|
||||
hash tables is turned off, and libc `malloc()` is used for all allocations.
|
||||
|
||||
* `$SYSTEMD_UTF8=` — takes a boolean value, and overrides whether to generate
|
||||
non-ASCII special glyphs at various places (i.e. "→" instead of
|
||||
"->"). Usually this is deterined automatically, based on $LC_CTYPE, but in
|
||||
scenarios where locale definitions are not installed it might make sense to
|
||||
override this check explicitly.
|
||||
|
||||
* `$SYSTEMD_EMOJI=0` — if set, tools such as `systemd-analyze security` will
|
||||
not output graphical smiley emojis, but ASCII alternatives instead. Note that
|
||||
this only controls use of Unicode emoji glyphs, and has no effect on other
|
||||
|
||||
@@ -286,8 +286,9 @@ void init_gettext(void) {
|
||||
}
|
||||
|
||||
bool is_locale_utf8(void) {
|
||||
const char *set;
|
||||
static int cached_answer = -1;
|
||||
const char *set;
|
||||
int r;
|
||||
|
||||
/* Note that we default to 'true' here, since today UTF8 is
|
||||
* pretty much supported everywhere. */
|
||||
@@ -295,6 +296,13 @@ bool is_locale_utf8(void) {
|
||||
if (cached_answer >= 0)
|
||||
goto out;
|
||||
|
||||
r = getenv_bool_secure("SYSTEMD_UTF8");
|
||||
if (r >= 0) {
|
||||
cached_answer = r;
|
||||
goto out;
|
||||
} else if (r != -ENXIO)
|
||||
log_debug_errno(r, "Failed to parse $SYSTEMD_UTF8, ignoring: %m");
|
||||
|
||||
if (!setlocale(LC_ALL, "")) {
|
||||
cached_answer = true;
|
||||
goto out;
|
||||
|
||||
@@ -568,7 +568,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
pager_open(arg_pager_flags);
|
||||
|
||||
if (arg_json_format_flags & JSON_FORMAT_OFF)
|
||||
printf(" Name: %s\n", bn);
|
||||
printf(" Name: %s%s%s\n", ansi_highlight(), bn, ansi_normal());
|
||||
|
||||
if (ioctl(d->fd, BLKGETSIZE64, &size) < 0)
|
||||
log_debug_errno(errno, "Failed to query size of loopback device: %m");
|
||||
@@ -594,6 +594,9 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
else if (arg_json_format_flags & JSON_FORMAT_OFF) {
|
||||
_cleanup_strv_free_ char **sysext_scopes = NULL;
|
||||
|
||||
if (!sd_id128_is_null(m->image_uuid))
|
||||
printf("Image UUID: %s\n", SD_ID128_TO_UUID_STRING(m->image_uuid));
|
||||
|
||||
if (m->hostname)
|
||||
printf(" Hostname: %s\n", m->hostname);
|
||||
|
||||
@@ -673,6 +676,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
|
||||
|
||||
r = json_build(&v, JSON_BUILD_OBJECT(
|
||||
JSON_BUILD_PAIR("name", JSON_BUILD_STRING(bn)),
|
||||
JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->image_uuid), "imageUuid", JSON_BUILD_UUID(m->image_uuid)),
|
||||
JSON_BUILD_PAIR("size", JSON_BUILD_INTEGER(size)),
|
||||
JSON_BUILD_PAIR_CONDITION(m->hostname, "hostname", JSON_BUILD_STRING(m->hostname)),
|
||||
JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->machine_id), "machineId", JSON_BUILD_ID128(m->machine_id)),
|
||||
|
||||
@@ -349,7 +349,7 @@ static int dissect_image(
|
||||
_cleanup_(blkid_free_probep) blkid_probe b = NULL;
|
||||
_cleanup_free_ char *generic_node = NULL;
|
||||
sd_id128_t generic_uuid = SD_ID128_NULL;
|
||||
const char *pttype = NULL;
|
||||
const char *pttype = NULL, *sptuuid = NULL;
|
||||
blkid_partlist pl;
|
||||
int r, generic_nr = -1, n_partitions;
|
||||
|
||||
@@ -410,7 +410,7 @@ static int dissect_image(
|
||||
if ((flags & DISSECT_IMAGE_GPT_ONLY) == 0) {
|
||||
/* Look for file system superblocks, unless we only shall look for GPT partition tables */
|
||||
blkid_probe_enable_superblocks(b, 1);
|
||||
blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE);
|
||||
blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE|BLKID_SUBLKS_USAGE|BLKID_SUBLKS_UUID);
|
||||
}
|
||||
|
||||
blkid_probe_enable_partitions(b, 1);
|
||||
@@ -433,8 +433,9 @@ static int dissect_image(
|
||||
(void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL);
|
||||
if (STRPTR_IN_SET(usage, "filesystem", "crypto")) {
|
||||
_cleanup_free_ char *t = NULL, *n = NULL, *o = NULL;
|
||||
const char *fstype = NULL, *options = NULL;
|
||||
const char *fstype = NULL, *options = NULL, *suuid = NULL;
|
||||
_cleanup_close_ int mount_node_fd = -1;
|
||||
sd_id128_t uuid = SD_ID128_NULL;
|
||||
|
||||
if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) {
|
||||
mount_node_fd = open_partition(devname, /* is_partition = */ false, m->loop);
|
||||
@@ -444,6 +445,7 @@ static int dissect_image(
|
||||
|
||||
/* OK, we have found a file system, that's our root partition then. */
|
||||
(void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
|
||||
(void) blkid_probe_lookup_value(b, "UUID", &suuid, NULL);
|
||||
|
||||
if (fstype) {
|
||||
t = strdup(fstype);
|
||||
@@ -451,6 +453,15 @@ static int dissect_image(
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (suuid) {
|
||||
/* blkid will return FAT's serial number as UUID, hence it is quite possible
|
||||
* that parsing this will fail. We'll ignore the ID, since it's just too
|
||||
* short to be useful as tru identifier. */
|
||||
r = sd_id128_from_string(suuid, &uuid);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse file system UUID '%s', ignoring: %m", suuid);
|
||||
}
|
||||
|
||||
n = strdup(devname);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
@@ -467,6 +478,8 @@ static int dissect_image(
|
||||
m->verity_sig_ready = m->verity_ready &&
|
||||
verity->root_hash_sig;
|
||||
|
||||
m->image_uuid = uuid;
|
||||
|
||||
options = mount_options_from_designator(mount_options, PARTITION_ROOT);
|
||||
if (options) {
|
||||
o = strdup(options);
|
||||
@@ -515,6 +528,13 @@ static int dissect_image(
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
(void) blkid_probe_lookup_value(b, "PTUUID", &sptuuid, NULL);
|
||||
if (sptuuid) {
|
||||
r = sd_id128_from_string(sptuuid, &m->image_uuid);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse partition table UUID '%s', ignoring: %m", sptuuid);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
pl = blkid_probe_get_partitions(b);
|
||||
if (!pl)
|
||||
|
||||
@@ -229,6 +229,7 @@ struct DissectedImage {
|
||||
|
||||
/* Meta information extracted from /etc/os-release and similar */
|
||||
char *image_name;
|
||||
sd_id128_t image_uuid;
|
||||
char *hostname;
|
||||
sd_id128_t machine_id;
|
||||
char **machine_info;
|
||||
|
||||
@@ -2573,10 +2573,10 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
|
||||
return json_variant_new_array_bytes(ret, &d->address, FAMILY_ADDRESS_SIZE(AF_INET6));
|
||||
|
||||
case TABLE_ID128:
|
||||
return json_variant_new_string(ret, SD_ID128_TO_STRING(d->id128));
|
||||
return json_variant_new_id128(ret, d->id128);
|
||||
|
||||
case TABLE_UUID:
|
||||
return json_variant_new_string(ret, SD_ID128_TO_UUID_STRING(d->id128));
|
||||
return json_variant_new_uuid(ret, d->id128);
|
||||
|
||||
case TABLE_UID:
|
||||
if (!uid_is_valid(d->uid))
|
||||
|
||||
+9
-2
@@ -481,6 +481,10 @@ int json_variant_new_id128(JsonVariant **ret, sd_id128_t id) {
|
||||
return json_variant_new_string(ret, SD_ID128_TO_STRING(id));
|
||||
}
|
||||
|
||||
int json_variant_new_uuid(JsonVariant **ret, sd_id128_t id) {
|
||||
return json_variant_new_string(ret, SD_ID128_TO_UUID_STRING(id));
|
||||
}
|
||||
|
||||
static void json_variant_set(JsonVariant *a, JsonVariant *b) {
|
||||
assert(a);
|
||||
|
||||
@@ -3609,7 +3613,8 @@ int json_buildv(JsonVariant **ret, va_list ap) {
|
||||
break;
|
||||
}
|
||||
|
||||
case _JSON_BUILD_ID128: {
|
||||
case _JSON_BUILD_ID128:
|
||||
case _JSON_BUILD_UUID: {
|
||||
const sd_id128_t *id;
|
||||
|
||||
if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
|
||||
@@ -3620,7 +3625,9 @@ int json_buildv(JsonVariant **ret, va_list ap) {
|
||||
assert_se(id = va_arg(ap, sd_id128_t*));
|
||||
|
||||
if (current->n_suppress == 0) {
|
||||
r = json_variant_new_id128(&add, *id);
|
||||
r = command == _JSON_BUILD_ID128 ?
|
||||
json_variant_new_id128(&add, *id) :
|
||||
json_variant_new_uuid(&add, *id);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ int json_variant_new_array_strv(JsonVariant **ret, char **l);
|
||||
int json_variant_new_object(JsonVariant **ret, JsonVariant **array, size_t n);
|
||||
int json_variant_new_null(JsonVariant **ret);
|
||||
int json_variant_new_id128(JsonVariant **ret, sd_id128_t id);
|
||||
int json_variant_new_uuid(JsonVariant **ret, sd_id128_t id);
|
||||
|
||||
static inline int json_variant_new_string(JsonVariant **ret, const char *s) {
|
||||
return json_variant_new_stringn(ret, s, SIZE_MAX);
|
||||
@@ -251,6 +252,7 @@ enum {
|
||||
_JSON_BUILD_HEX,
|
||||
_JSON_BUILD_OCTESCAPE,
|
||||
_JSON_BUILD_ID128,
|
||||
_JSON_BUILD_UUID,
|
||||
_JSON_BUILD_BYTE_ARRAY,
|
||||
_JSON_BUILD_HW_ADDR,
|
||||
_JSON_BUILD_PAIR_UNSIGNED_NON_ZERO,
|
||||
@@ -288,6 +290,7 @@ enum {
|
||||
#define JSON_BUILD_HEX(p, n) _JSON_BUILD_HEX, (const void*) { p }, (size_t) { n }
|
||||
#define JSON_BUILD_OCTESCAPE(p, n) _JSON_BUILD_OCTESCAPE, (const void*) { p }, (size_t) { n }
|
||||
#define JSON_BUILD_ID128(id) _JSON_BUILD_ID128, (const sd_id128_t*) { &(id) }
|
||||
#define JSON_BUILD_UUID(id) _JSON_BUILD_UUID, (const sd_id128_t*) { &(id) }
|
||||
#define JSON_BUILD_BYTE_ARRAY(v, n) _JSON_BUILD_BYTE_ARRAY, (const void*) { v }, (size_t) { n }
|
||||
#define JSON_BUILD_CONST_STRING(s) _JSON_BUILD_VARIANT, JSON_VARIANT_STRING_CONST(s)
|
||||
#define JSON_BUILD_IN4_ADDR(v) JSON_BUILD_BYTE_ARRAY((const struct in_addr*) { v }, sizeof(struct in_addr))
|
||||
@@ -313,6 +316,7 @@ enum {
|
||||
#define JSON_BUILD_PAIR_BASE64(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_BASE64(p, n))
|
||||
#define JSON_BUILD_PAIR_HEX(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_HEX(p, n))
|
||||
#define JSON_BUILD_PAIR_ID128(name, id) JSON_BUILD_PAIR(name, JSON_BUILD_ID128(id))
|
||||
#define JSON_BUILD_PAIR_UUID(name, id) JSON_BUILD_PAIR(name, JSON_BUILD_UUID(id))
|
||||
#define JSON_BUILD_PAIR_BYTE_ARRAY(name, v, n) JSON_BUILD_PAIR(name, JSON_BUILD_BYTE_ARRAY(v, n))
|
||||
#define JSON_BUILD_PAIR_IN4_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_IN4_ADDR(v))
|
||||
#define JSON_BUILD_PAIR_IN6_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_IN6_ADDR(v))
|
||||
|
||||
@@ -14,6 +14,9 @@ fi
|
||||
export SYSTEMD_LOG_LEVEL=debug
|
||||
export PAGER=cat
|
||||
|
||||
# Disable use of special glyphs such as →
|
||||
export SYSTEMD_UTF8=0
|
||||
|
||||
seed=750b6cd5c4ae4012a15e7be3c29e6a47
|
||||
|
||||
if ! systemd-detect-virt --quiet --container; then
|
||||
@@ -327,7 +330,7 @@ EOF
|
||||
|
||||
output=$(systemd-repart --definitions="$defs" --empty=create --size=100M --json=pretty "$imgs/zzz")
|
||||
|
||||
diff <(echo "$output") - <<EOF
|
||||
diff -u <(echo "$output") - <<EOF
|
||||
[
|
||||
{
|
||||
"type" : "swap",
|
||||
@@ -338,10 +341,10 @@ EOF
|
||||
"offset" : 1048576,
|
||||
"old_size" : 0,
|
||||
"raw_size" : 33554432,
|
||||
"size" : "→ 32.0M",
|
||||
"size" : "-> 32.0M",
|
||||
"old_padding" : 0,
|
||||
"raw_padding" : 0,
|
||||
"padding" : "→ 0B",
|
||||
"padding" : "-> 0B",
|
||||
"activity" : "create",
|
||||
"drop-in_files" : [
|
||||
"$defs/root.conf.d/override1.conf",
|
||||
@@ -382,7 +385,7 @@ EOF
|
||||
|
||||
output=$(systemd-repart --definitions="$defs/1" --definitions="$defs/2" --empty=create --size=100M --json=pretty "$imgs/zzz")
|
||||
|
||||
diff <(echo "$output") - <<EOF
|
||||
diff -u <(echo "$output") - <<EOF
|
||||
[
|
||||
{
|
||||
"type" : "swap",
|
||||
@@ -393,10 +396,10 @@ EOF
|
||||
"offset" : 1048576,
|
||||
"old_size" : 0,
|
||||
"raw_size" : 33554432,
|
||||
"size" : "→ 32.0M",
|
||||
"size" : "-> 32.0M",
|
||||
"old_padding" : 0,
|
||||
"raw_padding" : 0,
|
||||
"padding" : "→ 0B",
|
||||
"padding" : "-> 0B",
|
||||
"activity" : "create"
|
||||
},
|
||||
{
|
||||
@@ -408,10 +411,10 @@ EOF
|
||||
"offset" : 34603008,
|
||||
"old_size" : 0,
|
||||
"raw_size" : 33554432,
|
||||
"size" : "→ 32.0M",
|
||||
"size" : "-> 32.0M",
|
||||
"old_padding" : 0,
|
||||
"raw_padding" : 0,
|
||||
"padding" : "→ 0B",
|
||||
"padding" : "-> 0B",
|
||||
"activity" : "create"
|
||||
}
|
||||
]
|
||||
@@ -766,9 +769,10 @@ EOF
|
||||
|
||||
roothash=$(jq -r ".[] | select(.type == \"root-${architecture}-verity\") | .roothash" <<< "$output")
|
||||
|
||||
# Check that we can dissect, mount and unmount a repart verity image.
|
||||
# Check that we can dissect, mount and unmount a repart verity image. (and that the image UUID is deterministic)
|
||||
|
||||
systemd-dissect "$imgs/verity" --root-hash "$roothash"
|
||||
systemd-dissect "$imgs/verity" --root-hash "$roothash" --json=short | grep -q '"imageUuid":"1d2ce291-7cce-4f7d-bc83-fdb49ad74ebd"'
|
||||
systemd-dissect "$imgs/verity" --root-hash "$roothash" -M "$imgs/mnt"
|
||||
systemd-dissect -U "$imgs/mnt"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user