Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/api-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,10 @@ This adds the new options `cgroup2`, `cgroup2:ro`, `cgroup2:force`,
`cgroup2:ro:force` for the `lxc.mount.auto` configuration key. For example, if
a user specifies `cgroup2:force` LXC will pre-mount a pure `cgroup2` layout for
the container even if the host is running with a hybrid layout.

## environment\_runtime\_hooks

This introduces `lxc.environment.runtime` and `lxc.environment.hooks`
configuration keys to allow environment variables to be applied only to the
container init process or only to hooks respectively.
`lxc.environment` remains and still applies to both.
36 changes: 33 additions & 3 deletions doc/lxc.container.conf.sgml.in
Original file line number Diff line number Diff line change
Expand Up @@ -2990,7 +2990,14 @@
</para>

<para>
This configuration parameter can be specified multiple times; once
Subkeys are available to narrow the scope of environment variables:
<command>lxc.environment.runtime</command> applies only to
the container's init process (and all its descendents),
and <command>lxc.environment.hooks</command> applies only to hooks.
</para>

<para>
These configuration parameters can be specified multiple times; once
for each environment variable you wish to configure.
</para>

Expand All @@ -3001,8 +3008,8 @@
</term>
<listitem>
<para>
Specify an environment variable to pass into the container.
Example:
Environment variables applied both to the container init process
and to hooks. Example:
</para>
<programlisting>
lxc.environment = APP_ENV=production
Expand All @@ -3017,6 +3024,29 @@
</programlisting>
</listitem>
</varlistentry>

<varlistentry>
<term>
<option>lxc.environment.runtime</option>
</term>
<listitem>
<para>
Environment variables applied only to the container's init
process.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term>
<option>lxc.environment.hooks</option>
</term>
<listitem>
<para>
Environment variables applied only to hooks.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>

Expand Down
1 change: 1 addition & 0 deletions src/lxc/api_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ static char *api_extensions[] = {
"idmapped_mounts_v2",
"core_scheduling",
"cgroup2_auto_mounting",
"environment_runtime_hooks",
};

static size_t nr_api_extensions = sizeof(api_extensions) / sizeof(*api_extensions);
Expand Down
6 changes: 5 additions & 1 deletion src/lxc/attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,11 @@ static int lxc_attach_set_environment(struct attach_context *ctx,

/* Set container environment variables.*/
if (ctx->container->lxc_conf) {
ret = lxc_set_environment(ctx->container->lxc_conf);
ret = lxc_set_environment(&ctx->container->lxc_conf->environment);
if (ret < 0)
return -1;

ret = lxc_set_environment(&ctx->container->lxc_conf->environment_runtime);
if (ret < 0)
return -1;
}
Expand Down
14 changes: 8 additions & 6 deletions src/lxc/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3209,6 +3209,8 @@ struct lxc_conf *lxc_conf_init(void)
new->root_nsuid_map = NULL;
new->root_nsgid_map = NULL;
INIT_LIST_HEAD(&new->environment);
INIT_LIST_HEAD(&new->environment_runtime);
INIT_LIST_HEAD(&new->environment_hooks);
INIT_LIST_HEAD(&new->limits);
INIT_LIST_HEAD(&new->sysctls);
INIT_LIST_HEAD(&new->procs);
Expand Down Expand Up @@ -4239,18 +4241,18 @@ int lxc_clear_groups(struct lxc_conf *c)
return 0;
}

int lxc_clear_environment(struct lxc_conf *c)
int lxc_clear_environment(struct list_head *environment)
{
struct environment_entry *env, *nenv;

list_for_each_entry_safe(env, nenv, &c->environment, head) {
list_for_each_entry_safe(env, nenv, environment, head) {
list_del(&env->head);
free(env->key);
free(env->val);
free(env);
}

INIT_LIST_HEAD(&c->environment);
INIT_LIST_HEAD(environment);
return 0;
}

Expand Down Expand Up @@ -4359,7 +4361,7 @@ void lxc_conf_free(struct lxc_conf *conf)
lxc_clear_mount_entries(conf);
lxc_clear_idmaps(conf);
lxc_clear_groups(conf);
lxc_clear_environment(conf);
lxc_clear_environment(&conf->environment);
lxc_clear_limits(conf, "lxc.prlimit");
lxc_clear_sysctls(conf, "lxc.sysctl");
lxc_clear_procs(conf, "lxc.proc");
Expand Down Expand Up @@ -5210,11 +5212,11 @@ void suggest_default_idmap(void)
ERROR("lxc.idmap = g 0 %u %u", gid, grange);
}

int lxc_set_environment(const struct lxc_conf *conf)
int lxc_set_environment(const struct list_head *environment)
{
struct environment_entry *env;

list_for_each_entry(env, &conf->environment, head) {
list_for_each_entry(env, environment, head) {
int ret;

ret = setenv(env->key, env->val, 1);
Expand Down
15 changes: 11 additions & 4 deletions src/lxc/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,10 +506,17 @@ struct lxc_conf {
unsigned int monitor_unshare;
unsigned int monitor_signal_pdeath;

/* list of environment variables we'll add to the container when
* started */
/* list of environment variables to provide to both the container's init
* process and hooks */
struct list_head environment;

/* list of environment variables to provide to the container's init
* process */
struct list_head environment_runtime;

/* list of environment variables to provide to container hooks */
struct list_head environment_hooks;

/* text representation of the config file */
char *unexpanded_config;
size_t unexpanded_len;
Expand Down Expand Up @@ -599,7 +606,7 @@ __hidden extern int lxc_clear_automounts(struct lxc_conf *c);
__hidden extern int lxc_clear_hooks(struct lxc_conf *c, const char *key);
__hidden extern int lxc_clear_idmaps(struct lxc_conf *c);
__hidden extern int lxc_clear_groups(struct lxc_conf *c);
__hidden extern int lxc_clear_environment(struct lxc_conf *c);
__hidden extern int lxc_clear_environment(struct list_head *environment);
__hidden extern int lxc_clear_limits(struct lxc_conf *c, const char *key);
__hidden extern int lxc_delete_autodev(struct lxc_handler *handler);
__hidden extern int lxc_clear_autodev_tmpfs_size(struct lxc_conf *c);
Expand Down Expand Up @@ -710,7 +717,7 @@ static inline int lxc_personality(personality_t persona)
return personality(persona);
}

__hidden extern int lxc_set_environment(const struct lxc_conf *conf);
__hidden extern int lxc_set_environment(const struct list_head *environment);
__hidden extern int parse_cap(const char *cap_name, __u32 *cap);

#endif /* __LXC_CONF_H */
72 changes: 64 additions & 8 deletions src/lxc/confile.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ lxc_config_define(console_rotate);
lxc_config_define(console_size);
lxc_config_define(unsupported_key);
lxc_config_define(environment);
lxc_config_define(environment_runtime);
lxc_config_define(environment_hooks);
lxc_config_define(ephemeral);
lxc_config_define(execute_cmd);
lxc_config_define(group);
Expand Down Expand Up @@ -211,6 +213,8 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.console.rotate", true, set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, },
{ "lxc.console.size", true, set_config_console_size, get_config_console_size, clr_config_console_size, },
{ "lxc.sched.core", true, set_config_sched_core, get_config_sched_core, clr_config_sched_core, },
{ "lxc.environment.runtime", true, set_config_environment_runtime, get_config_environment_runtime, clr_config_environment_runtime },
{ "lxc.environment.hooks", true, set_config_environment_hooks, get_config_environment_hooks, clr_config_environment_hooks },
{ "lxc.environment", true, set_config_environment, get_config_environment, clr_config_environment, },
{ "lxc.ephemeral", true, set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, },
{ "lxc.execute.cmd", true, set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, },
Expand Down Expand Up @@ -1574,15 +1578,15 @@ static int set_config_group(const char *key, const char *value,
return 0;
}

static int set_config_environment(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
static int set_config_environment_impl(const char *value,
struct list_head *environment)
{
__do_free char *dup = NULL, *val = NULL;
__do_free struct environment_entry *new_env = NULL;
char *env_val;

if (lxc_config_value_empty(value))
return lxc_clear_environment(lxc_conf);
return lxc_clear_environment(environment);

new_env = zalloc(sizeof(struct environment_entry));
if (!new_env)
Expand All @@ -1609,12 +1613,30 @@ static int set_config_environment(const char *key, const char *value,
new_env->key = move_ptr(dup);
new_env->val = move_ptr(val);

list_add_tail(&new_env->head, &lxc_conf->environment);
list_add_tail(&new_env->head, environment);
move_ptr(new_env);

return 0;
}

static int set_config_environment(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
return set_config_environment_impl(value, &lxc_conf->environment);
}

static int set_config_environment_runtime(const char *key, const char* value,
struct lxc_conf *lxc_conf, void *data)
{
return set_config_environment_impl(value, &lxc_conf->environment_runtime);
}

static int set_config_environment_hooks(const char *key, const char* value,
struct lxc_conf *lxc_conf, void *data)
{
return set_config_environment_impl(value, &lxc_conf->environment_hooks);
}

static int set_config_tty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
Expand Down Expand Up @@ -4473,8 +4495,8 @@ static int get_config_group(const char *key, char *retv, int inlen,
return fulllen;
}

static int get_config_environment(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
static int get_config_environment_impl(char *retv, int inlen,
struct list_head *environment)
{
int len, fulllen = 0;
struct environment_entry *env;
Expand All @@ -4484,13 +4506,32 @@ static int get_config_environment(const char *key, char *retv, int inlen,
else
memset(retv, 0, inlen);

list_for_each_entry(env, &c->environment, head) {
list_for_each_entry(env, environment, head) {
strprint(retv, inlen, "%s=%s\n", env->key, env->val);
}

return fulllen;
}

static int get_config_environment(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return get_config_environment_impl(retv, inlen, &c->environment);
}

static int get_config_environment_runtime(const char *key, char *retv,
int inlen, struct lxc_conf *c,
void *data)
{
return get_config_environment_impl(retv, inlen, &c->environment_runtime);
}

static int get_config_environment_hooks(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return get_config_environment_impl(retv, inlen, &c->environment_hooks);
}

static int get_config_execute_cmd(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
Expand Down Expand Up @@ -5211,7 +5252,19 @@ static inline int clr_config_group(const char *key, struct lxc_conf *c,
static inline int clr_config_environment(const char *key, struct lxc_conf *c,
void *data)
{
return lxc_clear_environment(c);
return lxc_clear_environment(&c->environment);
}

static inline int clr_config_environment_runtime(const char *key,
struct lxc_conf *c, void *data)
{
return lxc_clear_environment(&c->environment_runtime);
}

static inline int clr_config_environment_hooks(const char *key,
struct lxc_conf *c, void *data)
{
return lxc_clear_environment(&c->environment_hooks);
}

static inline int clr_config_execute_cmd(const char *key, struct lxc_conf *c,
Expand Down Expand Up @@ -6607,6 +6660,9 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
} else if (strequal(key, "lxc.console")) {
strprint(retv, inlen, "logfile\n");
strprint(retv, inlen, "path\n");
} else if (strequal(key, "lxc.environment")) {
strprint(retv, inlen, "runtime\n");
strprint(retv, inlen, "hooks\n");
} else if (strequal(key, "lxc.seccomp")) {
strprint(retv, inlen, "profile\n");
} else if (strequal(key, "lxc.signal")) {
Expand Down
12 changes: 10 additions & 2 deletions src/lxc/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,11 @@ static int do_start(void *data)
* to allow them to be used by the various hooks, such as the start
* hook below.
*/
ret = lxc_set_environment(handler->conf);
ret = lxc_set_environment(&handler->conf->environment);
if (ret < 0)
goto out_warn_father;

ret = lxc_set_environment(&handler->conf->environment_hooks);
if (ret < 0)
goto out_warn_father;

Expand Down Expand Up @@ -1552,7 +1556,11 @@ static int do_start(void *data)
if (ret < 0)
SYSERROR("Failed to clear environment.");

ret = lxc_set_environment(handler->conf);
ret = lxc_set_environment(&handler->conf->environment);
if (ret < 0)
goto out_warn_father;

ret = lxc_set_environment(&handler->conf->environment_runtime);
if (ret < 0)
goto out_warn_father;

Expand Down