diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index ed8bef7e1..cd49b8662 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -1636,9 +1636,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA at various times in a container's lifetime. - When a container hook is executed, information is passed both - as command line arguments and through environment variables. - The arguments are: + When a container hook is executed, additional information is passed + along. The argument can be used to + determine if the following arguments are passed as command line + arguments or through environment variables. The arguments are: Container name. Section (always 'lxc'). @@ -1652,13 +1653,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA The following environment variables are set: + LXC_CGNS_AWARE: indicator whether the container is + cgroup namespace aware. + LXC_CONFIG_FILE: the path to the container + configuration file. + LXC_HOOK_TYPE: the hook type (e.g. 'clone', 'mount', + 'pre-mount'). Note that the existence of this environment variable is + conditional on the value of . If it + is set to 1 then LXC_HOOK_TYPE will be set. + + LXC_HOOK_SECTION: the section type (e.g. 'lxc', + 'net'). Note that the existence of this environment variable is + conditional on the value of . If it + is set to 1 then LXC_HOOK_SECTION will be set. + + LXC_LOG_LEVEL: the container's log level. LXC_NAME: is the container's name. LXC_ROOTFS_MOUNT: the path to the mounted root filesystem. - LXC_CONFIG_FILE: the path to the container configuration file. - LXC_SRC_NAME: in the case of the clone hook, this is the original container's name. - LXC_ROOTFS_PATH: this is the lxc.rootfs.path entry for the container. Note this is likely not where the mounted rootfs is to be found, use LXC_ROOTFS_MOUNT for that. - LXC_CGNS_AWARE: indicated whether the container is cgroup namespace aware. - LXC_LOG_LEVEL: the container's log level. + LXC_ROOTFS_PATH: this is the lxc.rootfs.path entry + for the container. Note this is likely not where the mounted rootfs is + to be found, use LXC_ROOTFS_MOUNT for that. + LXC_SRC_NAME: in the case of the clone hook, this is + the original container's name. @@ -1666,6 +1682,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Standard error is not logged, but can be captured by the hook redirecting its standard error to standard output. + + + + + + + + To pass the arguments in new style via environment variables set to + 1 otherwise set to 0 to pass them as arguments. + This setting affects all hooks arguments that were traditionally + passed as arguments to the script. Specifically, it affects the + container name, section (e.g. 'lxc', 'net') and hook type (e.g. + 'clone', 'mount', 'pre-mount') arguments. If new-style hooks are + used then the arguments will be available as environment variables. + The container name will be set in LXC_NAME. (This is set + independently of the value used for this config item.) The section + will be set in LXC_HOOK_SECTION and the hook type will be set in + LXC_HOOK_TYPE. + + + + diff --git a/src/lxc/conf.c b/src/lxc/conf.c index e1973a10c..0da760933 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2484,6 +2484,7 @@ struct lxc_conf *lxc_conf_init(void) lxc_list_init(&new->limits); lxc_list_init(&new->sysctls); lxc_list_init(&new->procs); + new->hooks_version = 0; 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 f7a2ed2a8..d4b48cc40 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -295,7 +295,11 @@ struct lxc_conf { struct lxc_rootfs rootfs; char *ttydir; int close_all_fds; - struct lxc_list hooks[NUM_LXC_HOOKS]; + + struct { + unsigned int hooks_version; + struct lxc_list hooks[NUM_LXC_HOOKS]; + }; char *lsm_aa_profile; unsigned int lsm_aa_allow_incomplete; diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 5a11d7828..cde4f3e86 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -92,6 +92,7 @@ lxc_config_define(ephemeral); lxc_config_define(execute_cmd); lxc_config_define(group); lxc_config_define(hooks); +lxc_config_define(hooks_version); lxc_config_define(idmaps); lxc_config_define(includefiles); lxc_config_define(init_cmd); @@ -168,11 +169,12 @@ static struct lxc_config_t config[] = { { "lxc.hook.destroy", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, { "lxc.hook.mount", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, { "lxc.hook.post-stop", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.start-host", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, - { "lxc.hook.pre-start", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, { "lxc.hook.pre-mount", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.pre-start", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, { "lxc.hook.start", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.start-host", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, { "lxc.hook.stop", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, + { "lxc.hook.version", false, set_config_hooks_version, get_config_hooks_version, clr_config_hooks_version, }, { "lxc.hook", false, set_config_hooks, get_config_hooks, clr_config_hooks, }, { "lxc.idmap", false, set_config_idmaps, get_config_idmaps, clr_config_idmaps, }, { "lxc.include", false, set_config_includefiles, get_config_includefiles, clr_config_includefiles, }, @@ -980,6 +982,29 @@ static int set_config_hooks(const char *key, const char *value, return -1; } +static int set_config_hooks_version(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) +{ + int ret; + unsigned int tmp; + + if (lxc_config_value_empty(value)) + return clr_config_hooks_version(key, lxc_conf, NULL); + + ret = lxc_safe_uint(value, &tmp); + if (ret < 0) + return -1; + + if (tmp > 1) { + ERROR("Invalid hook version specified. Currently only 0 " + "(legacy) and 1 are supported"); + return -1; + } + + lxc_conf->hooks_version = tmp; + return 0; +} + static int set_config_personality(const char *key, const char *value, struct lxc_conf *lxc_conf, void *data) { @@ -3154,6 +3179,12 @@ static int get_config_hooks(const char *key, char *retv, int inlen, return fulllen; } +static int get_config_hooks_version(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) +{ + return lxc_get_conf_int(c, retv, inlen, c->hooks_version); +} + static int get_config_net(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) { @@ -3688,6 +3719,14 @@ static inline int clr_config_hooks(const char *key, struct lxc_conf *c, return lxc_clear_hooks(c, key); } +static inline int clr_config_hooks_version(const char *key, struct lxc_conf *c, + void *data) +{ + /* default to legacy hooks version */ + c->hooks_version = 0; + return 0; +} + static inline int clr_config_net(const char *key, struct lxc_conf *c, void *data) { diff --git a/src/tests/parse_config_file.c b/src/tests/parse_config_file.c index f6fda5a05..8c19ea2b8 100644 --- a/src/tests/parse_config_file.c +++ b/src/tests/parse_config_file.c @@ -301,16 +301,16 @@ static int set_get_compare_clear_save_load_network( int main(int argc, char *argv[]) { + int ret; struct lxc_container *c; - int fd = -1; - int ret = EXIT_FAILURE; + int fd = -1, fret = EXIT_FAILURE; char tmpf[] = "lxc-parse-config-file-XXXXXX"; char retval[4096] = {0}; fd = mkstemp(tmpf); if (fd < 0) { lxc_error("%s\n", "Could not create temporary file"); - exit(ret); + exit(fret); } close(fd); @@ -1110,10 +1110,23 @@ int main(int argc, char *argv[]) goto non_test_error; } - ret = EXIT_SUCCESS; + ret = set_get_compare_clear_save_load(c, "lxc.hook.version", "1", tmpf, true); + if (ret < 0) { + lxc_error("%s\n", "lxc.hook.version"); + goto non_test_error; + } + + ret = set_get_compare_clear_save_load(c, "lxc.hook.version", "2", tmpf, true); + if (ret == 0) { + lxc_error("%s\n", "lxc.hook.version"); + goto non_test_error; + } + + fret = EXIT_SUCCESS; + non_test_error: (void)unlink(tmpf); (void)rmdir(dirname(c->configfile)); lxc_container_put(c); - exit(ret); + exit(fret); }