1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-03-06 12:58:22 +03:00

nspawn: add new --setenv= switch to set an environment variable for the container to spawn

This commit is contained in:
Lennart Poettering 2013-12-13 16:37:16 +01:00
parent a56b63f41d
commit f4889f656b
2 changed files with 59 additions and 7 deletions

View File

@ -380,6 +380,21 @@
creates read-only bind creates read-only bind
mount.</para></listitem> mount.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--setenv=</option></term>
<listitem><para>Specifies an
environment variable assignment to
pass to the init process in the
container, in the format
<literal>NAME=VALUE</literal>. This
may be used to override the default
variables or to set additional
variables. This parameter may be used
more than once.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -62,6 +62,7 @@
#include "bus-error.h" #include "bus-error.h"
#include "ptyfwd.h" #include "ptyfwd.h"
#include "bus-kernel.h" #include "bus-kernel.h"
#include "env-util.h"
#ifndef TTY_GID #ifndef TTY_GID
#define TTY_GID 5 #define TTY_GID 5
@ -111,6 +112,7 @@ static uint64_t arg_retain =
(1ULL << CAP_AUDIT_CONTROL); (1ULL << CAP_AUDIT_CONTROL);
static char **arg_bind = NULL; static char **arg_bind = NULL;
static char **arg_bind_ro = NULL; static char **arg_bind_ro = NULL;
static char **arg_setenv = NULL;
static int help(void) { static int help(void) {
@ -133,7 +135,8 @@ static int help(void) {
" -j Equivalent to --link-journal=host\n" " -j Equivalent to --link-journal=host\n"
" --bind=PATH[:PATH] Bind mount a file or directory from the host into\n" " --bind=PATH[:PATH] Bind mount a file or directory from the host into\n"
" the container\n" " the container\n"
" --bind-ro=PATH[:PATH] Similar, but creates a read-only bind mount\n", " --bind-ro=PATH[:PATH] Similar, but creates a read-only bind mount\n"
" --setenv=NAME=VALUE Pass an environment variable to PID 1\n",
program_invocation_short_name); program_invocation_short_name);
return 0; return 0;
@ -150,7 +153,8 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DROP_CAPABILITY, ARG_DROP_CAPABILITY,
ARG_LINK_JOURNAL, ARG_LINK_JOURNAL,
ARG_BIND, ARG_BIND,
ARG_BIND_RO ARG_BIND_RO,
ARG_SETENV,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -169,6 +173,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "bind-ro", required_argument, NULL, ARG_BIND_RO }, { "bind-ro", required_argument, NULL, ARG_BIND_RO },
{ "machine", required_argument, NULL, 'M' }, { "machine", required_argument, NULL, 'M' },
{ "slice", required_argument, NULL, 'S' }, { "slice", required_argument, NULL, 'S' },
{ "setenv", required_argument, NULL, ARG_SETENV },
{} {}
}; };
@ -333,6 +338,23 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
} }
case ARG_SETENV: {
char **n;
if (!env_assignment_is_valid(optarg)) {
log_error("Environment variable assignment '%s' is not valid.", optarg);
return -EINVAL;
}
n = strv_env_set(arg_setenv, optarg);
if (!n)
return log_oom();
strv_free(arg_setenv);
arg_setenv = n;
break;
}
case '?': case '?':
return -EINVAL; return -EINVAL;
@ -1232,6 +1254,7 @@ int main(int argc, char *argv[]) {
NULL, /* LISTEN_PID */ NULL, /* LISTEN_PID */
NULL NULL
}; };
char **env_use;
envp[n_env] = strv_find_prefix(environ, "TERM="); envp[n_env] = strv_find_prefix(environ, "TERM=");
if (envp[n_env]) if (envp[n_env])
@ -1459,6 +1482,19 @@ int main(int argc, char *argv[]) {
setup_hostname(); setup_hostname();
if (!strv_isempty(arg_setenv)) {
char **n;
n = strv_env_merge(2, envp, arg_setenv);
if (!n) {
log_oom();
goto child_fail;
}
env_use = n;
} else
env_use = (char**) envp;
if (arg_boot) { if (arg_boot) {
char **a; char **a;
size_t l; size_t l;
@ -1470,18 +1506,18 @@ int main(int argc, char *argv[]) {
memcpy(a + 1, argv + optind, l * sizeof(char*)); memcpy(a + 1, argv + optind, l * sizeof(char*));
a[0] = (char*) "/usr/lib/systemd/systemd"; a[0] = (char*) "/usr/lib/systemd/systemd";
execve(a[0], a, (char**) envp); execve(a[0], a, env_use);
a[0] = (char*) "/lib/systemd/systemd"; a[0] = (char*) "/lib/systemd/systemd";
execve(a[0], a, (char**) envp); execve(a[0], a, env_use);
a[0] = (char*) "/sbin/init"; a[0] = (char*) "/sbin/init";
execve(a[0], a, (char**) envp); execve(a[0], a, env_use);
} else if (argc > optind) } else if (argc > optind)
execvpe(argv[optind], argv + optind, (char**) envp); execvpe(argv[optind], argv + optind, env_use);
else { else {
chdir(home ? home : "/root"); chdir(home ? home : "/root");
execle("/bin/bash", "-bash", NULL, (char**) envp); execle("/bin/bash", "-bash", NULL, env_use);
} }
log_error("execv() failed: %m"); log_error("execv() failed: %m");
@ -1552,6 +1588,7 @@ finish:
free(arg_directory); free(arg_directory);
free(arg_machine); free(arg_machine);
free(arg_setenv);
return r; return r;
} }