To test this patch:
$ curl -k -u test -H "Content-Type: application/json" -H "Accept:
application/json" '
https://localhost:8001/plugins/kimchi/vms/kimchi-vm-new/storages' -X
POST -d '{ "vol": "new_vol", "type": "disk",
"pool": "default",
"format": "qcow2", "capacity": 1024 }'
Enter host password for user 'test':
{
"bus":"virtio",
"path":"/var/lib/libvirt/images/2477bfd8-a9e2-4887-a683-e89015b3ba11
-1.img",
"type":"disk",
"dev":"vdb",
"format":"qcow2"
}
$ curl -k -u test -H "Content-Type: application/json" -H "Accept:
application/json" '
https://localhost:8001/plugins/kimchi/vms/kimchi-vm-new/storages' -X
GET
Enter host password for user 'test':
[
{
"bus":"virtio",
"path":"/var/lib/libvirt/images/2477bfd8-a9e2-4887-a683
-e89015b3ba11-0.img",
"type":"disk",
"dev":"vda",
"format":"qcow2"
},
{
"bus":"virtio",
"path":"/var/lib/libvirt/images/2477bfd8-a9e2-4887-a683
-e89015b3ba11-1.img",
"type":"disk",
"dev":"vdb",
"format":"qcow2"
},
{
"bus":"ide",
"path":"/var/lib/kimchi/tests/ubuntu14.04.iso",
"type":"cdrom",
"dev":"hdc",
"format":"raw"
}
]
On Tue, 2015-11-10 at 16:12 -0200, pvital(a)linux.vnet.ibm.com wrote:
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
Add back-end support to create new storage volume (new virtual disk)
when
attaching disk to a guest created before.
There are three essential parameters to create the new volume:
* vol: Storage volume name of disk image, that should be 'new_vol'.
* capacity: The total space which can be used to store new volumes.
The unit is bytes.
* format: The format of the defined Storage Volume. Only used when
creating
a storage volume with 'capacity'.
Signed-off-by: Paulo Vital <pvital(a)linux.vnet.ibm.com>
---
src/wok/plugins/kimchi/API.json | 12 ++++++++++++
src/wok/plugins/kimchi/docs/API.md | 6 +++++-
src/wok/plugins/kimchi/i18n.py | 1 +
src/wok/plugins/kimchi/model/vmstorages.py | 28
+++++++++++++++++++++++++++-
4 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/src/wok/plugins/kimchi/API.json
b/src/wok/plugins/kimchi/API.json
index 961f35f..8822520 100644
--- a/src/wok/plugins/kimchi/API.json
+++ b/src/wok/plugins/kimchi/API.json
@@ -564,6 +564,18 @@
"type": "string",
"pattern":
"^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
"error": "KCHVMSTOR0003E"
+ },
+ "capacity": {
+ "description": "The total size (MiB) of the
storage volume",
+ "type": "number",
+ "minimum": 1,
+ "error": "KCHVOL0020E"
+ },
+ "format": {
+ "description": "The format of the volume",
+ "type": "string",
+ "pattern":
"^(|bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
+ "error": "KCHVOL0015E"
}
}
},
diff --git a/src/wok/plugins/kimchi/docs/API.md
b/src/wok/plugins/kimchi/docs/API.md
index 52368b7..d00c2fe 100644
--- a/src/wok/plugins/kimchi/docs/API.md
+++ b/src/wok/plugins/kimchi/docs/API.md
@@ -205,7 +205,11 @@ Represents a snapshot of the Virtual Machine's
primary monitor.
* type: The type of the storage (currently support 'cdrom' and
'disk').
* path: Path of cdrom iso.
* pool: Storage pool which disk image file locate in.
- * vol: Storage volume name of disk image.
+ * vol: Storage volume name of disk image ('new_vol' for create a
new volume).
+ * capacity: The total space which can be used to store new
volumes.
+ The unit is bytes.
+ * format: The format of the defined Storage Volume. Only used
when creating
+ a storage volume with 'capacity'.
### Sub-resource: storage
**URI:** /plugins/kimchi/vms/*:name*/storages/*:dev*
diff --git a/src/wok/plugins/kimchi/i18n.py
b/src/wok/plugins/kimchi/i18n.py
index 42a5e16..53a0b6b 100644
--- a/src/wok/plugins/kimchi/i18n.py
+++ b/src/wok/plugins/kimchi/i18n.py
@@ -278,6 +278,7 @@ messages = {
"KCHVMSTOR0016E": _("Volume already in use by other virtual
machine."),
"KCHVMSTOR0017E": _("Only one of path or pool/volume can be
specified to add a new virtual machine disk"),
"KCHVMSTOR0018E": _("Volume chosen with format %(format)s does
not fit in the storage type %(type)s"),
+ "KCHVMSTOR0019E": _("The format msust be used only when creating
a new storage volume with 'capacity'."),
"KCHSNAP0001E": _("Virtual machine '%(vm)s' must be stopped
before creating a snapshot of it."),
"KCHSNAP0002E": _("Unable to create snapshot '%(name)s' on
virtual machine '%(vm)s'. Details: %(err)s"),
diff --git a/src/wok/plugins/kimchi/model/vmstorages.py
b/src/wok/plugins/kimchi/model/vmstorages.py
index 23db0a6..f6b3918 100644
--- a/src/wok/plugins/kimchi/model/vmstorages.py
+++ b/src/wok/plugins/kimchi/model/vmstorages.py
@@ -22,12 +22,14 @@ from lxml import etree
from wok.exception import InvalidOperation, InvalidParameter,
NotFoundError
from wok.exception import OperationFailed
+from wok.model.tasks import TaskModel
from wok.utils import wok_log
from wok.plugins.kimchi.model.config import CapabilitiesModel
from wok.plugins.kimchi.model.diskutils import get_disk_used_by
from wok.plugins.kimchi.model.diskutils import set_disk_used_by
from wok.plugins.kimchi.model.storagevolumes import
StorageVolumeModel
+from wok.plugins.kimchi.model.storagevolumes import
StorageVolumesModel
from wok.plugins.kimchi.model.utils import get_vm_config_flag
from wok.plugins.kimchi.model.vms import DOM_STATE_MAP, VMModel
from wok.plugins.kimchi.osinfo import lookup
@@ -51,6 +53,7 @@ class VMStoragesModel(object):
self.conn = kargs['conn']
self.objstore = kargs['objstore']
self.caps = CapabilitiesModel(**kargs)
+ self.task = TaskModel(**kargs)
def _get_available_bus_address(self, bus_type, vm_name):
if bus_type not in ['ide']:
@@ -85,9 +88,12 @@ class VMStoragesModel(object):
if not ('vol' in params) ^ ('path' in params):
raise InvalidParameter("KCHVMSTOR0017E")
+ if ('format' in params) and ('capacity' not in params):
+ raise InvalidParameter("KCHVMSTOR0019E")
+
dom = VMModel.get_vm(vm_name, self.conn)
params['bus'] = _get_device_bus(params['type'], dom)
- params['format'] = 'raw'
+ params['format'] = params['format'] if 'format' in
params
else 'raw'
dev_list = [dev for dev, bus in
get_vm_disks(dom).iteritems()
if bus == params['bus']]
@@ -102,6 +108,26 @@ class VMStoragesModel(object):
DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
raise InvalidOperation('KCHVMSTOR0011E')
+ if params.get('capacity'):
+ # If 'capacity' is in the parameters a new storage
volume will
+ # be created and allocated to the VM.
+ if params['vol'] == 'new_vol':
+ # Set the name of the volume as the same pattern
used when
+ # creating a VM based on Template (VM UUID + disk
index).
+ # Otherwise, use the name provided by the user.
+ params['vol'] = "%s-%s.img" % (dom.UUIDString(),
+ params['index'])
+ vol_info = dict(name=params['vol'],
+ type=params['type'],
+ capacity=params['capacity'],
+ allocation=params['capacity'],
+ format=params['format'],
+ )
+ storage_volumes = StorageVolumesModel(conn=self.conn,
+
objstore=self.objstore)
+ mytask = storage_volumes.create(params['pool'],
vol_info)
+ self.task.wait(mytask['id'])
+
if params.get('vol'):
try:
pool = params['pool']