hostnamed: introduce "machine tags" concept

For management purposes it's useful to be able to "tag" a machine with
various labels. Let's add a field for that to /etc/machine-info and make
it settable.

Fixes: #38591
This commit is contained in:
Lennart Poettering
2026-05-21 18:30:16 +02:00
parent 5e82a8d6ee
commit 1b94530b14
6 changed files with 299 additions and 13 deletions
+69
View File
@@ -253,3 +253,72 @@ int machine_spec_valid(const char *s) {
return true;
}
bool machine_tag_is_valid(const char *s) {
size_t n = strlen_ptr(s);
if (n <= 0 || n >= 256)
return false;
return in_charset(s, ALPHANUMERICAL "-.");
}
bool machine_tag_list_is_valid(char **l) {
size_t n = 0;
STRV_FOREACH(i, l) {
n++;
if (n > MACHINE_TAGS_MAX)
return false;
if (!machine_tag_is_valid(*i))
return false;
}
return true;
}
int machine_tags_from_string(const char *s, bool graceful, char ***ret) {
int r;
assert(ret);
/* Parses the colon-separated TAGS= machine-info field into a sorted, deduplicated strv. Each tag is
* validated: if 'graceful' is true invalid tags are silently dropped, otherwise an invalid tag makes
* us fail with -EINVAL. The result is NULL if no (valid) tags remain. */
if (isempty(s)) {
*ret = NULL;
return 0;
}
_cleanup_strv_free_ char **l = strv_split(s, ":");
if (!l)
return -ENOMEM;
strv_sort_uniq(l);
if (!graceful) {
if (!machine_tag_list_is_valid(l))
return -EINVAL;
*ret = strv_isempty(l) ? NULL : TAKE_PTR(l);
return 0;
}
size_t n = 0;
_cleanup_strv_free_ char **cleaned = NULL;
STRV_FOREACH(i, l) {
if (!machine_tag_is_valid(*i))
continue;
n++;
if (n > MACHINE_TAGS_MAX)
return -E2BIG;
r = strv_extend(&cleaned, *i);
if (r < 0)
return r;
}
*ret = TAKE_PTR(cleaned);
return 0;
}
+6
View File
@@ -47,3 +47,9 @@ int get_pretty_hostname(char **ret);
int machine_spec_valid(const char *s);
int split_user_at_host(const char *s, char **ret_user, char **ret_host);
#define MACHINE_TAGS_MAX 1024U
bool machine_tag_is_valid(const char *s);
bool machine_tag_list_is_valid(char **l);
int machine_tags_from_string(const char *s, bool graceful, char ***ret);