os-util: split extension_release_validate out of sysext

This commit is contained in:
Luca Boccassi
2021-02-17 21:45:31 +00:00
parent bcf94222a5
commit 7eda2d7fa5
3 changed files with 109 additions and 53 deletions
+67
View File
@@ -3,6 +3,7 @@
#include "alloc-util.h"
#include "discover-image.h"
#include "env-file.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
@@ -192,3 +193,69 @@ int load_extension_release_pairs(const char *root, const char *extension, char *
return load_env_file_pairs(f, p, ret);
}
int extension_release_validate(
const char *name,
const char *host_os_release_id,
const char *host_os_release_version_id,
const char *host_os_release_sysext_level,
char **extension_release) {
const char *extension_release_id = NULL, *extension_release_sysext_level = NULL;
assert(name);
assert(!isempty(host_os_release_id));
assert(!isempty(host_os_release_version_id) || !isempty(host_os_release_sysext_level));
/* Now that we can look into the extension image, let's see if the OS version is compatible */
if (strv_isempty(extension_release)) {
log_debug("Extension '%s' carries no extension-release data, ignoring extension.", name);
return 0;
}
extension_release_id = strv_env_pairs_get(extension_release, "ID");
if (isempty(extension_release_id)) {
log_debug("Extension '%s' does not contain ID in extension-release but requested to match '%s'",
name, strna(host_os_release_id));
return 0;
}
if (!streq_ptr(host_os_release_id, extension_release_id)) {
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'.",
name, strna(extension_release_id), strna(host_os_release_id));
return 0;
}
/* If the extension has a sysext API level declared, then it must match the host API
* level. Otherwise, compare OS version as a whole */
extension_release_sysext_level = strv_env_pairs_get(extension_release, "SYSEXT_LEVEL");
if (!isempty(host_os_release_sysext_level) && !isempty(extension_release_sysext_level)) {
if (!streq_ptr(host_os_release_sysext_level, extension_release_sysext_level)) {
log_debug("Extension '%s' is for sysext API level '%s', but running on sysext API level '%s'",
name, strna(extension_release_sysext_level), strna(host_os_release_sysext_level));
return 0;
}
} else if (!isempty(host_os_release_version_id)) {
const char *extension_release_version_id;
extension_release_version_id = strv_env_pairs_get(extension_release, "VERSION_ID");
if (isempty(extension_release_version_id)) {
log_debug("Extension '%s' does not contain VERSION_ID in extension-release but requested to match '%s'",
name, strna(host_os_release_version_id));
return 0;
}
if (!streq_ptr(host_os_release_version_id, extension_release_version_id)) {
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'.",
name, strna(extension_release_version_id), strna(host_os_release_version_id));
return 0;
}
} else if (isempty(host_os_release_version_id) && isempty(host_os_release_sysext_level)) {
/* Rolling releases do not typically set VERSION_ID (eg: ArchLinux) */
log_debug("No version info on the host (rolling release?), but ID in %s matched.", name);
return 1;
}
log_debug("Version info of extension '%s' matches host.", name);
return 1;
}