[Kimchi-devel] [PATCH] Create new storage volume when attaching disk to a guest.

Paulo Ricardo Paz Vital pvital at linux.vnet.ibm.com
Tue Nov 10 19:29:07 UTC 2015


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 at linux.vnet.ibm.com wrote:
> From: Paulo Vital <pvital at 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 at 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']




More information about the Kimchi-devel mailing list