def bulk_new_run_status( runs: List[BaseRun], condition: V1StatusCondition, additional_fields: List[str] = None, ): for run in runs: set_entity_status(entity=run, condition=condition) additional_fields = additional_fields or [] get_run_model().objects.bulk_update( runs, additional_fields + ["status_conditions", "status"])
class Meta: model = get_run_model() fields = ( "uuid", "name", "description", "created_at", "updated_at", "started_at", "finished_at", "duration", "kind", "meta_kind", "meta_info", "status", "pipeline", "original", "is_managed", "inputs", "outputs", "tags", "settings", ) extra_kwargs = { "is_managed": {"read_only": True}, "cloning_kind": {"read_only": True}, }
class Meta: model = get_run_model() fields = ("uuid", "status", "condition", "status_conditions") extra_kwargs = { "status": {"read_only": True}, "status_conditions": {"read_only": True}, }
def create_run( project_id: int, user_id: int, name: str = None, description: str = None, readme: str = None, tags: List[int] = None, raw_content: str = None, ) -> BaseRun: instance = get_run_model().objects.create( project_id=project_id, user_id=user_id, name=name, description=description, readme=readme, tags=tags, kind=V1RunKind.JOB, is_managed=False, raw_content=raw_content, status_conditions=[ V1StatusCondition.get_condition( type=V1Statuses.CREATED, status="True", reason="PolyaxonRunCreated", message="Run is created", ).to_dict() ], ) return instance
class Meta: model = get_run_model() fields = ( "uuid", "name", "description", "content", "is_managed", "tags", )
def get_run(run_id: int, run: BaseRun) -> Optional[BaseRun]: run_model = get_run_model() if run: return run try: return run_model.objects.get(id=run_id) except run_model.DoesNotExist: _logger.info( "Something went wrong, " "the run `%s` does not exist anymore.", run_id)
def bulk_new_run_status( runs: List[BaseRun], condition: V1StatusCondition, additional_fields: List[str] = None, ): bulk_new_entity_status( model_class=get_run_model(), entities=runs, condition=condition, additional_fields=additional_fields, )
def stop_runs(view, request, actor, *args, **kwargs): # Immediate stop queryset = ( get_run_model() .objects.filter(project=view.project, uuid__in=request.data.get("uuids", [])) .filter(status__in=LifeCycle.SAFE_STOP_VALUES) ) condition = V1StatusCondition.get_condition( type=V1Statuses.STOPPED, status="True", reason="EventHandler", message="User requested to stop the run.", ) bulk_new_run_status(queryset, condition) queryset = ( get_run_model() .objects.filter(project=view.project, uuid__in=request.data.get("uuids", [])) .exclude(status__in=LifeCycle.DONE_OR_IN_PROGRESS_VALUES) ) runs = [r for r in queryset] condition = V1StatusCondition.get_condition( type=V1Statuses.STOPPING, status="True", reason="EventHandler", message="User requested to stop the run.", ) bulk_new_run_status(runs, condition) for run in runs: auditor.record( event_type=RUN_STOPPED_ACTOR, instance=run, actor_id=actor.id, actor_name=actor.username, owner_id=view.project.owner_id, owner_name=view.owner_name, project_name=view.project_name, ) return Response(status=status.HTTP_200_OK, data={})
class Meta: model = get_run_model() fields = ( "uuid", "name", "description", "content", "is_managed", "is_approved", "meta_info", "tags", ) extra_kwargs = { "meta_info": {"write_only": True}, "is_approved": {"write_only": True}, }
def create_runs_tags(view, request, *args, **kwargs): tags = request.data.get("tags", []) if not tags: return Response(status=status.HTTP_200_OK, data={}) updated = [] run_model = get_run_model() for run in run_model.all.filter( project=view.project, uuid__in=request.data.get("uuids", []) ).only("id", "tags"): run.tags = TagsMixin.validated_tags({"tags": tags, "merge": True}, run.tags)[ "tags" ] updated.append(run) run_model.objects.bulk_update(updated, ["tags"]) return Response(status=status.HTTP_200_OK, data={})
def delete_runs(view, request, actor, *args, **kwargs): runs = get_run_model().objects.filter(project=view.project, uuid__in=request.data.get( "uuids", [])) for run in runs.only("id"): auditor.record( event_type=RUN_DELETED_ACTOR, instance=run, actor_id=actor.id, actor_name=actor.username, owner_id=view.project.owner_id, owner_name=view.owner_name, project_name=view.project_name, ) # Deletion in progress runs.update(live_state=live_state.STATE_DELETION_PROGRESSING) return Response(status=status.HTTP_200_OK, data={})
def stop_runs(view, request, actor, *args, **kwargs): runs = (get_run_model().objects.filter( project=view.project, uuid__in=request.data.get( "uuids", [])).exclude(status__in=LifeCycle.DONE_VALUES).only("id")) runs.update(status=V1Statuses.STOPPING) for run in runs: auditor.record( event_type=RUN_STOPPED_ACTOR, instance=run, actor_id=actor.id, actor_name=actor.username, owner_id=view.project.owner_id, owner_name=view.owner_name, project_name=view.project_name, ) return Response(status=status.HTTP_200_OK, data={})
def approve_runs(view, request, actor, *args, **kwargs): queryset = (get_run_model().objects.filter( project=view.project, uuid__in=request.data.get("uuids", [])).exclude(is_approved=True)) runs = [r for r in queryset] queryset.update(is_approved=True) for run in runs: auditor.record( event_type=RUN_APPROVED_ACTOR, instance=run, actor_id=actor.id, actor_name=actor.username, owner_id=view.project.owner_id, owner_name=view.owner_name, project_name=view.project_name, ) return Response(status=status.HTTP_200_OK, data={})
def get_run( run_id: int, run: Optional[BaseRun], use_all: bool = False, only: List[str] = None, defer: List[str] = None, ) -> Optional[BaseRun]: if run: return run run_model = get_run_model() query = run_model.all if use_all else run_model.objects if only: query = query.only(*only) if defer: query = query.only(*defer) try: return query.get(id=run_id) except run_model.DoesNotExist: _logger.info( "Something went wrong, the run `%s` does not exist anymore.", run_id)
class Meta: model = get_run_model() fields = ( "uuid", "name", "description", "tags", "created_at", "updated_at", "started_at", "finished_at", "wait_time", "duration", "kind", "runtime", "meta_info", "status", "status_conditions", "is_managed", "inputs", "outputs", )
def bulk_new_run_status(runs: List[BaseRun], condition: V1StatusCondition): for run in runs: set_entity_status(entity=run, condition=condition) get_run_model().objects.bulk_update(runs, ["status_conditions", "status"])
def init_run( self, project_id: int, user_id: int, op_spec: V1Operation = None, compiled_operation: V1CompiledOperation = None, name: str = None, description: str = None, tags: str = None, override: Union[str, Dict] = None, override_post: bool = True, params: Dict = None, readme: str = None, original_id: int = None, cloning_kind: str = None, **kwargs, ) -> Tuple[V1CompiledOperation, BaseRun]: content = None raw_content = None if op_spec: op_spec = self.set_spec(op_spec) raw_content = op_spec.to_dict(dump=True) if op_spec: if not compiled_operation or override: compiled_operation = OperationSpecification.compile_operation( op_spec, override=override, override_post=override_post) params = op_spec.params params = params or {} inputs = {p: pv.value for p, pv in params.items() if pv.is_literal} params = {p: pv.to_dict() for p, pv in params.items()} kind = None meta_info = {} if compiled_operation: content = compiled_operation.to_dict(dump=True) name = name or compiled_operation.name description = description or compiled_operation.description tags = tags or compiled_operation.tags kind, meta_kind = self.get_kind(compiled_operation) kind, meta_info = self.get_meta_info(compiled_operation, kind, meta_kind) instance = get_run_model()( project_id=project_id, user_id=user_id, name=name, description=description, tags=tags, readme=readme, raw_content=raw_content, content=content, params=params, inputs=inputs, kind=kind, meta_info=meta_info, original_id=original_id, cloning_kind=cloning_kind, status_conditions=[ V1StatusCondition.get_condition( type=V1Statuses.CREATED, status="True", reason="PolyaxonRunCreated", message="Run is created", ).to_dict() ], **self.sanitize_kwargs(**kwargs), ) return compiled_operation, instance
#!/usr/bin/python # # Copyright 2018-2020 Polyaxon, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from django.contrib.admin import site from django.contrib.auth import get_user_model from django.contrib.auth.admin import UserAdmin from coredb.abstracts.getter import get_artifact_model, get_project_model, get_run_model from coredb.administration.artifacts import ArtifactAdmin from coredb.administration.projects import ProjectAdmin from coredb.administration.runs import RunLightAdmin site.register(get_user_model(), UserAdmin) site.register(get_artifact_model(), ArtifactAdmin) site.register(get_project_model(), ProjectAdmin) site.register(get_run_model(), RunLightAdmin)
# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from rest_framework.exceptions import ValidationError from django.db.models.signals import post_save from django.dispatch import receiver from coredb.abstracts.getter import get_run_model from polyaxon.utils.signal_decorators import ignore_raw, ignore_updates from polycommon import auditor from polycommon.events.registry.run import RUN_CREATED @receiver(post_save, sender=get_run_model(), dispatch_uid="run_created") @ignore_updates @ignore_raw def run_created(sender, **kwargs): instance = kwargs["instance"] if instance.is_managed: if (instance.is_clone and instance.content is None) or ( not instance.is_clone and instance.raw_content is None): raise ValidationError( "A managed run should have a valid specification.") auditor.record(event_type=RUN_CREATED, instance=instance)
def init_run( self, project_id: int, user_id: int, op_spec: V1Operation = None, compiled_operation: V1CompiledOperation = None, name: str = None, description: str = None, tags: str = None, override: Union[str, Dict] = None, override_post: bool = True, params: Dict = None, readme: str = None, original_id: int = None, original_uuid: int = None, cloning_kind: str = None, is_managed: bool = True, supported_kinds: Set[str] = None, **kwargs, ) -> Tuple[V1CompiledOperation, BaseRun]: content = None raw_content = None if op_spec: op_spec = self.set_spec(op_spec) raw_content = op_spec.to_dict(dump=True) if op_spec: if not compiled_operation or override: compiled_operation = OperationSpecification.compile_operation( op_spec, override=override, override_post=override_post) params = op_spec.params params = params or {} inputs = {p: pv.value for p, pv in params.items() if pv.is_literal} params = {p: pv.to_dict() for p, pv in params.items()} kind = None meta_info = {} if compiled_operation: name = name or compiled_operation.name description = description or compiled_operation.description tags = tags or compiled_operation.tags kind, meta_kind = self.get_kind(compiled_operation) kind, meta_info = self.get_meta_info(compiled_operation, kind, meta_kind) self.supports_kind(kind, meta_kind, supported_kinds, is_managed) if cloning_kind == V1CloningKind.COPY: if meta_kind not in {V1RunKind.JOB, V1RunKind.SERVICE}: raise ValueError( "Operation with kind `{}` does not support restart with copy mode." ) compiled_operation.run.add_init( V1Init(artifacts=V1ArtifactsType(dirs=[original_uuid]))) content = compiled_operation.to_dict(dump=True) instance = get_run_model()( project_id=project_id, user_id=user_id, name=name, description=description, tags=tags, readme=readme, raw_content=raw_content, content=content, params=params, inputs=inputs, kind=kind, meta_info=meta_info, original_id=original_id, cloning_kind=cloning_kind, is_managed=is_managed, status_conditions=[ V1StatusCondition.get_condition( type=V1Statuses.CREATED, status="True", reason="PolyaxonRunCreated", message="Run is created", ).to_dict() ], **self.sanitize_kwargs(**kwargs), ) return compiled_operation, instance
def init_run( self, project_id: int, user_id: int, op_spec: V1Operation = None, compiled_operation: V1CompiledOperation = None, name: str = None, description: str = None, tags: str = None, override: Union[str, Dict] = None, params: Dict = None, readme: str = None, original_id: int = None, original_uuid: int = None, cloning_kind: str = None, is_managed: bool = True, pending: str = None, meta_info: Dict = None, supported_kinds: Set[str] = None, **kwargs, ) -> Tuple[V1CompiledOperation, BaseRun]: if op_spec: op_spec, kwargs = self.set_spec(op_spec, **kwargs) if op_spec: if not compiled_operation or override: compiled_operation = OperationSpecification.compile_operation( op_spec, override=override) params = op_spec.params params = params or {} inputs = {p: pv.value for p, pv in params.items() if pv.is_literal} params = {p: pv.to_dict() for p, pv in params.items()} kind = None meta_info = meta_info or {} if compiled_operation: if pending is None and compiled_operation.is_approved is False: pending = V1RunPending.APPROVAL name = name or compiled_operation.name description = description or compiled_operation.description tags = tags or compiled_operation.tags kind, runtime = self.get_kind(compiled_operation) kind, runtime, meta_info = self.get_meta_info( compiled_operation, kind, runtime, meta_info, **kwargs) self.supports_kind(kind, runtime, supported_kinds, is_managed) kwargs["content"] = compiled_operation.to_dict(dump=True) instance = get_run_model()( project_id=project_id, user_id=user_id, name=name, description=description, tags=tags, readme=readme, params=params, inputs=inputs, kind=kind, runtime=runtime, meta_info=meta_info, original_id=original_id, cloning_kind=cloning_kind, is_managed=is_managed, pending=pending, status_conditions=[ V1StatusCondition.get_condition( type=V1Statuses.CREATED, status="True", reason=kwargs.pop("reason", "OperationServiceInit"), message=kwargs.pop("message", "Run is created"), ).to_dict() ], **self.sanitize_kwargs(**kwargs), ) return compiled_operation, instance
#!/usr/bin/python # # Copyright 2018-2020 Polyaxon, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from coredb.abstracts.getter import get_run_model from coredb.queries.runs import SINGLE_RUN runs = get_run_model().all.select_related("original") runs = runs.only(*SINGLE_RUN)
def init_run( self, project_id: int, user_id: int, op_spec: V1Operation = None, compiled_operation: V1CompiledOperation = None, name: str = None, description: str = None, tags: str = None, override: Union[str, Dict] = None, params: Dict = None, readme: str = None, original_id: int = None, original_uuid: int = None, cloning_kind: str = None, is_managed: bool = True, is_approved: bool = True, meta_info: Dict = None, supported_kinds: Set[str] = None, init: Optional[List[V1Init]] = None, **kwargs, ) -> Tuple[V1CompiledOperation, BaseRun]: if op_spec: op_spec, kwargs = self.set_spec(op_spec, **kwargs) if op_spec: if not compiled_operation or override: compiled_operation = OperationSpecification.compile_operation( op_spec, override=override ) params = op_spec.params params = params or {} inputs = {p: pv.value for p, pv in params.items() if pv.is_literal} params = {p: pv.to_dict() for p, pv in params.items()} kind = None meta_info = meta_info or {} if compiled_operation: if is_approved and compiled_operation.is_approved is not None: is_approved = compiled_operation.is_approved name = name or compiled_operation.name description = description or compiled_operation.description tags = tags or compiled_operation.tags kind, runtime = self.get_kind(compiled_operation) kind, runtime, meta_info = self.get_meta_info( compiled_operation, kind, runtime, meta_info, **kwargs ) self.supports_kind(kind, runtime, supported_kinds, is_managed) if cloning_kind == V1CloningKind.COPY: if runtime not in {V1RunKind.JOB, V1RunKind.SERVICE}: raise ValueError( "Operation with kind `{}` does not support restart with copy mode.".format( runtime ) ) compiled_operation.run.add_init( V1Init( artifacts=V1ArtifactsType( dirs=[[original_uuid, "{{ globals.run_artifacts_path }}"]] ) ) ) if init: if runtime not in {V1RunKind.JOB, V1RunKind.SERVICE}: raise ValueError( "Operation with kind `{}` does not support " "additional init containers.".format(runtime) ) compiled_operation.run.add_init(init) kwargs["content"] = compiled_operation.to_dict(dump=True) instance = get_run_model()( project_id=project_id, user_id=user_id, name=name, description=description, tags=tags, readme=readme, params=params, inputs=inputs, kind=kind, runtime=runtime, meta_info=meta_info, original_id=original_id, cloning_kind=cloning_kind, is_managed=is_managed, is_approved=is_approved, status_conditions=[ V1StatusCondition.get_condition( type=V1Statuses.CREATED, status="True", reason=kwargs.pop("reason", "OperationServiceInit"), message=kwargs.pop("message", "Run is created"), ).to_dict() ], **self.sanitize_kwargs(**kwargs), ) return compiled_operation, instance
class Meta: model = get_run_model()