]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
conf: split `lxc.environment` into `runtime` and `hooks`
authorFilip Schauer <f.schauer@proxmox.com>
Mon, 8 Sep 2025 09:11:31 +0000 (11:11 +0200)
committerFiliprogrammer <44641787+Filiprogrammer@users.noreply.github.com>
Mon, 15 Sep 2025 09:16:12 +0000 (11:16 +0200)
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 <f.schauer@proxmox.com>
src/lxc/attach.c
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/start.c

index 8f2f7a37c3a5e27667ed9db12ada1d12c8cb5f85..f22f83f0df201f87e6b37adf9d3f31f7ed47df0d 100644 (file)
@@ -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;
        }
index 1899b2806d70a367d0df7ac558bab1c823f51f0b..7533e283098e06603e0d2fbd0faa9cfe3b1d8c4d 100644 (file)
@@ -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);
index 31cd39e3f71a0bce9151309077ec4d45ecc4accf..762d58901de2f34c6cd25398ffbfe794ebefd4d3 100644 (file)
@@ -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 */
index 5045741bb010ca757115dadafed0ef3ed3e93f01..7163cd1b227b62f4652411a4bd8c1e08c3ca7b83 100644 (file)
@@ -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")) {
index d566dd5ddbf95e2b35b82cf4387787e0c4a31c0b..b8559bbebf3963413e289119587d5217ed57930d 100644 (file)
@@ -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;