mirror of
https://github.com/systemd/systemd.git
synced 2025-02-28 05:57:33 +03:00
Merge pull request #19737 from poettering/default-specifiers-env
pid1: add specifier expansion for DefaultEnvironment=
This commit is contained in:
commit
83aab043d3
@ -622,7 +622,9 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Specifiers</title>
|
<title>Specifiers</title>
|
||||||
|
|
||||||
<para>Specifiers may be used in the <varname>Label=</varname> setting. The following expansions are understood:</para>
|
<para>Specifiers may be used in the <varname>Label=</varname>, <varname>CopyBlocks=</varname>,
|
||||||
|
<varname>CopyFiles=</varname>, <varname>MakeDirectories=</varname> settings. The following expansions are
|
||||||
|
understood:</para>
|
||||||
<table class='specifiers'>
|
<table class='specifiers'>
|
||||||
<title>Specifiers available</title>
|
<title>Specifiers available</title>
|
||||||
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
|
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
|
||||||
@ -649,6 +651,8 @@
|
|||||||
<xi:include href="standard-specifiers.xml" xpointer="v"/>
|
<xi:include href="standard-specifiers.xml" xpointer="v"/>
|
||||||
<xi:include href="standard-specifiers.xml" xpointer="w"/>
|
<xi:include href="standard-specifiers.xml" xpointer="w"/>
|
||||||
<xi:include href="standard-specifiers.xml" xpointer="W"/>
|
<xi:include href="standard-specifiers.xml" xpointer="W"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="T"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="V"/>
|
||||||
<xi:include href="standard-specifiers.xml" xpointer="percent"/>
|
<xi:include href="standard-specifiers.xml" xpointer="percent"/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
|
@ -328,6 +328,9 @@
|
|||||||
project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
||||||
details about environment variables.</para>
|
details about environment variables.</para>
|
||||||
|
|
||||||
|
<para>Simple <literal>%</literal>-specifier expansion is supported, see below for a list of supported
|
||||||
|
specifiers.</para>
|
||||||
|
|
||||||
<para>Example:
|
<para>Example:
|
||||||
|
|
||||||
<programlisting>DefaultEnvironment="VAR1=word1 word2" VAR2=word3 "VAR3=word 5 6"</programlisting>
|
<programlisting>DefaultEnvironment="VAR1=word1 word2" VAR2=word3 "VAR3=word 5 6"</programlisting>
|
||||||
@ -349,7 +352,11 @@
|
|||||||
|
|
||||||
<para>Setting environment variables for the manager process may be useful to modify its behaviour.
|
<para>Setting environment variables for the manager process may be useful to modify its behaviour.
|
||||||
See <ulink url="https://systemd.io/ENVIRONMENT">ENVIRONMENT</ulink> for a descriptions of some
|
See <ulink url="https://systemd.io/ENVIRONMENT">ENVIRONMENT</ulink> for a descriptions of some
|
||||||
variables understood by <command>systemd</command>.</para></listitem>
|
variables understood by <command>systemd</command>.</para>
|
||||||
|
|
||||||
|
<para>Simple <literal>%</literal>-specifier expansion is supported, see below for a list of supported
|
||||||
|
specifiers.</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -440,6 +447,45 @@
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Specifiers</title>
|
||||||
|
|
||||||
|
<para>Specifiers may be used in the <varname>DefaultEnvironment=</varname> and
|
||||||
|
<varname>ManagerEnvironment=</varname> settings. The following expansions are understood:</para>
|
||||||
|
<table class='specifiers'>
|
||||||
|
<title>Specifiers available</title>
|
||||||
|
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
|
||||||
|
<colspec colname="spec" />
|
||||||
|
<colspec colname="mean" />
|
||||||
|
<colspec colname="detail" />
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Specifier</entry>
|
||||||
|
<entry>Meaning</entry>
|
||||||
|
<entry>Details</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="a"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="A"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="b"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="B"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="H"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="l"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="m"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="M"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="o"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="v"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="w"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="W"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="T"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="V"/>
|
||||||
|
<xi:include href="standard-specifiers.xml" xpointer="percent"/>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>See Also</title>
|
<title>See Also</title>
|
||||||
<para>
|
<para>
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
#include "socket-bind.h"
|
#include "socket-bind.h"
|
||||||
#include "socket-netlink.h"
|
#include "socket-netlink.h"
|
||||||
|
#include "specifier.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
@ -2656,15 +2657,15 @@ int config_parse_environ(
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (u) {
|
if (u)
|
||||||
r = unit_env_printf(u, word, &resolved);
|
r = unit_env_printf(u, word, &resolved);
|
||||||
if (r < 0) {
|
else
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
r = specifier_printf(word, sc_arg_max(), system_and_tmp_specifier_table, NULL, &resolved);
|
||||||
"Failed to resolve unit specifiers in %s, ignoring: %m", word);
|
if (r < 0) {
|
||||||
continue;
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
}
|
"Failed to resolve specifiers in %s, ignoring: %m", word);
|
||||||
} else
|
continue;
|
||||||
resolved = TAKE_PTR(word);
|
}
|
||||||
|
|
||||||
if (!env_assignment_is_valid(resolved)) {
|
if (!env_assignment_is_valid(resolved)) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
@ -949,11 +949,6 @@ static int config_parse_type(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Specifier specifier_table[] = {
|
|
||||||
COMMON_SYSTEM_SPECIFIERS,
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int config_parse_label(
|
static int config_parse_label(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
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
|
/* 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. */
|
* 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) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in Label=, ignoring: %s", rvalue);
|
"Failed to expand specifiers in Label=, ignoring: %s", rvalue);
|
||||||
@ -1141,7 +1136,7 @@ static int config_parse_copy_files(
|
|||||||
if (!isempty(p))
|
if (!isempty(p))
|
||||||
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue);
|
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) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue);
|
"Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue);
|
||||||
@ -1152,7 +1147,7 @@ static int config_parse_copy_files(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return 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) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target);
|
"Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target);
|
||||||
@ -1201,7 +1196,7 @@ static int config_parse_copy_blocks(
|
|||||||
return 0;
|
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) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue);
|
"Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue);
|
||||||
@ -1249,7 +1244,7 @@ static int config_parse_make_dirs(
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 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) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word);
|
"Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word);
|
||||||
|
@ -364,3 +364,9 @@ int specifier_escape_strv(char **l, char ***ret) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Specifier system_and_tmp_specifier_table[] = {
|
||||||
|
COMMON_SYSTEM_SPECIFIERS,
|
||||||
|
COMMON_TMP_SPECIFIERS,
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
@ -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_version_id, NULL }, \
|
||||||
{ 'W', specifier_os_variant_id, NULL }
|
{ 'W', specifier_os_variant_id, NULL }
|
||||||
|
|
||||||
|
|
||||||
#define COMMON_CREDS_SPECIFIERS \
|
#define COMMON_CREDS_SPECIFIERS \
|
||||||
{ 'g', specifier_group_name, NULL }, \
|
{ 'g', specifier_group_name, NULL }, \
|
||||||
{ 'G', specifier_group_id, 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);
|
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[];
|
||||||
|
@ -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 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,
|
_cleanup_free_ char *action = NULL,
|
||||||
*name = NULL, *resolved_name = NULL,
|
*name = NULL, *resolved_name = NULL,
|
||||||
*id = NULL, *resolved_id = 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);
|
name = mfree(name);
|
||||||
|
|
||||||
if (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)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name);
|
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);
|
id = mfree(id);
|
||||||
|
|
||||||
if (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)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, name);
|
fname, line, name);
|
||||||
@ -1541,7 +1535,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
description = mfree(description);
|
description = mfree(description);
|
||||||
|
|
||||||
if (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)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, description);
|
fname, line, description);
|
||||||
@ -1557,7 +1551,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
home = mfree(home);
|
home = mfree(home);
|
||||||
|
|
||||||
if (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)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, home);
|
fname, line, home);
|
||||||
@ -1573,7 +1567,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
shell = mfree(shell);
|
shell = mfree(shell);
|
||||||
|
|
||||||
if (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)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, shell);
|
fname, line, shell);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user