Skip to content

Commit 7f912ff

Browse files
authored
Merge pull request #909 from QualiSystems/igor_cancellation_added
Cancellation added for the all deployment options
2 parents fcc0489 + 1658b5b commit 7f912ff

File tree

14 files changed

+174
-99
lines changed

14 files changed

+174
-99
lines changed

package/cloudshell/cp/vcenter/commands/command_orchestrator.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from cloudshell.cp.vcenter.vm.vnic_to_network_mapper import VnicToNetworkMapper
5353
from cloudshell.cp.vcenter.models.DeployFromTemplateDetails import DeployFromTemplateDetails
5454

55+
5556
class CommandOrchestrator(object):
5657
def __init__(self):
5758
"""
@@ -159,10 +160,11 @@ def connect_bulk(self, context, request):
159160
driver_response_root.driverResponse = driver_response
160161
return set_command_result(result=driver_response_root, unpicklable=False)
161162

162-
def deploy_from_template(self, context, request):
163+
def deploy_from_template(self, context, request, cancellation_context):
163164
"""
164165
Deploy From Template Command, will deploy vm from template
165166
167+
:param cancellation_context:
166168
:param models.QualiDriverModels.ResourceCommandContext context: the context of the command
167169
:param str request: represent a json string '{ "DeploymentServiceName": "..", "AppName": "..", "Attributes": {"Key1": "Value1", ..} }'
168170
:return str deploy results
@@ -171,21 +173,24 @@ def deploy_from_template(self, context, request):
171173
# get command parameters from the environment
172174
data = jsonpickle.decode(request)
173175
data['Attributes']['vCenter Name'] = context.resource.name
174-
clone_from_vm_model = ResourceModelParser().convert_to_resource_model(data['Attributes'], vCenterVMFromTemplateResourceModel)
176+
clone_from_vm_model = ResourceModelParser().convert_to_resource_model(data['Attributes'],
177+
vCenterVMFromTemplateResourceModel)
175178
data_holder = DeployFromTemplateDetails(clone_from_vm_model, data['UserRequestedAppName'] or data['AppName'])
176179

177180
# execute command
178181
result = self.command_wrapper.execute_command_with_connection(
179182
context,
180183
self.deploy_command.execute_deploy_from_template,
181-
data_holder)
184+
data_holder,
185+
cancellation_context)
182186

183187
return set_command_result(result=result, unpicklable=False)
184188

185-
def deploy_clone_from_vm(self, context, request):
189+
def deploy_clone_from_vm(self, context, request, cancellation_context):
186190
"""
187191
Deploy Cloned VM From VM Command, will deploy vm from template
188192
193+
:param cancellation_context:
189194
:param models.QualiDriverModels.ResourceCommandContext context: the context of the command
190195
:param str request: represent a json string '{ "DeploymentServiceName": "..", "AppName": "..", "Attributes": {"Key1": "Value1", ..} }'
191196
:return str deploy results
@@ -194,22 +199,25 @@ def deploy_clone_from_vm(self, context, request):
194199
# get command parameters from the environment
195200
data = jsonpickle.decode(request)
196201
data['Attributes']['vCenter Name'] = context.resource.name
197-
clone_from_vm_model = ResourceModelParser().convert_to_resource_model(data['Attributes'], vCenterCloneVMFromVMResourceModel)
202+
clone_from_vm_model = ResourceModelParser().convert_to_resource_model(data['Attributes'],
203+
vCenterCloneVMFromVMResourceModel)
198204
data_holder = DeployFromTemplateDetails(clone_from_vm_model, data['UserRequestedAppName'] or data['AppName'])
199205

200206
# execute command
201207
result = self.command_wrapper.execute_command_with_connection(
202208
context,
203209
self.deploy_command.execute_deploy_clone_from_vm,
204-
data_holder)
210+
data_holder,
211+
cancellation_context)
205212

206213
res = set_command_result(result=result, unpicklable=False)
207214
return res
208215

209-
def deploy_from_linked_clone(self, context, request):
216+
def deploy_from_linked_clone(self, context, request, cancellation_context):
210217
"""
211218
Deploy Cloned VM From VM Command, will deploy vm from template
212219
220+
:param cancellation_context:
213221
:param models.QualiDriverModels.ResourceCommandContext context: the context of the command
214222
:param str request: represent a json string '{ "DeploymentServiceName": "..", "AppName": "..", "Attributes": {"Key1": "Value1", ..} }'
215223
:return str deploy results
@@ -218,25 +226,29 @@ def deploy_from_linked_clone(self, context, request):
218226
# get command parameters from the environment
219227
data = jsonpickle.decode(request)
220228
data['Attributes']['vCenter Name'] = context.resource.name
221-
linked_clone_from_vm_model = self.resource_model_parser.convert_to_resource_model(data['Attributes'], VCenterDeployVMFromLinkedCloneResourceModel)
229+
linked_clone_from_vm_model = self.resource_model_parser.convert_to_resource_model(data['Attributes'],
230+
VCenterDeployVMFromLinkedCloneResourceModel)
222231

223232
if not linked_clone_from_vm_model.vcenter_vm_snapshot:
224233
raise ValueError('Please insert snapshot to deploy from')
225234

226-
data_holder = DeployFromTemplateDetails(linked_clone_from_vm_model, data['UserRequestedAppName'] or data['AppName'])
235+
data_holder = DeployFromTemplateDetails(linked_clone_from_vm_model,
236+
data['UserRequestedAppName'] or data['AppName'])
227237

228238
# execute command
229239
result = self.command_wrapper.execute_command_with_connection(
230240
context,
231241
self.deploy_command.execute_deploy_from_linked_clone,
232-
data_holder)
242+
data_holder,
243+
cancellation_context)
233244

234245
return set_command_result(result=result, unpicklable=False)
235246

236-
def deploy_from_image(self, context, request):
247+
def deploy_from_image(self, context, request, cancellation_context):
237248
"""
238249
Deploy From Image Command, will deploy vm from ovf image
239250
251+
:param cancellation_context:
240252
:param models.QualiDriverModels.ResourceCommandContext context: the context of the command
241253
:param str request: represent a json string '{ "DeploymentServiceName": "..", "AppName": "..", "Attributes": {"Key1": "Value1", ..} }'
242254
:return str deploy results
@@ -245,15 +257,17 @@ def deploy_from_image(self, context, request):
245257
# get command parameters from the environment
246258
data = jsonpickle.decode(request)
247259
data['Attributes']['vCenter Name'] = context.resource.name
248-
deploy_from_image_model = self.resource_model_parser.convert_to_resource_model(data['Attributes'], vCenterVMFromImageResourceModel)
260+
deploy_from_image_model = self.resource_model_parser.convert_to_resource_model(data['Attributes'],
261+
vCenterVMFromImageResourceModel)
249262
data_holder = DeployFromImageDetails(deploy_from_image_model, data['UserRequestedAppName'] or data['AppName'])
250263

251264
# execute command
252265
result = self.command_wrapper.execute_command_with_connection(
253266
context,
254267
self.deploy_command.execute_deploy_from_image,
255268
data_holder,
256-
context.resource)
269+
context.resource,
270+
cancellation_context)
257271

258272
return set_command_result(result=result, unpicklable=False)
259273

@@ -325,7 +339,8 @@ def refresh_ip(self, context, cancellation_context, ports):
325339
self.refresh_ip_command.refresh_ip,
326340
resource_details,
327341
cancellation_context,
328-
context.remote_endpoints[0].app_context.app_request_json)
342+
context.remote_endpoints[
343+
0].app_context.app_request_json)
329344
return set_command_result(result=res, unpicklable=False)
330345

331346
# remote command
@@ -402,7 +417,7 @@ def get_vm_uuid_by_name(self, context, vm_name):
402417
vm_name)
403418
return set_command_result(result=res, unpicklable=False)
404419

405-
def get_vm_details(self, context,cancellation_context, requests_json):
420+
def get_vm_details(self, context, cancellation_context, requests_json):
406421
requests = DeployDataHolder(jsonpickle.decode(requests_json)).items
407422
res = self.command_wrapper.execute_command_with_connection(context,
408423
self.vm_details.get_vm_details,

package/cloudshell/cp/vcenter/commands/deploy_vm.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ def __init__(self, deployer):
1111
"""
1212
self.deployer = deployer
1313

14-
def execute_deploy_from_linked_clone(self, si, logger, vcenter_data_model, reservation_id, deployment_params):
14+
def execute_deploy_from_linked_clone(self, si, logger, vcenter_data_model, reservation_id, deployment_params, cancellation_context):
1515
"""
1616
Calls the deployer to deploy vm from snapshot
17+
:param cancellation_context:
1718
:param str reservation_id:
1819
:param si:
1920
:param logger:
@@ -22,12 +23,13 @@ def execute_deploy_from_linked_clone(self, si, logger, vcenter_data_model, reser
2223
:return:
2324
"""
2425
deploy_result = self.deployer.deploy_from_linked_clone(si, logger, deployment_params, vcenter_data_model,
25-
reservation_id)
26+
reservation_id, cancellation_context)
2627
return deploy_result
2728

28-
def execute_deploy_clone_from_vm(self, si, logger, vcenter_data_model, reservation_id, deployment_params):
29+
def execute_deploy_clone_from_vm(self, si, logger, vcenter_data_model, reservation_id, deployment_params, cancellation_context):
2930
"""
3031
Calls the deployer to deploy vm from another vm
32+
:param cancellation_context:
3133
:param str reservation_id:
3234
:param si:
3335
:param logger:
@@ -36,10 +38,10 @@ def execute_deploy_clone_from_vm(self, si, logger, vcenter_data_model, reservati
3638
:return:
3739
"""
3840
deploy_result = self.deployer.deploy_clone_from_vm(si, logger, deployment_params, vcenter_data_model,
39-
reservation_id)
41+
reservation_id, cancellation_context)
4042
return deploy_result
4143

42-
def execute_deploy_from_template(self, si, logger, vcenter_data_model, reservation_id, deployment_params):
44+
def execute_deploy_from_template(self, si, logger, vcenter_data_model, reservation_id, deployment_params, cancellation_context):
4345
"""
4446
4547
:param str reservation_id:
@@ -50,13 +52,14 @@ def execute_deploy_from_template(self, si, logger, vcenter_data_model, reservati
5052
:return:
5153
"""
5254
deploy_result = self.deployer.deploy_from_template(si, logger, deployment_params, vcenter_data_model,
53-
reservation_id)
55+
reservation_id, cancellation_context)
5456
return deploy_result
5557

5658
def execute_deploy_from_image(self, si, logger, session, vcenter_data_model, reservation_id, deployment_params,
57-
resource_context):
59+
resource_context, cancellation_context):
5860
"""
5961
62+
:param cancellation_context:
6063
:param str reservation_id:
6164
:param si:
6265
:param logger:
@@ -72,5 +75,6 @@ def execute_deploy_from_image(self, si, logger, session, vcenter_data_model, res
7275
vcenter_data_model=vcenter_data_model,
7376
data_holder=deployment_params,
7477
resource_context=resource_context,
75-
reservation_id=reservation_id)
78+
reservation_id=reservation_id,
79+
cancellation_context=cancellation_context)
7680
return deploy_result

package/cloudshell/cp/vcenter/common/vcenter/task_waiter.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ def __init__(self):
1010
pass
1111

1212
# noinspection PyMethodMayBeStatic
13-
def wait_for_task(self, task, logger, action_name='job', hide_result=False):
13+
def wait_for_task(self, task, logger, action_name='job', hide_result=False, cancellation_context=None):
1414
"""
1515
Waits and provides updates on a vSphere task
16+
:param cancellation_context: package.cloudshell.cp.vcenter.models.QualiDriverModels.CancellationContext
1617
:param task:
1718
:param action_name:
1819
:param hide_result:
@@ -21,6 +22,13 @@ def wait_for_task(self, task, logger, action_name='job', hide_result=False):
2122

2223
while task.info.state in [vim.TaskInfo.State.running, vim.TaskInfo.State.queued]:
2324
time.sleep(2)
25+
if cancellation_context is not None and task.info.cancelable and cancellation_context.is_cancelled and not task.info.cancelled:
26+
# some times the cancel operation doesn't really cancel the task
27+
# so consider an additional handling of the canceling
28+
task.CancelTask()
29+
logger.info("SynchronousTaskWaiter: task.CancelTask() " + str(task.info.name.info.name))
30+
logger.info("SynchronousTaskWaiter: task.info.cancelled " + str(task.info.cancelled))
31+
logger.info("SynchronousTaskWaiter: task.info.state " + str(task.info.state))
2432

2533
if task.info.state == vim.TaskInfo.State.success:
2634
if task.info.result is not None and not hide_result:

package/cloudshell/cp/vcenter/common/vcenter/vmomi_service.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,11 @@ def __init__(self, vm=None, error=None):
405405
self.vm = vm
406406
self.error = error
407407

408-
def clone_vm(self, clone_params, logger):
408+
def clone_vm(self, clone_params, logger, cancellation_context):
409409
"""
410410
Clone a VM from a template/VM and return the vm oject or throws argument is not valid
411411
412+
:param cancellation_context:
412413
:param clone_params: CloneVmParameters =
413414
:param logger:
414415
"""
@@ -470,7 +471,8 @@ def clone_vm(self, clone_params, logger):
470471
logger.info("cloning VM...")
471472
try:
472473
task = template.Clone(folder=dest_folder, name=clone_params.vm_name, spec=clone_spec)
473-
vm = self.task_waiter.wait_for_task(task=task, logger=logger, action_name='Clone VM')
474+
vm = self.task_waiter.wait_for_task(task=task, logger=logger, action_name='Clone VM',
475+
cancellation_context=cancellation_context)
474476
except TaskFaultException:
475477
raise
476478
except vim.fault.NoPermission as error:

package/cloudshell/cp/vcenter/common/wrappers/command_wrapper.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ def execute_command_with_connection(self, context, command, *args):
5959
"""
6060

6161
logger = self.context_based_logger_factory.create_logger_for_context(
62-
logger_name='vCenterShell',
63-
context=context)
62+
logger_name='vCenterShell',
63+
context=context)
6464

6565
if not command:
6666
logger.error(COMMAND_CANNOT_BE_NONE)
@@ -82,15 +82,15 @@ def execute_command_with_connection(self, context, command, *args):
8282

8383
vcenter_data_model = self.resource_model_parser.convert_to_vcenter_model(context.resource)
8484
connection_details = ResourceConnectionDetailsRetriever.get_connection_details(session=session,
85-
vcenter_resource_model=vcenter_data_model,
86-
resource_context=context.resource)
85+
vcenter_resource_model=vcenter_data_model,
86+
resource_context=context.resource)
8787

8888
if connection_details:
8989
logger.info(INFO_CONNECTING_TO_VCENTER.format(connection_details.host))
9090
logger.debug(
91-
DEBUG_CONNECTION_INFO.format(connection_details.host,
92-
connection_details.username,
93-
connection_details.port))
91+
DEBUG_CONNECTION_INFO.format(connection_details.host,
92+
connection_details.username,
93+
connection_details.port))
9494

9595
si = self.get_py_service_connection(connection_details, logger)
9696
if si:
@@ -127,7 +127,7 @@ def execute_command_with_connection(self, context, command, *args):
127127
return results
128128
except Exception as ex:
129129
logger.exception(COMMAND_ERROR.format(command_name))
130-
logger.exception(str(type(ex)) + ': '+ str(ex))
130+
logger.exception(str(type(ex)) + ': ' + str(ex))
131131
raise
132132
finally:
133133
logger.info(LOG_FORMAT.format(END, command_name))

0 commit comments

Comments
 (0)