mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
unit: add new ConditionHost= condition type
This commit is contained in:
parent
ddfa5101a2
commit
c0d6e764d1
4
TODO
4
TODO
@ -49,6 +49,8 @@ Bugfixes:
|
||||
|
||||
Features:
|
||||
|
||||
* There's something wrong with escaping unit names: http://lists.freedesktop.org/archives/systemd-devel/2012-August/006292.html
|
||||
|
||||
* cleanup ellipsation for log output in journalctl and systemctl status: have a sane way to disable ellipsation, and disable it by default when invoked in less/more
|
||||
|
||||
* enforce limits on fds openened by socket units
|
||||
@ -59,8 +61,6 @@ Features:
|
||||
|
||||
* testing tool for socket activation: some binary that listens on a socket and passes it on using the usual socket activation protocol to some server.
|
||||
|
||||
* ConditionHost= for filtering services for clusters
|
||||
|
||||
* journald: add symlinks and device names to kernel messages
|
||||
|
||||
* maybe make systemd-detect-virt suid? or use fscaps?
|
||||
|
@ -586,7 +586,7 @@
|
||||
<term><varname>RequiresMountsFor=</varname></term>
|
||||
|
||||
<listitem><para>Takes a space
|
||||
separated list of paths. Automatically
|
||||
separated list of absolute paths. Automatically
|
||||
adds dependencies of type
|
||||
<varname>Requires=</varname> and
|
||||
<varname>After=</varname> for all
|
||||
@ -760,65 +760,86 @@
|
||||
<term><varname>ConditionVirtualization=</varname></term>
|
||||
<term><varname>ConditionSecurity=</varname></term>
|
||||
<term><varname>ConditionCapability=</varname></term>
|
||||
<term><varname>ConditionHost=</varname></term>
|
||||
<term><varname>ConditionNull=</varname></term>
|
||||
|
||||
<listitem><para>Before starting a unit
|
||||
verify that the specified condition is
|
||||
true. With
|
||||
true. If it is not true the starting
|
||||
of the unit will be skipped, however
|
||||
all ordering dependencies of it are
|
||||
still respected. A failing condition
|
||||
will not result in the unit being
|
||||
moved into a failure state. The
|
||||
condition is checked at the time the
|
||||
queued start job is to be
|
||||
executed.</para>
|
||||
|
||||
<para>With
|
||||
<varname>ConditionPathExists=</varname>
|
||||
a file existence condition can be
|
||||
a file existence condition is
|
||||
checked before a unit is started. If
|
||||
the specified absolute path name does
|
||||
not exist, startup of a unit will not
|
||||
actually happen, however the unit is
|
||||
still useful for ordering purposes in
|
||||
this case. The condition is checked at
|
||||
the time the queued start job is to be
|
||||
executed. If the absolute path name
|
||||
passed to
|
||||
not exist the condition will
|
||||
fail. If the absolute path name passed
|
||||
to
|
||||
<varname>ConditionPathExists=</varname>
|
||||
is prefixed with an exclamation mark
|
||||
(!), the test is negated, and the unit
|
||||
('!'), the test is negated, and the unit
|
||||
is only started if the path does not
|
||||
exist.
|
||||
<varname>ConditionPathExistsGlob=</varname>
|
||||
works in a similar way, but checks for
|
||||
the existence of at least one file or
|
||||
directory matching the specified
|
||||
globbing
|
||||
pattern. <varname>ConditionPathIsDirectory=</varname>
|
||||
exist.</para>
|
||||
|
||||
<para><varname>ConditionPathExistsGlob=</varname>
|
||||
is similar to
|
||||
<varname>ConditionPathExists=</varname>,
|
||||
but checks for the existence of at
|
||||
least one file or directory matching
|
||||
the specified globbing pattern.</para>
|
||||
|
||||
<para><varname>ConditionPathIsDirectory=</varname>
|
||||
is similar to
|
||||
<varname>ConditionPathExists=</varname>
|
||||
but verifies whether a certain path
|
||||
exists and is a
|
||||
directory. <varname>ConditionPathIsSymbolicLink=</varname>
|
||||
directory.</para>
|
||||
|
||||
<para><varname>ConditionPathIsSymbolicLink=</varname>
|
||||
is similar to
|
||||
<varname>ConditionPathExists=</varname>
|
||||
but verifies whether a certain path
|
||||
exists and is a symbolic
|
||||
link. <varname>ConditionPathIsMountPoint=</varname>
|
||||
link.</para>
|
||||
|
||||
<para><varname>ConditionPathIsMountPoint=</varname>
|
||||
is similar to
|
||||
<varname>ConditionPathExists=</varname>
|
||||
but verifies whether a certain path
|
||||
exists and is a mount
|
||||
point. <varname>ConditionPathIsReadWrite=</varname>
|
||||
point.</para>
|
||||
|
||||
<para><varname>ConditionPathIsReadWrite=</varname>
|
||||
is similar to
|
||||
<varname>ConditionPathExists=</varname>
|
||||
but verifies whether the underlying
|
||||
file system is read and writable
|
||||
file system is readable and writable
|
||||
(i.e. not mounted
|
||||
read-only). <varname>ConditionFileIsExecutable=</varname>
|
||||
read-only).</para>
|
||||
|
||||
<para><varname>ConditionFileIsExecutable=</varname>
|
||||
is similar to
|
||||
<varname>ConditionPathExists=</varname>
|
||||
but verifies whether a certain path
|
||||
exists, is a regular file and marked
|
||||
executable.
|
||||
<varname>ConditionDirectoryNotEmpty=</varname>
|
||||
executable.</para>
|
||||
|
||||
<para><varname>ConditionDirectoryNotEmpty=</varname>
|
||||
is similar to
|
||||
<varname>ConditionPathExists=</varname>
|
||||
but verifies whether a certain path
|
||||
exists and is a non-empty
|
||||
directory. Similarly
|
||||
directory.</para>
|
||||
|
||||
<para>Similarly,
|
||||
<varname>ConditionKernelCommandLine=</varname>
|
||||
may be used to check whether a
|
||||
specific kernel command line option is
|
||||
@ -826,14 +847,16 @@
|
||||
exclamation mark unset). The argument
|
||||
must either be a single word, or an
|
||||
assignment (i.e. two words, separated
|
||||
by the equality sign). In the former
|
||||
'='). In the former
|
||||
case the kernel command line is
|
||||
searched for the word appearing as is,
|
||||
or as left hand side of an
|
||||
assignment. In the latter case the
|
||||
exact assignment is looked for with
|
||||
right and left hand side
|
||||
matching. <varname>ConditionVirtualization=</varname>
|
||||
matching.</para>
|
||||
|
||||
<para><varname>ConditionVirtualization=</varname>
|
||||
may be used to check whether the
|
||||
system is executed in a virtualized
|
||||
environment and optionally test
|
||||
@ -843,7 +866,7 @@
|
||||
any virtualized environment, or one of
|
||||
<varname>vm</varname> and
|
||||
<varname>container</varname> to test
|
||||
against a specific type of
|
||||
against a generic type of
|
||||
virtualization solution, or one of
|
||||
<varname>qemu</varname>,
|
||||
<varname>kvm</varname>,
|
||||
@ -862,15 +885,18 @@
|
||||
virtualization technologies are nested
|
||||
only the innermost is considered. The
|
||||
test may be negated by prepending an
|
||||
exclamation mark.
|
||||
<varname>ConditionSecurity=</varname>
|
||||
exclamation mark.</para>
|
||||
|
||||
<para><varname>ConditionSecurity=</varname>
|
||||
may be used to check whether the given
|
||||
security module is enabled on the
|
||||
system. Currently the only recognized
|
||||
value is <varname>selinux</varname>.
|
||||
The test may be negated by prepending
|
||||
an exclamation
|
||||
mark. <varname>ConditionCapability=</varname>
|
||||
mark.</para>
|
||||
|
||||
<para><varname>ConditionCapability=</varname>
|
||||
may be used to check whether the given
|
||||
capability exists in the capability
|
||||
bounding set of the service manager
|
||||
@ -881,14 +907,32 @@
|
||||
for details). Pass a capability name
|
||||
such as <literal>CAP_MKNOD</literal>,
|
||||
possibly prefixed with an exclamation
|
||||
mark to negate the check. Finally,
|
||||
mark to negate the check.</para>
|
||||
|
||||
<para><varname>ConditionHost=</varname>
|
||||
may be used to match against the
|
||||
host name or machine ID of the
|
||||
host. This either takes a host name
|
||||
string (optionally with shell style
|
||||
globs) which is tested against the
|
||||
locally set host name as returned by
|
||||
<citerefentry><refentrytitle>gethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
||||
or a machine ID formatted as string
|
||||
(see
|
||||
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||
The test may be negated by prepending
|
||||
an exclamation mark.</para>
|
||||
|
||||
<para>Finally,
|
||||
<varname>ConditionNull=</varname> may
|
||||
be used to add a constant condition
|
||||
check value to the unit. It takes a
|
||||
boolean argument. If set to
|
||||
<varname>false</varname> the condition
|
||||
will always fail, otherwise
|
||||
succeed. If multiple conditions are
|
||||
succeed.</para>
|
||||
|
||||
<para>If multiple conditions are
|
||||
specified the unit will be executed if
|
||||
all of them apply (i.e. a logical AND
|
||||
is applied). Condition checks can be
|
||||
|
@ -25,11 +25,13 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/capability.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
#endif
|
||||
|
||||
#include <systemd/sd-id128.h>
|
||||
#include "util.h"
|
||||
#include "condition.h"
|
||||
#include "virt.h"
|
||||
@ -194,6 +196,31 @@ static bool test_capability(const char *parameter) {
|
||||
return !!(capabilities & (1ULL << value));
|
||||
}
|
||||
|
||||
static bool test_host(const char *parameter) {
|
||||
sd_id128_t x, y;
|
||||
char *h;
|
||||
int r;
|
||||
bool b;
|
||||
|
||||
if (sd_id128_from_string(parameter, &x) >= 0) {
|
||||
|
||||
r = sd_id128_get_machine(&y);
|
||||
if (r < 0)
|
||||
return false;
|
||||
|
||||
return sd_id128_equal(x, y);
|
||||
}
|
||||
|
||||
h = gethostname_malloc();
|
||||
if (!h)
|
||||
return false;
|
||||
|
||||
b = fnmatch(parameter, h, FNM_CASEFOLD) == 0;
|
||||
free(h);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
bool condition_test(Condition *c) {
|
||||
assert(c);
|
||||
|
||||
@ -255,6 +282,9 @@ bool condition_test(Condition *c) {
|
||||
case CONDITION_CAPABILITY:
|
||||
return test_capability(c->parameter) == !c->negate;
|
||||
|
||||
case CONDITION_HOST:
|
||||
return test_host(c->parameter) == !c->negate;
|
||||
|
||||
case CONDITION_NULL:
|
||||
return !c->negate;
|
||||
|
||||
@ -323,6 +353,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
|
||||
[CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
|
||||
[CONDITION_SECURITY] = "ConditionSecurity",
|
||||
[CONDITION_HOST] = "ConditionHost",
|
||||
[CONDITION_NULL] = "ConditionNull"
|
||||
};
|
||||
|
||||
|
@ -38,6 +38,7 @@ typedef enum ConditionType {
|
||||
CONDITION_VIRTUALIZATION,
|
||||
CONDITION_SECURITY,
|
||||
CONDITION_CAPABILITY,
|
||||
CONDITION_HOST,
|
||||
CONDITION_NULL,
|
||||
_CONDITION_TYPE_MAX,
|
||||
_CONDITION_TYPE_INVALID = -1
|
||||
|
@ -135,6 +135,7 @@ Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_K
|
||||
Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0
|
||||
Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, 0
|
||||
Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, 0
|
||||
Unit.ConditionHost, config_parse_unit_condition_string, CONDITION_HOST, 0
|
||||
Unit.ConditionNull, config_parse_unit_condition_null, 0, 0
|
||||
m4_dnl
|
||||
Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file)
|
||||
|
@ -1516,14 +1516,17 @@ int config_parse_unit_condition_string(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if ((trigger = rvalue[0] == '|'))
|
||||
trigger = rvalue[0] == '|';
|
||||
if (trigger)
|
||||
rvalue++;
|
||||
|
||||
if ((negate = rvalue[0] == '!'))
|
||||
negate = rvalue[0] == '!';
|
||||
if (negate)
|
||||
rvalue++;
|
||||
|
||||
if (!(c = condition_new(cond, rvalue, trigger, negate)))
|
||||
return -ENOMEM;
|
||||
c = condition_new(cond, rvalue, trigger, negate);
|
||||
if (!c)
|
||||
return log_oom();
|
||||
|
||||
LIST_PREPEND(Condition, conditions, u->conditions, c);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user