lxc: allow user to specify command working directory

Some containers may want the application to run in a special directory.
Add <initdir> element in the domain configuration to handle this case
and use it in the lxc driver.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Cédric Bosdonnat 2017-05-31 15:32:11 +02:00
parent 0980764dee
commit 552f7c139a
7 changed files with 49 additions and 0 deletions

View File

@ -330,6 +330,10 @@
To set environment variables, use the <code>initenv</code> element, one
for each variable.
</p>
<p>
To set a custom work directory for the init, use the <code>initdir</code>
element.
</p>
<pre>
&lt;os&gt;
@ -338,6 +342,7 @@
&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;initdir&gt;/my/custom/cwd&lt;/initdir&gt;
&lt;/os&gt;
</pre>

View File

@ -395,6 +395,11 @@
<text/>
</element>
</zeroOrMore>
<optional>
<element name="initdir">
<ref name="absFilePath"/>
</element>
</optional>
</interleave>
</element>
</define>

View File

@ -2876,6 +2876,7 @@ void virDomainDefFree(virDomainDefPtr def)
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.initdir);
VIR_FREE(def->os.initenv);
VIR_FREE(def->os.kernel);
VIR_FREE(def->os.initrd);
@ -17068,6 +17069,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def,
if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) {
def->os.init = virXPathString("string(./os/init[1])", ctxt);
def->os.cmdline = virXPathString("string(./os/cmdline[1])", ctxt);
def->os.initdir = virXPathString("string(./os/initdir[1])", ctxt);
if ((n = virXPathNodeSet("./os/initarg", ctxt, &nodes)) < 0)
goto error;
@ -24953,6 +24955,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
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.initdir)
virBufferEscapeString(buf, "<initdir>%s</initdir>\n",
def->os.initdir);
if (def->os.loader)
virDomainLoaderDefFormat(buf, def->os.loader);
virBufferEscapeString(buf, "<kernel>%s</kernel>\n",

View File

@ -1869,6 +1869,7 @@ struct _virDomainOSDef {
char *init;
char **initargv;
virDomainOSEnvPtr *initenv;
char *initdir;
char *kernel;
char *initrd;
char *cmdline;

View File

@ -245,6 +245,8 @@ static virCommandPtr lxcContainerBuildInitCmd(virDomainDefPtr vmDef,
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_NAME", vmDef->name);
if (vmDef->os.cmdline)
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_CMDLINE", vmDef->os.cmdline);
if (vmDef->os.initdir)
virCommandSetWorkingDirectory(cmd, vmDef->os.initdir);
for (i = 0; vmDef->os.initenv[i]; i++) {
virCommandAddEnvPair(cmd, vmDef->os.initenv[i]->name,

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>
<initdir>/path/to/pwd</initdir>
</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

@ -99,6 +99,7 @@ mymain(void)
DO_TEST_FULL("filesystem-root", 0, false,
VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS);
DO_TEST("initenv");
DO_TEST("initdir");
virObjectUnref(caps);
virObjectUnref(xmlopt);