This patch fixes the backend code in order to allow create templates
with multiple disks and update them correctly.
Backend supports adding multiple disks with a json like:
"disks": [{"size": 3,
"format": "qcow"},
{"size": 5,
"pool": {"name":
"/plugins/kimchi/storagepools/poolX"}},
{"size": 7,
"format": "raw",
"pool": {"name":
"/plugins/kimchi/storagepools/poolY"}}
]
If any information is missing, Kimchi will use values from
template.conf.
Kimchi will expose template disk data like:
"disks": [{"index" : ... ,
"size" : ... ,
"format" : ... ,
"pool" : {
"name" : ... ,
"type" : ... } ,
}, ...
]
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
src/wok/plugins/kimchi/API.json | 31 ++++++++++++++++++++++++++++++-
src/wok/plugins/kimchi/docs/API.md | 8 ++++++++
src/wok/plugins/kimchi/model/templates.py | 9 +++++----
src/wok/plugins/kimchi/osinfo.py | 14 +++++++-------
src/wok/plugins/kimchi/template.conf | 7 ++++---
src/wok/plugins/kimchi/vmtemplate.py | 26 +++++++++++++++++++++-----
6 files changed, 75 insertions(+), 20 deletions(-)
diff --git a/src/wok/plugins/kimchi/API.json b/src/wok/plugins/kimchi/API.json
index 7addfc7..265ae36 100644
--- a/src/wok/plugins/kimchi/API.json
+++ b/src/wok/plugins/kimchi/API.json
@@ -477,6 +477,12 @@
"type": "integer",
"minimum": 0
},
+ "format": {
+ "description": "Type of the image of the
disk",
+ "type": "string",
+ "pattern":
"^(bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
+ "error": "KCHTMPL0027E"
+ },
"size": {
"description": "Size (GB) of the
disk",
"type": "number",
@@ -488,8 +494,19 @@
"type": "string",
"pattern": "^/.+$",
"error": "KCHTMPL0023E"
+ },
+ "pool": {
+ "description": "Storage pool
information",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Location (URI) of
the storage pool",
+ "type": "string",
+ "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHTMPL0015E"
+ }
+ }
}
-
}
},
"minItems": 1,
@@ -660,6 +677,18 @@
"type": "string",
"pattern":
"^(bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
"error": "KCHTMPL0027E"
+ },
+ "pool": {
+ "description": "Storage pool
information",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Location (URI) of
the storage pool",
+ "type": "string",
+ "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHTMPL0015E"
+ }
+ }
}
}
},
diff --git a/src/wok/plugins/kimchi/docs/API.md b/src/wok/plugins/kimchi/docs/API.md
index 1e7d8ca..8ef48d6 100644
--- a/src/wok/plugins/kimchi/docs/API.md
+++ b/src/wok/plugins/kimchi/docs/API.md
@@ -289,6 +289,9 @@ Represents a snapshot of the Virtual Machine's primary monitor.
(either *size* or *volume* must be specified):
* index: The device index
* size: The device size in GB
+ * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow,
qcow2, qed, raw, vmdk, vpc
+ * pool: Storage pool information
+ * name: URI of the storagepool where disk will be created
* base: Base image of this disk
* graphics *(optional)*: The graphics paramenters of this template
@@ -388,6 +391,9 @@ A interface represents available network interface on VM.
* size: The device size in GB
* volume: A volume name that contains the initial disk contents
* format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow,
qcow2, qed, raw, vmdk, vpc.
+ * pool: Information about the pool where disk or volume will be created
+ * name: URI of the storagepool
+ * type: Type of the storagepool (dir, nfs, scsci, iscsi, etc)
* graphics: A dict of graphics paramenters of this template
* type: The type of graphics. It can be VNC or spice or None.
* vnc: Graphical display using the Virtual Network
@@ -422,6 +428,8 @@ A interface represents available network interface on VM.
* size: The device size in GB
* volume: A volume name that contains the initial disk contents
* format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow,
qcow2, qed, raw, vmdk, vpc.
+ * pool: Storage pool information
+ * name: URI of the storagepool where template allocates vm disk.
* graphics *(optional)*: A dict of graphics paramenters of this template
* type: The type of graphics. It can be VNC or spice or None.
* vnc: Graphical display using the Virtual Network
diff --git a/src/wok/plugins/kimchi/model/templates.py
b/src/wok/plugins/kimchi/model/templates.py
index 47b2c9e..bac6e47 100644
--- a/src/wok/plugins/kimchi/model/templates.py
+++ b/src/wok/plugins/kimchi/model/templates.py
@@ -234,8 +234,9 @@ class LibvirtVMTemplate(VMTemplate):
self.conn = conn
VMTemplate.__init__(self, args, scan)
- def _storage_validate(self):
- pool_uri = self.info['storagepool']
+ def _storage_validate(self, pool_uri=None):
+ if pool_uri is None:
+ pool_uri = self.info['storagepool']
pool_name = pool_name_from_uri(pool_uri)
try:
conn = self.conn.get()
@@ -278,8 +279,8 @@ class LibvirtVMTemplate(VMTemplate):
xml = pool.XMLDesc(0)
return xpath_get_text(xml, "/pool/target/path")[0]
- def _get_storage_type(self):
- pool = self._storage_validate()
+ def _get_storage_type(self, pool_uri=None):
+ pool = self._storage_validate(pool_uri)
xml = pool.XMLDesc(0)
return xpath_get_text(xml, "/pool/@type")[0]
diff --git a/src/wok/plugins/kimchi/osinfo.py b/src/wok/plugins/kimchi/osinfo.py
index 30ecd4f..1891398 100644
--- a/src/wok/plugins/kimchi/osinfo.py
+++ b/src/wok/plugins/kimchi/osinfo.py
@@ -118,8 +118,8 @@ def _get_tmpl_defaults():
The default values should be like below:
{'main': {'networks': ['default'], 'memory':
'1024'},
- 'storage': {'pool': 'default',
- 'disk.0': {'format': 'qcow2', 'size':
'10'}},
+ 'storage': { 'disk.0': {'format': 'qcow2',
'size': '10',
+ 'pool':
'/plugins/kimchi/storagepools/default'}},
'processor': {'cpus': '1'},
'graphics': {'type': 'spice', 'listen':
'127.0.0.1'}}
"""
@@ -127,8 +127,8 @@ def _get_tmpl_defaults():
tmpl_defaults = defaultdict(dict)
tmpl_defaults['main']['networks'] = ['default']
tmpl_defaults['main']['memory'] = _get_default_template_mem()
- tmpl_defaults['storage']['pool'] = 'default'
- tmpl_defaults['storage']['disk.0'] = {'size': 10,
'format': 'qcow2'}
+ tmpl_defaults['storage']['disk.0'] = {'size': 10,
'format': 'qcow2',
+ 'pool': 'default'}
tmpl_defaults['processor']['cpus'] = 1
tmpl_defaults['graphics'] = {'type': 'vnc', 'listen':
'127.0.0.1'}
@@ -150,14 +150,14 @@ def _get_tmpl_defaults():
main_section = default_config.pop('main')
defaults.update(main_section)
- # Parse storage section to get storage pool and disks values
+ # Parse storage section to get disks values
storage_section = default_config.pop('storage')
- defaults['storagepool'] = '/plugins/kimchi/storagepools/' + \
- storage_section.pop('pool')
defaults['disks'] = []
for disk in storage_section.keys():
data = storage_section[disk]
data['index'] = int(disk.split('.')[1])
+ data['pool'] = {"name": '/plugins/kimchi/storagepools/'
+
+ storage_section[disk].pop('pool')}
defaults['disks'].append(data)
# Parse processor section to get cpus and cpu_topology values
diff --git a/src/wok/plugins/kimchi/template.conf b/src/wok/plugins/kimchi/template.conf
index f3615e6..37fadb8 100644
--- a/src/wok/plugins/kimchi/template.conf
+++ b/src/wok/plugins/kimchi/template.conf
@@ -11,11 +11,9 @@
#networks = default,
[storage]
-# Storage pool used to handle the guest disk
-#pool = default
# Specify multiple [[disk.X]] sub-sections to add multiples disks to guest
-# All the disk files will be created in the same storage pool as set above
+# Each disk files will be created in respective storage pool set
[[disk.0]]
# Disk size in GB
#size = 10
@@ -23,6 +21,9 @@
# Disk format
#format = qcow2
+# Storage pool used to handle the guest disk
+#pool = default
+
[graphics]
# Graphics type
# Valid options: vnc | spice
diff --git a/src/wok/plugins/kimchi/vmtemplate.py b/src/wok/plugins/kimchi/vmtemplate.py
index 3097b66..c7635b0 100644
--- a/src/wok/plugins/kimchi/vmtemplate.py
+++ b/src/wok/plugins/kimchi/vmtemplate.py
@@ -76,14 +76,30 @@ class VMTemplate(object):
graphics.update(graph_args)
args['graphics'] = graphics
- # Merge disks dict
+ # Provide compatibility with old template version and sets data to
+ # correct output format if necessary
+ def _fix_disk_compatibilities(disks):
+ for i, disk in enumerate(disks):
+ if 'pool' not in disk:
+ disk['pool'] = {'name':
self.info['storagepool']}
+ if (isinstance(disk['pool'], str) or
+ isinstance(disk['pool'], unicode)):
+ disk['pool'] = {'name': disk['pool']}
+ disk['pool']['type'] = \
+ self._get_storage_type(disk['pool']['name'])
+
+ if self.info.get('disks') is not None:
+ _fix_disk_compatibilities(self.info['disks'])
+ if args.get('disks') is not None:
+ _fix_disk_compatibilities(args['disks'])
+
+ # Merge disks dict with disks provided by user
default_disk = self.info['disks'][0]
for i, d in enumerate(args.get('disks', [])):
disk = dict(default_disk)
+ disk['index'] = i
disk.update(d)
-
- # Assign right disk format to logical and [i]scsi storagepools
- if self._get_storage_type() in ['logical', 'iscsi',
'scsi']:
+ if disk['pool']['type'] in ['logical',
'iscsi', 'scsi']:
disk['format'] = 'raw'
args['disks'][i] = disk
@@ -401,7 +417,7 @@ class VMTemplate(object):
def _get_storage_path(self):
return ''
- def _get_storage_type(self):
+ def _get_storage_type(self, pool=None):
return ''
def _get_volume_path(self):
--
2.1.0