Skip to content

Commit 94a7a9f

Browse files
Add --verbose to dstack apply and enhance run plan output (show creation policy and reservation only if non-default or verbose); replaced - with actual defaults (off) (#3572)
1 parent 3d8c9ba commit 94a7a9f

File tree

3 files changed

+44
-31
lines changed

3 files changed

+44
-31
lines changed

src/dstack/_internal/cli/commands/apply.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ def _register(self):
6262
help="Exit immediately after submitting configuration",
6363
action="store_true",
6464
)
65+
self._parser.add_argument(
66+
"-v",
67+
"--verbose",
68+
help="Show all plan properties including those with default values",
69+
action="store_true",
70+
)
6571

6672
def _command(self, args: argparse.Namespace):
6773
try:

src/dstack/_internal/cli/services/configurators/run.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,12 @@ def apply_configuration(
115115
if len(self.api.client.fleets.list(self.api.project)) == 0:
116116
no_fleets = True
117117

118-
print_run_plan(run_plan, max_offers=configurator_args.max_offers, no_fleets=no_fleets)
118+
print_run_plan(
119+
run_plan,
120+
max_offers=configurator_args.max_offers,
121+
no_fleets=no_fleets,
122+
verbose=command_args.verbose,
123+
)
119124

120125
confirm_message = "Submit a new run?"
121126
if conf.name:

src/dstack/_internal/cli/utils/run.py

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
)
2222
from dstack._internal.core.models.profiles import (
2323
DEFAULT_RUN_TERMINATION_IDLE_TIME,
24+
CreationPolicy,
2425
SpotPolicy,
2526
TerminationPolicy,
2627
)
@@ -84,6 +85,7 @@ def print_run_plan(
8485
max_offers: Optional[int] = None,
8586
include_run_properties: bool = True,
8687
no_fleets: bool = False,
88+
verbose: bool = False,
8789
):
8890
run_spec = run_plan.get_effective_run_spec()
8991
job_plan = run_plan.job_plans[0]
@@ -94,36 +96,35 @@ def print_run_plan(
9496

9597
req = job_plan.job_spec.requirements
9698
pretty_req = req.pretty_format(resources_only=True)
97-
max_price = f"${req.max_price:3f}".rstrip("0").rstrip(".") if req.max_price else "-"
99+
max_price = f"${req.max_price:3f}".rstrip("0").rstrip(".") if req.max_price else "off"
98100
max_duration = (
99101
format_pretty_duration(job_plan.job_spec.max_duration)
100102
if job_plan.job_spec.max_duration
101-
else "-"
103+
else "off"
102104
)
103-
if include_run_properties:
104-
inactivity_duration = None
105-
if isinstance(run_spec.configuration, DevEnvironmentConfiguration):
106-
inactivity_duration = "-"
107-
if isinstance(run_spec.configuration.inactivity_duration, int):
108-
inactivity_duration = format_pretty_duration(
109-
run_spec.configuration.inactivity_duration
110-
)
111-
if job_plan.job_spec.retry is None:
112-
retry = "-"
113-
else:
114-
retry = escape(job_plan.job_spec.retry.pretty_format())
115-
116-
profile = run_spec.merged_profile
117-
creation_policy = profile.creation_policy
118-
# FIXME: This assumes the default idle_duration is the same for client and server.
119-
# If the server changes idle_duration, old clients will see incorrect value.
120-
termination_policy, termination_idle_time = get_termination(
121-
profile, DEFAULT_RUN_TERMINATION_IDLE_TIME
122-
)
123-
if termination_policy == TerminationPolicy.DONT_DESTROY:
124-
idle_duration = "-"
125-
else:
126-
idle_duration = format_pretty_duration(termination_idle_time)
105+
inactivity_duration = None
106+
if isinstance(run_spec.configuration, DevEnvironmentConfiguration):
107+
inactivity_duration = "off"
108+
if isinstance(run_spec.configuration.inactivity_duration, int):
109+
inactivity_duration = format_pretty_duration(
110+
run_spec.configuration.inactivity_duration
111+
)
112+
if job_plan.job_spec.retry is None:
113+
retry = "off"
114+
else:
115+
retry = escape(job_plan.job_spec.retry.pretty_format())
116+
117+
profile = run_spec.merged_profile
118+
creation_policy = profile.creation_policy
119+
# FIXME: This assumes the default idle_duration is the same for client and server.
120+
# If the server changes idle_duration, old clients will see incorrect value.
121+
termination_policy, termination_idle_time = get_termination(
122+
profile, DEFAULT_RUN_TERMINATION_IDLE_TIME
123+
)
124+
if termination_policy == TerminationPolicy.DONT_DESTROY:
125+
idle_duration = "-"
126+
else:
127+
idle_duration = format_pretty_duration(termination_idle_time)
127128

128129
if req.spot is None:
129130
spot_policy = "auto"
@@ -138,7 +139,6 @@ def th(s: str) -> str:
138139
props.add_row(th("Project"), run_plan.project_name)
139140
props.add_row(th("User"), run_plan.user)
140141
if include_run_properties:
141-
props.add_row(th("Configuration"), run_spec.configuration_path)
142142
configuration_type = run_spec.configuration.type
143143
if run_spec.configuration.type == "task":
144144
configuration_type += f" (nodes={run_spec.configuration.nodes})"
@@ -148,12 +148,14 @@ def th(s: str) -> str:
148148
props.add_row(th("Max price"), max_price)
149149
if include_run_properties:
150150
props.add_row(th("Retry policy"), retry)
151-
props.add_row(th("Creation policy"), creation_policy)
151+
if verbose or creation_policy != CreationPolicy.REUSE_OR_CREATE:
152+
props.add_row(th("Creation policy"), creation_policy)
152153
props.add_row(th("Idle duration"), idle_duration)
153154
props.add_row(th("Max duration"), max_duration)
154-
if inactivity_duration is not None: # None means n/a
155+
if inactivity_duration is not None: # only set for dev-environment
155156
props.add_row(th("Inactivity duration"), inactivity_duration)
156-
props.add_row(th("Reservation"), run_spec.configuration.reservation or "-")
157+
if verbose or run_spec.configuration.reservation:
158+
props.add_row(th("Reservation"), run_spec.configuration.reservation or "no")
157159

158160
offers = Table(box=None, expand=shutil.get_terminal_size(fallback=(120, 40)).columns <= 110)
159161
offers.add_column("#")

0 commit comments

Comments
 (0)