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