From c2286d9ae1f09c627fe4e2b6981f21aa94fa13bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 28 Oct 2026 00:15:27 +0100 Subject: [PATCH] meson,docs: add machine-tags.d(5) and install empty config dirs --- man/machine-info.xml | 6 +- man/machine-tags.d.xml | 139 ++++++++++++++++++++++++++++++++++++++ man/rules/meson.build | 1 + meson.build | 2 + src/core/systemd.pc.in | 2 + src/hostname/meson.build | 5 ++ src/rpm/macros.systemd.in | 1 + 7 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 man/machine-tags.d.xml diff --git a/man/machine-info.xml b/man/machine-info.xml index 1e75037f730..e259ec5cd45 100644 --- a/man/machine-info.xml +++ b/man/machine-info.xml @@ -179,7 +179,10 @@ ConditionMachineTag= and AssertMachineTag= unit settings, see systemd.unit5 for details. They may be queried and changed with the tags command of - hostnamectl1. + hostnamectl1. + Tags may also be declared in machine-tags.d/ drop-in directories, see + machine-tags.d5, + and applied with hostnamectl tags --apply. @@ -252,6 +255,7 @@ TAGS=room=kitchen:company.location=berlin:company.role=personal hostname5 machine-id5 hostnamectl1 + machine-tags.d5 systemd-hostnamed.service8 diff --git a/man/machine-tags.d.xml b/man/machine-tags.d.xml new file mode 100644 index 00000000000..2996f2d5a7b --- /dev/null +++ b/man/machine-tags.d.xml @@ -0,0 +1,139 @@ + + + + + + + + machine-tags.d + systemd + + + + machine-tags.d + 5 + + + + machine-tags.d + Configure machine tags + + + + + /etc/machine-tags.d/*.tags + /run/machine-tags.d/*.tags + /usr/local/lib/machine-tags.d/*.tags + /usr/lib/machine-tags.d/*.tags + + + + + Description + + The files in the above directories declare machine tags to be added or removed from the list of + tags in the TAGS= field of + machine-info5. + See that page for the details of how tags are defined and used. + + Those files are read and applied by + systemd-hostnamed.service8 + when requested via hostnamectl tags --apply, see + hostnamectl1, or + directly via the io.systemd.Hostname.ApplyTags() call. The resulting tag list is + stored in /etc/machine-info, thus applying the same configuration repeatedly has no + further effect. + + This allows OS vendors, image builders and system extensions (see + systemd-sysext8) to + declare tags in a drop-in directory hierarchy, instead of setting them imperatively. + + + + + + Configuration Format + + Each file contains a list of entries separated by whitespace (spaces, tabs, or newlines). Empty + lines and comments (lines starting with # or ;) are ignored. + + + An entry without prefix (or, equivalently, prefixed with +) adds a tag. An + entry prefixed with - removes matching tags. The pattern may be a literal tag value, + or a shell-style glob, see + glob7. + For example, -vendor.install.* removes all tags starting with + vendor.install., -company.role=* removes any value assigned to the + company.role key, and -* removes all tags. Removing a tag that is + not set has no effect. + + Entries are applied in the order they appear, across all files in the order described below. A tag + may hence be removed by a glob and added back by a later entry. When a parameterized tag + key=value is added and a + different value is already assigned to the same key, the previous assignment is replaced. + + Each tag must be a valid machine tag, see + machine-info5 for + the syntax. Invalid entries are ignored with a warning, and the remaining entries are still applied. + + + + + Configuration Directories and Precedence + + Configuration files are read from directories in /etc/, + /run/, /usr/local/lib/, and /usr/lib/, in + order of precedence, as listed in the SYNOPSIS section above. Files must have the + .tags extension. Files in /etc/ override files with the same name + in /run/, /usr/local/lib/, and + /usr/lib/. Files in /run/ override files with the same name + under /usr/. + + All configuration files are sorted by their filename in lexicographic order, regardless of which of + the directories they reside in, following the usual semantics of systemd configuration files. Empty + files and symlinks to /dev/null mask files in directories with lower priority. + + + Note that masking or removing a file only affects future applications of the configuration. Tags + that were applied earlier remain configured until they are removed explicitly, for example with a + - entry in another file, or with hostnamectl tags. + + + + Examples + + /usr/lib/machine-tags.d/20-vendor.tags example: + + # Tags declared by the OS vendor +vendor.role=webserver +vendor.env=production +vendor.region=eu + + + + /etc/machine-tags.d/70-local.tags example: + + # Drop the vendor's environment and region tags, but keep the role, and add a local tag +-vendor.env=* -vendor.region=* +local.rack=7 + + + After hostnamectl tags --apply, the configured tags include + local.rack=7 and vendor.role=webserver, in addition to any tags + that were configured before. + + + + See Also + + systemd1 + hostnamectl1 + machine-info5 + systemd-hostnamed.service8 + systemd.unit5 + + + + diff --git a/man/rules/meson.build b/man/rules/meson.build index c0869c4b5f3..ede758ec11c 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -50,6 +50,7 @@ manpages = [ ['logind.conf', '5', ['logind.conf.d'], 'ENABLE_LOGIND'], ['machine-id', '5', [], ''], ['machine-info', '5', [], ''], + ['machine-tags.d', '5', [], 'ENABLE_HOSTNAMED'], ['machinectl', '1', [], 'ENABLE_MACHINED'], ['modules-load.d', '5', [], 'HAVE_KMOD'], ['networkctl', '1', [], 'ENABLE_NETWORKD'], diff --git a/meson.build b/meson.build index d3e24dc868e..e450a98e1bd 100644 --- a/meson.build +++ b/meson.build @@ -161,6 +161,7 @@ rpmmacrosdir = get_option('rpmmacrosdir') if rpmmacrosdir != 'no' rpmmacrosdir = prefixdir / rpmmacrosdir endif +machinetagsdir = prefixdir / 'lib/machine-tags.d' modprobedir = prefixdir / 'lib/modprobe.d' # Our own paths @@ -276,6 +277,7 @@ conf.set_quoted('INCLUDE_DIR', includedir) conf.set_quoted('LIBDIR', libdir) conf.set_quoted('LIBEXECDIR', libexecdir) conf.set_quoted('KERNEL_INSTALL_DIR', kernelinstalldir) +conf.set_quoted('MACHINE_TAGS_DIR', machinetagsdir) conf.set_quoted('MODPROBE_DIR', modprobedir) conf.set_quoted('MODULESLOAD_DIR', modulesloaddir) conf.set_quoted('PKGSYSCONFDIR', pkgsysconfdir) diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in index 862d57dcb6c..3fac1657a42 100644 --- a/src/core/systemd.pc.in +++ b/src/core/systemd.pc.in @@ -84,6 +84,8 @@ sysctldir=${sysctl_dir} binfmt_dir=${prefix}/lib/binfmt.d binfmtdir=${binfmt_dir} +machine_tags_dir=${prefix}/lib/machine-tags.d + modules_load_dir=${prefix}/lib/modules-load.d modulesloaddir=${modules_load_dir} diff --git a/src/hostname/meson.build b/src/hostname/meson.build index 8a8321f184c..9520df35e83 100644 --- a/src/hostname/meson.build +++ b/src/hostname/meson.build @@ -22,3 +22,8 @@ install_data('org.freedesktop.hostname1.service', install_dir : dbussystemservicedir) install_data('org.freedesktop.hostname1.policy', install_dir : polkitpolicydir) + +install_emptydir(machinetagsdir) +if install_sysconfdir + install_emptydir(sysconfdir / 'machine-tags.d') +endif diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in index b3d87b3d3a8..96eb7680926 100644 --- a/src/rpm/macros.systemd.in +++ b/src/rpm/macros.systemd.in @@ -21,6 +21,7 @@ %_user_tmpfilesdir {{USER_TMPFILES_DIR}} %_environmentdir {{ENVIRONMENT_DIR}} %_modulesloaddir {{MODULESLOAD_DIR}} +%_machine_tags_dir {{MACHINE_TAGS_DIR}} %_modprobedir {{MODPROBE_DIR}} %_systemdgeneratordir {{SYSTEM_GENERATOR_DIR}} %_systemdusergeneratordir {{USER_GENERATOR_DIR}}