Change in vdsm[master]: v2v: Job related actions

shavivi at redhat.com shavivi at redhat.com
Mon Mar 30 13:22:18 UTC 2015


Shahar Havivi has uploaded a new change for review.

Change subject: v2v: Job related actions
......................................................................

v2v: Job related actions

Added few job related actions:
Delete job
Abort Job
Get ovf (jobs output)

Change-Id: I9a58583a88e2f17ce0847626cd601efbe1a00ac9
Signed-off-by: Shahar Havivi <shaharh at redhat.com>
---
M client/vdsClient.py
M vdsm/API.py
M vdsm/rpc/BindingXMLRPC.py
M vdsm/rpc/Bridge.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/v2v.py
6 files changed, 181 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/61/39361/1

diff --git a/client/vdsClient.py b/client/vdsClient.py
index 9704fdb..b5be5a1 100755
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -1928,6 +1928,26 @@
             print "v2v job started"
         return status['status']['code'], status['status']['message']
 
+    def getConvertedVm(self, args):
+        if len(args) != 1:
+            raise ValueError('Wrong number of arguments')
+        status = self.s.getConvertedVm(args[0])
+        if status['status']['code'] == 0:
+            print status['ovf']
+        return status['status']['code'], status['status']['message']
+
+    def abortV2VJob(self, args):
+        if len(args) != 1:
+            raise ValueError('Wrong number of arguments')
+        status = self.s.abortV2VJob(args[0])
+        return status['status']['code'], status['status']['message']
+
+    def deleteV2VJob(self, args):
+        if len(args) != 1:
+            raise ValueError('Wrong number of arguments')
+        status = self.s.deleteV2VJob(args[0])
+        return status['status']['code'], status['status']['message']
+
 if __name__ == '__main__':
     if _glusterEnabled:
         serv = ge.GlusterService()
@@ -2811,6 +2831,21 @@
                 'If auth argument is provided, password will be '
                 'ignored (yet has to be specified, ie -)'
             )),
+        'getConvertedVm': (
+            serv.getConvertedVm, (
+                '<jobId>',
+                'Return converted VMs OVF'
+            )),
+        'abortV2VJob': (
+            serv.abortV2VJob, (
+                '<jobId>',
+                'Abort running V2V convert process'
+            )),
+        'deleteV2VJob': (
+            serv.deleteV2VJob, (
+                '<jobId>',
+                'Delete V2v job when job is done'
+            )),
     }
     if _glusterEnabled:
         commands.update(ge.getGlusterCmdDict(serv))
diff --git a/vdsm/API.py b/vdsm/API.py
index e9454b4..f2bbfe9 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -1410,6 +1410,15 @@
         return v2v.convert(uri, username, password, vmProperties, jobId,
                            self._cif)
 
+    def getConvertedVm(self, jobId):
+        return v2v.get_converted_vm(jobId)
+
+    def deleteV2VJob(self, jobId):
+        return v2v.delete_job(jobId)
+
+    def abortV2VJob(self, jobId):
+        return v2v.abort_job(jobId)
+
     # Networking-related functions
     def setupNetworks(self, networks, bondings, options):
         """Add a new network to this vds, replacing an old one."""
diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index 9aefe9f..68d8b44 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -370,6 +370,18 @@
         return api.convertVmFromExternalSystem(uri, username, password,
                                                vmProperties, jobId)
 
+    def getConvertedVm(self, jobId):
+        api = API.Global()
+        return api.getConvertedVm(jobId)
+
+    def abortV2VJob(self, jobId):
+        api = API.Global()
+        return api.abortV2VJob(jobId)
+
+    def deleteV2VJob(self, jobId):
+        api = API.Global()
+        return api.deleteV2VJob(jobId)
+
     def vmPause(self, vmId):
         vm = API.VM(vmId)
         return vm.pause()
@@ -1044,7 +1056,10 @@
                 (self.vmGetIoTunePolicy, 'getIoTunePolicy'),
                 (self.getExternalVMs, 'getExternalVMs'),
                 (self.convertVmFromExternalSystem,
-                 'convertVmFromExternalSystem'))
+                 'convertVmFromExternalSystem'),
+                (self.getConvertedVm, 'getConvertedVm'),
+                (self.abortV2VJob, 'abortV2VJob'),
+                (self.deleteV2VJob, 'deleteV2VJob'))
 
     def getIrsMethods(self):
         return ((self.domainActivate, 'activateStorageDomain'),
diff --git a/vdsm/rpc/Bridge.py b/vdsm/rpc/Bridge.py
index 3adb71b..30c9579 100644
--- a/vdsm/rpc/Bridge.py
+++ b/vdsm/rpc/Bridge.py
@@ -403,6 +403,7 @@
     'Host_getDeviceList': {'ret': 'devList'},
     'Host_getDevicesVisibility': {'ret': 'visible'},
     'Host_getExternalVMs': {'ret': 'vmList'},
+    'Host_getConvertedVm': {'ret': 'ovf'},
     'Host_getHardwareInfo': {'ret': 'info'},
     'Host_getLVMVolumeGroups': {'ret': 'vglist'},
     'Host_getRoute': {'ret': 'info'},
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 7a8b2f9..c22ab94 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -3816,6 +3816,43 @@
   'vmProperties': 'ExternalVmInfo', 'jobId': 'UUID'}}
 
 ##
+# @Host.getConvertedVm:
+#
+# Return OVF string that created via convertVmFromExternalSystem call
+#
+# @jobId:  UUID to identify the job that created in convertVmFromExternalSystem
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'Host', 'name': 'getConvertedVm'},
+  'data': {'jobId': 'UUID'}
+  'returns': 'str'}
+
+##
+# @Host.abortV2VJob:
+#
+# Abort V2V importing process
+#
+# @jobId:  UUID to identify the job that created in convertVmFromExternalSystem
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'Host', 'name': 'abortV2VJob'},
+  'data': {'jobId': 'UUID'}}
+
+##
+# @Host.deleteV2VJob:
+#
+# Delete V2V job when job is done or stop due to errors
+#
+# @jobId:  UUID to identify the job that created in convertVmFromExternalSystem
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'Host', 'name': 'deleteV2VJob'},
+  'data': {'jobId': 'UUID'}}
+
+##
 # @VMFullInfo:
 #
 # Full information about VM.
diff --git a/vdsm/v2v.py b/vdsm/v2v.py
index 9b63f70..a0370f7 100644
--- a/vdsm/v2v.py
+++ b/vdsm/v2v.py
@@ -89,6 +89,21 @@
     err_name = 'V2VJobExists'
 
 
+class NoSuchJob(V2VError):
+    ''' Job not exists in _jobs collection '''
+    err_name = 'V2VNoSuchJob'
+
+
+class JobNotDone(V2VError):
+    ''' Import process still in progress '''
+    err_name = 'V2VJobNotDone'
+
+
+class NoSuchOvf(V2VError):
+    ''' Ovf path is not exists in /var/run/vdsm/v2v/ '''
+    err_name = 'V2VNoSuchOvf'
+
+
 class VolumeError(RuntimeError):
     ''' Error preparing volume '''
 
@@ -150,6 +165,39 @@
     return {'status': doneCode}
 
 
+def get_converted_vm(job_id):
+    try:
+        job = _get_job(job_id)
+        _validate_job_done(job)
+        ovf = _read_ovf(job_id)
+    except V2VError as e:
+        logging.warning('Converted VM error %s', e)
+        return errCode[e.err_name]
+    return {'status': doneCode, 'ovf': ovf}
+
+
+def delete_job(job_id):
+    try:
+        job = _get_job(job_id)
+        _validate_job_finished(job)
+        _remove_job(job_id)
+    except V2VError as e:
+        logging.warning('Error deleting job: %s, error: %s', job_id, e)
+        return errCode[e.err_name]
+    return {'status': doneCode}
+
+
+def abort_job(job_id):
+    try:
+        job = _get_job(job_id)
+        job.abort()
+        _remove_job(job_id)
+    except V2VError as e:
+        logging.warning('Error aboring job: %s, error: %s', job_id, e)
+        return errCode[e.err_name]
+    return {'status': doneCode}
+
+
 def jobs():
     ret = {}
     with _lock:
@@ -162,6 +210,17 @@
             'progress': job.progress
         }
     return ret
+
+
+def _read_ovf(job_id):
+    file_name = os.path.join(_V2V_DIR, "%s.ovf" % job_id)
+    try:
+        with open(file_name, 'r') as f:
+            return f.read()
+    except IOError as e:
+        if e.errno != errno.ENOENT:
+            raise
+        raise NoSuchOvf("No such ovf %r" % file_name)
 
 
 def _add_job(job_id, job):
@@ -179,6 +238,30 @@
     return path.rsplit(os.sep, 3)[0]
 
 
+def _get_job(job_id):
+    with _lock:
+        if job_id not in _jobs:
+            raise NoSuchJob()
+        return _jobs[job_id]
+
+
+def _remove_job(job_id):
+    with _lock:
+        if job_id not in _jobs:
+            raise NoSuchJob("No such job %r" % job_id)
+        del _jobs[job_id]
+
+
+def _validate_job_done(job):
+    if job.status != STATUS.DONE:
+        raise JobNotDone("Job %r is %s" % (job.id, job.status))
+
+
+def _validate_job_finished(job):
+    if job.status not in (STATUS.DONE, STATUS.FAILED, STATUS.ABORTED):
+        raise JobNotDone("Job %r is %s" % (job.id, job.status))
+
+
 class ImportVm(object):
     ABORT_RETRIES = 3
     ABORT_DELAY = 10


-- 
To view, visit https://gerrit.ovirt.org/39361
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9a58583a88e2f17ce0847626cd601efbe1a00ac9
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