[lxc-devel] [PATCH 1/2] Support providing env vars to container init

Serge Hallyn serge.hallyn at ubuntu.com
Mon Jul 21 23:44:50 UTC 2014


Quoting Stéphane Graber (stgraber at ubuntu.com):
> From: Matt Palmer <mpalmer at hezmatt.org>
> 
> 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 at hezmatt.org>
> Acked-by: Stéphane Graber <stgraber at ubuntu.com>
> ---
>  doc/lxc.container.conf.sgml.in | 38 ++++++++++++++++++++++++++++++++++++++
>  src/lxc/conf.c                 |  1 +
>  src/lxc/conf.h                 |  4 ++++
>  src/lxc/confile.c              | 23 +++++++++++++++++++++++
>  src/lxc/start.c                | 10 +++++++++-
>  5 files changed, 75 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
> index 4f8e4e9..d0c18fe 100644
> --- a/doc/lxc.container.conf.sgml.in
> +++ b/doc/lxc.container.conf.sgml.in
> @@ -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>
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index 052db98..e930b4d 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; i<NUM_LXC_HOOKS; i++)
>  		lxc_list_init(&new->hooks[i]);
>  	lxc_list_init(&new->groups);
> diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> index 3527c44..1bc6ba3 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 f3cab6b..2f32776 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,27 @@ 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);

putenv will segv if the allocation fails here (i.e. list_item->elem is NULL).
Please do add a check for that.  Other than that,

Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>


> +	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 555e4c4..bb136af 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;
>  	}
>  
> -- 
> 1.9.1
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel


More information about the lxc-devel mailing list