virt-install: add support for user namespace

This patch will enable configuring idmap.
It could be used as enable user namespace
for LXC containers.

Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
This commit is contained in:
Chen Hanxiao 2014-02-09 23:25:25 +08:00 committed by Cole Robinson
parent e067051287
commit fcac052cdc
22 changed files with 137 additions and 12 deletions

View File

@ -442,6 +442,20 @@ will default to /bin/sh.
Use --boot=? to see a list of all available sub options. Complete details at L<http://libvirt.org/formatdomain.html#elementsOS>
=item --idmap=IDMAPOPTS
If the guest configuration declares a UID or GID mapping,
the 'user' namespace will be enabled to apply these.
A suitably configured UID/GID mapping is a pre-requisite to
make containers secure, in the absence of sVirt confinement.
--idmap can be sepicified to enable user namespace for LXC containers
Example:
--idmap uid_start=0,uid_target=1000,uid_count=10,gid_start=0,gid_target=1000,gid_count=10
Use --idmap=? to see a list of all available sub options. Complete details at L<http://libvirt.org/formatdomain.html#elementsOSContainer>
=back

View File

@ -20,6 +20,10 @@
<boot dev="network"/>
<boot dev="hd"/>
</os>
<idmap>
<uid start="0" target="1000" count="10"/>
<gid start="0" target="1000" count="10"/>
</idmap>
<features>
<apic eoi="on"/>
<pae/>
@ -150,6 +154,10 @@
<loader>/foo/bar</loader>
<boot dev="hd"/>
</os>
<idmap>
<uid start="0" target="1000" count="10"/>
<gid start="0" target="1000" count="10"/>
</idmap>
<features>
<apic eoi="on"/>
<pae/>

View File

@ -0,0 +1,4 @@
<idmap>
<uid start="0" target="1000" count="10"/>
<gid start="0" target="1000" count="10"/>
</idmap>

View File

@ -9,7 +9,7 @@
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
@@ -321,4 +316,5 @@
@@ -325,4 +320,5 @@
<address type="isa" iobase="0x505"/>
</panic>
</devices>

View File

@ -21,7 +21,7 @@
<clock offset="utc">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
@@ -321,4 +304,5 @@
@@ -325,4 +308,5 @@
<address type="isa" iobase="0x505"/>
</panic>
</devices>

View File

@ -8,8 +8,8 @@
+ <bios useserial="yes"/>
+ <init>/bin/bash</init>
</os>
<features>
<acpi/>
<idmap>
<uid start="0" target="1000" count="10"/>
Domain 'test-many-devices' defined successfully.
Changes will take effect after the next domain shutdown.

View File

@ -9,7 +9,7 @@
<feature policy="require" name="tm2"/>
<feature policy="require" name="est"/>
<feature policy="require" name="ss"/>
@@ -50,6 +50,7 @@
@@ -54,6 +54,7 @@
<feature policy="require" name="ds_cpl"/>
<feature policy="require" name="xtpr"/>
<feature policy="require" name="acpi"/>

View File

@ -1,5 +1,5 @@
<boot dev="hd"/>
</os>
<gid start="0" target="1000" count="10"/>
</idmap>
<features>
- <acpi/>
- <apic eoi="off"/>

View File

@ -0,0 +1,13 @@
<boot dev="hd"/>
</os>
<idmap>
- <uid start="0" target="1000" count="10"/>
- <gid start="0" target="1000" count="10"/>
+ <uid start="0" target="2000" count="30"/>
+ <gid start="0" target="3000" count="40"/>
</idmap>
<features>
<acpi/>
Domain 'test-many-devices' defined successfully.
Changes will take effect after the next domain shutdown.

View File

@ -12,7 +12,7 @@
<memory unit="KiB">409600</memory>
<currentMemory unit="KiB">204800</currentMemory>
<blkiotune>
@@ -321,4 +321,5 @@
@@ -325,4 +325,5 @@
<address type="isa" iobase="0x505"/>
</panic>
</devices>

View File

@ -6,7 +6,7 @@
<numatune>
<memory mode="interleave" placement="auto"/>
</numatune>
@@ -50,6 +50,7 @@
@@ -54,6 +54,7 @@
<feature policy="require" name="ds_cpl"/>
<feature policy="require" name="xtpr"/>
<feature policy="require" name="acpi"/>

View File

@ -9,7 +9,7 @@
<disk type="dir" device="floppy">
<source dir="/tmp"/>
<target dev="fdb" bus="fdc"/>
@@ -88,12 +83,6 @@
@@ -92,12 +87,6 @@
<target dev="hdb" bus="ide"/>
<readonly/>
<address type="drive" controller="0" bus="0" target="0" unit="1"/>

View File

@ -464,6 +464,7 @@ c.add_valid("--cpu foobar,+x2apic,+x2apicagain,-distest,forbid=foo,forbid=bar,di
c.add_valid("--numatune 1,2,3,5-7,^6") # Simple --numatune
c.add_valid("--numatune 1-3,4,mode=strict") # More complex, parser should do the right thing here
c.add_valid("--blkiotune weight=100,device_path=/home/test/1.img,device_weight=200") # --blkiotune
c.add_valid("--idmap uid_start=0,uid_target=1000,uid_count=10,gid_start=0,gid_target=1000,gid_count=10") # --idmap
c.add_compare("--connect %(DEFAULTURI)s --cpuset auto --vcpus 2", "cpuset-auto") # --cpuset=auto actually works
c.add_invalid("--vcpus 32 --cpuset=969-1000") # Bogus cpuset
c.add_invalid("--vcpus 32 --cpuset=autofoo") # Bogus cpuset
@ -559,6 +560,7 @@ c.add_compare("""--hvm --pxe \
--security type=static,label='system_u:object_r:svirt_image_t:s0:c100,c200',relabel=yes \
--numatune \\"1-3,5\\",mode=preferred \
--blkiotune weight=200,device_path=/dev/sdc,device_weight=300 \
--idmap uid_start=0,uid_target=1000,uid_count=10,gid_start=0,gid_target=1000,gid_count=10 \
--boot loader=/foo/bar \
--host-device net_00_1c_25_10_b1_e4 \
--features acpi=off,eoi=on,privnet=on,hyperv_spinlocks=on,hyperv_spinlocks_retries=1234 \
@ -785,6 +787,7 @@ c.add_compare("--edit --cpu host-passthrough", "stdin-edit", input_file=(xmldir
c.add_compare("--build-xml --cpu pentium3,+x2apic", "build-cpu")
c.add_compare("--build-xml --tpm /dev/tpm", "build-tpm")
c.add_compare("--build-xml --blkiotune weight=100,device_path=/dev/sdf,device_weight=200", "build-blkiotune")
c.add_compare("--build-xml --idmap uid_start=0,uid_target=1000,uid_count=10,gid_start=0,gid_target=1000,gid_count=10", "build-idmap")
c = vixml.add_category("simple edit diff", "test-many-devices --edit --print-diff --define", compare_check=support.SUPPORT_CONN_PANIC_DEVICE)
@ -796,6 +799,7 @@ c.add_compare("--vcpus 10,maxvcpus=20,cores=5,sockets=4,threads=1", "edit-simple
c.add_compare("--cpu model=pentium2,+x2apic,forbid=pbe", "edit-simple-cpu")
c.add_compare("--numatune 1-5,7,mode=strict", "edit-simple-numatune")
c.add_compare("--blkiotune weight=500,device_path=/dev/sdf,device_weight=600", "edit-simple-blkiotune")
c.add_compare("--idmap uid_start=0,uid_target=2000,uid_count=30,gid_start=0,gid_target=3000,gid_count=40", "edit-simple-idmap")
c.add_compare("--boot loader=foo.bar,network,useserial=on,init=/bin/bash", "edit-simple-boot")
c.add_compare("--security label=foo,bar,baz,UNKNOWN=val,relabel=on", "edit-simple-security")
c.add_compare("--features eoi=on,hyperv_relaxed=off,acpi=", "edit-simple-features")

View File

@ -74,6 +74,10 @@
<loader>/usr/lib/xen/boot/hvmloader</loader>
<boot dev='hd'/>
</os>
<idmap>
<uid start='0' target='1000' count='10'/>
<gid start='0' target='1000' count='10'/>
</idmap>
<description>Foo bar baz &amp;
yeah boii &lt; &gt; yeahfoo
</description>

View File

@ -89,4 +89,8 @@
</device>
</blkiotune>
<bootloader>pygrub</bootloader>
<idmap>
<uid start="0" target="1000" count="10"/>
<gid start="0" target="1000" count="10"/>
</idmap>
</domain>

View File

@ -197,6 +197,14 @@ class XMLParseTest(unittest.TestCase):
check("device_weight", None, 300)
check("device_path", None, "/home/1.img")
check = self._make_checker(guest.idmap)
check("uid_start", None, 0)
check("uid_target", None, 1000)
check("uid_count", None, 10)
check("gid_start", None, 0)
check("gid_target", None, 1000)
check("gid_count", None, 10)
check = self._make_checker(guest.get_devices("memballoon")[0])
check("model", "virtio", "none")

View File

@ -768,6 +768,7 @@ def parse_args():
cli.add_distro_options(insg)
cli.add_boot_option(insg)
insg.add_argument("--init", help=argparse.SUPPRESS)
cli.add_idmap_option(insg)
stog = parser.add_argument_group(_("Storage Configuration"))
cli.add_disk_option(stog)

View File

@ -350,6 +350,7 @@ def parse_args():
cli.vcpu_cli_options(g, editexample=True)
cli.add_guest_xml_options(g)
cli.add_boot_option(g)
cli.add_idmap_option(g)
cli.add_fs_option(g)
cli.add_device_options(g)

View File

@ -31,6 +31,7 @@ from virtinst.clock import Clock
from virtinst.cpu import CPU, CPUFeature
from virtinst.seclabel import Seclabel
from virtinst.pm import PM
from virtinst.idmap import IdMap
import virtinst.capabilities as CapabilitiesParser
from virtinst.interface import Interface, InterfaceProtocol

View File

@ -802,6 +802,12 @@ def add_disk_option(stog, editexample=False):
"--disk=?") + editmsg)
def add_idmap_option(insg):
insg.add_argument("--idmap",
help=_("Enable user namespace for LXC container. Ex.\n"
"--idmap uid_start=0,uid_target=1000,uid_count=10,gid_start=0,gid_target=1000,gid_count=10"))
#############################################
# CLI complex parsing helpers #
# (for options like --disk, --network, etc. #
@ -1399,6 +1405,23 @@ class ParserBoot(VirtCLIParser):
VirtCLIParser._parse(self, opts, inst)
######################
# --idmap parsing #
######################
class ParserIdmap(VirtCLIParser):
def _init_params(self):
self.clear_attr = "idmap"
self.set_param("idmap.uid_start", "uid_start")
self.set_param("idmap.uid_target", "uid_target")
self.set_param("idmap.uid_count", "uid_count")
self.set_param("idmap.gid_start", "gid_start")
self.set_param("idmap.gid_target", "gid_target")
self.set_param("idmap.gid_count", "gid_count")
######################
# --security parsing #
######################
@ -2129,6 +2152,7 @@ def build_parser_map(options, skip=None, only=None):
register_parser("cpu", ParserCPU)
register_parser("numatune", ParserNumatune)
register_parser("blkiotune", ParserBlkiotune)
register_parser("idmap", ParserIdmap)
register_parser("boot", ParserBoot)
register_parser("security", ParserSecurity)
register_parser("features", ParserFeatures)

View File

@ -38,6 +38,7 @@ from virtinst import DomainNumatune
from virtinst import DomainBlkiotune
from virtinst import DomainFeatures
from virtinst import PM
from virtinst import IdMap
from virtinst.xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
from virtinst import osdict
@ -91,8 +92,8 @@ class Guest(XMLBuilder):
_XML_ROOT_NAME = "domain"
_XML_PROP_ORDER = ["type", "name", "uuid", "title", "description",
"maxmemory", "memory", "hugepage", "vcpus", "curvcpus",
"numatune", "blkiotune", "bootloader", "os", "features", "cpu", "clock",
"on_poweroff", "on_reboot", "on_crash", "pm", "emulator", "_devices",
"numatune", "blkiotune", "bootloader", "os", "idmap", "features", "cpu",
"clock", "on_poweroff", "on_reboot", "on_crash", "pm", "emulator", "_devices",
"seclabel"]
def __init__(self, *args, **kwargs):
@ -191,6 +192,7 @@ class Guest(XMLBuilder):
numatune = XMLChildProperty(DomainNumatune, is_single=True)
pm = XMLChildProperty(PM, is_single=True)
blkiotune = XMLChildProperty(DomainBlkiotune, is_single=True)
idmap = XMLChildProperty(IdMap, is_single=True)
###############################

37
virtinst/idmap.py Normal file
View File

@ -0,0 +1,37 @@
#
# Copyright 2014 Fujitsu Limited.
# Chen Hanxiao <chenhanxiao at cn.fujitsu.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
from virtinst.xmlbuilder import XMLBuilder, XMLProperty
class IdMap(XMLBuilder):
"""
Class for generating user namespace related XML
"""
_XML_ROOT_NAME = "idmap"
_XML_PROP_ORDER = ["uid_start", "uid_target", "uid_count",
"gid_start", "gid_target", "gid_count"]
uid_start = XMLProperty("./uid/@start", is_int=True)
uid_target = XMLProperty("./uid/@target", is_int=True)
uid_count = XMLProperty("./uid/@count", is_int=True)
gid_start = XMLProperty("./gid/@start", is_int=True)
gid_target = XMLProperty("./gid/@target", is_int=True)
gid_count = XMLProperty("./gid/@count", is_int=True)