From 7c6617262d4cd1f8f2c1721aca980ecd71117bd5 Mon Sep 17 00:00:00 2001 From: Matt Palmer Date: Tue, 1 Jul 2014 17:01:39 +1000 Subject: [PATCH] Support providing env vars to container init MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit It's quite useful to be able to configure containers by specifying environment variables, which init (or initscripts) can use to adjust the container's operation. This patch adds one new configuration parameter, `lxc.environment`, which can be specified zero or more times to define env vars to set in the container, like this: lxc.environment = APP_ENV=production lxc.environment = SYSLOG_SERVER=192.0.2.42 lxc.environment = SOMETHING_FUNNY=platypus Default operation is unchanged; if the user doesn't specify any lxc.environment parameters, the container environment will be what it is today ('container=lxc'). Signed-off-by: Matt Palmer Acked-by: Stéphane Graber Acked-by: Serge E. Hallyn --- doc/lxc.container.conf.sgml.in | 38 ++++++++++++++++++++++++++++++++++ src/lxc/conf.c | 1 + src/lxc/conf.h | 4 ++++ src/lxc/confile.c | 26 +++++++++++++++++++++++ src/lxc/start.c | 10 ++++++++- 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index 4f8e4e9ec..d0c18fe46 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -1514,6 +1514,44 @@ mknod errno 0 + + + Container Environment + + If you want to pass environment variables into the container (that + is, environment variables which will be available to init and all of + its descendents), you can use lxc.environment + parameters to do so. Be careful that you do not pass in anything + sensitive; any process in the container which doesn't have its + environment scrubbed will have these variables available to it, and + environment variables are always available via + /proc/PID/environ. + + + + This configuration parameter can be specified multiple times; once + for each environment variable you wish to configure. + + + + + + + + + + Specify an environment variable to pass into the container. + Example: + + + lxc.environment = APP_ENV=production + lxc.environment = SYSLOG_SERVER=192.0.2.42 + + + + + + diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 052db9841..e930b4de6 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2701,6 +2701,7 @@ struct lxc_conf *lxc_conf_init(void) lxc_list_init(&new->id_map); lxc_list_init(&new->includes); lxc_list_init(&new->aliens); + lxc_list_init(&new->environment); for (i=0; ihooks[i]); lxc_list_init(&new->groups); diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 3527c4403..1bc6ba310 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -344,6 +344,10 @@ struct lxc_conf { struct lxc_list includes; /* config entries which are not "lxc.*" are aliens */ struct lxc_list aliens; + + /* list of environment variables we'll add to the container when + * started */ + struct lxc_list environment; }; int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, diff --git a/src/lxc/confile.c b/src/lxc/confile.c index f3cab6be8..44e28d5a3 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -96,6 +96,7 @@ static int config_haltsignal(const char *, const char *, struct lxc_conf *); static int config_stopsignal(const char *, const char *, struct lxc_conf *); static int config_start(const char *, const char *, struct lxc_conf *); static int config_group(const char *, const char *, struct lxc_conf *); +static int config_environment(const char *, const char *, struct lxc_conf *); static struct lxc_config_t config[] = { @@ -152,6 +153,7 @@ static struct lxc_config_t config[] = { { "lxc.start.delay", config_start }, { "lxc.start.order", config_start }, { "lxc.group", config_group }, + { "lxc.environment", config_environment }, }; struct signame { @@ -1064,6 +1066,30 @@ static int config_group(const char *key, const char *value, return ret; } +static int config_environment(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + struct lxc_list *list_item = NULL; + + list_item = malloc(sizeof(*list_item)); + if (!list_item) + goto freak_out; + + list_item->elem = strdup(value); + + if (!list_item->elem) + goto freak_out; + + lxc_list_add_tail(&lxc_conf->environment, list_item); + + return 0; + +freak_out: + if (list_item) free(list_item); + + return -1; +} + static int config_tty(const char *key, const char *value, struct lxc_conf *lxc_conf) { diff --git a/src/lxc/start.c b/src/lxc/start.c index 555e4c47e..bb136af0d 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -609,6 +609,7 @@ static int read_unpriv_netifindex(struct lxc_list *network) static int do_start(void *data) { + struct lxc_list *iterator; struct lxc_handler *handler = data; const char *lsm_label = NULL; @@ -727,8 +728,15 @@ static int do_start(void *data) /* don't error out though */ } + lxc_list_for_each(iterator, &handler->conf->environment) { + if (putenv((char *)iterator->elem)) { + SYSERROR("failed to set environment variable '%s'", (char *)iterator->elem); + goto out_warn_father; + } + } + if (putenv("container=lxc")) { - SYSERROR("failed to set environment variable"); + SYSERROR("failed to set environment variable 'container=lxc'"); goto out_warn_father; } -- 2.47.2