diff --git a/man/virt-install.pod b/man/virt-install.pod index ff08d725..1fe0ec1e 100644 --- a/man/virt-install.pod +++ b/man/virt-install.pod @@ -442,6 +442,20 @@ will default to /bin/sh. Use --boot=? to see a list of all available sub options. Complete details at L +=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 + =back diff --git a/tests/cli-test-xml/compare/virt-install-many-devices.xml b/tests/cli-test-xml/compare/virt-install-many-devices.xml index ad00b4d3..d1a9d4b3 100644 --- a/tests/cli-test-xml/compare/virt-install-many-devices.xml +++ b/tests/cli-test-xml/compare/virt-install-many-devices.xml @@ -20,6 +20,10 @@ + + + + @@ -150,6 +154,10 @@ /foo/bar + + + + diff --git a/tests/cli-test-xml/compare/virt-xml-build-idmap.xml b/tests/cli-test-xml/compare/virt-xml-build-idmap.xml new file mode 100644 index 00000000..c8ed7650 --- /dev/null +++ b/tests/cli-test-xml/compare/virt-xml-build-idmap.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/cli-test-xml/compare/virt-xml-edit-clear-clock.xml b/tests/cli-test-xml/compare/virt-xml-edit-clear-clock.xml index db893a70..c98e0c87 100644 --- a/tests/cli-test-xml/compare/virt-xml-edit-clear-clock.xml +++ b/tests/cli-test-xml/compare/virt-xml-edit-clear-clock.xml @@ -9,7 +9,7 @@ destroy restart restart -@@ -321,4 +316,5 @@ +@@ -325,4 +320,5 @@
diff --git a/tests/cli-test-xml/compare/virt-xml-edit-clear-cpu.xml b/tests/cli-test-xml/compare/virt-xml-edit-clear-cpu.xml index da90fa1a..5382971a 100644 --- a/tests/cli-test-xml/compare/virt-xml-edit-clear-cpu.xml +++ b/tests/cli-test-xml/compare/virt-xml-edit-clear-cpu.xml @@ -21,7 +21,7 @@ -@@ -321,4 +304,5 @@ +@@ -325,4 +308,5 @@
diff --git a/tests/cli-test-xml/compare/virt-xml-edit-simple-boot.xml b/tests/cli-test-xml/compare/virt-xml-edit-simple-boot.xml index 2e85c637..8194918c 100644 --- a/tests/cli-test-xml/compare/virt-xml-edit-simple-boot.xml +++ b/tests/cli-test-xml/compare/virt-xml-edit-simple-boot.xml @@ -8,8 +8,8 @@ + + /bin/bash - - + + Domain 'test-many-devices' defined successfully. Changes will take effect after the next domain shutdown. \ No newline at end of file diff --git a/tests/cli-test-xml/compare/virt-xml-edit-simple-cpu.xml b/tests/cli-test-xml/compare/virt-xml-edit-simple-cpu.xml index 8da55c2d..6e6e6d15 100644 --- a/tests/cli-test-xml/compare/virt-xml-edit-simple-cpu.xml +++ b/tests/cli-test-xml/compare/virt-xml-edit-simple-cpu.xml @@ -9,7 +9,7 @@ -@@ -50,6 +50,7 @@ +@@ -54,6 +54,7 @@ diff --git a/tests/cli-test-xml/compare/virt-xml-edit-simple-features.xml b/tests/cli-test-xml/compare/virt-xml-edit-simple-features.xml index 8d8b7760..039dca29 100644 --- a/tests/cli-test-xml/compare/virt-xml-edit-simple-features.xml +++ b/tests/cli-test-xml/compare/virt-xml-edit-simple-features.xml @@ -1,5 +1,5 @@ - - + + - - diff --git a/tests/cli-test-xml/compare/virt-xml-edit-simple-idmap.xml b/tests/cli-test-xml/compare/virt-xml-edit-simple-idmap.xml new file mode 100644 index 00000000..5b60cc8e --- /dev/null +++ b/tests/cli-test-xml/compare/virt-xml-edit-simple-idmap.xml @@ -0,0 +1,13 @@ + + + +- +- ++ ++ + + + + +Domain 'test-many-devices' defined successfully. +Changes will take effect after the next domain shutdown. \ No newline at end of file diff --git a/tests/cli-test-xml/compare/virt-xml-edit-simple-metadata.xml b/tests/cli-test-xml/compare/virt-xml-edit-simple-metadata.xml index 28817fce..25fc3c6d 100644 --- a/tests/cli-test-xml/compare/virt-xml-edit-simple-metadata.xml +++ b/tests/cli-test-xml/compare/virt-xml-edit-simple-metadata.xml @@ -12,7 +12,7 @@ 409600 204800 -@@ -321,4 +321,5 @@ +@@ -325,4 +325,5 @@
diff --git a/tests/cli-test-xml/compare/virt-xml-edit-simple-vcpus.xml b/tests/cli-test-xml/compare/virt-xml-edit-simple-vcpus.xml index c5af43c4..26333d07 100644 --- a/tests/cli-test-xml/compare/virt-xml-edit-simple-vcpus.xml +++ b/tests/cli-test-xml/compare/virt-xml-edit-simple-vcpus.xml @@ -6,7 +6,7 @@ -@@ -50,6 +50,7 @@ +@@ -54,6 +54,7 @@ diff --git a/tests/cli-test-xml/compare/virt-xml-remove-disk-path.xml b/tests/cli-test-xml/compare/virt-xml-remove-disk-path.xml index 831e0dc3..b0b0b950 100644 --- a/tests/cli-test-xml/compare/virt-xml-remove-disk-path.xml +++ b/tests/cli-test-xml/compare/virt-xml-remove-disk-path.xml @@ -9,7 +9,7 @@ -@@ -88,12 +83,6 @@ +@@ -92,12 +87,6 @@
diff --git a/tests/clitest.py b/tests/clitest.py index d845a128..73362629 100644 --- a/tests/clitest.py +++ b/tests/clitest.py @@ -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") diff --git a/tests/testdriver.xml b/tests/testdriver.xml index 762f0ae2..8dec2b90 100644 --- a/tests/testdriver.xml +++ b/tests/testdriver.xml @@ -74,6 +74,10 @@ /usr/lib/xen/boot/hvmloader + + + + Foo bar baz & yeah boii < > yeahfoo diff --git a/tests/xmlparse-xml/change-guest-out.xml b/tests/xmlparse-xml/change-guest-out.xml index ec861ec2..2996ba39 100644 --- a/tests/xmlparse-xml/change-guest-out.xml +++ b/tests/xmlparse-xml/change-guest-out.xml @@ -89,4 +89,8 @@ pygrub + + + + diff --git a/tests/xmlparse.py b/tests/xmlparse.py index 834afa83..9581947f 100644 --- a/tests/xmlparse.py +++ b/tests/xmlparse.py @@ -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") diff --git a/virt-install b/virt-install index 2a24d41c..069eb550 100755 --- a/virt-install +++ b/virt-install @@ -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) diff --git a/virt-xml b/virt-xml index 8ca0fc4c..df750778 100755 --- a/virt-xml +++ b/virt-xml @@ -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) diff --git a/virtinst/__init__.py b/virtinst/__init__.py index b9186e0d..62b6b364 100644 --- a/virtinst/__init__.py +++ b/virtinst/__init__.py @@ -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 diff --git a/virtinst/cli.py b/virtinst/cli.py index 6b0c12ac..09e24174 100644 --- a/virtinst/cli.py +++ b/virtinst/cli.py @@ -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) diff --git a/virtinst/guest.py b/virtinst/guest.py index d55c2a0e..0cbda08e 100644 --- a/virtinst/guest.py +++ b/virtinst/guest.py @@ -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) ############################### diff --git a/virtinst/idmap.py b/virtinst/idmap.py new file mode 100644 index 00000000..dae499ec --- /dev/null +++ b/virtinst/idmap.py @@ -0,0 +1,37 @@ +# +# Copyright 2014 Fujitsu Limited. +# Chen Hanxiao +# +# 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)