When running an application container, setting environment variables
could be important.
The newly introduced tag in domain configuration will allow
setting environment variables to the init program.
---
docs/formatdomain.html.in| 5 +
docs/schemas/domaincommon.rng| 10 ++
src/conf/domain_conf.c | 38
src/conf/domain_conf.h | 8
src/lxc/lxc_container.c | 5 +
tests/lxcxml2xmldata/lxc-initenv.xml | 30
tests/lxcxml2xmltest.c | 1 +
7 files changed, 97 insertions(+)
create mode 100644 tests/lxcxml2xmldata/lxc-initenv.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 07208eef8..8da50875b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -326,6 +326,10 @@
element, if set will be used to provide an equivalent to
/proc/cmdline
but will not affect init argv.
+
+ To set environment variables, use the initenv element, one
+ for each variable.
+
os
@@ -333,6 +337,7 @@
init/bin/systemd/init
initarg--unit/initarg
initargemergency.service/initarg
+ initenv name='MYENV'some value/initenv
/os
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4d9f8d1a2..695214816 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -385,6 +385,16 @@
+
+
+
+
+[a-zA-Z_]+[a-zA-Z0-9_]*
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c7e20b8ba..89c803047 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2799,6 +2799,9 @@ void virDomainDefFree(virDomainDefPtr def)
for (i = 0; def->os.initargv && def->os.initargv[i]; i++)
VIR_FREE(def->os.initargv[i]);
VIR_FREE(def->os.initargv);
+for (i = 0; def->os.initenv && def->os.initenv[i]; i++)
+VIR_FREE(def->os.initenv[i]);
+VIR_FREE(def->os.initenv);
VIR_FREE(def->os.kernel);
VIR_FREE(def->os.initrd);
VIR_FREE(def->os.cmdline);
@@ -16776,6 +16779,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def,
xmlNodePtr *nodes = NULL;
xmlNodePtr oldnode;
char *tmp = NULL;
+char *name = NULL;
int ret = -1;
size_t i;
int n;
@@ -16811,6 +16815,37 @@ virDomainDefParseBootOptions(virDomainDefPtr def,
}
def->os.initargv[n] = NULL;
VIR_FREE(nodes);
+
+if ((n = virXPathNodeSet("./os/initenv", ctxt, )) < 0)
+goto error;
+
+if (VIR_ALLOC_N(def->os.initenv, n+1) < 0)
+goto error;
+for (i = 0; i < n; i++) {
+if (!(name = virXMLPropString(nodes[i], "name"))) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+_("No name supplied for element"));
+goto error;
+}
+
+if (!nodes[i]->children ||
+!nodes[i]->children->content) {
+virReportError(VIR_ERR_XML_ERROR,
+ _("No value supplied for
element"),
+ name);
+goto error;
+}
+
+if (VIR_ALLOC(def->os.initenv[i]) < 0)
+goto error;
+
+def->os.initenv[i]->name = name;
+if (VIR_STRDUP(def->os.initenv[i]->value,
+ (const char*) nodes[i]->children->content) < 0)
+goto error;
+}
+def->os.initenv[n] = NULL;
+VIR_FREE(nodes);
}
if (def->os.type == VIR_DOMAIN_OSTYPE_XEN ||
@@ -24524,6 +24559,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
for (i = 0; def->os.initargv && def->os.initargv[i]; i++)
virBufferEscapeString(buf, "%s\n",
def->os.initargv[i]);
+for (i = 0; def->os.initenv && def->os.initenv[i]; i++)
+virBufferAsprintf(buf, "%s\n",
+ def->os.initenv[i]->name, def->os.initenv[i]->value);
if (def->os.loader)
virDomainLoaderDefFormat(buf, def->os.loader);
virBufferEscapeString(buf, "%s\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 83e067269..03153b972 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1820,6 +1820,13 @@ typedef enum {
VIR_ENUM_DECL(virDomainIOAPIC);
/* Operating system configuration data & machine / arch */
+typedef struct _virDomainOSEnv virDomainOSEnv;
+typedef virDomainOSEnv *virDomainOSEnvPtr;
+struct _virDomainOSEnv {
+char *name;
+char *value;
+};
+
typedef struct _virDomainOSDef virDomainOSDef;
typedef virDomainOSDef *virDomainOSDefPtr;
struct _virDomainOSDef {
@@ -1833,6 +1840,7 @@ struct _virDomainOSDef {
bool bm_timeout_set;
char