def _internal_start_expr(self, context): hackathon = Hackathon.objects.get(id=context.hackathon_id) experiment = Experiment.objects.get(id=context.experiment_id) if not experiment or not hackathon: return internal_server_error( 'Failed starting k8s: experiment or hackathon not found.') user = experiment.user or None _virtual_envs = [] try: if user: _virtual_envs = experiment.virtual_environments if not _virtual_envs: # Get None VirtualEnvironment, create new one: for template_unit in context.template_content.units: k8s_dict = self.__create_useful_k8s_dict( hackathon, experiment, template_unit) experiment.virtual_environments.append( VirtualEnvironment( provider=VE_PROVIDER.K8S, name=k8s_dict['name'], k8s_resource=k8s_dict, status=VEStatus.INIT, remote_provider=VERemoteProvider.Guacamole)) # save constructed experiment, and execute from first job content experiment.save() self.__schedule_create(context) else: self.__schedule_start(context) except Exception as e: self.log.error(e) experiment.status = EStatus.FAILED experiment.save() return internal_server_error('Failed starting k8s')
def __start_new_expr(self, hackathon, template, user_id): # new expr expr = self.db.add_object_kwargs(Experiment, user_id=user_id, hackathon_id=hackathon.id, status=EStatus.INIT, template_id=template.id, create_time=self.util.get_now()) self.db.commit() if template.provider == VE_PROVIDER.DOCKER: try: template_content = self.template_library.load_template(template) virtual_environments_units = template_content.units expr.status = EStatus.STARTING self.db.commit() map(lambda unit: self.__remote_start_container(hackathon, expr, unit), virtual_environments_units) except Exception as e: self.log.error(e) self.log.error("Failed starting containers") self.__roll_back(expr.id) return internal_server_error('Failed starting containers') else: expr.status = EStatus.STARTING self.db.commit() try: # af = AzureFormation(self.hosted_docker.load_azure_key_id(expr.id)) # af.create(expr.id) template_content = self.template_library.load_template(template) azure_keys = self.azure_cert_manager.get_certificates_by_expr(expr.id) # TODO: which key to use? azure_key = azure_keys[0] # create virtual environments for units expr_id = expr.id ves = [] for unit in template_content.units: ve = VirtualEnvironment( provider=VE_PROVIDER.AZURE, # TODO: when to set name? name=self.azure_formation.get_virtual_machine_name(unit.get_virtual_machine_name(), expr_id), image=unit.get_image_name(), status=VEStatus.INIT, remote_provider=VERemoteProvider.Guacamole, experiment=expr) self.db.add_object(ve) ves.append(ve) # TODO: elimate virtual_environments arg self.azure_formation.start_vm(expr_id, azure_key, template_content.units, ves) except Exception as e: self.log.error(e) return internal_server_error('Failed starting azure vm') # after everything is ready, set the expr state to running # response to caller return self.__report_expr_status(expr)
def stop_expr(self, expr_id, force=0): """ :param expr_id: experiment id :param force: 0: only stop container and release ports, 1: force stop and delete container and release ports. :return: """ self.log.debug("begin to stop %d" % expr_id) expr = self.db.find_first_object_by(Experiment, id=expr_id, status=EStatus.RUNNING) if expr is not None: # Docker docker = self.docker.get_docker(expr.hackathon) if expr.template.provider == VE_PROVIDER.DOCKER: # stop containers for c in expr.virtual_environments.all(): try: self.log.debug("begin to stop %s" % c.name) if force: docker.delete(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.DELETED else: docker.stop(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.STOPPED except Exception as e: self.log.error(e) self.__roll_back(expr_id) return internal_server_error( 'Failed stop/delete container') if force: expr.status = EStatus.DELETED else: expr.status = EStatus.STOPPED self.db.commit() else: try: # todo support delete azure vm azure_key_id = self.docker.load_azure_key_id(expr.id) context = Context(azure_key_id=azure_key_id, experiment_id=expr.id, action=AVMStatus.STOPPED_DEALLOCATED) self.azure_vm_service.stop_vm_entry(context) except Exception as e: self.log.error(e) return internal_server_error('Failed stopping azure') self.log.debug("experiment %d ended success" % expr_id) return ok('OK') else: return ok('expr not exist')
def stop_expr(self, expr_id, force=0): """ :param expr_id: experiment id :param force: 0: only stop container and release ports, 1: force stop and delete container and release ports. :return: """ self.log.debug("begin to stop %d" % expr_id) expr = self.db.find_first_object_by(Experiment, id=expr_id, status=EStatus.RUNNING) if expr is not None: # Docker if expr.template.provider == VE_PROVIDER.DOCKER: # stop containers for c in expr.virtual_environments.all(): try: self.log.debug("begin to stop %s" % c.name) docker = self.__get_docker(expr.hackathon, c) if force: docker.delete(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.DELETED else: docker.stop(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.STOPPED except Exception as e: self.log.error(e) self.__roll_back(expr_id) return internal_server_error('Failed stop/delete container') if force: expr.status = EStatus.DELETED else: expr.status = EStatus.STOPPED self.db.commit() else: try: # todo support delete azure vm # hosted_docker = RequiredFeature("hosted_docker") # af = AzureFormation(hosted_docker.load_azure_key_id(expr_id)) # af.stop(expr_id, AVMStatus.STOPPED_DEALLOCATED) template = self.db.get_object(Template, expr.template_id) template_content = self.template_library.load_template(template) azure_keys = self.azure_cert_manager.get_certificates_by_expr(expr_id) # TODO: which key to use azure_key = azure_keys[0] # TODO: elimate virtual_environments arg and expr_id arg self.azure_formation.stop_vm( expr_id, azure_key, template_content.units, expr.virtual_environments.all(), expr_id) except Exception as e: self.log.error(e) return internal_server_error('Failed stopping azure') self.log.debug("experiment %d ended success" % expr_id) return ok('OK') else: return ok()
def __start_new_expr(self, hackathon, template, user_id): # new expr expr = self.db.add_object_kwargs(Experiment, user_id=user_id, hackathon_id=hackathon.id, status=EStatus.INIT, template_id=template.id) self.db.commit() curr_num = self.db.count( Experiment, Experiment.user_id == ReservedUser.DefaultUserID, Experiment.template == template, (Experiment.status == EStatus.STARTING) | (Experiment.status == EStatus.RUNNING)) if template.provider == VE_PROVIDER.DOCKER: try: template_dic = self.template_manager.load_template(template) virtual_environments_list = template_dic[ BaseTemplate.VIRTUAL_ENVIRONMENTS] if curr_num != 0 and curr_num >= self.util.get_config( "pre_allocate.docker"): return expr.status = EStatus.STARTING self.db.commit() map( lambda virtual_environment_dic: self.__remote_start_container( hackathon, expr, virtual_environment_dic), virtual_environments_list) expr.status = EStatus.RUNNING self.db.commit() except Exception as e: self.log.error(e) self.log.error("Failed starting containers") self.__roll_back(expr.id) return internal_server_error('Failed starting containers') else: if curr_num != 0 and curr_num >= self.util.get_config( "pre_allocate.azure"): return expr.status = EStatus.STARTING self.db.commit() try: azure_key_id = self.docker.load_azure_key_id(expr.id) context = Context(azure_key_id=azure_key_id, experiment_id=expr.id) self.azure_vm_service.create_vm_for_expr_entry(context) except Exception as e: self.log.error(e) return internal_server_error('Failed starting azure vm') # after everything is ready, set the expr state to running # response to caller return self.__report_expr_status(expr)
def _internal_stop_expr(self, context): experiment = Experiment.objects.get(id=context.experiment_id) if not experiment: return internal_server_error( 'Failed stop k8s: experiment not found.') try: self.__schedule_stop(context) except Exception as e: self.log.error(e) experiment.status = EStatus.FAILED experiment.save() return internal_server_error('Failed stopping k8s')
def _internal_stop_expr(self, context): experiment = Experiment.objects.get(id=context.experiment_id) if not experiment: return internal_server_error('Failed stop k8s: experiment not found.') try: context.virtual_environments = experiment.virtual_environments self.__schedule_stop(context) experiment.delete() except Exception as e: self.log.error(e) experiment.status = EStatus.FAILED experiment.save() return internal_server_error('Failed stopping k8s')
def __start_new_expr(self, hackathon, template, user_id): # new expr expr = self.db.add_object_kwargs(Experiment, user_id=user_id, hackathon_id=hackathon.id, status=EStatus.INIT, template_id=template.id) self.db.commit() curr_num = self.db.count(Experiment, Experiment.user_id == ReservedUser.DefaultUserID, Experiment.template == template, (Experiment.status == EStatus.STARTING) | (Experiment.status == EStatus.RUNNING)) if template.provider == VE_PROVIDER.DOCKER: try: template_dic = self.template_manager.load_template(template) virtual_environments_list = template_dic[BaseTemplate.VIRTUAL_ENVIRONMENTS] if curr_num != 0 and curr_num >= self.util.get_config("pre_allocate.docker"): return expr.status = EStatus.STARTING self.db.commit() map(lambda virtual_environment_dic: self.__remote_start_container(hackathon, expr, virtual_environment_dic), virtual_environments_list) expr.status = EStatus.RUNNING self.db.commit() except Exception as e: self.log.error(e) self.log.error("Failed starting containers") self.__roll_back(expr.id) return internal_server_error('Failed starting containers') else: if curr_num != 0 and curr_num >= self.util.get_config("pre_allocate.azure"): return expr.status = EStatus.STARTING self.db.commit() try: azure_key_id = self.docker.load_azure_key_id(expr.id) context = Context(azure_key_id=azure_key_id, experiment_id=expr.id) self.azure_vm_service.create_vm_for_expr_entry(context) except Exception as e: self.log.error(e) return internal_server_error('Failed starting azure vm') # after everything is ready, set the expr state to running # response to caller return self.__report_expr_status(expr)
def delete_template(self, template_id): self.log.debug("delete template [%d]" % template_id) try: template = self.db.get_object(Template, template_id) if template is None: return ok("already removed") # user can only delete the template which created by himself except super admin if g.user.id != template.creator_id and not self.user_manager.is_super_admin( g.user): return forbidden() if len( self.db.find_all_objects_by(Experiment, template_id=template_id)) > 0: return forbidden("template already in use") # remove template cache and storage self.cache.invalidate(self.__get_template_cache_key(template_id)) self.storage.delete(template.url) # remove record in DB self.db.delete_all_objects_by(HackathonTemplateRel, template_id=template.id) self.db.delete_object(template) return ok("delete template success") except Exception as ex: self.log.error(ex) return internal_server_error("delete template failed")
def update_user_profile(self, args): """ Update user profile with fields and values specified in 'args' :param args: (key=value) paris, whose keys match the column name of DB table user_profile and values are corresponding column values :type args: dict :return: a record of related user profile in DB table user_profile :rtype: class UserProfile object :raise: raise error when something goes wrong with DB operation :type: internal server error """ self.log.debug("update_user_profile") try: u_id = args["user_id"] user_profile = self.db.find_first_object_by(UserProfile, user_id=u_id) if user_profile: self.db.update_object(user_profile, **args) return user_profile.dic() else: return not_found("fail to update user profile") except Exception as e: self.log.debug(e) return internal_server_error("failed to update user profile")
def create_user_profile(self, args): """ Create a user profile in DB table user_profile if user does not exist, otherwise update user profile with fields and values specified in 'args' :param args: (key=value) paris, whose keys match the column name of DB table user_profile and values are corresponding column values :type args: dict :return: a record of related user profile in DB table user_profile :rtype: class UserProfile object :raise: raise error when something goes wrong with DB operation :type: internal server error """ self.log.debug("create_user_profile: %r" % args) try: exist = self.get_user_profile(g.user.id) if not exist: return self.db.add_object_kwargs(UserProfile, **args).dic() else: return self.update_user_profile(args) except Exception as e: self.log.debug(e) return internal_server_error("failed to create user profile")
def update_hackathon(self, args): """Update hackathon properties :type args: dict :param args: arguments from http request body that contains properties with new values :rtype dict :return hackathon in dict if updated successfully. """ hackathon = g.hackathon try: update_items = self.__parse_update_items(args, hackathon) self.log.debug("update hackathon items :" + str(args.keys())) # basic xss prevention if 'description' in update_items and update_items['description']: update_items['description'] = self.cleaner.clean_html(update_items['description']) self.log.debug("hackathon description :" + update_items['description']) self.db.update_object(hackathon, **update_items) return hackathon.dic() except Exception as e: self.log.error(e) return internal_server_error("fail to update hackathon")
def _internal_start_expr(self, context): try: # TODO: context.hackathon may be None when tesing a template before any hackathon bind it azure_keys = context.hackathon.azure_keys # TODO: which key to use? azure_key = azure_keys[0] # create virtual environments for units expr_id = context.experiment.id ves = [] for unit in context.template_content.units: ve = VirtualEnvironment( provider=VE_PROVIDER.AZURE, # TODO: when to set name? name=self.azure_formation.get_virtual_machine_name(unit.get_virtual_machine_name(), expr_id), image=unit.get_image_name(), status=VEStatus.INIT, remote_provider=VERemoteProvider.Guacamole, experiment=context.experiment) self.db.add_object(ve) ves.append(ve) # TODO: elimate virtual_environments arg self.azure_formation.start_vm(expr_id, azure_key, context.template_content.units, ves) except Exception as e: self.log.error(e) return internal_server_error('Failed starting azure vm')
def delete_registration(self, args): """ Delete the registration of a user in a hackathon, also do operation on the user's team. """ if "id" not in args: return bad_request("id not invalid") try: register = self.get_registration_by_id(args["id"]) if register is not None: register.delete() hackathon = register.hackathon self.__update_register_stat(hackathon) team = self.team_manager.get_team_by_user_and_hackathon( register.user, hackathon) if not team: self.log.warn("team of this registered user is not found!") return ok() self.team_manager.quit_team_forcedly(team, register.user) return ok() except Exception as ex: self.log.error(ex) return internal_server_error("failed in delete register: %s" % args["id"])
def update_registration(self, context): try: registration_id = context.id register = self.get_registration_by_id(registration_id) if register is None or register.hackathon.id != g.hackathon.id: # we can also create a new object here. return not_found("registration not found") register.update_time = self.util.get_now() register.status = context.status register.save() if register.status == HACK_USER_STATUS.AUDIT_PASSED: self.team_manager.create_default_team(register.hackathon, register.user) self.__ask_for_dev_plan(register.hackathon, register.user) hackathon = self.hackathon_manager.get_hackathon_by_id( register.hackathon.id) self.__update_register_stat(hackathon) return register.dic() except Exception as e: self.log.error(e) return internal_server_error("fail to update register")
def update_hackathon(self, args): """Update hackathon properties :type args: dict :param args: arguments from http request body that contains properties with new values :rtype dict :return hackathon in dict if updated successfully. """ hackathon = g.hackathon try: update_items = self.__parse_update_items(args, hackathon) self.log.debug("update hackathon items :" + str(args.keys())) # basic xss prevention if 'description' in update_items and update_items['description']: update_items['description'] = self.cleaner.clean_html( update_items['description']) self.log.debug("hackathon description :" + update_items['description']) self.db.update_object(hackathon, **update_items) return hackathon.dic() except Exception as e: self.log.error(e) return internal_server_error("fail to update hackathon")
def add_admin(self, args): """Add a new administrator on a hackathon :type args: dict :param args: http request body in json format :return hackathon response 'ok' if successfully added. 'not_found' if email is invalid or user not found. 'internal_server_error' if any other unexpected exception caught """ user = self.user_manager.get_user_by_email(args.get("email")) if user is None: return not_found("user not found") try: ahl = self.db.find_first_object(AdminHackathonRel, AdminHackathonRel.user_id == user.id, AdminHackathonRel.hackathon_id == g.hackathon.id) if ahl is None: ahl = AdminHackathonRel( user_id=user.id, role_type=args.get("role_type", ADMIN_ROLE_TYPE.ADMIN), hackathon_id=g.hackathon.id, remarks=args.get("remarks"), create_time=self.util.get_now() ) self.db.add_object(ahl) return ok() except Exception as e: self.log.error(e) return internal_server_error("create admin failed")
def update_admin(self, args): """Update hackathon admin :returns ok() if updated successfully bad_request() if "id" not in request body not_found() if specific AdminHackathonRel not found internal_server_error() if DB exception raised """ user_hackathon_id = args.get("id", None) if not user_hackathon_id: return bad_request("invalid user_hackathon_id") user_hackathon = UserHackathon.objects(id=user_hackathon_id).first() if not user_hackathon: return not_found("admin does not exist") try: user_hackathon.update_time = self.util.get_now() if 'role' in args: user_hackathon.role = args['role'] if 'remark' in args: user_hackathon.remark = args['remark'] user_hackathon.save() return ok('update hackathon admin successfully') except Exception as e: self.log.error(e) return internal_server_error(e)
def update_hackathon(self, args): """Update hackathon properties :type args: dict :param args: arguments from http request body that contains properties with new values :rtype dict :return hackathon in dict if updated successfully. """ hackathon = g.hackathon try: update_items = self.__parse_update_items(args, hackathon) self.log.debug("update hackathon items :" + str(args.keys())) if 'config' in update_items: self.set_basic_property(hackathon, update_items.get('config', {})) update_items.pop('config', None) if 'status' in update_items and int(update_items['status']) == HACK_STATUS.ONLINE: self.create_hackathon_notice(hackathon.id, HACK_NOTICE_EVENT.HACK_ONLINE, HACK_NOTICE_CATEGORY.HACKATHON) # hackathon online # basic xss prevention if 'description' in update_items and update_items['description']: update_items['description'] = self.cleaner.clean_html(update_items['description']) self.log.debug("hackathon description :" + update_items['description']) hackathon.modify(**update_items) hackathon.save() return ok() except Exception as e: self.log.error(e) return internal_server_error("fail to update hackathon")
def update_admin(self, args): """Update hackathon admin :returns ok() if updated successfully bad_request() if "id" not in request body not_found() if specific AdminHackathonRel not found internal_server_error() if DB exception raised """ user_hackathon_id = args.get("id", None) if not user_hackathon_id: return bad_request("invalid user_hackathon_id") user_hackathon = UserHackathon.objects(id=user_hackathon_id).first() if not user_hackathon: return not_found("admin does not exist") try: user_hackathon.update_time = self.util.get_now() if 'role' in args: user_hackathon.role = args['role'] if 'remark' in args: user_hackathon.remark = args['remark'] user_hackathon.save() return ok('update hackathon admin successfully') except Exception as e: self.log.error(e) return internal_server_error(e)
def update_hackathon(self, args): """Update hackathon properties :type args: dict :param args: arguments from http request body that contains properties with new values :rtype dict :return hackathon in dict if updated successfully. """ hackathon = g.hackathon try: update_items = self.__parse_update_items(args, hackathon) self.log.debug("update hackathon items :" + str(args.keys())) if 'config' in update_items: self.set_basic_property(hackathon, update_items.get('config', {})) update_items.pop('config', None) # basic xss prevention if 'description' in update_items and update_items['description']: #update_items['description'] = self.cleaner.clean_html(update_items['description']) self.log.debug("hackathon description :" + update_items['description']) hackathon.modify(**update_items) hackathon.save() return ok() except Exception as e: self.log.error(e) return internal_server_error("fail to update hackathon")
def add_admin(self, args): """Add a new administrator on a hackathon :type args: dict :param args: http request body in json format :return hackathon response 'ok' if successfully added. 'not_found' if email is invalid or user not found. 'internal_server_error' if any other unexpected exception caught """ user = self.user_manager.get_user_by_email(args.get("email")) if user is None: return not_found("user not found") try: ahl = self.db.find_first_object( AdminHackathonRel, AdminHackathonRel.user_id == user.id, AdminHackathonRel.hackathon_id == g.hackathon.id) if ahl is None: ahl = AdminHackathonRel(user_id=user.id, role_type=args.get( "role_type", ADMIN_ROLE_TYPE.ADMIN), hackathon_id=g.hackathon.id, remarks=args.get("remarks"), create_time=self.util.get_now()) self.db.add_object(ahl) return ok() except Exception as e: self.log.error(e) return internal_server_error("create admin failed")
def create_registration(self, hackathon, user, args): """Register hackathon for user Will add a new record in table UserRegistrationRel if precondition fulfilled """ self.log.debug("create_register: %r" % args) user_id = args['user_id'] check_login_provider = self.__is_user_hackathon_login_provider(user, hackathon) if check_login_provider["fail"]: return login_provider_error( "hackathon registration not login provider", friendly_message="当前黑客松活动只是使用" + ",".join(check_login_provider["provides"]) + "账户才能报名", provides=",".join(check_login_provider["provides"])) if self.is_user_registered(user.id, hackathon): self.log.debug("user %s already registered on hackathon %s" % (user_id, hackathon.id)) return self.get_registration_detail(user, hackathon) if self.admin_manager.is_hackathon_admin(hackathon.id, user.id): return precondition_failed("administrator cannot register the hackathon", friendly_message="管理员或裁判不能报名") if hackathon.registration_start_time and hackathon.registration_start_time > self.util.get_now(): return precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time and hackathon.registration_end_time < self.util.get_now(): return precondition_failed("hackathon registration has ended", friendly_message="报名已经结束") if self.__is_hackathon_filled_up(hackathon): return precondition_failed("hackathon registers reach the upper threshold", friendly_message="报名人数已满") try: is_auto_approve = hackathon.config.get(HACKATHON_CONFIG.AUTO_APPROVE, True) status = HACK_USER_STATUS.AUTO_PASSED if is_auto_approve else HACK_USER_STATUS.UNAUDIT args.pop("user_id") args.pop("hackathon_id") user_hackathon = UserHackathon.objects(user=user, hackathon=hackathon).first() if not user_hackathon: user_hackathon = UserHackathon.objects.create( user=user, hackathon=hackathon, status=status, **args) else: # visitor -> competitor user_hackathon.role = HACK_USER_TYPE.COMPETITOR user_hackathon.status = status user_hackathon.save() # create a team as soon as user registration approved(auto or manually) if is_auto_approve: self.team_manager.create_default_team(hackathon, user) self.__ask_for_dev_plan(hackathon, user) self.__update_register_stat(hackathon) return user_hackathon.dic() except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def create_registration(self, hackathon, user, args): """Register hackathon for user Will add a new record in table UserRegistrationRel if precondition fulfilled """ self.log.debug("create_register: %r" % args) user_id = args['user_id'] check_login_provider = self.__is_user_hackathon_login_provider(user, hackathon) if check_login_provider["fail"]: return login_provider_error( "hackathon registration not login provider", friendly_message="当前黑客松活动只是使用" + ",".join(check_login_provider["provides"]) + "账户才能报名", provides=",".join(check_login_provider["provides"])) if self.is_user_registered(user.id, hackathon): self.log.debug("user %s already registered on hackathon %s" % (user_id, hackathon.id)) return self.get_registration_detail(user, hackathon) if self.admin_manager.is_hackathon_admin(hackathon.id, user.id): return precondition_failed("administrator cannot register the hackathon", friendly_message="管理员或裁判不能报名") if hackathon.registration_start_time and hackathon.registration_start_time > self.util.get_now(): return precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time and hackathon.registration_end_time < self.util.get_now(): return precondition_failed("hackathon registration has ended", friendly_message="报名已经结束") if self.__is_hackathon_filled_up(hackathon): return precondition_failed("hackathon registers reach the upper threshold", friendly_message="报名人数已满") try: is_auto_approve = hackathon.config.get(HACKATHON_CONFIG.AUTO_APPROVE, True) status = HACK_USER_STATUS.AUTO_PASSED if is_auto_approve else HACK_USER_STATUS.UNAUDIT args.pop("user_id") args.pop("hackathon_id") user_hackathon = UserHackathon.objects(user=user, hackathon=hackathon).first() if not user_hackathon: user_hackathon = UserHackathon.objects.create( user=user, hackathon=hackathon, status=status, **args) else: # visitor -> competitor user_hackathon.role = HACK_USER_TYPE.COMPETITOR user_hackathon.status = status user_hackathon.save() # create a team as soon as user registration approved(auto or manually) if is_auto_approve: self.team_manager.create_default_team(hackathon, user) self.__ask_for_dev_plan(hackathon, user) self.__update_register_stat(hackathon) return user_hackathon.dic() except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def update_hackathon(self, args): """Update hackathon properties :type args: dict :param args: arguments from http request body that contains properties with new values :rtype dict :return hackathon in dict if updated successfully. """ hackathon = g.hackathon try: update_items = self.__parse_update_items(args, hackathon) self.log.debug("update hackathon items :" + str(args.keys())) if 'config' in update_items: self.set_basic_property(hackathon, update_items.get('config', {})) update_items.pop('config', None) # basic xss prevention if 'description' in update_items and update_items['description']: #update_items['description'] = self.cleaner.clean_html(update_items['description']) self.log.debug("hackathon description :" + update_items['description']) hackathon.modify(**update_items) hackathon.save() return ok() except Exception as e: self.log.error(e) return internal_server_error("fail to update hackathon")
def stop_expr(self, expr_id, force=0): """ :param expr_id: experiment id :param force: 0: only stop container and release ports, 1: force stop and delete container and release ports. :return: """ self.log.debug("begin to stop %d" % expr_id) expr = self.db.find_first_object_by(Experiment, id=expr_id, status=EStatus.RUNNING) if expr is not None: # Docker docker = self.docker.get_docker(expr.hackathon) if expr.template.provider == VE_PROVIDER.DOCKER: # stop containers for c in expr.virtual_environments.all(): try: self.log.debug("begin to stop %s" % c.name) if force: docker.delete(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.DELETED else: docker.stop(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.STOPPED except Exception as e: self.log.error(e) self.__roll_back(expr_id) return internal_server_error('Failed stop/delete container') if force: expr.status = EStatus.DELETED else: expr.status = EStatus.STOPPED self.db.commit() else: try: # todo support delete azure vm azure_key_id = self.docker.load_azure_key_id(expr.id) context = Context(azure_key_id=azure_key_id, experiment_id=expr.id, action=AVMStatus.STOPPED_DEALLOCATED) self.azure_vm_service.stop_vm_entry(context) except Exception as e: self.log.error(e) return internal_server_error('Failed stopping azure') self.log.debug("experiment %d ended success" % expr_id) return ok('OK') else: return ok('expr not exist')
def create_registration(self, hackathon, user, args): """Register hackathon for user Will add a new record in table UserRegistrationRel if precondition fulfilled """ self.log.debug("create_register: %r" % args) user_id = args['user_id'] check_login_provider = self.__is_user_hackathon_login_provider( user, hackathon) if check_login_provider["fail"]: return login_provider_error( "hackathon registration not login provider", friendly_message="当前黑客松活动只是使用" + ",".join(check_login_provider["provides"]) + "账户才能报名", provides=",".join(check_login_provider["provides"])) if self.is_user_registered(user.id, hackathon): self.log.debug("user %d already registered on hackathon %d" % (user_id, hackathon.id)) return self.get_registration_detail(user, hackathon) if self.admin_manager.is_hackathon_admin(hackathon.id, user.id): return precondition_failed( "administrator cannot register the hackathon", friendly_message="管理员或裁判不能报名") if hackathon.registration_start_time and hackathon.registration_start_time > self.util.get_now( ): return precondition_failed("hackathon registration not opened", friendly_message="报名尚未开始") if hackathon.registration_end_time and hackathon.registration_end_time < self.util.get_now( ): return precondition_failed("hackathon registration has ended", friendly_message="报名已经结束") if self.__is_hackathon_filled_up(hackathon): return precondition_failed( "hackathon registers reach the upper threshold", friendly_message="报名人数已满") try: args["status"] = RGStatus.AUTO_PASSED if hackathon.is_auto_approve( ) else RGStatus.UNAUDIT args['create_time'] = self.util.get_now() user_hackathon_rel = self.db.add_object_kwargs( UserHackathonRel, **args).dic() # create a team as soon as user registration approved(auto or manually) if hackathon.is_auto_approve(): self.team_manager.create_default_team(hackathon, user) self.__update_register_stat(hackathon) return user_hackathon_rel except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def stop_expr(self, expr_id, force=0): """ :param expr_id: experiment id :param force: 0: only stop container and release ports, 1: force stop and delete container and release ports. :return: """ self.log.debug("begin to stop %d" % expr_id) expr = self.db.find_first_object_by(Experiment, id=expr_id, status=EStatus.RUNNING) if expr is not None: # Docker if expr.template.provider == VE_PROVIDER.DOCKER: # stop containers for c in expr.virtual_environments.all(): try: self.log.debug("begin to stop %s" % c.name) docker = self.__get_docker(expr.hackathon, c) if force: docker.delete(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.DELETED else: docker.stop(c.name, virtual_environment=c, container=c.container, expr_id=expr_id) c.status = VEStatus.STOPPED except Exception as e: self.log.error(e) self.__roll_back(expr_id) return internal_server_error("Failed stop/delete container") if force: expr.status = EStatus.DELETED else: expr.status = EStatus.STOPPED self.db.commit() else: try: # todo support delete azure vm hosted_docker = RequiredFeature("hosted_docker") af = AzureFormation(hosted_docker.load_azure_key_id(expr_id)) af.stop(expr_id, AVMStatus.STOPPED_DEALLOCATED) except Exception as e: self.log.error(e) return internal_server_error("Failed stopping azure") self.log.debug("experiment %d ended success" % expr_id) return ok("OK") else: return ok()
def test_update_admin_raise_exception(self, generate_update_items, validate_updated_args): self.assertEqual(1, 1) db_adapter = Mock() args = {'test': 'test'} db_adapter.update_object.side_effect = [Exception] am = AdminManager(db_adapter) self.assertEqual(am.update_admin(args), internal_server_error(ANY)) generate_update_items.assert_called_once_with(args) validate_updated_args.assert_called_once_with(args)
def get(self): parser = reqparse.RequestParser() parser.add_argument('id', type=int, location='args', required=True) args = parser.parse_args() try: return expr_manager.get_expr_status(args['id']) except Exception as e: self.log.error(e) return internal_server_error("cannot find the experiment")
def get(self): parser = reqparse.RequestParser() parser.add_argument('id', type=int, location='args', required=True) args = parser.parse_args() try: return expr_manager.get_expr_status(args['id']) except Exception as e: self.log.error(e) return internal_server_error("cannot find the experiment")
def logout(self, user_id): try: user = self.get_user_by_id(user_id) if user: user.online = False user.save() return ok() except Exception as e: self.log.error(e) return internal_server_error(e.message)
def logout(self, user_id): try: user = self.get_user_by_id(user_id) if user: user.online = False user.save() return ok() except Exception as e: self.log.error(e) return internal_server_error(e.message)
def __get_available_public_ports(self, expr_id, host_server, host_ports): self.log.debug("starting to get azure ports") ep = Endpoint(Service(self.load_azure_key_id(expr_id))) host_server_name = host_server.vm_name host_server_dns = host_server.public_dns.split('.')[0] public_endpoints = ep.assign_public_endpoints(host_server_dns, 'Production', host_server_name, host_ports) if not isinstance(public_endpoints, list): self.log.debug("failed to get public ports") return internal_server_error('cannot get public ports') self.log.debug("public ports : %s" % public_endpoints) return public_endpoints
def create_registration(self, hackathon, args): state, return_info = self.validate_created_args(hackathon, args) if not state: return return_info try: args["status"] = hackathon.is_auto_approve() and RGStatus.AUTO_PASSED or RGStatus.UNAUDIT args['create_time'] = self.util.get_now() return self.db.add_object_kwargs(UserHackathonRel, **args).dic() except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def create_user_profile(self, args): self.log.debug("create_user_profile: %r" % args) try: u_id = g.user.id user = User.objects.get(id=u_id) user.profile = UserProfile(**args) user.save() return user.dic() except Exception as e: self.log.debug(e) return internal_server_error("failed to create user profile")
def delete_registration(self, args): if "id" not in args: return bad_request("id not invalid") try: register = self.db.find_first_object_by(UserHackathonRel, id == args['id']) if register is not None: self.db.delete_object(register) return ok() except Exception as ex: self.log.error(ex) return internal_server_error("failed in delete register: %s" % args["id"])
def __get_available_public_ports(self, expr_id, host_server, host_ports): self.log.debug("starting to get azure ports") ep = EndpointService(AzureAdapter(self.load_azure_key_id(expr_id))) host_server_name = host_server.vm_name host_server_dns = host_server.public_dns.split('.')[0] public_endpoints = ep.assign_public_endpoints(host_server_dns, 'Production', host_server_name, host_ports) if not isinstance(public_endpoints, list): self.log.debug("failed to get public ports") return internal_server_error('cannot get public ports') self.log.debug("public ports : %s" % public_endpoints) return public_endpoints
def create_user_profile(self, args): self.log.debug("create_user_profile: %r" % args) try: exist = self.get_user_profile(g.user.id) if not exist: return self.db.add_object_kwargs(UserProfile, **args).dic() else: return self.update_user_profile(args) except Exception as e: self.log.debug(e) return internal_server_error("failed to create user profile")
def update_user_profile(self, args): self.log.debug("update_user_profile") try: u_id = args["user_id"] user = User.objects.get(id=u_id) user.profile = UserProfile(**args) user.save() return user.dic() except Exception as e: self.log.debug(e) return internal_server_error("failed to update user profile")
def create_user_profile(self, args): self.log.debug("create_user_profile: %r" % args) try: u_id = g.user.id user = User.objects.get(id=u_id) user.profile = UserProfile(**args) user.save() return user.dic() except Exception as e: self.log.debug(e) return internal_server_error("failed to create user profile")
def update_user_profile(self, args): self.log.debug("update_user_profile") try: u_id = args["user_id"] user = User.objects.get(id=u_id) user.profile = UserProfile(**args) user.save() return user.dic() except Exception as e: self.log.debug(e) return internal_server_error("failed to update user profile")
def _internal_stop_expr(self, context): try: experiment = Experiment.objects.get(id=context.experiment_id) template_content = self.template_library.load_template(experiment.template) azure_key = experiment.azure_key self.__stop_vm(experiment, azure_key, template_content.units) except Exception as e: self.log.error(e) experiment.status = EStatus.FAILED experiment.save() return internal_server_error('Failed stopping azure')
def _internal_start_expr(self, context): try: # TODO: context.hackathon may be None when tesing a template before any hackathon bind it hackathon = Hackathon.objects.get(id=context.hackathon_id) experiment = Experiment.objects.get(id=context.experiment_id) self.__start_vm(experiment, hackathon, context.template_content.units) except Exception as e: self.log.error(e) experiment.status = EStatus.FAILED experiment.save() return internal_server_error('Failed starting azure vm')
def create_registration(self, hackathon, args): state, return_info = self.validate_created_args(hackathon, args) if not state: return return_info try: args["status"] = hackathon.is_auto_approve( ) and RGStatus.AUTO_PASSED or RGStatus.UNAUDIT args['create_time'] = self.util.get_now() return self.db.add_object_kwargs(UserHackathonRel, **args).dic() except Exception as e: self.log.error(e) return internal_server_error("fail to create register")
def __start_new_expr(self, hackathon, template, user_id): # new expr expr = self.db.add_object_kwargs(Experiment, user_id=user_id, hackathon_id=hackathon.id, status=EStatus.INIT, template_id=template.id) self.db.commit() if template.provider == VE_PROVIDER.DOCKER: try: template_content = self.template_library.load_template(template) virtual_environments_units = template_content.units expr.status = EStatus.STARTING self.db.commit() map(lambda unit: self.__remote_start_container(hackathon, expr, unit), virtual_environments_units) expr.status = EStatus.RUNNING self.db.commit() self.template_library.template_verified(template.id) except Exception as e: self.log.error(e) self.log.error("Failed starting containers") self.__roll_back(expr.id) return internal_server_error('Failed starting containers') else: expr.status = EStatus.STARTING self.db.commit() try: af = AzureFormation(self.hosted_docker.load_azure_key_id(expr.id)) af.create(expr.id) except Exception as e: self.log.error(e) return internal_server_error('Failed starting azure vm') # after everything is ready, set the expr state to running # response to caller return self.__report_expr_status(expr)
def _internal_stop_expr(self, context): try: experiment = Experiment.objects.get(id=context.experiment_id) template_content = self.template_library.load_template( experiment.template) azure_key = experiment.azure_key self.__stop_vm(experiment, azure_key, template_content.units) except Exception as e: self.log.error(e) experiment.status = EStatus.FAILED experiment.save() return internal_server_error('Failed stopping azure')
def __create_or_update_template(self, template_content): """Internally create template Save template to storage and then insert into DB :type template_content: TemplateContent :param template_content: instance of TemplateContent that owns the full content of a template """ context = self.__save_template_to_storage(template_content) if not context: return internal_server_error("save template failed") return self.__save_template_to_database(template_content, context)
def update_user_profile(self, args): self.log.debug("update_user_profile") try: u_id = args["user_id"] user_profile = self.db.find_first_object_by(UserProfile, user_id=u_id) if user_profile: self.db.update_object(user_profile, **args) return user_profile.dic() else: return not_found("fail to update user profile") except Exception as e: self.log.debug(e) return internal_server_error("failed to update user profile")
def _internal_start_expr(self, context): try: # TODO: context.hackathon may be None when tesing a template before any hackathon bind it hackathon = Hackathon.objects.get(id=context.hackathon_id) experiment = Experiment.objects.get(id=context.experiment_id) self.__start_vm(experiment, hackathon, context.template_content.units) except Exception as e: self.log.error(e) experiment.status = EStatus.FAILED experiment.save() return internal_server_error('Failed starting azure vm')
def __start_new_expr(self, hackathon, template, user_id): # new expr expr = self.db.add_object_kwargs(Experiment, user_id=user_id, hackathon_id=hackathon.id, status=EStatus.INIT, template_id=template.id, create_time=self.util.get_now()) self.db.commit() if template.provider == VE_PROVIDER.DOCKER: try: template_content = self.template_library.load_template( template) virtual_environments_units = template_content.units expr.status = EStatus.STARTING self.db.commit() map( lambda unit: self.__remote_start_container( hackathon, expr, unit), virtual_environments_units) except Exception as e: self.log.error(e) self.log.error("Failed starting containers") self.__roll_back(expr.id) return internal_server_error('Failed starting containers') else: expr.status = EStatus.STARTING self.db.commit() try: af = AzureFormation( self.hosted_docker.load_azure_key_id(expr.id)) af.create(expr.id) except Exception as e: self.log.error(e) return internal_server_error('Failed starting azure vm') # after everything is ready, set the expr state to running # response to caller return self.__report_expr_status(expr)
def __create_or_update_template(self, template_content): """Internally create template Save template to storage and then insert into DB :type template_content: TemplateContent :param template_content: instance of TemplateContent that owns the full content of a template """ context = self.__save_template_to_storage(template_content) if not context: return internal_server_error("save template failed") return self.__save_template_to_database(template_content, context)
def delete_registration(self, args): if "id" not in args: return bad_request("id not invalid") try: register = self.db.find_first_object_by(UserHackathonRel, id == args['id']) if register is not None: self.db.delete_object(register) return ok() except Exception as ex: self.log.error(ex) return internal_server_error("failed in delete register: %s" % args["id"])
def delete_hackathon(self): """delete hackathon :return hackathon in dict if updated successfully. """ hackathon = g.hackathon try: UserHackathon.objects(hackathon=hackathon).delete() self.log.debug("delete hackathon:" + hackathon.name) hackathon.delete() hackathon.save() return ok() except Exception as e: self.log.error(e) return internal_server_error("fail to delete hackathon" + hackathon.name)
def _internal_start_expr(self, context): hackathon = Hackathon.objects.get(id=context.hackathon_id) experiment = Experiment.objects.get(id=context.experiment_id) template_content = context.template_content if not experiment or not hackathon: return internal_server_error( 'Failed starting k8s: experiment or hackathon not found.') user = experiment.user or None _virtual_envs = [] _env_name = str(hackathon.name + "-" + template_content.name).lower() if user: _virtual_envs = experiment.virtual_environments _env_name += str("-" + user.name).lower() _env_name = "{}-{}".format(_env_name, "".join(random.sample(string.lowercase, 6))) try: if not _virtual_envs: # Get None VirtualEnvironment, create new one: labels = { "hacking.kaiyuanshe.cn/hackathon": str(hackathon.id), "hacking.kaiyuanshe.cn/experiment": str(experiment.id), "hacking.kaiyuanshe.cn/virtual_environment": _env_name, } k8s_env = self.__create_useful_k8s_resource( _env_name, template_content, labels) experiment.virtual_environments.append( VirtualEnvironment( provider=VirtualEnvProvider.K8S, name=_env_name, k8s_resource=k8s_env, status=ExprEnvStatus.INIT, remote_provider=VERemoteProvider.Guacamole)) experiment.status = ExprStatus.INIT experiment.save() self.log.debug( "virtual_environments %s created, creating k8s..." % _env_name) self.__schedule_start(context) except Exception as e: self.log.error(e) experiment.status = ExprStatus.FAILED experiment.save() return False return True
def delete_hackathon(self): """delete hackathon :return hackathon in dict if updated successfully. """ hackathon = g.hackathon try: UserHackathon.objects(hackathon=hackathon).delete() self.log.debug("delete hackathon:" + hackathon.name) hackathon.delete() hackathon.save() return ok() except Exception as e: self.log.error(e) return internal_server_error("fail to delete hackathon" + hackathon.name)
def apply_online_hackathon(self, hackathon): """apply for onlining a hackathon, should be called by the hackathon creator :return hackathon in dict if updated successfully. """ try: req = ok() if hackathon.status == HACK_STATUS.OFFLINE or hackathon.status == HACK_STATUS.DRAFT: hackathon.status = HACK_STATUS.APPLY_ONLINE hackathon.save() elif hackathon.status == HACK_STATUS.INIT: req = general_error(code=HTTP_CODE.CREATE_NOT_FINISHED) return req except Exception as e: self.log.error(e) return internal_server_error("fail to delete hackathon" + hackathon.name)