From: Luca Boccassi Date: Wed, 27 Jan 2021 13:03:37 +0000 (+0000) Subject: dissect: parse, store and show extension-release info X-Git-Tag: v248-rc1~66^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7718ac97219d3bcfcc79b5a10e3e46c2099154d5;p=thirdparty%2Fsystemd.git dissect: parse, store and show extension-release info --- diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index f8f34dcc4dd..85102d3efa4 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -412,13 +412,23 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) { *p, *q); } + if (!strv_isempty(m->extension_release)) { + char **p, **q; + + STRV_FOREACH_PAIR(p, q, m->extension_release) + printf("%s %s=%s\n", + p == m->extension_release ? "Extension Release:" : " ", + *p, *q); + } + if (m->hostname || !sd_id128_is_null(m->machine_id) || !strv_isempty(m->machine_info) || + !strv_isempty(m->extension_release) || !strv_isempty(m->os_release)) putc('\n', stdout); } else { - _cleanup_(json_variant_unrefp) JsonVariant *mi = NULL, *osr = NULL; + _cleanup_(json_variant_unrefp) JsonVariant *mi = NULL, *osr = NULL, *exr = NULL; if (!strv_isempty(m->machine_info)) { r = strv_pair_to_json(m->machine_info, &mi); @@ -432,13 +442,20 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) { return log_oom(); } + if (!strv_isempty(m->extension_release)) { + r = strv_pair_to_json(m->extension_release, &exr); + if (r < 0) + return log_oom(); + } + r = json_build(&v, JSON_BUILD_OBJECT( JSON_BUILD_PAIR("name", JSON_BUILD_STRING(basename(arg_image))), 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)), 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, "osRelease", JSON_BUILD_VARIANT(osr)), + JSON_BUILD_PAIR_CONDITION(exr, "extensionRelease", JSON_BUILD_VARIANT(exr)))); if (r < 0) return log_oom(); } diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index d557b46e909..2799f4f268e 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -23,6 +23,7 @@ #include "def.h" #include "device-nodes.h" #include "device-util.h" +#include "discover-image.h" #include "dissect-image.h" #include "dm-util.h" #include "env-file.h" @@ -1230,6 +1231,7 @@ DissectedImage* dissected_image_unref(DissectedImage *m) { free(m->hostname); strv_free(m->machine_info); strv_free(m->os_release); + strv_free(m->extension_release); return mfree(m); } @@ -1400,7 +1402,7 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, /* Returns: * * -ENXIO → No root partition found - * -EMEDIUMTYPE → DISSECT_IMAGE_VALIDATE_OS set but no os-release file found + * -EMEDIUMTYPE → DISSECT_IMAGE_VALIDATE_OS set but no os-release/extension-release file found * -EUNATCH → Encrypted partition found for which no dm-crypt was set up yet * -EUCLEAN → fsck for file system failed * -EBUSY → File system already mounted/used elsewhere (kernel) @@ -1430,8 +1432,13 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, r = path_is_os_tree(where); if (r < 0) return r; - if (r == 0) - return -EMEDIUMTYPE; + if (r == 0) { + r = path_is_extension_tree(where, m->image_name); + if (r < 0) + return r; + if (r == 0) + return -EMEDIUMTYPE; + } } } @@ -1511,7 +1518,7 @@ int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t u if (r == -ENXIO) return log_error_errno(r, "Not root file system found in image."); if (r == -EMEDIUMTYPE) - return log_error_errno(r, "No suitable os-release file in image found."); + return log_error_errno(r, "No suitable os-release/extension-release file in image found."); if (r == -EUNATCH) return log_error_errno(r, "Encrypted file system discovered, but decryption not requested."); if (r == -EUCLEAN) @@ -2237,18 +2244,20 @@ int dissected_image_acquire_metadata(DissectedImage *m) { META_MACHINE_ID, META_MACHINE_INFO, META_OS_RELEASE, + META_EXTENSION_RELEASE, _META_MAX, }; - static const char *const paths[_META_MAX] = { - [META_HOSTNAME] = "/etc/hostname\0", - [META_MACHINE_ID] = "/etc/machine-id\0", - [META_MACHINE_INFO] = "/etc/machine-info\0", - [META_OS_RELEASE] = ("/etc/os-release\0" - "/usr/lib/os-release\0"), + static const char *paths[_META_MAX] = { + [META_HOSTNAME] = "/etc/hostname\0", + [META_MACHINE_ID] = "/etc/machine-id\0", + [META_MACHINE_INFO] = "/etc/machine-info\0", + [META_OS_RELEASE] = ("/etc/os-release\0" + "/usr/lib/os-release\0"), + [META_EXTENSION_RELEASE] = NULL, }; - _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL; + _cleanup_strv_free_ char **machine_info = NULL, **os_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; @@ -2262,11 +2271,21 @@ int dissected_image_acquire_metadata(DissectedImage *m) { assert(m); - for (; n_meta_initialized < _META_MAX; n_meta_initialized ++) + /* As per the os-release spec, if the image is an extension it will have a file + * named after the image name in extension-release.d/ */ + if (m->image_name) + paths[META_EXTENSION_RELEASE] = strjoina("/usr/lib/extension-release.d/extension-release.", m->image_name); + else + log_debug("No image name available, will skip extension-release metadata"); + + for (; n_meta_initialized < _META_MAX; n_meta_initialized ++) { + if (!paths[n_meta_initialized]) + continue; if (pipe2(fds + 2*n_meta_initialized, O_CLOEXEC) < 0) { r = -errno; goto finish; } + } r = mkdtemp_malloc("/tmp/dissect-XXXXXX", &t); if (r < 0) @@ -2296,6 +2315,9 @@ int dissected_image_acquire_metadata(DissectedImage *m) { _cleanup_close_ int fd = -ENOENT; const char *p; + if (!paths[k]) + continue; + fds[2*k] = safe_close(fds[2*k]); NULSTR_FOREACH(p, paths[k]) { @@ -2326,6 +2348,9 @@ int dissected_image_acquire_metadata(DissectedImage *m) { for (k = 0; k < _META_MAX; k++) { _cleanup_fclose_ FILE *f = NULL; + if (!paths[k]) + continue; + fds[2*k+1] = safe_close(fds[2*k+1]); f = take_fdopen(&fds[2*k], "r"); @@ -2376,6 +2401,13 @@ int dissected_image_acquire_metadata(DissectedImage *m) { log_debug_errno(r, "Failed to read OS release file: %m"); break; + + case META_EXTENSION_RELEASE: + r = load_env_file_pairs(f, "extension-release", &extension_release); + if (r < 0) + log_debug_errno(r, "Failed to read extension release file: %m"); + + break; } } @@ -2399,10 +2431,14 @@ int dissected_image_acquire_metadata(DissectedImage *m) { 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->extension_release, extension_release); finish: - for (k = 0; k < n_meta_initialized; k++) + for (k = 0; k < n_meta_initialized; k++) { + if (!paths[k]) + continue; safe_close_pair(fds + 2*k); + } return r; } diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index fc120b29b47..89078500007 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -102,6 +102,7 @@ struct DissectedImage { sd_id128_t machine_id; char **machine_info; char **os_release; + char **extension_release; }; struct MountOptions {