virt-install: support network --disk's
Handle type=network in devicedisk.py, and wire up all the network fields for virt-install --disk. Right now it requires manually spelling out all the protocol, name, host/port etc fields. The one 'magic' bit is that VirtualDisk.path will be a pretty URL when all those network fields are specified. This is keeps things mostly working in various parts of the code where we expect 'path' to be an identifier for a VirtualDisk.
This commit is contained in:
parent
c5f5827499
commit
cd305da3f8
|
@ -77,6 +77,18 @@
|
|||
<source volume="some-rbd-vol" pool="rbd-ceph"/>
|
||||
<target dev="hdd" bus="ide"/>
|
||||
</disk>
|
||||
<disk type="network" device="disk">
|
||||
<source protocol="http" name="/path/to/my/file">
|
||||
<host name="example.com" port="8000"/>
|
||||
</source>
|
||||
<target dev="sdb" bus="scsi"/>
|
||||
</disk>
|
||||
<disk type="network" device="disk">
|
||||
<source protocol="nbd">
|
||||
<host transport="unix" socket="/tmp/socket"/>
|
||||
</source>
|
||||
<target dev="sdc" bus="scsi"/>
|
||||
</disk>
|
||||
<controller type="usb" index="0" model="ich9-ehci1">
|
||||
<address type="pci" domain="0" bus="0" slot="4" function="7"/>
|
||||
</controller>
|
||||
|
@ -226,6 +238,18 @@
|
|||
<source volume="some-rbd-vol" pool="rbd-ceph"/>
|
||||
<target dev="hdd" bus="ide"/>
|
||||
</disk>
|
||||
<disk type="network" device="disk">
|
||||
<source protocol="http" name="/path/to/my/file">
|
||||
<host name="example.com" port="8000"/>
|
||||
</source>
|
||||
<target dev="sdb" bus="scsi"/>
|
||||
</disk>
|
||||
<disk type="network" device="disk">
|
||||
<source protocol="nbd">
|
||||
<host transport="unix" socket="/tmp/socket"/>
|
||||
</source>
|
||||
<target dev="sdc" bus="scsi"/>
|
||||
</disk>
|
||||
<controller type="usb" index="0" model="ich9-ehci1">
|
||||
<address type="pci" domain="0" bus="0" slot="4" function="7"/>
|
||||
</controller>
|
||||
|
|
|
@ -562,6 +562,8 @@ c.add_compare("""--hvm --pxe \
|
|||
--disk device=cdrom,bus=sata,read_bytes_sec=1,read_iops_sec=2,total_bytes_sec=10,total_iops_sec=20,write_bytes_sec=5,write_iops_sec=6 \
|
||||
--disk size=1 \
|
||||
--disk source_pool=rbd-ceph,source_volume=some-rbd-vol \
|
||||
--disk source_protocol=http,source_host_name=example.com,source_host_port=8000,source_name=/path/to/my/file,bus=scsi \
|
||||
--disk source_protocol=nbd,source_host_transport=unix,source_host_socket=/tmp/socket,bus=scsi \
|
||||
--serial tcp,host=:2222,mode=bind,protocol=telnet \
|
||||
--filesystem /source,/target,mode=squash \
|
||||
--network user,mac=12:34:56:78:11:22,portgroup=foo \
|
||||
|
|
|
@ -68,6 +68,22 @@
|
|||
<target dev='vdb' bus='virtio'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type='network' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source protocol='rbd' name='pool/image'>
|
||||
<host name='mon1.example.org' port='6321'/>
|
||||
<host name='mon2.example.org' port='6322'/>
|
||||
<host name='mon3.example.org' port='6322'/>
|
||||
</source>
|
||||
<target dev='vdc' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='network' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source protocol='nbd'>
|
||||
<host transport='unix' socket='/var/run/nbdsock'/>
|
||||
</source>
|
||||
<target dev='vdd' bus='virtio'/>
|
||||
</disk>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<graphics type="vnc" display=":3.4" xauth="/tmp/.Xauthority"/>
|
||||
<console type="pty"/>
|
||||
|
|
|
@ -36,9 +36,12 @@
|
|||
<source dev="/dev/null"/>
|
||||
<target dev="hdd" bus="ide"/>
|
||||
</disk>
|
||||
<disk type="block" device="cdrom">
|
||||
<disk type="network" device="cdrom">
|
||||
<target dev="sda" bus="scsi"/>
|
||||
<readonly/>
|
||||
<source protocol="http" name="/my/file">
|
||||
<host name="exaaaaample.com"/>
|
||||
</source>
|
||||
</disk>
|
||||
<disk type="file" device="floppy">
|
||||
<target dev="fda" bus="fdc"/>
|
||||
|
@ -66,10 +69,26 @@
|
|||
</disk>
|
||||
<disk type="volume" device="disk">
|
||||
<driver name="qemu"/>
|
||||
<source pool="anotherPool" volume="foobar"/>
|
||||
<source pool="anotherPool" volume="newvol"/>
|
||||
<target dev="vdb" bus="virtio"/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type="network" device="disk">
|
||||
<driver name="qemu" type="raw"/>
|
||||
<source protocol="gluster" name="new-val/vol">
|
||||
<host name="diff.example.org" port="1234"/>
|
||||
<host name="mon2.example.org" port="6322"/>
|
||||
<host name="mon3.example.org" port="6322"/>
|
||||
</source>
|
||||
<target dev="vdc" bus="virtio"/>
|
||||
</disk>
|
||||
<disk type="network" device="disk">
|
||||
<driver name="qemu" type="raw"/>
|
||||
<source protocol="nbd">
|
||||
<host transport="unix" socket="/var/run/nbdsock"/>
|
||||
</source>
|
||||
<target dev="vdd" bus="virtio"/>
|
||||
</disk>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<graphics type="vnc" display=":3.4" xauth="/tmp/.Xauthority"/>
|
||||
<console type="pty"/>
|
||||
|
|
|
@ -347,6 +347,14 @@ class XMLParseTest(unittest.TestCase):
|
|||
check("bus", "ide", "fdc")
|
||||
check("error_policy", "stop", None)
|
||||
|
||||
disk = _get_disk("sda")
|
||||
check = self._make_checker(disk)
|
||||
check("source_protocol", None, "http")
|
||||
check("source_name", None, "/my/file")
|
||||
check("source_host_name", None, "exaaaaample.com")
|
||||
disk.sync_path_props()
|
||||
check("path", "http://exaaaaample.com/my/file")
|
||||
|
||||
disk = _get_disk("fda")
|
||||
check = self._make_checker(disk)
|
||||
check("path", None, "/dev/default-pool/default-vol")
|
||||
|
@ -369,6 +377,22 @@ class XMLParseTest(unittest.TestCase):
|
|||
disk = _get_disk("vdb")
|
||||
check = self._make_checker(disk)
|
||||
check("source_pool", "defaultPool", "anotherPool")
|
||||
check("source_volume", "foobar", "newvol")
|
||||
|
||||
disk = _get_disk("vdc")
|
||||
check = self._make_checker(disk)
|
||||
check("source_protocol", "rbd", "gluster")
|
||||
check("source_name", "pool/image", "new-val/vol")
|
||||
check("source_host_name", "mon1.example.org", "diff.example.org")
|
||||
check("source_host_port", 6321, 1234)
|
||||
check("path", "gluster://diff.example.org:1234/new-val/vol")
|
||||
|
||||
disk = _get_disk("vdd")
|
||||
check = self._make_checker(disk)
|
||||
check("source_protocol", "nbd")
|
||||
check("source_host_transport", "unix")
|
||||
check("source_host_socket", "/var/run/nbdsock")
|
||||
check("path", "nbd+unix:///var/run/nbdsock")
|
||||
|
||||
self._alter_compare(guest.get_xml_config(), outfile)
|
||||
|
||||
|
|
|
@ -1486,6 +1486,13 @@ class ParserDisk(VirtCLIParser):
|
|||
|
||||
self.set_param("source_pool", "source_pool")
|
||||
self.set_param("source_volume", "source_volume")
|
||||
self.set_param("source_name", "source_name")
|
||||
self.set_param("source_protocol", "source_protocol")
|
||||
self.set_param("source_host_name", "source_host_name")
|
||||
self.set_param("source_host_port", "source_host_port")
|
||||
self.set_param("source_host_socket", "source_host_socket")
|
||||
self.set_param("source_host_transport", "source_host_transport")
|
||||
|
||||
self.set_param("path", "path")
|
||||
self.set_param("device", "device")
|
||||
self.set_param("bus", "bus")
|
||||
|
|
|
@ -139,7 +139,8 @@ class VirtualDisk(VirtualDevice):
|
|||
TYPE_BLOCK = "block"
|
||||
TYPE_DIR = "dir"
|
||||
TYPE_VOLUME = "volume"
|
||||
types = [TYPE_FILE, TYPE_BLOCK, TYPE_DIR, TYPE_VOLUME]
|
||||
TYPE_NETWORK = "network"
|
||||
types = [TYPE_FILE, TYPE_BLOCK, TYPE_DIR, TYPE_NETWORK]
|
||||
|
||||
IO_MODE_NATIVE = "native"
|
||||
IO_MODE_THREADS = "threads"
|
||||
|
@ -490,7 +491,9 @@ class VirtualDisk(VirtualDevice):
|
|||
"driver_name", "driver_type",
|
||||
"driver_cache", "driver_discard", "driver_io", "error_policy",
|
||||
"_source_file", "_source_dev", "_source_dir",
|
||||
"source_volume", "source_pool",
|
||||
"source_volume", "source_pool", "source_protocol", "source_name",
|
||||
"source_host_name", "source_host_port",
|
||||
"source_host_transport", "source_host_socket",
|
||||
"target", "bus",
|
||||
]
|
||||
|
||||
|
@ -506,6 +509,10 @@ class VirtualDisk(VirtualDevice):
|
|||
#############################
|
||||
|
||||
def _get_path(self):
|
||||
if self.type == VirtualDisk.TYPE_NETWORK:
|
||||
# Fill in a completed URL for virt-manager UI, path comparison, etc
|
||||
return self._url_from_network_source()
|
||||
|
||||
if self._storage_creator:
|
||||
return self._storage_creator.path
|
||||
return self._storage_backend.path
|
||||
|
@ -585,11 +592,42 @@ class VirtualDisk(VirtualDevice):
|
|||
source_pool = XMLProperty("./source/@pool")
|
||||
source_volume = XMLProperty("./source/@volume")
|
||||
|
||||
def _get_default_type(self):
|
||||
source_name = XMLProperty("./source/@name")
|
||||
source_protocol = XMLProperty("./source/@protocol")
|
||||
# Technically multiple host lines can be listed
|
||||
source_host_name = XMLProperty("./source/host/@name")
|
||||
source_host_port = XMLProperty("./source/host/@port", is_int=True)
|
||||
source_host_transport = XMLProperty("./source/host/@transport")
|
||||
source_host_socket = XMLProperty("./source/host/@socket")
|
||||
|
||||
def _url_from_network_source(self):
|
||||
ret = self.source_protocol
|
||||
if self.source_host_transport:
|
||||
ret += "+%s" % self.source_host_transport
|
||||
ret += "://"
|
||||
if self.source_host_name:
|
||||
ret += self.source_host_name
|
||||
if self.source_host_port:
|
||||
ret += ":" + str(self.source_host_port)
|
||||
if self.source_name:
|
||||
if not self.source_name.startswith("/"):
|
||||
ret += "/"
|
||||
ret += self.source_name
|
||||
elif self.source_host_socket:
|
||||
if not self.source_host_socket.startswith("/"):
|
||||
ret += "/"
|
||||
ret += self.source_host_socket
|
||||
return ret
|
||||
|
||||
def _get_default_type(self, skip_backend=False):
|
||||
if self.source_pool or self.source_volume:
|
||||
return VirtualDisk.TYPE_VOLUME
|
||||
if self.source_protocol:
|
||||
return VirtualDisk.TYPE_NETWORK
|
||||
if self._storage_creator:
|
||||
return self._storage_creator.get_dev_type()
|
||||
if not self.__storage_backend and skip_backend:
|
||||
return self.TYPE_FILE
|
||||
return self._storage_backend.get_dev_type()
|
||||
type = XMLProperty("./@type", default_cb=_get_default_type)
|
||||
|
||||
|
@ -602,6 +640,12 @@ class VirtualDisk(VirtualDevice):
|
|||
self._source_dir = None
|
||||
self.source_volume = None
|
||||
self.source_pool = None
|
||||
self.source_name = None
|
||||
self.source_protocol = None
|
||||
self.source_host_name = None
|
||||
self.source_host_port = None
|
||||
self.source_host_transport = None
|
||||
self.source_host_socket = None
|
||||
|
||||
def _disk_type_to_object_prop_name(self):
|
||||
disk_type = self.type
|
||||
|
@ -673,8 +717,11 @@ class VirtualDisk(VirtualDevice):
|
|||
path = None
|
||||
vol_object = None
|
||||
parent_pool = None
|
||||
is_network = False
|
||||
typ = self._get_default_type(skip_backend=True)
|
||||
is_network = (typ == VirtualDisk.TYPE_NETWORK)
|
||||
|
||||
if self.source_pool and self.source_volume:
|
||||
if typ == VirtualDisk.TYPE_VOLUME:
|
||||
conn = self.conn
|
||||
is_weak = "weakref" in str(type(conn))
|
||||
if is_weak:
|
||||
|
@ -695,7 +742,7 @@ class VirtualDisk(VirtualDevice):
|
|||
path = self._get_xmlpath()
|
||||
|
||||
return diskbackend.StorageBackend(self.conn, path,
|
||||
vol_object, parent_pool)
|
||||
vol_object, parent_pool, is_network=is_network)
|
||||
|
||||
def _get_storage_backend(self):
|
||||
if self.__storage_backend is None:
|
||||
|
@ -747,7 +794,8 @@ class VirtualDisk(VirtualDevice):
|
|||
self.driver_type = self._get_default_driver_type()
|
||||
|
||||
# Need to retrigger this if self.type changed
|
||||
self._set_xmlpath(path)
|
||||
if path:
|
||||
self._set_xmlpath(path)
|
||||
|
||||
def wants_storage_creation(self):
|
||||
"""
|
||||
|
|
|
@ -373,12 +373,14 @@ class StorageBackend(_StorageBase):
|
|||
Class that carries all the info about any existing storage that
|
||||
the disk references
|
||||
"""
|
||||
def __init__(self, conn, path, vol_object, parent_pool):
|
||||
def __init__(self, conn, path, vol_object, parent_pool,
|
||||
is_network=False):
|
||||
_StorageBase.__init__(self, conn)
|
||||
|
||||
self._vol_object = vol_object
|
||||
self._parent_pool = parent_pool
|
||||
self._path = path
|
||||
self._is_network = is_network
|
||||
|
||||
if self._vol_object is not None:
|
||||
self._path = None
|
||||
|
@ -437,10 +439,14 @@ class StorageBackend(_StorageBase):
|
|||
self._exists = True
|
||||
elif self._vol_object:
|
||||
self._exists = True
|
||||
elif not self._conn.is_remote() and os.path.exists(self._path):
|
||||
elif (not self._is_network and
|
||||
not self._conn.is_remote() and
|
||||
os.path.exists(self._path)):
|
||||
self._exists = True
|
||||
elif self._parent_pool:
|
||||
self._exists = False
|
||||
elif self._is_network:
|
||||
self._exists = True
|
||||
elif (self._conn.is_remote() and
|
||||
not _can_auto_manage(self._path)):
|
||||
# This allows users to pass /dev/sdX and we don't try to
|
||||
|
@ -466,7 +472,9 @@ class StorageBackend(_StorageBase):
|
|||
else:
|
||||
self._dev_type = "file"
|
||||
|
||||
elif self._path and not self._conn.is_remote():
|
||||
elif (not self._is_network and
|
||||
self._path and
|
||||
not self._conn.is_remote()):
|
||||
if os.path.isdir(self._path):
|
||||
self._dev_type = "dir"
|
||||
elif util.stat_disk(self._path)[0]:
|
||||
|
|
Loading…
Reference in New Issue