diff --git a/src/dstack/_internal/core/models/configurations.py b/src/dstack/_internal/core/models/configurations.py index 6bd9f0827e..3b2c7812b9 100644 --- a/src/dstack/_internal/core/models/configurations.py +++ b/src/dstack/_internal/core/models/configurations.py @@ -31,7 +31,7 @@ from dstack._internal.core.models.services import AnyModel, OpenAIChatModel from dstack._internal.core.models.unix import UnixUser from dstack._internal.core.models.volumes import MountPoint, VolumeConfiguration, parse_mount_point -from dstack._internal.core.services import is_valid_dstack_resource_name +from dstack._internal.core.services import is_valid_replica_group_name from dstack._internal.utils.common import has_duplicates, list_enum_values_for_annotation from dstack._internal.utils.json_schema import add_extra_schema_types from dstack._internal.utils.json_utils import ( @@ -55,7 +55,7 @@ DEFAULT_PROBE_READY_AFTER = 1 DEFAULT_PROBE_METHOD = "get" MAX_PROBE_URL_LEN = 2048 -DEFAULT_REPLICA_GROUP_NAME = "default" +DEFAULT_REPLICA_GROUP_NAME = "0" class RunConfigurationType(str, Enum): @@ -756,7 +756,7 @@ class ReplicaGroup(CoreModel): name: Annotated[ Optional[str], Field( - description="The name of the replica group. If not provided, defaults to 'replica-group-0', 'replica-group-1', etc. based on position." + description="The name of the replica group. If not provided, defaults to '0', '1', etc. based on position." ), ] count: Annotated[ @@ -784,8 +784,8 @@ class ReplicaGroup(CoreModel): @validator("name") def validate_name(cls, v: Optional[str]) -> Optional[str]: if v is not None: - if not is_valid_dstack_resource_name(v): - raise ValueError("Resource name should match regex '^[a-z][a-z0-9-]{1,40}$'") + if not is_valid_replica_group_name(v): + raise ValueError("Resource name should match regex '^[a-z0-9][a-z0-9-]{0,39}$'") return v @validator("count") @@ -920,7 +920,7 @@ def validate_replicas( # Assign default names to groups without names for index, group in enumerate(v): if group.name is None: - group.name = f"replica-group-{index}" + group.name = str(index) # Check for duplicate names names = [group.name for group in v] diff --git a/src/dstack/_internal/core/services/__init__.py b/src/dstack/_internal/core/services/__init__.py index 89ec6d8520..6d698e1228 100644 --- a/src/dstack/_internal/core/services/__init__.py +++ b/src/dstack/_internal/core/services/__init__.py @@ -10,3 +10,7 @@ def validate_dstack_resource_name(resource_name: str): def is_valid_dstack_resource_name(resource_name: str) -> bool: return re.match("^[a-z][a-z0-9-]{1,40}$", resource_name) is not None + + +def is_valid_replica_group_name(name: str) -> bool: + return re.match("^[a-z0-9][a-z0-9-]{0,39}$", name) is not None diff --git a/src/tests/_internal/server/routers/test_runs.py b/src/tests/_internal/server/routers/test_runs.py index 9485ed1abb..70ab54bd16 100644 --- a/src/tests/_internal/server/routers/test_runs.py +++ b/src/tests/_internal/server/routers/test_runs.py @@ -257,7 +257,7 @@ def get_dev_env_run_plan_dict( "replica_num": 0, "job_num": 0, "jobs_per_replica": 1, - "replica_group": "default", + "replica_group": "0", "single_branch": False, "max_duration": None, "stop_duration": 300, @@ -494,7 +494,7 @@ def get_dev_env_run_dict( "replica_num": 0, "job_num": 0, "jobs_per_replica": 1, - "replica_group": "default", + "replica_group": "0", "single_branch": False, "max_duration": None, "stop_duration": 300,