diff --git a/man/repart.d.xml b/man/repart.d.xml index 6e3322e064b..8f86c41547f 100644 --- a/man/repart.d.xml +++ b/man/repart.d.xml @@ -622,7 +622,9 @@ Specifiers - Specifiers may be used in the Label= setting. The following expansions are understood: + Specifiers may be used in the Label=, CopyBlocks=, + CopyFiles=, MakeDirectories= settings. The following expansions are + understood: Specifiers available @@ -649,6 +651,8 @@ + + diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 3f229908c92..2851bae31e7 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -328,6 +328,9 @@ project='man-pages'>environ7 for details about environment variables. + Simple %-specifier expansion is supported, see below for a list of supported + specifiers. + Example: DefaultEnvironment="VAR1=word1 word2" VAR2=word3 "VAR3=word 5 6" @@ -349,7 +352,11 @@ Setting environment variables for the manager process may be useful to modify its behaviour. See ENVIRONMENT for a descriptions of some - variables understood by systemd. + variables understood by systemd. + + Simple %-specifier expansion is supported, see below for a list of supported + specifiers. + @@ -440,6 +447,45 @@ + + Specifiers + + Specifiers may be used in the DefaultEnvironment= and + ManagerEnvironment= settings. The following expansions are understood: +
+ Specifiers available + + + + + + + Specifier + Meaning + Details + + + + + + + + + + + + + + + + + + + + +
+
+ See Also diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index ff6eaf32ef6..d31d6420170 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -57,6 +57,7 @@ #include "signal-util.h" #include "socket-bind.h" #include "socket-netlink.h" +#include "specifier.h" #include "stat-util.h" #include "string-util.h" #include "strv.h" @@ -2656,15 +2657,15 @@ int config_parse_environ( if (r == 0) return 0; - if (u) { + if (u) r = unit_env_printf(u, word, &resolved); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to resolve unit specifiers in %s, ignoring: %m", word); - continue; - } - } else - resolved = TAKE_PTR(word); + else + r = specifier_printf(word, sc_arg_max(), system_and_tmp_specifier_table, NULL, &resolved); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to resolve specifiers in %s, ignoring: %m", word); + continue; + } if (!env_assignment_is_valid(resolved)) { log_syntax(unit, LOG_WARNING, filename, line, 0, diff --git a/src/partition/repart.c b/src/partition/repart.c index 877d2a091d7..cd2d02a3b89 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -949,11 +949,6 @@ static int config_parse_type( return 0; } -static const Specifier specifier_table[] = { - COMMON_SYSTEM_SPECIFIERS, - {} -}; - static int config_parse_label( const char *unit, const char *filename, @@ -976,7 +971,7 @@ static int config_parse_label( /* Nota bene: the empty label is a totally valid one. Let's hence not follow our usual rule of * assigning the empty string to reset to default here, but really accept it as label to set. */ - r = specifier_printf(rvalue, GPT_LABEL_MAX, specifier_table, NULL, &resolved); + r = specifier_printf(rvalue, GPT_LABEL_MAX, system_and_tmp_specifier_table, NULL, &resolved); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to expand specifiers in Label=, ignoring: %s", rvalue); @@ -1141,7 +1136,7 @@ static int config_parse_copy_files( if (!isempty(p)) return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue); - r = specifier_printf(source, PATH_MAX-1, specifier_table, NULL, &resolved_source); + r = specifier_printf(source, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_source); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue); @@ -1152,7 +1147,7 @@ static int config_parse_copy_files( if (r < 0) return 0; - r = specifier_printf(target, PATH_MAX-1, specifier_table, NULL, &resolved_target); + r = specifier_printf(target, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_target); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target); @@ -1201,7 +1196,7 @@ static int config_parse_copy_blocks( return 0; } - r = specifier_printf(rvalue, PATH_MAX-1, specifier_table, NULL, &d); + r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &d); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue); @@ -1249,7 +1244,7 @@ static int config_parse_make_dirs( if (r == 0) return 0; - r = specifier_printf(word, PATH_MAX-1, specifier_table, NULL, &d); + r = specifier_printf(word, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &d); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word); diff --git a/src/shared/specifier.c b/src/shared/specifier.c index f4c73b2741e..1712c1c295f 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -364,3 +364,9 @@ int specifier_escape_strv(char **l, char ***ret) { return 0; } + +const Specifier system_and_tmp_specifier_table[] = { + COMMON_SYSTEM_SPECIFIERS, + COMMON_TMP_SPECIFIERS, + {} +}; diff --git a/src/shared/specifier.h b/src/shared/specifier.h index 0c5bb3d0c42..839515da427 100644 --- a/src/shared/specifier.h +++ b/src/shared/specifier.h @@ -80,7 +80,6 @@ int specifier_var_tmp_dir(char specifier, const void *data, const void *userdata { 'w', specifier_os_version_id, NULL }, \ { 'W', specifier_os_variant_id, NULL } - #define COMMON_CREDS_SPECIFIERS \ { 'g', specifier_group_name, NULL }, \ { 'G', specifier_group_id, NULL }, \ @@ -96,3 +95,6 @@ static inline char* specifier_escape(const char *string) { } int specifier_escape_strv(char **l, char ***ret); + +/* A generic specifier table consisting of COMMON_SYSTEM_SPECIFIERS and COMMON_TMP_SPECIFIERS */ +extern const Specifier system_and_tmp_specifier_table[]; diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 5aa3531012c..c9eda29b49f 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1466,12 +1466,6 @@ static bool item_equal(Item *a, Item *b) { static int parse_line(const char *fname, unsigned line, const char *buffer) { - static const Specifier specifier_table[] = { - COMMON_SYSTEM_SPECIFIERS, - COMMON_TMP_SPECIFIERS, - {} - }; - _cleanup_free_ char *action = NULL, *name = NULL, *resolved_name = NULL, *id = NULL, *resolved_id = NULL, @@ -1515,7 +1509,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { name = mfree(name); if (name) { - r = specifier_printf(name, NAME_MAX, specifier_table, NULL, &resolved_name); + r = specifier_printf(name, NAME_MAX, system_and_tmp_specifier_table, NULL, &resolved_name); if (r < 0) return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name); @@ -1530,7 +1524,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { id = mfree(id); if (id) { - r = specifier_printf(id, PATH_MAX-1, specifier_table, NULL, &resolved_id); + r = specifier_printf(id, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_id); if (r < 0) return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name); @@ -1541,7 +1535,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { description = mfree(description); if (description) { - r = specifier_printf(description, LONG_LINE_MAX, specifier_table, NULL, &resolved_description); + r = specifier_printf(description, LONG_LINE_MAX, system_and_tmp_specifier_table, NULL, &resolved_description); if (r < 0) return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, description); @@ -1557,7 +1551,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { home = mfree(home); if (home) { - r = specifier_printf(home, PATH_MAX-1, specifier_table, NULL, &resolved_home); + r = specifier_printf(home, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_home); if (r < 0) return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, home); @@ -1573,7 +1567,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { shell = mfree(shell); if (shell) { - r = specifier_printf(shell, PATH_MAX-1, specifier_table, NULL, &resolved_shell); + r = specifier_printf(shell, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_shell); if (r < 0) return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, shell);