def test_rpc_service_handler(self): service = RpcService() ret = service.exposed_get_user_space_pod('not_exist', 'not_exist') self.assertFalse(ret) TaskExecutor._instance = None TaskExecutor.instance(new=True, test=True) ret = service.exposed_get_user_space_pod('test', self.admin.uuid) self.assertFalse(ret)
def test_get_user_space_pod_avoid_deleting(self): corr = TaskSettings.objects.create(name='task', uuid='my_uuid', description='', container_config=json.dumps( get_container_config()), replica=2, max_sharing_users=2, time_limit=0) task = TaskExecutor.instance(new=True, test=True) TaskStorage.objects.create(user=self.admin, settings=corr, pod_name='my_uuid', expire_time=round(time.time() + 100000)) ret = task.get_user_space_pod( corr.uuid, self.admin) # should never get available pod self.assertFalse(ret) task._ttl_check(corr.uuid) # should have 2 available pods for item in MockCoreV1ApiForTTL.pod_map['task=my_uuid']: item.status.phase = 'Running' # make'em running ret = task.get_user_space_pod(corr.uuid, self.admin) self.assertTrue(ret) for item in MockCoreV1ApiForTTL.pod_map['task=my_uuid']: if item.metadata.name == ret.metadata.name: self.assertEqual(ret.metadata.labels['occupied'], '1')
def test_get_user_vnc_pod(self): TaskSettings.objects.create(name='task_okay', uuid='my_uuid_okay', description='', container_config=json.dumps( get_container_config()), replica=1, max_sharing_users=1, time_limit=0) task = TaskExecutor.instance(new=True, test=True) res = task.get_user_vnc_pod('my_uuid_okay', self.admin) res2 = task.get_user_vnc_pod('my_uuid_okay', self.admin) self.assertEqual(res, res2)
def get(self, request, **kwargs): """ @api {get} /user_space/<str:uuid>/reset/ Reset user space @apiDescription Reset user space, copy initial task files into it @apiName ResetUserSpace @apiGroup UserSpace @apiVersion 0.1.0 @apiPermission user @apiParam {Boolean} [purge] Whether to clean all changes made by the user. If `true`, user changes will be dropped and then initial files get copied, otherwise initial files overwrite user changes only if necessary. @apiUse Success @apiUse APIHeader @apiUse InvalidRequest @apiUse OperationFailed @apiUse Unauthorized @apiUse ServerError """ try: user = kwargs.get('__user', None) uuid = kwargs.get('uuid', None) purge = request.GET.get('purge', 'false') purge = purge.lower() == 'true' if user is None: raise Exception( "Internal exception raised when trying to get `User` object." ) if uuid is None: raise ValueError settings = TaskSettings.objects.get(uuid=uuid) executor = TaskExecutor.instance(new=False) if executor is None: raise TaskSettings.DoesNotExist else: pod = executor.get_user_space_pod( settings.uuid, user, True, isinstance(purge, bool) and purge is True) if pod is None: raise TaskSettings.DoesNotExist return JsonResponse(RESPONSE.SUCCESS) except TaskSettings.DoesNotExist: res = RESPONSE.OPERATION_FAILED return JsonResponse(res) except ValueError: return JsonResponse(RESPONSE.INVALID_REQUEST) except Exception as ex: LOGGER.exception(ex) return JsonResponse(RESPONSE.SERVER_ERROR)
def get(self, _, **kwargs): """ @api {get} /vnc/<str:uuid>/ Get VNC pod @apiDescription Get a VNC pod where user can edit files in user space in a GUI environment. Typically, the full VNC url can be `wss://vnc_host:vnc_port/url_path`. Only secure socket it supported to ensure security. @apiName GetVNCPod @apiGroup UserSpace @apiVersion 0.1.0 @apiPermission user @apiSuccess {Object} payload Payload object @apiSuccess {String} payload.url_path WebSocket URL path for VNC @apiSuccess {String} payload.vnc_password VNC password @apiSuccess {String} payload.deployment_name Kubernetes deployment name @apiSuccess {String} payload.vnc_host WebSocket host for VNC @apiSuccess {Number} payload.vnc_port WebSocket port for VNC @apiUse APIHeader @apiUse InvalidRequest @apiUse OperationFailed @apiUse Unauthorized @apiUse ServerError """ try: user = kwargs.get('__user', None) if user is None: raise Exception( "Internal exception raised when trying to get `User` object." ) settings_uuid = kwargs.get('uuid', None) if settings_uuid is None: raise ValueError executor = TaskExecutor.instance(new=False) res = {} if executor is not None: res = executor.get_user_vnc_pod(settings_uuid, user) if res: response = RESPONSE.SUCCESS response['payload'] = res else: response = RESPONSE.OPERATION_FAILED return JsonResponse(response) except ValueError: return JsonResponse(RESPONSE.INVALID_REQUEST) except Exception as ex: LOGGER.exception(ex) return JsonResponse(RESPONSE.SERVER_ERROR)
def test_ttl_check(self): corr = TaskSettings.objects.create(name='task', uuid='my_uuid', description='', container_config=json.dumps( get_container_config()), replica=2, max_sharing_users=2, time_limit=0) task = TaskExecutor.instance(new=True, test=True) task._ttl_check('does-not-exist') # affect nothing task._ttl_check(corr.uuid) self.assertEqual(len(MockCoreV1ApiForTTL.pod_map['task=my_uuid']), 2) # maintain curr status task._ttl_check(corr.uuid) self.assertEqual(len(MockCoreV1ApiForTTL.pod_map['task=my_uuid']), 2) for item in MockCoreV1ApiForTTL.pod_map['task=my_uuid']: item.status.phase = 'Failed' task._ttl_check(corr.uuid) self.assertEqual(len(MockCoreV1ApiForTTL.pod_map['task=my_uuid']), 0) # restore task._ttl_check(corr.uuid) self.assertEqual(len(MockCoreV1ApiForTTL.pod_map['task=my_uuid']), 2) for item in MockCoreV1ApiForTTL.pod_map['task=my_uuid']: item.status.phase = 'Running' item_0 = MockCoreV1ApiForTTL.pod_map['task=my_uuid'][0] item_1 = MockCoreV1ApiForTTL.pod_map['task=my_uuid'][1] item_0.metadata.labels['occupied'] = str(2) item_1.metadata.labels['occupied'] = str(1) task._ttl_check(corr.uuid) self.assertEqual(len(MockCoreV1ApiForTTL.pod_map['task=my_uuid']), 2) item_1.metadata.labels['occupied'] = str(2) # all occupied, should expand task._ttl_check(corr.uuid) self.assertEqual(len(MockCoreV1ApiForTTL.pod_map['task=my_uuid']), 4) # should recycle item_1.metadata.labels['occupied'] = str(0) MockCoreV1ApiForTTL.pod_map['task=my_uuid'][2].status.phase = 'Running' task._ttl_check(corr.uuid) self.assertEqual(len(MockCoreV1ApiForTTL.pod_map['task=my_uuid']), 3)
def _get_pod(self, **kwargs): """ :param kwargs: parameters needed :return: pod: the pod allocated; username: the username to execute file ops """ user = kwargs.get('__user', None) if user is None: raise Exception( "Internal exception raised when trying to get `User` object.") settings_uuid = kwargs.get('uuid', None) if settings_uuid is None: raise ValueError settings = TaskSettings.objects.get(uuid=settings_uuid) username = '******'.format(user.username, settings.id) executor = TaskExecutor.instance(new=False) if executor is None: return None, username else: pod = executor.get_user_space_pod(settings_uuid, user) return pod, username
path('pods/', permission_required(monitor_views.PodListHandler.as_view())), # storage path('storage/', storage_views.StorageHandler.as_view()), path('storage/upload_file/', storage_views.StorageFileHandler.as_view()), path('storage/pod/', storage_views.PVCPodHandler.as_view()), path('storage/ide/<str:pvcname>/', storage_views.FileDisplayHandler.as_view()), # user space for webIDE path('user_space/<str:uuid>/', login_required(user_space_views.UserSpaceHandler.as_view())), path('user_space/<str:uuid>/reset/', login_required(user_space_views.UserSpaceResetHandler.as_view())), path('vnc/<str:uuid>/', login_required(user_space_views.UserVNCHandler.as_view())), # registry management path('registry/', registry_mgmt_views.RegistryHandler.as_view()), path('registry/repository/<str:repo>/', registry_mgmt_views.RepositoryHandler.as_view()), path('registry/repository/upload/', registry_mgmt_views.RepositoryHandler.as_view()), path('registry/repository/<str:repo>/<str:tag>/', registry_mgmt_views.RepositoryHandler.as_view()), path('registry/history/', registry_mgmt_views.UploadHandler.as_view()) ] RUNNING_DEV_SERVER = (len(sys.argv) > 1 and sys.argv[1] == 'runserver') if RUNNING_DEV_SERVER: from task_manager.executor import TaskExecutor executor = TaskExecutor.instance() executor.start()
def test_executor(self): settings_correct = TaskSettings.objects.create( name='task', uuid='my_uuid', description='', container_config=json.dumps(get_container_config()), replica=1, max_sharing_users=1, time_limit=0) settings_wrong = TaskSettings.objects.create(name='task_invalid', uuid='my_uuid_2', description='', container_config='{}', replica=1, max_sharing_users=1, time_limit=0) TaskSettings.objects.create(name='task_invalid_2', uuid='my_uuid_3', description='', container_config='bad_json', replica=1, max_sharing_users=1, time_limit=0) Task.objects.create(settings=settings_correct, user=self.admin, uuid='task', status=TASK.SCHEDULED, logs='') Task.objects.create(settings=settings_wrong, user=self.admin, uuid='task_err', status=TASK.SCHEDULED, logs='') TaskExecutor._instance = None task = TaskExecutor.instance(new=True, test=True) task.start() task.dispatch() task._ttl_check('my_uuid') task._job_dispatch() item = Task.objects.get(uuid='task') item_err = Task.objects.get(uuid='task_err') self.assertEqual(item.status, TASK.WAITING) self.assertEqual(item_err.status, TASK.FAILED) task._job_monitor() item = Task.objects.get(uuid='task') self.assertEqual(item.status, TASK.PENDING) task._job_monitor() item = Task.objects.get(uuid='task') self.assertEqual(item.status, TASK.RUNNING) task._job_monitor() item = Task.objects.get(uuid='task') self.assertTrue(item.status in (TASK.SUCCEEDED, TASK.FAILED)) TaskStorage.objects.create(settings=settings_correct, user=self.admin, pod_name='magic_pod', expire_time=round(time.time()) - 100) TaskVNCPod.objects.create(settings=settings_correct, user=self.admin, pod_name='magic_pod', expire_time=round(time.time() - 100)) task._storage_pod_monitor() task_storage = TaskStorage.objects.get(user=self.admin, settings=settings_correct) self.assertEqual(task_storage.pod_name, '') self.assertEqual(task_storage.expire_time, 0) task.get_user_space_pod('my_uuid', self.admin)