lxc: allow defining environment variables

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.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Cédric Bosdonnat 2017-05-30 17:03:58 +02:00
parent 5b16a499f8
commit 25630a3735
7 changed files with 97 additions and 0 deletions

View File

@ -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>
&lt;os&gt;
@ -333,6 +337,7 @@
&lt;init&gt;/bin/systemd&lt;/init&gt;
&lt;initarg&gt;--unit&lt;/initarg&gt;
&lt;initarg&gt;emergency.service&lt;/initarg&gt;
&lt;initenv name='MYENV'&gt;some value&lt;/initenv&gt;
&lt;/os&gt;
</pre>

View File

@ -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>

View File

@ -2874,6 +2874,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);
@ -17048,6 +17051,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def,
xmlNodePtr *nodes = NULL;
xmlNodePtr oldnode;
char *tmp = NULL;
char *name = NULL;
int ret = -1;
size_t i;
int n;
@ -17083,6 +17087,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 ||
@ -24915,6 +24950,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",

View File

@ -1848,6 +1848,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 {
@ -1861,6 +1868,7 @@ struct _virDomainOSDef {
bool bm_timeout_set;
char *init;
char **initargv;
virDomainOSEnvPtr *initenv;
char *kernel;
char *initrd;
char *cmdline;

View File

@ -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;
}

View File

@ -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>

View File

@ -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);