From: Filip Schauer Date: Mon, 8 Sep 2025 09:11:31 +0000 (+0200) Subject: conf: split `lxc.environment` into `runtime` and `hooks` X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbd37f04c5aebc06ab2a2066fd56787a4c71820a;p=thirdparty%2Flxc.git conf: split `lxc.environment` into `runtime` and `hooks` Introduce `lxc.environment.runtime` to set environment variables only for the container init process and `lxc.environment.hooks` to set environment variables only for hooks. Leave the original `lxc.environment` unchanged. It still applies to everything. Signed-off-by: Filip Schauer --- diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 8f2f7a37c..f22f83f0d 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -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; } diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 1899b2806..7533e2830 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -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); @@ -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; } @@ -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"); @@ -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); diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 31cd39e3f..762d58901 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -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; @@ -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); @@ -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 */ diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 5045741bb..7163cd1b2 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -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); @@ -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, }, @@ -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) @@ -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) { @@ -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; @@ -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) { @@ -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, @@ -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")) { diff --git a/src/lxc/start.c b/src/lxc/start.c index d566dd5dd..b8559bbeb 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -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; @@ -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;