diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-06-25 09:22:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-25 09:22:50 +0200 |
commit | a2e2917162e7ca587cbad94b5366f5cee0385b29 (patch) | |
tree | 83181f2197b2c1e2fbe26b15ade4f75a3abd7f32 /src/shared/condition.c | |
parent | tree-wide: make specifier expansion --root= aware (diff) | |
parent | core: add ConditionOSRelease= directive (diff) | |
download | systemd-a2e2917162e7ca587cbad94b5366f5cee0385b29.tar.xz systemd-a2e2917162e7ca587cbad94b5366f5cee0385b29.zip |
Merge pull request #19941 from bluca/condition_os_release
core: add ConditionOSRelease= directive
Diffstat (limited to 'src/shared/condition.c')
-rw-r--r-- | src/shared/condition.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/shared/condition.c b/src/shared/condition.c index 55fb636673..ec9d57b292 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -24,6 +24,7 @@ #include "cpu-set-util.h" #include "efi-loader.h" #include "env-file.h" +#include "env-util.h" #include "extract-word.h" #include "fd-util.h" #include "fileio.h" @@ -35,6 +36,7 @@ #include "list.h" #include "macro.h" #include "mountpoint-util.h" +#include "os-util.h" #include "parse-util.h" #include "path-util.h" #include "proc-cmdline.h" @@ -263,6 +265,61 @@ static int condition_test_kernel_version(Condition *c, char **env) { return true; } +static int condition_test_osrelease(Condition *c, char **env) { + const char *parameter = c->parameter; + int r; + + assert(c); + assert(c->parameter); + assert(c->type == CONDITION_OS_RELEASE); + + for (;;) { + _cleanup_free_ char *key = NULL, *condition = NULL, *actual_value = NULL; + OrderOperator order; + const char *word; + bool matches; + + r = extract_first_word(¶meter, &condition, NULL, EXTRACT_UNQUOTE); + if (r < 0) + return log_debug_errno(r, "Failed to parse parameter: %m"); + if (r == 0) + break; + + /* parse_order() needs the string to start with the comparators */ + word = condition; + r = extract_first_word(&word, &key, "!<=>", EXTRACT_RETAIN_SEPARATORS); + if (r < 0) + return log_debug_errno(r, "Failed to parse parameter: %m"); + /* The os-release spec mandates env-var-like key names */ + if (r == 0 || isempty(word) || !env_name_is_valid(key)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "Failed to parse parameter, key/value format expected: %m"); + + /* Do not allow whitespace after the separator, as that's not a valid os-release format */ + order = parse_order(&word); + if (order < 0 || isempty(word) || strchr(WHITESPACE, *word) != NULL) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "Failed to parse parameter, key/value format expected: %m"); + + r = parse_os_release(NULL, key, &actual_value); + if (r < 0) + return log_debug_errno(r, "Failed to parse os-release: %m"); + + /* Might not be comparing versions, so do exact string matching */ + if (order == ORDER_EQUAL) + matches = streq_ptr(actual_value, word); + else if (order == ORDER_UNEQUAL) + matches = !streq_ptr(actual_value, word); + else + matches = test_order(strverscmp_improved(actual_value, word), order); + + if (!matches) + return false; + } + + return true; +} + static int condition_test_memory(Condition *c, char **env) { OrderOperator order; uint64_t m, k; @@ -935,6 +992,7 @@ int condition_test(Condition *c, char **env) { [CONDITION_MEMORY] = condition_test_memory, [CONDITION_ENVIRONMENT] = condition_test_environment, [CONDITION_CPU_FEATURE] = condition_test_cpufeature, + [CONDITION_OS_RELEASE] = condition_test_osrelease, }; int r, b; @@ -1059,6 +1117,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_MEMORY] = "ConditionMemory", [CONDITION_ENVIRONMENT] = "ConditionEnvironment", [CONDITION_CPU_FEATURE] = "ConditionCPUFeature", + [CONDITION_OS_RELEASE] = "ConditionOSRelease", }; DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType); @@ -1092,6 +1151,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_MEMORY] = "AssertMemory", [CONDITION_ENVIRONMENT] = "AssertEnvironment", [CONDITION_CPU_FEATURE] = "AssertCPUFeature", + [CONDITION_OS_RELEASE] = "AssertOSRelease", }; DEFINE_STRING_TABLE_LOOKUP(assert_type, ConditionType); |