It is the first step to have xmlutils/disk.py holding all the disk XML
manipulation.
So we can reuse the same function on vmtemplate.py to build the guest XML.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
src/kimchi/model/vmstorages.py | 49 ++++------------------------
src/kimchi/xmlutils/disk.py | 73 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 43 deletions(-)
create mode 100644 src/kimchi/xmlutils/disk.py
diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py
index 055aa50..808b3d7 100644
--- a/src/kimchi/model/vmstorages.py
+++ b/src/kimchi/model/vmstorages.py
@@ -18,14 +18,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import os
-import socket
import stat
import string
-import urlparse
-import lxml.etree as ET
from lxml import etree
-from lxml.builder import E
from kimchi.exception import InvalidOperation, InvalidParameter, NotFoundError
from kimchi.exception import OperationFailed
@@ -35,7 +31,7 @@ from kimchi.model.utils import get_vm_config_flag
from kimchi.utils import check_url_path
from kimchi.osinfo import lookup
from kimchi.vmdisks import get_device_xml, get_vm_disk, get_vm_disk_list
-from kimchi.vmdisks import DEV_TYPE_SRC_ATTR_MAP
+from kimchi.xmlutils.disk import get_disk_xml
HOTPLUG_TYPE = ['scsi', 'virtio']
PREFIX_MAP = {'ide': 'hd', 'virtio': 'vd',
'scsi': 'sd'}
@@ -49,39 +45,6 @@ def _get_device_bus(dev_type, dom):
return lookup(distro, version)[dev_type+'_bus']
-def _get_storage_xml(params, ignore_source=False):
- src_type = params.get('src_type')
- disk = E.disk(type=src_type, device=params.get('type'))
- disk.append(E.driver(name='qemu', type=params['format']))
-
- disk.append(E.target(dev=params.get('dev'), bus=params['bus']))
- if params.get('address'):
- # ide disk target id is always '0'
- disk.append(E.address(
- type='drive',
controller=params['address']['controller'],
- bus=params['address']['bus'], target='0',
- unit=params['address']['unit']))
-
- if ignore_source:
- return ET.tostring(disk)
-
- # Working with url paths
- if src_type == 'network':
- output = urlparse.urlparse(params.get('path'))
- port = str(output.port or socket.getservbyname(output.scheme))
- host = E.host(name=output.hostname, port=port)
- source = E.source(protocol=output.scheme, name=output.path)
- source.append(host)
- disk.append(source)
- else:
- # Fixing source attribute
- source = E.source()
- source.set(DEV_TYPE_SRC_ATTR_MAP[src_type], params.get('path'))
- disk.append(source)
-
- return ET.tostring(disk)
-
-
def _check_path(path):
if check_url_path(path):
src_type = 'network'
@@ -164,14 +127,14 @@ class VMStoragesModel(object):
{"format": vol_info['format'],
"type": params['type']})
params['path'] = vol_info['path']
- params['src_type'] = _check_path(params['path'])
+
if (params['bus'] not in HOTPLUG_TYPE
and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
raise InvalidOperation('KCHVMSTOR0011E')
params.update(self._get_available_bus_address(params['bus'], vm_name))
# Add device to VM
- dev_xml = _get_storage_xml(params)
+ dev_xml = get_disk_xml(_check_path(params['path']), params)
try:
conn = self.conn.get()
dom = conn.lookupByName(vm_name)
@@ -234,10 +197,10 @@ class VMStorageModel(object):
def update(self, vm_name, dev_name, params):
path = params.get('path')
if path and len(path) != 0:
- params['src_type'] = _check_path(path)
+ src_type = _check_path(path)
ignore_source = False
else:
- params['src_type'] = 'file'
+ src_type = 'file'
ignore_source = True
dom = VMModel.get_vm(vm_name, self.conn)
@@ -245,8 +208,8 @@ class VMStorageModel(object):
if dev_info['type'] != 'cdrom':
raise InvalidOperation("KCHVMSTOR0006E")
dev_info.update(params)
- xml = _get_storage_xml(dev_info, ignore_source)
+ xml = get_disk_xml(src_type, dev_info, ignore_source)
try:
dom.updateDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
except Exception as e:
diff --git a/src/kimchi/xmlutils/disk.py b/src/kimchi/xmlutils/disk.py
new file mode 100644
index 0000000..8c64ff4
--- /dev/null
+++ b/src/kimchi/xmlutils/disk.py
@@ -0,0 +1,73 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+import socket
+import urlparse
+
+from lxml.builder import E
+
+DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', 'block': 'dev'}
+
+
+def get_disk_xml(src_type, params, ignore_src=False):
+ """
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+
+ [source XML according to src_type]
+
+ <target dev='%(dev)s' bus='%(bus)s'/>
+ <readonly/>
+ </disk>
+ """
+ disk = E.disk(type=src_type, device=params['type'])
+ disk.append(E.driver(name='qemu', type=params['format']))
+ disk.append(E.target(dev=params['dev'], bus=params['bus']))
+
+ if params.get('address'):
+ # ide disk target id is always '0'
+ disk.append(E.address(
+ type='drive',
controller=params['address']['controller'],
+ bus=params['address']['bus'], target='0',
+ unit=params['address']['unit']))
+
+ if ignore_src:
+ return ET.tostring(disk, encoding='utf-8', pretty_print=True)
+
+ if src_type == 'network':
+ """
+ <source protocol='%(protocol)s' name='%(url_path)s'>
+ <host name='%(hostname)s' port='%(port)s'/>
+ </source>
+ """
+ output = urlparse.urlparse(params['path'])
+ port = str(output.port or socket.getservbyname(output.scheme))
+
+ source = E.source(protocol=output.scheme, name=output.path)
+ source.append(E.host(name=output.hostname, port=port))
+ else:
+ """
+ <source file='%(src)s' />
+ """
+ source = E.source()
+ source.set(DEV_TYPE_SRC_ATTR_MAP[src_type], params['path'])
+
+ disk.append(source)
+ return ET.tostring(disk, encoding='utf-8', pretty_print=True)
--
1.9.3