[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