|
9 | 9 | from copy import copy |
10 | 10 | from datetime import datetime |
11 | 11 | from pathlib import Path |
12 | | -from typing import BinaryIO, Dict, Iterable, List, Optional, Union |
| 12 | +from typing import BinaryIO, Dict, Iterable, List, Optional |
13 | 13 | from urllib.parse import urlencode, urlparse |
14 | 14 |
|
15 | 15 | from websocket import WebSocketApp |
|
25 | 25 | ) |
26 | 26 | from dstack._internal.core.models.files import FileArchiveMapping |
27 | 27 | from dstack._internal.core.models.profiles import ( |
28 | | - CreationPolicy, |
29 | 28 | Profile, |
30 | | - ProfileRetryPolicy, |
31 | | - SpotPolicy, |
32 | | - TerminationPolicy, |
33 | | - UtilizationPolicy, |
34 | 29 | ) |
35 | 30 | from dstack._internal.core.models.repos.base import Repo |
36 | 31 | from dstack._internal.core.models.repos.virtual import VirtualRepo |
37 | | -from dstack._internal.core.models.resources import ResourcesSpec |
38 | 32 | from dstack._internal.core.models.runs import ( |
39 | 33 | Job, |
40 | 34 | JobSpec, |
|
55 | 49 | from dstack._internal.utils.crypto import generate_rsa_key_pair |
56 | 50 | from dstack._internal.utils.files import create_file_archive |
57 | 51 | from dstack._internal.utils.logging import get_logger |
58 | | -from dstack._internal.utils.path import PathLike, path_in_dir |
| 52 | +from dstack._internal.utils.path import PathLike |
59 | 53 | from dstack.api.server import APIClient |
60 | 54 |
|
61 | 55 | logger = get_logger(__name__) |
@@ -616,196 +610,6 @@ def apply_configuration( |
616 | 610 | ) |
617 | 611 | return run |
618 | 612 |
|
619 | | - def submit( |
620 | | - self, |
621 | | - configuration: AnyRunConfiguration, |
622 | | - configuration_path: Optional[str] = None, |
623 | | - repo: Optional[Repo] = None, |
624 | | - backends: Optional[List[BackendType]] = None, |
625 | | - regions: Optional[List[str]] = None, |
626 | | - instance_types: Optional[List[str]] = None, |
627 | | - resources: Optional[ResourcesSpec] = None, |
628 | | - spot_policy: Optional[SpotPolicy] = None, |
629 | | - retry_policy: Optional[ProfileRetryPolicy] = None, |
630 | | - max_duration: Optional[Union[int, str]] = None, |
631 | | - max_price: Optional[float] = None, |
632 | | - working_dir: Optional[str] = None, |
633 | | - run_name: Optional[str] = None, |
634 | | - reserve_ports: bool = True, |
635 | | - ) -> Run: |
636 | | - # """ |
637 | | - # Submit a run |
638 | | - |
639 | | - # Args: |
640 | | - # configuration (Union[Task, Service]): A run configuration. |
641 | | - # configuration_path: The path to the configuration file, relative to the root directory of the repo. |
642 | | - # repo (Union[LocalRepo, RemoteRepo, VirtualRepo]): A repo to mount to the run. |
643 | | - # backends: A list of allowed backend for provisioning. |
644 | | - # regions: A list of cloud regions for provisioning. |
645 | | - # resources: The requirements to run the configuration. Overrides the configuration's resources. |
646 | | - # spot_policy: A spot policy for provisioning. |
647 | | - # retry_policy (RetryPolicy): A retry policy. |
648 | | - # max_duration: The max instance running duration in seconds. |
649 | | - # max_price: The max instance price in dollars per hour for provisioning. |
650 | | - # working_dir: A working directory relative to the repo root directory |
651 | | - # run_name: A desired name of the run. Must be unique in the project. If not specified, a random name is assigned. |
652 | | - # reserve_ports: Whether local ports should be reserved in advance. |
653 | | - |
654 | | - # Returns: |
655 | | - # Submitted run. |
656 | | - # """ |
657 | | - logger.warning("The submit() method is deprecated in favor of apply_configuration().") |
658 | | - if repo is None: |
659 | | - repo = VirtualRepo() |
660 | | - # TODO: Add Git credentials to RemoteRepo and if they are set, pass them here to RepoCollection.init |
661 | | - self._client.repos.init(repo) |
662 | | - |
663 | | - run_plan = self.get_plan( |
664 | | - configuration=configuration, |
665 | | - repo=repo, |
666 | | - configuration_path=configuration_path, |
667 | | - backends=backends, |
668 | | - regions=regions, |
669 | | - instance_types=instance_types, |
670 | | - resources=resources, |
671 | | - spot_policy=spot_policy, |
672 | | - retry_policy=retry_policy, |
673 | | - max_duration=max_duration, |
674 | | - max_price=max_price, |
675 | | - working_dir=working_dir, |
676 | | - run_name=run_name, |
677 | | - ) |
678 | | - return self.exec_plan(run_plan, repo, reserve_ports=reserve_ports) |
679 | | - |
680 | | - # Deprecated in favor of get_run_plan() |
681 | | - def get_plan( |
682 | | - self, |
683 | | - configuration: AnyRunConfiguration, |
684 | | - repo: Optional[Repo] = None, |
685 | | - configuration_path: Optional[str] = None, |
686 | | - # Unused profile args are deprecated and removed but |
687 | | - # kept for signature backward compatibility. |
688 | | - backends: Optional[List[BackendType]] = None, |
689 | | - regions: Optional[List[str]] = None, |
690 | | - instance_types: Optional[List[str]] = None, |
691 | | - resources: Optional[ResourcesSpec] = None, |
692 | | - spot_policy: Optional[SpotPolicy] = None, |
693 | | - retry_policy: Optional[ProfileRetryPolicy] = None, |
694 | | - utilization_policy: Optional[UtilizationPolicy] = None, |
695 | | - max_duration: Optional[Union[int, str]] = None, |
696 | | - max_price: Optional[float] = None, |
697 | | - working_dir: Optional[str] = None, |
698 | | - run_name: Optional[str] = None, |
699 | | - pool_name: Optional[str] = None, |
700 | | - instance_name: Optional[str] = None, |
701 | | - creation_policy: Optional[CreationPolicy] = None, |
702 | | - termination_policy: Optional[TerminationPolicy] = None, |
703 | | - termination_policy_idle: Optional[Union[str, int]] = None, |
704 | | - reservation: Optional[str] = None, |
705 | | - idle_duration: Optional[Union[str, int]] = None, |
706 | | - stop_duration: Optional[Union[str, int]] = None, |
707 | | - ) -> RunPlan: |
708 | | - # """ |
709 | | - # Get run plan. Same arguments as `submit` |
710 | | - # |
711 | | - # Returns: |
712 | | - # run plan |
713 | | - # """ |
714 | | - logger.warning("The get_plan() method is deprecated in favor of get_run_plan().") |
715 | | - if repo is None: |
716 | | - repo = VirtualRepo() |
717 | | - repo_code_hash = None |
718 | | - else: |
719 | | - with _prepare_code_file(repo) as (_, repo_code_hash): |
720 | | - pass |
721 | | - |
722 | | - if working_dir is None: |
723 | | - working_dir = "." |
724 | | - elif repo.repo_dir is not None: |
725 | | - working_dir_path = Path(repo.repo_dir) / working_dir |
726 | | - if not path_in_dir(working_dir_path, repo.repo_dir): |
727 | | - raise ConfigurationError("Working directory is outside of the repo") |
728 | | - working_dir = working_dir_path.relative_to(repo.repo_dir).as_posix() |
729 | | - |
730 | | - if configuration_path is None: |
731 | | - configuration_path = "(python)" |
732 | | - |
733 | | - if resources is not None: |
734 | | - configuration = configuration.copy(deep=True) |
735 | | - configuration.resources = resources |
736 | | - |
737 | | - # TODO: [Andrey] "(python") looks as a hack |
738 | | - profile = Profile( |
739 | | - name="(python)", |
740 | | - backends=backends, |
741 | | - regions=regions, |
742 | | - instance_types=instance_types, |
743 | | - reservation=reservation, |
744 | | - spot_policy=spot_policy, |
745 | | - retry=None, |
746 | | - utilization_policy=utilization_policy, |
747 | | - max_duration=max_duration, # type: ignore[assignment] |
748 | | - stop_duration=stop_duration, # type: ignore[assignment] |
749 | | - max_price=max_price, |
750 | | - creation_policy=creation_policy, |
751 | | - idle_duration=idle_duration, # type: ignore[assignment] |
752 | | - ) |
753 | | - config_manager = ConfigManager() |
754 | | - key_manager = UserSSHKeyManager(self._api_client, config_manager.dstack_ssh_dir) |
755 | | - if key_manager.get_user_key(): |
756 | | - ssh_key_pub = None # using the server-managed user key |
757 | | - else: |
758 | | - if not config_manager.dstack_key_path.exists(): |
759 | | - generate_rsa_key_pair(private_key_path=config_manager.dstack_key_path) |
760 | | - logger.warning( |
761 | | - f"Using legacy [code]{config_manager.dstack_key_path.with_suffix('.pub')}[/code]." |
762 | | - " You will only be able to attach to the run from this client." |
763 | | - " Update the [code]dstack[/] server to [code]0.19.34[/]+ to switch to user keys" |
764 | | - " automatically replicated to all clients.", |
765 | | - ) |
766 | | - ssh_key_pub = config_manager.dstack_key_path.with_suffix(".pub").read_text() |
767 | | - run_spec = RunSpec( |
768 | | - run_name=run_name, |
769 | | - repo_id=repo.repo_id, |
770 | | - repo_data=repo.run_repo_data, |
771 | | - repo_code_hash=repo_code_hash, |
772 | | - working_dir=working_dir, |
773 | | - configuration_path=configuration_path, |
774 | | - configuration=configuration, |
775 | | - profile=profile, |
776 | | - ssh_key_pub=ssh_key_pub, |
777 | | - ) |
778 | | - logger.debug("Getting run plan") |
779 | | - run_plan = self._api_client.runs.get_plan(self._project, run_spec) |
780 | | - if run_plan.current_resource is None and run_name is not None: |
781 | | - # If run_plan.current_resource is missing, this can mean old (0.18.x) server. |
782 | | - # TODO: Remove in 0.19 |
783 | | - try: |
784 | | - run_plan.current_resource = self._api_client.runs.get(self._project, run_name) |
785 | | - except ResourceNotExistsError: |
786 | | - pass |
787 | | - return run_plan |
788 | | - |
789 | | - def exec_plan( |
790 | | - self, |
791 | | - run_plan: RunPlan, |
792 | | - repo: Repo, |
793 | | - reserve_ports: bool = True, |
794 | | - ) -> Run: |
795 | | - # """ |
796 | | - # Execute the run plan. |
797 | | - |
798 | | - # Args: |
799 | | - # run_plan: Result of `get_run_plan` call. |
800 | | - # repo: Repo to use for the run. |
801 | | - # reserve_ports: Reserve local ports before submit. |
802 | | - |
803 | | - # Returns: |
804 | | - # Submitted run. |
805 | | - # """ |
806 | | - logger.warning("The exec_plan() method is deprecated in favor of apply_plan().") |
807 | | - return self.apply_plan(run_plan=run_plan, repo=repo, reserve_ports=reserve_ports) |
808 | | - |
809 | 613 | def list(self, all: bool = False, limit: Optional[int] = None) -> List[Run]: |
810 | 614 | """ |
811 | 615 | List runs. |
|
0 commit comments