def batch_loads(self, request): if request.method == 'GET': files = scan_task_event_resource() return response.Response({'files': files}) elif request.method == 'POST': UPLOADTOKEN = 'uploadToken' filenames = request.data.getlist('filenames', []) attachment_file = request.FILES.get('attachment', None) upload_token = request.query_params.get(UPLOADTOKEN, None) if attachment_file: destination = open( os.path.join(resource_api_setting.LOAD_TMP_DIR, attachment_file.name), 'wb+') for chunk in attachment_file.chunks(): # 分块写入文件 destination.write(chunk) destination.close() filenames = [attachment_file.name] if not filenames: return response.Response(status=status.HTTP_201_CREATED) delay_task.new_task( self._batch_loads, 2, (filenames, upload_token, attachment_file.name)) return response.Response(status=status.HTTP_201_CREATED)
def sub_perform_create(self, serializer): serializer.save() instance = serializer.instance file_path = instance.encrypt_file.path try: extract_to_path = self.unzip(file_path, serializer) new_task(self._do_update, 0, (extract_to_path, )) except Exception as e: logger.error("update error msg[%s]", str(e)) raise exceptions.ValidationError(error.WRONG_UPDATE_ZIP) return True
def create(self, image_name, vm_id=None, container_id=None, image_file=None, ftp_file_name=None, meta_data=None, created=None, failed=None, timeout_callback=None): check_type = 'Image' if vm_id: image_id = self.operator.create_snapshot(vm_id, image_name) image = self.get(image_id) # # snapshot # bdm = getattr(image, 'block_device_mapping', None) # if bdm: # try: # block_snap_id = json.loads(bdm)[0].get("snapshot_id") # self.operator.check_volume_snapshot_status(block_snap_id) # except Exception: # pass # else: # image = self.operator.check_image_status(image_id) check_type = 'Snapshot' elif container_id: image = self.operator.save_image(container_id, image_name) elif image_file: params = { 'name': image_name, 'image_file': image_file, } if meta_data: params.update(meta_data) image = self.operator.create_image(**params) elif ftp_file_name: params = { 'name': image_name, 'file_name': ftp_file_name, } if meta_data: params.update(meta_data) image = self.operator.create_image_by_ftp(**params) else: raise Exception('param error: no resource for creating image') if created or failed: new_task(self.operator.check_image_status, 0, (image.id, check_type, created, failed, timeout_callback)) return image
def clear_unexcept_standard_device_tmp_vm(): from common_env.models import StandardDeviceEditServer from common_env.utils.standard_device import delete_tmp_vm # 每隔半小时清除半小时内还没完成的机器 tmp_vms = StandardDeviceEditServer.objects.filter( create_time__lt=(timezone.now() - datetime.timedelta(minutes=30)), status__in=(StandardDeviceEditServer.Status.CREATING, StandardDeviceEditServer.Status.STARTING), ) for tmp_vm in tmp_vms: delete_tmp_vm(tmp_vm) # 半小时执行一次 from common_framework.utils import delay_task delay_task.new_task(clear_unexcept_standard_device_tmp_vm, 60 * 30, ())
def update_online(self, request): zip_url = self.shift_data.get('url') file_path = "/tmp/%s.zip" % str(uuid.uuid4()) import requests r = requests.get(zip_url, stream=True) with open(file_path, "wb") as zip: for chunk in r.iter_content(chunk_size=1024): if chunk: zip.write(chunk) extract_to_path = self.unzip(file_path) new_task(self._do_update, 0, (extract_to_path, )) return response.Response({'status': 'ok'})
def callback(**kwargs): from common_framework.utils import delay_task if not settings.DEBUG: delay_task.new_task(clear_not_use_resources, 0, ()) def normal_callback(): clear_expired_env() clear_unexcept_envs() clear_unexcept_standard_device_tmp_vm() delay_task.new_task(normal_callback, 0, ()) clear_uncontrol_standard_device_tmp_vm() from common_remote.managers import check_setting check_setting()
def clear_unexcept_envs(): from common_env.models import Env, EnvTerminal from common_env.handlers.manager import admin_delete_env unexcept_envs = Env.objects.exclude( envterminal__status=EnvTerminal.Status.DELETED, ).filter( status__in=Env.Status.DELETED, ) for env in unexcept_envs: try: admin_delete_env(env) logger.info('clear unexcept env[env_id=%s] ok', env.id) except Exception as e: logger.error('clear unexcept env[env_id=%s] error: %s', env.id, str(e)) # 半小时执行一次 from common_framework.utils import delay_task delay_task.new_task(clear_unexcept_envs, 60 * 30, ())
def recording_convert(request): host_ip = request.data.get('host_ip') convert_key = request.data.get('convert_key') convert_params = json.loads(request.data.get('convert_params', '{}')) recording_name = request.data.get('recording_name') screen_size = request.data.get('screen_size') or '1366x768' if not convert_key or not recording_name or not isinstance( convert_params, dict): raise PermissionDenied() convert_func = api_settings.RECORDING_CONVERT_CALLBACK.get(convert_key) if not convert_func: raise PermissionDenied() def tmp_task(): remote_manager = RemoteManager(host=host_ip) callback_script = '' if host_ip and host_ip != api_settings.OJ_SERVER['host_ip']: executor = { 'func': delay_convert_callback, 'params': { 'recording_name': recording_name, 'screen_size': screen_size, 'convert_func': convert_func, 'convert_params': convert_params, } } condition = RecordingConvertTask.dump_executor(executor) task = RecordingConvertTask.objects.filter(**condition).first() if not task: task = RecordingConvertTask.objects.create(extra=executor.get( 'extra', ''), **condition) callback_url = settings.SERVER_HOST + reverse( 'common_remote:recording_convert_over', (task.id, )) callback_script = 'curl {callback_url}'.format( callback_url=callback_url) video_names = remote_manager.convert_recording( recording_name, screen_size=screen_size, callback_script=callback_script) convert_func(video_names, screen_size, **convert_params) new_task(tmp_task, 0, ()) return Response({})
def _destroy_env_related(cls, env): def tmp_task(): logger.info('delete env[%s] related start', env.pk) # 删除关联测试场景 test_env_map = env_models.TestEnvMap.objects.filter( template_env=env).first() if test_env_map: try: admin_delete_env(test_env_map.test_env) except Exception as e: logger.error('delete env[%s] related test env error: %s', env.pk, e) # 删除关联快照场景 snapshot_env_map = env_models.SnapshotEnvMap.objects.filter( template_env=env).first() if snapshot_env_map: try: admin_delete_env(snapshot_env_map.tmp_env) except Exception as e: logger.error( 'delete env[%s] related snapshot env error: %s', env.pk, e) # 删除快照 image_ids = [ envterminal.image_id for envterminal in env.envterminal_set.all() ] image_ids = filter(lambda x: x, image_ids) for image_id in image_ids: try: scene.image.delete(image_id) except Exception as e: logger.error('delete env[%s] related snapshot error: %s', env.pk, e) logger.info('delete env[%s] related end', env.pk) new_task(tmp_task, 0, ())
def clear_expired_env(): try: from common_env.handlers.manager import admin_delete_env from common_env.models import Env, TestEnvMap from course.models import LessonEnv from practice.base_models import TaskEnv now_time = timezone.now() # 题目环境 expired_task_envs = TaskEnv.objects.exclude(env=None).filter( env__status__in=(Env.Status.CREATING, Env.Status.USING), destroy_time__lte=timezone.now()) for task_env in expired_task_envs: try: admin_delete_env(task_env.env) logger.info( 'clear expired task env[task_env_id=%s, env_id=%s] ok' % (task_env.id, task_env.env.id)) except Exception as e: logger.error( 'clear expired task env[task_env_id=%s, env_id=%s] error: %s' % (task_env.id, task_env.env.id, str(e))) # 实验环境 expired_lesson_envs = LessonEnv.objects.exclude(env=None).filter( env__status__in=(Env.Status.CREATING, Env.Status.USING), destroy_time__lte=timezone.now()) for lesson_env in expired_lesson_envs: try: admin_delete_env(lesson_env.env) logger.info( 'clear expired lesson env[lesson_env_id=%s, env_id=%s] ok' % (lesson_env.id, lesson_env.env.id)) except Exception as e: logger.error( 'clear expired lesson env[lesson_env_id=%s, env_id=%s] error: %s' % (lesson_env.id, lesson_env.env.id, str(e))) # 场景测试环境 prev_time = now_time - datetime.timedelta(hours=2) test_env_maps = TestEnvMap.objects.exclude(test_env=None).filter( test_env__status__in=Env.ActiveStatusList, test_env__create_time__lte=prev_time, ) for test_env_map in test_env_maps: try: admin_delete_env(test_env_map.test_env) logger.info( 'clear expired test env[test_env_map_id=%s, env_id=%s] ok' % (test_env_map.id, test_env_map.test_env.id)) except Exception as e: logger.error( 'clear expired test env[test_env_map_id=%s, env_id=%s] error: %s' % (test_env_map.id, test_env_map.test_env.id, str(e))) connection.close() except Exception as e: logger.error('clear expired task env error: %s' % str(e)) from common_framework.utils import delay_task delay_task.new_task(clear_expired_env, 60 * 2, ())
def clear_not_use_resources(): logger.info('clear not use resources start') # 清除场景相关的资源 try: from common_env.handlers.local_lib import scene from common_env.models import Env, EnvTerminal, EnvNet, EnvGateway, StandardDeviceEditServer from common_env.setting import api_settings as common_env_settings from common_scene.setting import api_settings as common_scene_settings from common_scene.complex.views import BaseScene from common_scene.clients.neutron_client import Client as NeutronClient operator = BaseScene() using_status = Env.ActiveStatusList vms = operator.list_server(prefix=common_env_settings.BASE_GROUP_NAME) dockers = operator.list_container( prefix=common_env_settings.BASE_GROUP_NAME) routers = operator.list_router( prefix=common_env_settings.BASE_GROUP_NAME) firewalls = operator.list_firewall( prefix=common_env_settings.BASE_GROUP_NAME) networks = operator.list_network( prefix=common_env_settings.BASE_GROUP_NAME) _clear_resources([vm.id for vm in vms], scene.vm.delete, [ (EnvTerminal.objects.filter( env__status__in=using_status, image_type=EnvTerminal.ImageType.VM), 'vm_id'), (StandardDeviceEditServer.objects.exclude( status=StandardDeviceEditServer.Status.DELETED), 'tmp_vm_id') ], 'clear not use env resources: not_use_vm_ids - %s') _clear_resources( [docker.id for docker in dockers], scene.docker.delete, [(EnvTerminal.objects.filter( env__status__in=using_status, image_type=EnvTerminal.ImageType.DOCKER), 'vm_id'), (StandardDeviceEditServer.objects.exclude( status=StandardDeviceEditServer.Status.DELETED), 'tmp_docker_id')], 'clear not use env resources: not_use_docker_ids - %s') _clear_resources( [router['id'] for router in routers], scene.router.delete, [(EnvGateway.objects.filter(env__status__in=using_status), 'router_id'), (StandardDeviceEditServer.objects.exclude( status=StandardDeviceEditServer.Status.DELETED), 'tmp_router_id')], 'clear not use env resources: not_use_router_ids - %s') _clear_resources( [firewall['id'] for firewall in firewalls], scene.firewall.delete, [ (EnvGateway.objects.filter(env__status__in=using_status), 'firewall_id'), ], 'clear not use env resources: not_use_firewall_ids - %s') _clear_resources( [network['id'] for network in networks], scene.network.delete, [(EnvNet.objects.filter(env__status__in=using_status), 'net_id'), (StandardDeviceEditServer.objects.exclude( status=StandardDeviceEditServer.Status.DELETED), 'tmp_network_id')], 'clear not use env resources: not_use_network_ids - %s') operator.clear_unused_port() logger.info('clear not use env resources ok') except Exception as e: logger.error('clear not use env resources error: %s' % str(e)) # 清除攻防赛相关的资源, 攻防赛机器使用的是场景的, 只需清理路由和网络 try: from event_attack_defense.models import AttackDefenseEvent from event_attack_defense.setting import api_settings as event_ad_settings routers = operator.list_router( prefix=event_ad_settings.BASE_GROUP_NAME) networks = operator.list_network( prefix=event_ad_settings.BASE_GROUP_NAME) _clear_resources( [router['id'] for router in routers], scene.router.delete, [ (AttackDefenseEvent.objects.all(), 'global_router'), ], 'clear not use ad event resources: not_use_router_ids - %s') _clear_resources( [network['id'] for network in networks], scene.network.delete, [ (AttackDefenseEvent.objects.all(), 'global_network'), ], 'clear not use ad event resources: not_use_network_ids - %s') logger.info('clear not use ad event resources ok') except Exception as e: logger.error('clear not use ad event resources error: %s' % str(e)) # 清除错误资源 try: error_vms = operator.list_server( prefix=common_env_settings.BASE_GROUP_NAME, search_opts={'status': 'ERROR'}) error_vm_ids = [error_vm.id for error_vm in error_vms] if error_vm_ids: logger.info('clear error resources: error_vm_ids - %s', error_vm_ids) for vm_id in error_vm_ids: scene.vm.delete(vm_id) dockers = operator.list_container( prefix=common_env_settings.BASE_GROUP_NAME) error_docker_ids = [ docker.id for docker in dockers if docker.status.lower() == 'error' ] if error_docker_ids: logger.info('clear error resources: error_docker_ids - %s', error_docker_ids) for docker_id in error_docker_ids: scene.docker.delete(docker_id) except Exception as e: logger.error('clear error resources error: %s' % str(e)) logger.info('clear not use resources end') # 一天执行一次 from common_framework.utils import delay_task delay_task.new_task(clear_not_use_resources, 60 * 60 * 24, ())
def image(self, request, pk=None): if request.method == 'POST': device = self.get_object() if not device.tmp_vm or (not device.tmp_vm.tmp_vm_id and not device.tmp_vm.tmp_docker_id): raise exceptions.ValidationError(error.NO_TMP_ENV) if device.image_status == env_models.StandardDevice.ImageStatus.CREATING: raise exceptions.ValidationError(error.IMAGE_SAVING) device.image_status = env_models.StandardDevice.ImageStatus.CREATING device.save() self.clear_cache() def _create_image(): image_name = device.name # # snapshot # image_name = '{}__$__{}'.format(image_name, str(uuid.uuid4())) # 删除旧的镜像 try: old_image_id = scene.image.get(image_name=image_name).id except: old_image_id = None def created(image): logger.info('device[%s] image created', device.pk) device.image_status = env_models.StandardDevice.ImageStatus.CREATED try: device.save() # # snapshot # env_models.StandardDeviceSnapshot.objects.create( # standard_device=device, # name=image_name, # ) except Exception as e: logger.error('save standard device[%s] error: %s', device.pk, e) # # snapshot # if device.tmp_vm.tmp_vm_id: # try: # delete_tmp_vm(device.tmp_vm) # except Exception as e: # logger.error('delete standard device[%s] tmp vm error: %s', device.pk, e) self.clear_cache() # 删除旧的镜像 if old_image_id: scene.image.delete(image_id=old_image_id) def failed(error): logger.info('device[%s] image failed', device.pk) device.image_status = env_models.StandardDevice.ImageStatus.ERROR try: device.save() except Exception as e: logger.error('save standard device[%s] error: %s', device.pk, e) self.clear_cache() # # snapshot # if device.tmp_vm.tmp_vm_id: # scene.vm.start(device.tmp_vm.tmp_vm_id) try: if device.tmp_vm.tmp_vm_id: # # snapshot # scene.vm.shutdown(device.tmp_vm.tmp_vm_id) scene.image.create(image_name, vm_id=device.tmp_vm.tmp_vm_id, created=created, failed=failed, timeout_callback=created) elif device.tmp_vm.tmp_docker_id: scene.image.create( image_name, container_id=device.tmp_vm.tmp_docker_id, created=created, failed=failed, timeout_callback=created) else: raise exceptions.ValidationError(error.NO_TMP_ENV) except Exception as e: logger.error('device[%s] save image error: %s', device.pk, e) device.error = e.message device.image_status = env_models.StandardDevice.ImageStatus.ERROR device.save() self.clear_cache() new_task(_create_image, 0, ()) return Response({})
def _create_vm(): if device.error: env_models.StandardDevice.objects.filter( pk=device.pk).update(error='') # 建机器 try: creater = StandardDeviceTmpVmCreater(image_name, device) ret = creater.create_resource() except Exception as e: env_models.StandardDevice.objects.filter( pk=device.pk).update(error=e.message) device.tmp_vm.delete() self.clear_cache() return logger.info( 'create template vm for device[%s] by image[%s] return[%s]: waiting for update' % (device.pk, image_name, ret)) float_ip = ret['float_ip'] port = device.access_port or env_models.EnvTerminal.AccessModeDefaultPort.get( device.access_mode) update_params = {} if device.access_mode in ( env_models.EnvTerminal.AccessMode.SSH, env_models.EnvTerminal.AccessMode.RDP): # 建连接 remote_manager = RemoteManager(request.user) connection_name = '%s:%s:%s:%s' % ( request.user.id, float_ip, port, hashlib.md5(str(uuid.uuid4())).hexdigest()) params = { 'username': ret['username'], 'password': ret['password'], } try: if device.access_mode == env_models.EnvTerminal.AccessMode.SSH: connection_id = remote_manager.create_ssh_connection( connection_name, float_ip, **params).connection_id elif device.access_mode == env_models.EnvTerminal.AccessMode.RDP: params[ 'security'] = device.access_connection_mode or 'rdp' if device.system_type == env_models.StandardDevice.SystemType.LINUX: params['enable-sftp'] = 'true' connection_id = remote_manager.create_rdp_connection( connection_name, float_ip, **params).connection_id update_params['connection_id'] = connection_id except Exception as e: logger.error('create guacamole connection error: %s', e) # 建代理 if port and proxy.PROXY_SWITCH: try: proxy_ports = proxy.create_proxy(float_ip, [port]) except Exception as e: logger.error('create tmp_vm[%s] proxy error: %s' % (device.tmp_vm.id, e)) env_models.StandardDevice.objects.filter( pk=device.pk).update(error=e.message) creater.rollback_resource() device.tmp_vm.delete() self.clear_cache() raise e logger.info( 'create template vm for device[%s] by image[%s]: create proxy %s:%s --> %s' % (device.pk, image_name, float_ip, port, proxy_ports)) if len(proxy_ports) > 0: update_params['proxy_port'] = proxy_ports[0] proxy.restart_proxy() tmp_vm = device.tmp_vm # 获取最新的数据 lastest_tmp_vm = env_models.StandardDeviceEditServer.objects.get( pk=tmp_vm.pk) if lastest_tmp_vm.status == env_models.StandardDeviceEditServer.Status.RUNNING: tmp_vm_status = env_models.StandardDeviceEditServer.Status.RUNNING else: tmp_vm_status = env_models.StandardDeviceEditServer.Status.STARTING update_params.update({ 'tmp_network_ids': json.dumps(ret['network_ids']), 'tmp_router_ids': json.dumps(ret['router_ids']), 'tmp_docker_id': ret['docker_id'], 'tmp_vm_id': ret['vm_id'], 'tmp_net_ports': json.dumps(ret['net_ports']), 'protocol': device.access_mode, 'float_ip': float_ip, 'host_ip': ret['host_ip'], 'host_name': ret['host_name'], 'port': port, 'username': ret['username'], 'password': ret['password'], 'status': tmp_vm_status, }) try: env_models.StandardDeviceEditServer.objects.filter( pk=tmp_vm.pk).update(**update_params) except Exception as e: logger.error('update tmp_vm[%s] error: %s' % (tmp_vm.id, e)) delete_tmp_vm(tmp_vm, destroy=False) raise e self.clear_cache() new_task(self._check_tmp_vm_status, 0, (tmp_vm.id, device))
def tmp_vm(self, request, pk=None): if request.method == 'GET': device = self.get_object() if device.tmp_vm: data = mserializers.StandardDeviceEditServerSerializer( device.tmp_vm).data else: data = None return Response(data) elif request.method == 'POST': device = self.get_object() if device.access_mode not in ( env_models.EnvTerminal.AccessMode.SSH, env_models.EnvTerminal.AccessMode.RDP, env_models.EnvTerminal.AccessMode.CONSOLE, env_models.EnvTerminal.AccessMode.TELNET, ): raise exceptions.ValidationError( error.STANDARD_DEVICE_ACCESSMODE_ERROR) # # snapshot # image_name = get_lastest_image_name(device.name, device) # if device.image_type == env_models.StandardDevice.ImageType.VM: # try: # image = scene.volume.get(snapshot_name=image_name) # except Exception: # image = None # # if not image: # try: # image = scene.image.get(image_name=image_name) # except: # image = None # # if not image: # if image_name != device.name: # raise exceptions.ValidationError(error.IMAGE_NOT_FOUND) # # # 没有镜像则从基础镜像创建 # image_name = device.source_image_name image_name = device.name try: image = scene.image.get(image_name=image_name) except: image = None # 没有镜像则从基础镜像创建 if not image: image_name = device.source_image_name if not image_name: raise exceptions.ValidationError(error.NO_BASE_IMAGE) if device.tmp_vm: edit_server = device.tmp_vm if edit_server.status != env_models.StandardDeviceEditServer.Status.DELETED: raise exceptions.ValidationError(error.TMP_ENV_CONFLICT) delete_tmp_vm(edit_server, destroy=False) edit_server.status = env_models.StandardDeviceEditServer.Status.CREATING edit_server.save() else: edit_server = env_models.StandardDeviceEditServer.objects.create( create_user=request.user) device.tmp_vm = edit_server device.save() self.clear_cache() def _create_vm(): if device.error: env_models.StandardDevice.objects.filter( pk=device.pk).update(error='') # 建机器 try: creater = StandardDeviceTmpVmCreater(image_name, device) ret = creater.create_resource() except Exception as e: env_models.StandardDevice.objects.filter( pk=device.pk).update(error=e.message) device.tmp_vm.delete() self.clear_cache() return logger.info( 'create template vm for device[%s] by image[%s] return[%s]: waiting for update' % (device.pk, image_name, ret)) float_ip = ret['float_ip'] port = device.access_port or env_models.EnvTerminal.AccessModeDefaultPort.get( device.access_mode) update_params = {} if device.access_mode in ( env_models.EnvTerminal.AccessMode.SSH, env_models.EnvTerminal.AccessMode.RDP): # 建连接 remote_manager = RemoteManager(request.user) connection_name = '%s:%s:%s:%s' % ( request.user.id, float_ip, port, hashlib.md5(str(uuid.uuid4())).hexdigest()) params = { 'username': ret['username'], 'password': ret['password'], } try: if device.access_mode == env_models.EnvTerminal.AccessMode.SSH: connection_id = remote_manager.create_ssh_connection( connection_name, float_ip, **params).connection_id elif device.access_mode == env_models.EnvTerminal.AccessMode.RDP: params[ 'security'] = device.access_connection_mode or 'rdp' if device.system_type == env_models.StandardDevice.SystemType.LINUX: params['enable-sftp'] = 'true' connection_id = remote_manager.create_rdp_connection( connection_name, float_ip, **params).connection_id update_params['connection_id'] = connection_id except Exception as e: logger.error('create guacamole connection error: %s', e) # 建代理 if port and proxy.PROXY_SWITCH: try: proxy_ports = proxy.create_proxy(float_ip, [port]) except Exception as e: logger.error('create tmp_vm[%s] proxy error: %s' % (device.tmp_vm.id, e)) env_models.StandardDevice.objects.filter( pk=device.pk).update(error=e.message) creater.rollback_resource() device.tmp_vm.delete() self.clear_cache() raise e logger.info( 'create template vm for device[%s] by image[%s]: create proxy %s:%s --> %s' % (device.pk, image_name, float_ip, port, proxy_ports)) if len(proxy_ports) > 0: update_params['proxy_port'] = proxy_ports[0] proxy.restart_proxy() tmp_vm = device.tmp_vm # 获取最新的数据 lastest_tmp_vm = env_models.StandardDeviceEditServer.objects.get( pk=tmp_vm.pk) if lastest_tmp_vm.status == env_models.StandardDeviceEditServer.Status.RUNNING: tmp_vm_status = env_models.StandardDeviceEditServer.Status.RUNNING else: tmp_vm_status = env_models.StandardDeviceEditServer.Status.STARTING update_params.update({ 'tmp_network_ids': json.dumps(ret['network_ids']), 'tmp_router_ids': json.dumps(ret['router_ids']), 'tmp_docker_id': ret['docker_id'], 'tmp_vm_id': ret['vm_id'], 'tmp_net_ports': json.dumps(ret['net_ports']), 'protocol': device.access_mode, 'float_ip': float_ip, 'host_ip': ret['host_ip'], 'host_name': ret['host_name'], 'port': port, 'username': ret['username'], 'password': ret['password'], 'status': tmp_vm_status, }) try: env_models.StandardDeviceEditServer.objects.filter( pk=tmp_vm.pk).update(**update_params) except Exception as e: logger.error('update tmp_vm[%s] error: %s' % (tmp_vm.id, e)) delete_tmp_vm(tmp_vm, destroy=False) raise e self.clear_cache() new_task(self._check_tmp_vm_status, 0, (tmp_vm.id, device)) new_task(_create_vm, 0, ()) return Response( mserializers.StandardDeviceEditServerSerializer( edit_server).data) elif request.method == 'DELETE': device = self.get_object() if device.tmp_vm: delete_tmp_vm(device.tmp_vm) self.clear_cache() return Response(status=status.HTTP_204_NO_CONTENT)