condition: allow fnmatch compares for ConditionOSRelease=

We support this for smbios matches, hence do so for /etc/os-release
matches too.
This commit is contained in:
Lennart Poettering 2022-08-26 16:59:47 +02:00
parent 57610982f7
commit 8daa674090
3 changed files with 11 additions and 8 deletions

View file

@ -1694,10 +1694,13 @@
<listitem><para>Verify that a specific <literal>key=value</literal> pair is set in the host's
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para>Other than exact matching with <literal>=</literal>, and <literal>!=</literal>, relative
comparisons are supported for versioned parameters (e.g. <literal>VERSION_ID</literal>). The
comparator can be one of <literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>=</literal>,
<literal>!=</literal>, <literal>&gt;=</literal> and <literal>&gt;</literal>.</para>
<para>Other than exact string matching with <literal>=</literal>, and <literal>!=</literal>,
relative comparisons are supported for versioned parameters (e.g. <literal>VERSION_ID</literal>),
and shell-style wildcard comparisons (<literal>*</literal>, <literal>?</literal>,
<literal>[]</literal>) are supported with the <literal>=$</literal> (match) and
<literal>!=$</literal> (non-match). The comparator can be one of <literal>&lt;</literal>,
<literal>&lt;=</literal>, <literal>=</literal>, <literal>!=</literal>, <literal>&gt;=</literal>,
<literal>&gt;</literal>, <literal>=$</literal> and <literal>!=$</literal>.</para>
</listitem>
</varlistentry>

View file

@ -257,7 +257,7 @@ static int condition_test_osrelease(Condition *c, char **env) {
/* parse_compare_operator() needs the string to start with the comparators */
word = condition;
r = extract_first_word(&word, &key, "!<=>", EXTRACT_RETAIN_SEPARATORS);
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 */
@ -266,7 +266,7 @@ static int condition_test_osrelease(Condition *c, char **env) {
"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 */
operator = parse_compare_operator(&word, COMPARE_EQUAL_BY_STRING);
operator = parse_compare_operator(&word, COMPARE_ALLOW_FNMATCH|COMPARE_EQUAL_BY_STRING);
if (operator < 0 || isempty(word) || strchr(WHITESPACE, *word) != NULL)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to parse parameter, key/value format expected: %m");

View file

@ -1177,13 +1177,13 @@ TEST(condition_test_os_release) {
key_value_pair = strjoina(os_release_pairs[0], "=$", quote, os_release_pairs[1], quote);
condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
assert_se(condition);
assert_se(condition_test(condition, environ) == -EINVAL);
assert_se(condition_test(condition, environ) > 0);
condition_free(condition);
key_value_pair = strjoina(os_release_pairs[0], "!=$", quote, os_release_pairs[1], quote);
condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
assert_se(condition);
assert_se(condition_test(condition, environ) == -EINVAL);
assert_se(condition_test(condition, environ) == 0);
condition_free(condition);
/* Some distros (eg: Arch) do not set VERSION_ID */