[Kimchi-devel] [PATCH 1/9 - v7] Fix Template backend create/update for multiple disks

Rodrigo Trujillo rodrigo.trujillo at linux.vnet.ibm.com
Wed Dec 2 18:38:03 UTC 2015


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 at linux.vnet.ibm.com>
---
 API.json           | 31 ++++++++++++++++++++++++++++++-
 docs/API.md        |  8 ++++++++
 model/templates.py |  9 +++++----
 osinfo.py          | 14 +++++++-------
 template.conf      |  7 ++++---
 vmtemplate.py      | 26 +++++++++++++++++++++-----
 6 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/API.json b/src/wok/plugins/kimchi/API.json
index 7addfc7..265ae36 100644
--- a/API.json
+++ b/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/docs/API.md b/src/wok/plugins/kimchi/docs/API.md
index 1e7d8ca..8ef48d6 100644
--- a/docs/API.md
+++ b/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/model/templates.py b/src/wok/plugins/kimchi/model/templates.py
index 47b2c9e..bac6e47 100644
--- a/model/templates.py
+++ b/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/osinfo.py b/src/wok/plugins/kimchi/osinfo.py
index 30ecd4f..1891398 100644
--- a/osinfo.py
+++ b/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/template.conf b/src/wok/plugins/kimchi/template.conf
index f3615e6..37fadb8 100644
--- a/template.conf
+++ b/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/vmtemplate.py b/src/wok/plugins/kimchi/vmtemplate.py
index 3097b66..c7635b0 100644
--- a/vmtemplate.py
+++ b/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




More information about the Kimchi-devel mailing list