Change in vdsm[master]: v2v: DRAFT: new verb convertFromFile
shavivi at redhat.com
shavivi at redhat.com
Tue Jun 9 07:00:52 UTC 2015
Shahar Havivi has uploaded a new change for review.
Change subject: v2v: DRAFT: new verb convertFromFile
......................................................................
v2v: DRAFT: new verb convertFromFile
NO NEED TO REVIEW
Change-Id: I8f67fa664630f51037deb67e6e78fbac87ed61a1
Signed-off-by: Shahar Havivi <shaharh at redhat.com>
---
M vdsm/API.py
M vdsm/rpc/bindingxmlrpc.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/v2v.py
4 files changed, 127 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/67/42067/1
diff --git a/vdsm/API.py b/vdsm/API.py
index 80586c7..8ae99b6 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -1400,6 +1400,9 @@
return v2v.convert_external_vm(uri, username, password, vminfo, jobid,
self._cif.irs)
+ def convertExternalVmFromFiles(self, vminfo, jobid):
+ return v2v.convert_from_files(vminfo, jobid, self._cif.irs)
+
def getConvertedVm(self, jobid):
return v2v.get_converted_vm(jobid)
diff --git a/vdsm/rpc/bindingxmlrpc.py b/vdsm/rpc/bindingxmlrpc.py
index 6bb7082..2105d0f 100644
--- a/vdsm/rpc/bindingxmlrpc.py
+++ b/vdsm/rpc/bindingxmlrpc.py
@@ -373,6 +373,10 @@
api = API.Global()
return api.convertExternalVm(uri, username, password, vminfo, jobid)
+ def convertExternalVmFromFiles(self, vminfo, jobid):
+ api = API.Global()
+ return api.convertExternalVmFromFiles(vminfo, jobid)
+
def getConvertedVm(self, jobid):
api = API.Global()
return api.getConvertedVm(jobid)
@@ -1057,6 +1061,8 @@
(self.vmGetIoTunePolicy, 'getIoTunePolicy'),
(self.getExternalVMs, 'getExternalVMs'),
(self.convertExternalVm, 'convertExternalVm'),
+ (self.convertExternalVmFromFiles,
+ 'convertExternalVmFromFiles'),
(self.getConvertedVm, 'getConvertedVm'),
(self.abortV2VJob, 'abortV2VJob'),
(self.deleteV2VJob, 'deleteV2VJob'))
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index b690440..32be99e 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -3756,6 +3756,22 @@
'*capacity': 'uint', '*allocation': 'uint'}}
##
+# @ExternalFileInfo:
+#
+# Disk information from external source
+#
+# @iface: #interface for driver use ide/virtio etc
+#
+# @index: numeric index of the disk controllers position
+#
+# @path: underline disk file path
+#
+# Since: 4.17.0
+##
+{'type': 'ExternalFileInfo',
+ 'data': {'*iface': 'str', 'index': 'uint', 'path': 'str' }}
+
+##
# @ExternalNetworkInfo:
#
# Network information from external source
@@ -3768,10 +3784,13 @@
#
# @macAddr: #optional phisical address
#
+# @iface: #interface for driver use ide/virtio etc
+#
# Since: 4.17.0
##
{'type': 'ExternalNetworkInfo',
- 'data': {'type': 'str', '*bridge': 'str', '*dev': 'str', '*macAddr': 'str'}}
+ 'data': {'type': 'str', '*bridge': 'str', '*dev': 'str', '*macAddr': 'str',
+ '*iface': 'str'}}
##
# @ExternalVmInfo:
@@ -3790,6 +3809,8 @@
#
# @disks: #optional list of disk devices
#
+# @files: #optional list of local disk files
+#
# @networks: #optional list of network devices
#
# @format: #optional converted disk format (raw, cow etc)
@@ -3801,8 +3822,9 @@
{'type': 'ExternalVmInfo',
'data': {'vmName': 'str', 'status': 'VmStatus', 'vmId': 'UUID', 'smp': 'uint',
'memSize': 'uint', '*disks': ['ExternalDiskInfo'],
- '*networks': ['ExternalNetworkInfo'], '*format': 'VolumeFormat',
- '*allocation': 'VolumeAllocation'}}
+ '*files': ['ExternalFileInfo'],
+ '*networks': ['ExternalNetworkInfo'],
+ '*format': 'VolumeFormat', '*allocation': 'VolumeAllocation'}}
##
# @Host.getExternalVMs:
@@ -3848,6 +3870,22 @@
'vminfo': 'ExternalVmInfo', 'jobid': 'UUID'}}
##
+# @Host.convertExternalVmFromFiles:
+#
+# Convert VM from local disk file/files - host must have read access
+# to the files
+#
+# @vminfo: information of the VM such as name, id and local files
+#
+# @jobid: Assign a UUID to this operation which can be used
+# to identify it in @HostStats
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'Host', 'name': 'convertExternalVmFromFiles'},
+ 'data': {'vminfo': 'ExternalVmInfo', 'jobid': 'UUID'}}
+
+##
# @Host.getConvertedVm:
#
# Return OVF string that created via convertExternalVm call
diff --git a/vdsm/v2v.py b/vdsm/v2v.py
index 18cc9bc..b5fe076 100644
--- a/vdsm/v2v.py
+++ b/vdsm/v2v.py
@@ -40,6 +40,7 @@
from vdsm import libvirtconnection
from vdsm.infra import zombiereaper
from vdsm.utils import traceback, CommandPath, execCmd
+from virt import vmxml, vmdevices
import caps
@@ -154,6 +155,13 @@
_add_disk_info(conn, disk)
vms.append(params)
return {'status': doneCode, 'vmList': vms}
+
+
+def convert_from_files(vminfo, job_id, irs):
+ job = ImportVm.from_disk_files(vminfo, job_id, irs)
+ job.start()
+ _add_job(job_id, job)
+ return {'status': doneCode}
def convert_external_vm(uri, username, password, vminfo, job_id, irs):
@@ -316,6 +324,12 @@
obj._create_command = cls._from_libvirt_command
return obj
+ @classmethod
+ def from_disk_files(cls, vminfo, job_id, irs):
+ obj = cls(vminfo, job_id, irs)
+ obj._create_command = cls._from_disk_files_command
+ return obj
+
def start(self):
t = threading.Thread(target=self._run)
t.daemon = True
@@ -433,6 +447,69 @@
self._vminfo['vmName']])
return cmd
+ def _from_disk_files_command(self):
+ cmd = [_VIRT_V2V.cmd,
+ '-i', 'libvirtxml', self._generate_vm_xml(),
+ '-o', 'vdsm',
+ '-of', self._get_disk_format(),
+ '-oa', self._vminfo.get('allocation', 'sparse').lower(),
+ self._generate_disk_parameters(),
+ '--vdsm-vm-uuid', self._id,
+ '--vdsm-ovf-output', _V2V_DIR,
+ '--machine-readable',
+ '-os',
+ get_storage_domain_path(self._prepared_volumes[0]['path'])]
+ return cmd
+
+ def _generate_vm_xml(self):
+ conf = {'vmId': self._id,
+ 'vmName': self._vminfo['vmName'],
+ 'memSize': self._vminfo['memSize'],
+ 'vcpu': self._vminfo['smp']}
+ domxml = vmxml.Domain(conf, logging, caps.Architecture.X86_64)
+ domxml.appendOs()
+ self._append_disks_xml(domxml)
+ self._append_networks_xml(domxml)
+
+ return domxml.toxml()
+
+ def _append_disks_xml(self, domxml):
+ conf = {'device': 'disk',
+ 'type': 'disk',
+ 'format': self._vminfo.get('format', 'raw').lower()}
+ for disk in self._vminfo['files']:
+ conf = {'iface': disk.get('iface', 'virtio'),
+ 'index': int(disk['index']),
+ 'path': disk['path'],
+ 'propagateErrors': 'off'}
+ drive = vmdevices.storage.Drive({}, logging, **conf)
+
+ driveXml = drive.getXML()
+ '''
+ Removing driver node, storage add 'qemu' driver which is not the
+ case for vmdk file types
+ '''
+ hasDriver = False
+ for elem in driveXml.childNodes:
+ if elem.tagName == 'driver':
+ hasDriver = True
+ break
+ if hasDriver:
+ driveXml.removeChild(elem)
+ domxml.appendDeviceXML(driveXml.toxml())
+
+ def _append_networks_xml(self, domxml):
+ if 'networks' in self._vminfo:
+ for net in self._vminfo['networks']:
+ conf = {'macAddr': net['macAddr'],
+ 'address': net['macAddr'],
+ 'name': net['dev'],
+ 'nicModel': net.get('iface', 'virtio'),
+ 'network': net['bridge'],
+ 'device': net['type']}
+ iface = vmdevices.network.Interface({}, logging, **conf)
+ domxml.appendDeviceXML(iface.getXML().toxml())
+
def abort(self):
self._status = STATUS.ABORTED
logging.info('Job %r aborting...', self._id)
--
To view, visit https://gerrit.ovirt.org/42067
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8f67fa664630f51037deb67e6e78fbac87ed61a1
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Shahar Havivi <shavivi at redhat.com>
More information about the vdsm-patches
mailing list