When running an application container, setting environment variables
could be important.
The newly introduced <initenv> 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
<code>/proc/cmdline</code>
but will not affect init argv.
</p>
+ <p>
+ To set environment variables, use the <code>initenv</code> element,
one
+ for each variable.
+ </p>
<pre>
<os>
@@ -333,6 +337,7 @@
<init>/bin/systemd</init>
<initarg>--unit</initarg>
<initarg>emergency.service</initarg>
+ <initenv name='MYENV'>some value</initenv>
</os>
</pre>
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 @@
<text/>
</element>
</zeroOrMore>
+ <zeroOrMore>
+ <element name="initenv">
+ <attribute name="name">
+ <data type='string'>
+ <param
name='pattern'>[a-zA-Z_]+[a-zA-Z0-9_]*</param>
+ </data>
+ </attribute>
+ <text/>
+ </element>
+ </zeroOrMore>
</interleave>
</element>
</define>
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, &nodes)) < 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 <initenv>
element"));
+ goto error;
+ }
+
+ if (!nodes[i]->children ||
+ !nodes[i]->children->content) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("No value supplied for <initenv
name='%s'> 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, "<initarg>%s</initarg>\n",
def->os.initargv[i]);
+ for (i = 0; def->os.initenv && def->os.initenv[i]; i++)
+ virBufferAsprintf(buf, "<initenv
name='%s'>%s</initenv>\n",
+ def->os.initenv[i]->name,
def->os.initenv[i]->value);
if (def->os.loader)
virDomainLoaderDefFormat(buf, def->os.loader);
virBufferEscapeString(buf, "<kernel>%s</kernel>\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 *init;
char **initargv;
+ virDomainOSEnvPtr *initenv;
char *kernel;
char *initrd;
char *cmdline;
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index af02b5460..ffafc39d7 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -246,6 +246,11 @@ static virCommandPtr lxcContainerBuildInitCmd(virDomainDefPtr vmDef,
if (vmDef->os.cmdline)
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_CMDLINE",
vmDef->os.cmdline);
+ for (i = 0; vmDef->os.initenv[i]; i++) {
+ virCommandAddEnvPair(cmd, vmDef->os.initenv[i]->name,
+ vmDef->os.initenv[i]->value);
+ }
+
virBufferFreeAndReset(&buf);
return cmd;
}
diff --git a/tests/lxcxml2xmldata/lxc-initenv.xml b/tests/lxcxml2xmldata/lxc-initenv.xml
new file mode 100644
index 000000000..933d836a2
--- /dev/null
+++ b/tests/lxcxml2xmldata/lxc-initenv.xml
@@ -0,0 +1,30 @@
+<domain type='lxc'>
+ <name>jessie</name>
+ <uuid>e21987a5-e98e-9c99-0e35-803e4d9ad1fe</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <resource>
+ <partition>/machine</partition>
+ </resource>
+ <os>
+ <type arch='x86_64'>exe</type>
+ <init>/sbin/sh</init>
+ <initenv name='FOO'>bar</initenv>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/libexec/libvirt_lxc</emulator>
+ <filesystem type='mount' accessmode='passthrough'>
+ <source dir='/mach/jessie'/>
+ <target dir='/'/>
+ </filesystem>
+ <console type='pty'>
+ <target type='lxc' port='0'/>
+ </console>
+ </devices>
+ <seclabel type='none'/>
+</domain>
diff --git a/tests/lxcxml2xmltest.c b/tests/lxcxml2xmltest.c
index 226a73d27..2a24b60b3 100644
--- a/tests/lxcxml2xmltest.c
+++ b/tests/lxcxml2xmltest.c
@@ -98,6 +98,7 @@ mymain(void)
DO_TEST("ethernet-hostip");
DO_TEST_FULL("filesystem-root", 0, false,
VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS);
+ DO_TEST("initenv");
virObjectUnref(caps);
virObjectUnref(xmlopt);
--
2.12.2