Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ target-version = "py310"
line-length = 99

[tool.ruff.lint]
select = ["E", "F", "I", "Q", "W", "PGH", "FLY", "S113"]
select = ["E", "F", "I", "Q", "W", "PGH", "FLY", "S113", "PLR1722"]
ignore = [
"E501",
"E712",
Expand Down
3 changes: 2 additions & 1 deletion scripts/docs/gen_cli_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import re
import shlex
import subprocess
import sys
from fnmatch import fnmatch
from functools import cache

Expand Down Expand Up @@ -58,7 +59,7 @@ def process_file(file: File):
def main():
if os.environ.get(DISABLE_ENV):
logger.warning("CLI reference generation is disabled")
exit()
sys.exit()

logger.info("Generating CLI reference...")
# Sequential processing take > 10s
Expand Down
3 changes: 2 additions & 1 deletion scripts/docs/gen_openapi_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import logging
import os
import re
import sys
from pathlib import Path
from typing import Any

Expand All @@ -31,7 +32,7 @@

if os.environ.get(disable_env):
logger.warning("OpenAPI reference generation is disabled")
exit(0)
sys.exit(0)


def _write_tag_references(tags: list[str]) -> None:
Expand Down
5 changes: 3 additions & 2 deletions scripts/docs/gen_rest_plugin_spec_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import json
import logging
import os
import sys
from pathlib import Path

from dstack._internal.settings import DSTACK_VERSION
Expand All @@ -13,7 +14,7 @@
disable_env = "DSTACK_DOCS_DISABLE_REST_PLUGIN_SPEC_REFERENCE"
if os.environ.get(disable_env):
logger.warning("REST plugin spec reference generation is disabled")
exit(0)
sys.exit(0)

try:
from example_plugin_server.main import app
Expand All @@ -23,7 +24,7 @@
" The REST Plugin API won't be generated."
" Run 'uv pip install examples/plugins/example_plugin_server' to install 'example_plugin_server'."
)
exit(0)
sys.exit(0)

app.title = "REST Plugin OpenAPI Spec"
app.servers = [
Expand Down
3 changes: 2 additions & 1 deletion src/dstack/_internal/cli/commands/apply.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import argparse
import shlex
import sys

from argcomplete import FilesCompleter # type: ignore[attr-defined]

Expand Down Expand Up @@ -103,4 +104,4 @@ def _command(self, args: argparse.Namespace):
)
except KeyboardInterrupt:
console.print("\nOperation interrupted by user. Exiting...")
exit(0)
sys.exit(0)
4 changes: 2 additions & 2 deletions src/dstack/_internal/cli/commands/attach.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def _command(self, args: argparse.Namespace):
f" Use [code]-p[/code] in [code]dstack attach[/code] to override the local"
f" port mapping, e.g. [code]-p {e.port + 1}:{e.port}[/code].[/]"
)
exit(1)
sys.exit(1)
if not attached:
raise CLIError(f"Failed to attach to run {args.run_name}")
_print_attached_message(
Expand Down Expand Up @@ -141,7 +141,7 @@ def _command(self, args: argparse.Namespace):
finally:
run.detach()
# TODO: Handle run resubmissions similar to dstack apply
exit(exit_code)
sys.exit(exit_code)


def _print_finished_message_when_available(run: Run) -> None:
Expand Down
7 changes: 4 additions & 3 deletions src/dstack/_internal/cli/commands/fleet.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import sys
import time
from uuid import UUID

Expand Down Expand Up @@ -120,14 +121,14 @@ def _delete(self, args: argparse.Namespace):
"The [code]<project>/<fleet>[/] format is not supported for fleet names."
" Can only delete fleets or instances owned by the current project"
)
exit(1)
sys.exit(1)
name = args.name.name

try:
self.api.client.fleets.get(project_name=self.api.project, name=name)
except ResourceNotExistsError:
console.print(f"Fleet [code]{name}[/] does not exist")
exit(1)
sys.exit(1)

if not args.instances:
if not args.yes and not confirm_ask(f"Delete the fleet [code]{name}[/]?"):
Expand Down Expand Up @@ -174,6 +175,6 @@ def _get(self, args: argparse.Namespace):
)
except ResourceNotExistsError:
error_console.print(f"Fleet [code]{args.name or args.id}[/] not found")
exit(1)
sys.exit(1)

print(fleet.model_dump_json(indent=2))
5 changes: 3 additions & 2 deletions src/dstack/_internal/cli/commands/gateway.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import sys
import time

from rich.live import Live
Expand Down Expand Up @@ -139,7 +140,7 @@ def _delete(self, args: argparse.Namespace):
"The [code]<project>/<gateway>[/] format is not supported for gateway names."
" Can only delete gateways owned by the current project"
)
exit(1)
sys.exit(1)
name = args.name.name
gateway = self.api.client.gateways.get(self.api.project, name)
print_gateways_table([gateway], current_project=self.api.project)
Expand All @@ -164,7 +165,7 @@ def _update(self, args: argparse.Namespace):
" when [code]--domain[/] is passed."
" Can only update gateways owned by the current project"
)
exit(1)
sys.exit(1)
self.api.client.gateways.set_wildcard_domain(
self.api.project, args.name.name, args.domain
)
Expand Down
4 changes: 2 additions & 2 deletions src/dstack/_internal/cli/commands/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def _prompt_url(self) -> str:
)
except KeyboardInterrupt:
console.print("\nCancelled by user")
raise SystemExit(1)
sys.exit(1)
if url is None:
raise CLIError("URL is required")
return url
Expand All @@ -137,7 +137,7 @@ def _prompt_provider(self, available_providers: list[str]) -> str:
instruction="(鈫戔啌 Enter)",
).ask()
if selected_provider is None:
raise SystemExit(1)
sys.exit(1)
return selected_provider

def _configure_projects(
Expand Down
2 changes: 1 addition & 1 deletion src/dstack/_internal/cli/commands/preset.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def _command(self, args: argparse.Namespace) -> None:
args.subfunc(args)
except KeyboardInterrupt:
console.print("\nOperation interrupted by user. Exiting...")
exit(0)
sys.exit(0)

def _reconcile(self) -> None:
"""Finalize any detached/orphaned session whose agent already completed,
Expand Down
3 changes: 2 additions & 1 deletion src/dstack/_internal/cli/commands/run.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import sys
from uuid import UUID

from dstack._internal.cli.commands import APIBaseCommand
Expand Down Expand Up @@ -63,6 +64,6 @@ def _get(self, args: argparse.Namespace):
run = self.api.client.runs.get(project_name=self.api.project, run_name=args.name)
except ResourceNotExistsError:
error_console.print(f"Run [code]{args.name or args.id}[/] not found")
exit(1)
sys.exit(1)

print(run.model_dump_json(indent=2))
5 changes: 3 additions & 2 deletions src/dstack/_internal/cli/commands/volume.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import sys
import time

from rich.live import Live
Expand Down Expand Up @@ -95,7 +96,7 @@ def _delete(self, args: argparse.Namespace):
self.api.client.volumes.get(project_name=self.api.project, name=args.name)
except ResourceNotExistsError:
console.print(f"Volume [code]{args.name}[/] does not exist")
exit(1)
sys.exit(1)

if not args.yes and not confirm_ask(f"Delete the volume [code]{args.name}[/]?"):
console.print("\nExiting...")
Expand All @@ -112,6 +113,6 @@ def _get(self, args: argparse.Namespace):
volume = self.api.client.volumes.get(project_name=self.api.project, name=args.name)
except ResourceNotExistsError:
error_console.print("Volume not found")
exit(1)
sys.exit(1)

print(volume.model_dump_json(indent=2))
3 changes: 2 additions & 1 deletion src/dstack/_internal/cli/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import sys

import argcomplete
from rich.markup import escape
Expand Down Expand Up @@ -100,7 +101,7 @@ def main():
except (ClientError, CLIError, ConfigurationError, SSHError) as e:
error_console.print(f"[error]{escape(str(e))}[/]")
logger.debug(e, exc_info=True)
exit(1)
sys.exit(1)


if __name__ == "__main__":
Expand Down
9 changes: 5 additions & 4 deletions src/dstack/_internal/cli/services/configurators/fleet.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import sys
import time
from pathlib import Path
from typing import Optional
Expand Down Expand Up @@ -186,7 +187,7 @@ def _apply_plan(self, plan: FleetPlan, command_args: argparse.Namespace):
console.print(
"\n[error]Some instances failed. Check the table above for errors.[/]"
)
exit(1)
sys.exit(1)

def _apply_plan_on_old_server(self, plan: FleetPlan, command_args: argparse.Namespace):
action_message = ""
Expand Down Expand Up @@ -281,7 +282,7 @@ def _apply_plan_on_old_server(self, plan: FleetPlan, command_args: argparse.Name
)
if _fleet_has_failed_instances(fleet):
console.print("\n[error]Some instances failed. Check the table above for errors.[/]")
exit(1)
sys.exit(1)

def delete_configuration(
self,
Expand All @@ -291,7 +292,7 @@ def delete_configuration(
):
if conf.name is None:
console.print("[error]Configuration specifies no fleet to delete[/]")
exit(1)
sys.exit(1)

try:
self.api.client.fleets.get(
Expand All @@ -300,7 +301,7 @@ def delete_configuration(
)
except ResourceNotExistsError:
console.print(f"Fleet [code]{conf.name}[/] does not exist")
exit(1)
sys.exit(1)

if not command_args.yes and not confirm_ask(f"Delete the fleet [code]{conf.name}[/]?"):
console.print("\nExiting...")
Expand Down
7 changes: 4 additions & 3 deletions src/dstack/_internal/cli/services/configurators/gateway.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import sys
import time

from rich.table import Table
Expand Down Expand Up @@ -160,7 +161,7 @@ def apply_configuration(
console.print(
f"\n[error]Provisioning failed. Error: {gateway.status_message or 'unknown'}[/]"
)
exit(1)
sys.exit(1)

def delete_configuration(
self,
Expand All @@ -170,13 +171,13 @@ def delete_configuration(
):
if conf.name is None:
console.print("[error]Configuration specifies no gateway to delete[/]")
exit(1)
sys.exit(1)

try:
self.api.client.gateways.get(project_name=self.api.project, gateway_name=conf.name)
except ResourceNotExistsError:
console.print(f"Gateway [code]{conf.name}[/] does not exist")
exit(1)
sys.exit(1)

if not command_args.yes and not confirm_ask(f"Delete the gateway [code]{conf.name}[/]?"):
console.print("\nExiting...")
Expand Down
14 changes: 7 additions & 7 deletions src/dstack/_internal/cli/services/configurators/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def apply_plan(
f" Use [code]-p[/code] in [code]dstack apply[/code] to override the local"
f" port mapping, e.g. [code]-p {e.port + 1}:{e.port}[/code].[/]"
)
exit(1)
sys.exit(1)

if command_args.detach:
detach_message = f"Run [code]{run.name}[/] submitted, detaching..."
Expand Down Expand Up @@ -286,14 +286,14 @@ def apply_plan(
f" Use [code]-p[/code] in [code]dstack attach[/code] to override the local"
f" port mapping, e.g. [code]-p {e.port + 1}:{e.port}[/code].[/]"
)
exit(1)
sys.exit(1)
if attached:
for entry in run.logs():
sys.stdout.buffer.write(entry)
sys.stdout.buffer.flush()
else:
console.print("[error]Failed to attach, exiting...[/]")
exit(1)
sys.exit(1)
finally:
run.detach()

Expand All @@ -308,14 +308,14 @@ def apply_plan(
break
if run.status.is_finished():
print_finished_message(run)
exit(get_run_exit_code(run))
sys.exit(get_run_exit_code(run))
time.sleep(1)
if not reattach:
console.print(
"[error]Lost run connection. Timed out waiting for run final status."
" Check `dstack ps` to see if it's done or failed."
)
exit(1)
sys.exit(1)
except KeyboardInterrupt:
try:
if command_args.yes or not confirm_ask(
Expand Down Expand Up @@ -348,15 +348,15 @@ def delete_configuration(
):
if conf.name is None:
console.print("[error]Configuration specifies no run to delete[/]")
exit(1)
sys.exit(1)
try:
self.api.client.runs.get(
project_name=self.api.project,
run_name=conf.name,
)
except ResourceNotExistsError:
console.print(f"Run [code]{conf.name}[/] does not exist")
exit(1)
sys.exit(1)
if not command_args.yes and not confirm_ask(f"Delete the run [code]{conf.name}[/]?"):
console.print("\nExiting...")
return
Expand Down
Loading
Loading