pid1: pass useful env vars to generators

This is inspired by this:

    https://github.com/systemd/zram-generator/blob/main/src/generator.rs#L29

Given it's easy for PID 1 to pass this to generators, I thin we should.
All generators not written by us likely want to know these things so
that the can adjust to the execution environment.
This commit is contained in:
Lennart Poettering
2022-04-13 10:07:46 +02:00
parent 87d44b6e1a
commit 82c5db16cc
+80 -10
View File
@@ -3665,9 +3665,67 @@ static int manager_run_environment_generators(Manager *m) {
return r;
}
static int build_generator_environment(Manager *m, char ***ret) {
_cleanup_strv_free_ char **nl = NULL;
Virtualization v;
int r;
assert(m);
assert(ret);
/* Generators oftentimes want to know some basic facts about the environment they run in, in order to
* adjust generated units to that. Let's pass down some bits of information that are easy for us to
* determine (but a bit harder for generator scripts to determine), as environment variables. */
nl = strv_copy(m->transient_environment);
if (!nl)
return -ENOMEM;
r = strv_env_assign(&nl, "SYSTEMD_SCOPE", MANAGER_IS_SYSTEM(m) ? "system" : "user");
if (r < 0)
return r;
if (MANAGER_IS_SYSTEM(m)) {
/* Note that $SYSTEMD_IN_INITRD may be used to override the initrd detection in much of our
* codebase. This is hence more than purely informational. It will shortcut detection of the
* initrd state if generators invoke our own tools. But that's OK, as it would come to the
* same results (hopefully). */
r = strv_env_assign(&nl, "SYSTEMD_IN_INITRD", one_zero(in_initrd()));
if (r < 0)
return r;
if (m->first_boot >= 0) {
r = strv_env_assign(&nl, "SYSTEMD_FIRST_BOOT", one_zero(m->first_boot));
if (r < 0)
return r;
}
}
v = detect_virtualization();
if (v < 0)
log_debug_errno(v, "Failed to detect virtualization, ignoring: %m");
else if (v > 0) {
const char *s;
s = strjoina(VIRTUALIZATION_IS_VM(v) ? "vm:" :
VIRTUALIZATION_IS_CONTAINER(v) ? "container:" : ":",
virtualization_to_string(v));
r = strv_env_assign(&nl, "SYSTEMD_VIRTUALIZATION", s);
if (r < 0)
return r;
}
r = strv_env_assign(&nl, "SYSTEMD_ARCHITECTURE", architecture_to_string(uname_architecture()));
if (r < 0)
return r;
*ret = TAKE_PTR(nl);
return 0;
}
static int manager_run_generators(Manager *m) {
_cleanup_strv_free_ char **paths = NULL;
const char *argv[5];
_cleanup_strv_free_ char **paths = NULL, **ge = NULL;
int r;
assert(m);
@@ -3688,16 +3746,28 @@ static int manager_run_generators(Manager *m) {
goto finish;
}
argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
argv[1] = m->lookup_paths.generator;
argv[2] = m->lookup_paths.generator_early;
argv[3] = m->lookup_paths.generator_late;
argv[4] = NULL;
const char *argv[] = {
NULL, /* Leave this empty, execute_directory() will fill something in */
m->lookup_paths.generator,
m->lookup_paths.generator_early,
m->lookup_paths.generator_late,
NULL,
};
r = build_generator_environment(m, &ge);
if (r < 0) {
log_error_errno(r, "Failed to build generator environment: %m");
goto finish;
}
RUN_WITH_UMASK(0022)
(void) execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, NULL, NULL,
(char**) argv, m->transient_environment,
EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS | EXEC_DIR_SET_SYSTEMD_EXEC_PID);
(void) execute_directories(
(const char* const*) paths,
DEFAULT_TIMEOUT_USEC,
/* callbacks= */ NULL, /* callback_args= */ NULL,
(char**) argv,
ge,
EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS | EXEC_DIR_SET_SYSTEMD_EXEC_PID);
r = 0;