[systemd-commits] 2 commits - man/systemd-nspawn.xml src/getty-generator src/nspawn
Lennart Poettering
lennart at kemper.freedesktop.org
Fri Dec 13 07:58:40 PST 2013
man/systemd-nspawn.xml | 15 ++++++++++
src/getty-generator/getty-generator.c | 49 ++++++++++++++++++++++++++++++++
src/nspawn/nspawn.c | 51 +++++++++++++++++++++++++++++-----
3 files changed, 108 insertions(+), 7 deletions(-)
New commits:
commit 1d97ff7dd71902a5604c2fed8964925d54e09de9
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 13 16:37:58 2013 +0100
getty-generator: look add an environment variable $container_ttys set for PID 1 and start gettys on all ttys listed therein
diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c
index 0dc407d..36a9369 100644
--- a/src/getty-generator/getty-generator.c
+++ b/src/getty-generator/getty-generator.c
@@ -29,6 +29,7 @@
#include "unit-name.h"
#include "virt.h"
#include "fileio.h"
+#include "path-util.h"
static const char *arg_dest = "/tmp";
@@ -77,6 +78,20 @@ static int add_serial_getty(const char *tty) {
return add_symlink("serial-getty at .service", n);
}
+static int add_container_getty(const char *tty) {
+ _cleanup_free_ char *n = NULL;
+
+ assert(tty);
+
+ log_debug("Automatically adding container getty for /dev/pts/%s.", tty);
+
+ n = unit_name_replace_instance("container-getty at .service", tty);
+ if (!n)
+ return log_oom();
+
+ return add_symlink("container-getty at .service", n);
+}
+
int main(int argc, char *argv[]) {
static const char virtualization_consoles[] =
@@ -86,6 +101,7 @@ int main(int argc, char *argv[]) {
_cleanup_free_ char *active = NULL;
const char *j;
+ int r;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
@@ -102,11 +118,44 @@ int main(int argc, char *argv[]) {
umask(0022);
if (detect_container(NULL) > 0) {
+ _cleanup_free_ char *container_ttys = NULL;
+
log_debug("Automatically adding console shell.");
if (add_symlink("console-getty.service", "console-getty.service") < 0)
return EXIT_FAILURE;
+ /* When $container_ttys is set for PID 1, spawn
+ * gettys on all ptys named therein. Note that despite
+ * the variable name we only support ptys here. */
+
+ r = getenv_for_pid(1, "container_ttys", &container_ttys);
+ if (r >= 0) {
+ char *w, *state;
+ size_t l;
+
+ FOREACH_WORD(w, l, container_ttys, state) {
+ const char *t;
+ char tty[l + 1];
+
+ memcpy(tty, w, l);
+ tty[l] = 0;
+
+ /* First strip off /dev/ if it is specified */
+ t = path_startswith(tty, "/dev/");
+ if (!t)
+ t = tty;
+
+ /* Then, make sure it's actually a pty */
+ t = path_startswith(tty, "pts/");
+ if (!t)
+ continue;
+
+ if (add_container_getty(t) < 0)
+ return EXIT_FAILURE;
+ }
+ }
+
/* Don't add any further magic if we are in a container */
return EXIT_SUCCESS;
}
commit f4889f656b477887b02caa5e9d27387309c75a87
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 13 16:37:16 2013 +0100
nspawn: add new --setenv= switch to set an environment variable for the container to spawn
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 6b7ba98..bec233c 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -380,6 +380,21 @@
creates read-only bind
mount.</para></listitem>
</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>
</refsect1>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index c5faac4..a85579b 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -62,6 +62,7 @@
#include "bus-error.h"
#include "ptyfwd.h"
#include "bus-kernel.h"
+#include "env-util.h"
#ifndef TTY_GID
#define TTY_GID 5
@@ -111,6 +112,7 @@ static uint64_t arg_retain =
(1ULL << CAP_AUDIT_CONTROL);
static char **arg_bind = NULL;
static char **arg_bind_ro = NULL;
+static char **arg_setenv = NULL;
static int help(void) {
@@ -133,7 +135,8 @@ static int help(void) {
" -j Equivalent to --link-journal=host\n"
" --bind=PATH[:PATH] Bind mount a file or directory from the host into\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);
return 0;
@@ -150,7 +153,8 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DROP_CAPABILITY,
ARG_LINK_JOURNAL,
ARG_BIND,
- ARG_BIND_RO
+ ARG_BIND_RO,
+ ARG_SETENV,
};
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 },
{ "machine", required_argument, NULL, 'M' },
{ "slice", required_argument, NULL, 'S' },
+ { "setenv", required_argument, NULL, ARG_SETENV },
{}
};
@@ -333,6 +338,23 @@ static int parse_argv(int argc, char *argv[]) {
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 '?':
return -EINVAL;
@@ -1232,6 +1254,7 @@ int main(int argc, char *argv[]) {
NULL, /* LISTEN_PID */
NULL
};
+ char **env_use;
envp[n_env] = strv_find_prefix(environ, "TERM=");
if (envp[n_env])
@@ -1459,6 +1482,19 @@ int main(int argc, char *argv[]) {
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) {
char **a;
size_t l;
@@ -1470,18 +1506,18 @@ int main(int argc, char *argv[]) {
memcpy(a + 1, argv + optind, l * sizeof(char*));
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";
- execve(a[0], a, (char**) envp);
+ execve(a[0], a, env_use);
a[0] = (char*) "/sbin/init";
- execve(a[0], a, (char**) envp);
+ execve(a[0], a, env_use);
} else if (argc > optind)
- execvpe(argv[optind], argv + optind, (char**) envp);
+ execvpe(argv[optind], argv + optind, env_use);
else {
chdir(home ? home : "/root");
- execle("/bin/bash", "-bash", NULL, (char**) envp);
+ execle("/bin/bash", "-bash", NULL, env_use);
}
log_error("execv() failed: %m");
@@ -1552,6 +1588,7 @@ finish:
free(arg_directory);
free(arg_machine);
+ free(arg_setenv);
return r;
}
More information about the systemd-commits
mailing list