Just a minor comment below
On 07/15/2014 06:11 AM, lvroyce(a)linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Creating volume base on backing store so that we can create
vm from this cow volume. Also change volume xml generation method
to lxml.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/i18n.py | 1 +
src/kimchi/model/vms.py | 1 +
src/kimchi/utils.py | 16 ++++++++++++++++
src/kimchi/vmtemplate.py | 33 ++++++++++++++++++++-------------
4 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 3ba1e23..b427c5d 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -126,6 +126,7 @@ messages = {
"KCHTMPL0021E": _("Unable to delete template due error:
%(err)s"),
"KCHTMPL0022E": _("Disk size must be greater than 1GB."),
"KCHTMPL0023E": _("Template base image must be a valid local image
file"),
+ "KCHTMPL0024E": _("Cannot identify base image %(path)s
format"),
"KCHPOOL0001E": _("Storage pool %(name)s already exists"),
"KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py
index 17bda04..55699d0 100644
--- a/src/kimchi/model/vms.py
+++ b/src/kimchi/model/vms.py
@@ -201,6 +201,7 @@ class VMsModel(object):
# the user from UI or manually.
vol_list = []
if t._get_storage_type() in ["iscsi", "scsi"]:
+ # FIXME: iscsi and scsi storage work with base image needs to be fixed.
vol_list = []
else:
vol_list = t.fork_vm_storage(vm_uuid)
diff --git a/src/kimchi/utils.py b/src/kimchi/utils.py
index 97adbf8..0fd59ff 100644
--- a/src/kimchi/utils.py
+++ b/src/kimchi/utils.py
@@ -20,6 +20,7 @@
import cherrypy
import grp
+import json
import os
import psutil
import pwd
@@ -213,6 +214,21 @@ def parse_cmd_output(output, output_items):
return res
+def probe_img_info(path):
+ cmd = ["qemu-img", "info", "--output=json", path]
+ info = dict()
+ try:
+ out = run_command(cmd, 10)[0]
+ except TimeoutExpired:
+ kimchi_log.warning("Cannot decide format of base img %s", path)
+ return None
+
+ info = json.loads(out)
+ info['virtual-size'] = info['virtual-size'] >> 30
+ info['actual-size'] = info['actual-size'] >> 30
+ return info
+
Maybe imageinfo.py is a better location for this code.
+
def patch_find_nfs_target(nfs_server):
cmd = ["showmount", "--no-headers", "--exports",
nfs_server]
try:
diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
index d531406..883455c 100644
--- a/src/kimchi/vmtemplate.py
+++ b/src/kimchi/vmtemplate.py
@@ -27,7 +27,7 @@ from kimchi import osinfo
from kimchi.exception import InvalidParameter, IsoFormatError, ImageFormatError
from kimchi.imageinfo import probe_image
from kimchi.isoinfo import IsoImage
-from kimchi.utils import check_url_path, pool_name_from_uri
+from kimchi.utils import check_url_path, pool_name_from_uri, probe_img_info
from lxml import etree
from lxml.builder import E
@@ -65,6 +65,8 @@ class VMTemplate(object):
except ImageFormatError:
pass
args['cdrom'] = ''
+ if 'size' not in d:
+ d['size'] =
probe_img_info(d['base'])['virtual-size']
break
if scan and len(iso) > 0:
@@ -254,6 +256,13 @@ drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'/>
fmt = 'raw' if self._get_storage_type() in ['logical'] else
'qcow2'
ret = []
for i, d in enumerate(self.info['disks']):
+ if 'base' in d:
+ base_fmt = probe_img_info(d['base'])['format']
+ if base_fmt is None:
+ raise InvalidParameter("KCHTMPL0024E", {'path':
d['base']})
+ base_path = d['base']
+ else:
+ base_path = None
index = d.get('index', i)
volume = "%s-%s.img" % (vm_uuid, index)
@@ -262,19 +271,17 @@ drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'/>
'type': 'disk',
'format': fmt,
'path': '%s/%s' % (storage_path, volume)}
-
info['allocation'] = 0 if fmt == 'qcow2' else
info['capacity']
- info['xml'] = """
- <volume>
- <name>%(name)s</name>
- <allocation unit="G">%(allocation)s</allocation>
- <capacity unit="G">%(capacity)s</capacity>
- <target>
- <format type='%(format)s'/>
- <path>%(path)s</path>
- </target>
- </volume>
- """ % info
+ v_tree = E.volume(E.name(info['name']))
+ v_tree.append(E.allocation(str(info['allocation']),
unit='G'))
+ v_tree.append(E.capacity(str(info['capacity']), unit='G'))
+ target = E.target(
+ E.format(type=info['format']), E.path(info['path']))
+ if base_path:
+ v_tree.append(E.backingStore(
+ E.path(base_path), E.format(type=base_fmt)))
+ v_tree.append(target)
+ info['xml'] = etree.tostring(v_tree)
ret.append(info)
return ret