Support providing env vars to container init

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 <mpalmer@hezmatt.org>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
Matt Palmer 2014-07-01 17:01:39 +10:00 committed by Stéphane Graber
parent acabe1faee
commit 7c6617262d
5 changed files with 78 additions and 1 deletions

View File

@ -1514,6 +1514,44 @@ mknod errno 0
</para>
</refsect2>
<refsect2>
<title>Container Environment</title>
<para>
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 <command>lxc.environment</command>
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
<command>/proc/PID/environ</command>.
</para>
<para>
This configuration parameter can be specified multiple times; once
for each environment variable you wish to configure.
</para>
<variablelist>
<varlistentry>
<term>
<option>lxc.environment</option>
</term>
<listitem>
<para>
Specify an environment variable to pass into the container.
Example:
</para>
<programlisting>
lxc.environment = APP_ENV=production
lxc.environment = SYSLOG_SERVER=192.0.2.42
</programlisting>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<refsect1>

View File

@ -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; i<NUM_LXC_HOOKS; i++)
lxc_list_init(&new->hooks[i]);
lxc_list_init(&new->groups);

View File

@ -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,

View File

@ -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)
{

View File

@ -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;
}