Skip to content

Commit 12d9c59

Browse files
committed
refactor: command ui
Signed-off-by: thxCode <[email protected]>
1 parent a47da8a commit 12d9c59

File tree

6 files changed

+93
-55
lines changed

6 files changed

+93
-55
lines changed

gpustack_runtime/cmds/deployer.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ def register(parser: _SubParsersAction):
111111
default=80,
112112
)
113113

114+
deploy_parser.add_argument(
115+
"--host-network",
116+
action="store_true",
117+
help="use host network (default: False)",
118+
default=False,
119+
)
120+
114121
deploy_parser.add_argument(
115122
"--namespace",
116123
type=str,
@@ -147,6 +154,7 @@ def __init__(self, args: Namespace):
147154
self.backend = args.backend
148155
self.device = args.device
149156
self.port = args.port
157+
self.host_network = args.host_network
150158
self.service = args.service
151159
self.version = args.version
152160
self.namespace = args.namespace
@@ -209,7 +217,7 @@ def run(self):
209217
plan = WorkloadPlan(
210218
name=self.name,
211219
namespace=self.namespace,
212-
host_network=True,
220+
host_network=self.host_network,
213221
containers=[
214222
Container(
215223
image=f"gpustack/runner:{self.backend if self.backend else 'Host'}X.Y-{self.service}{self.version}",
@@ -289,6 +297,13 @@ def register(parser: _SubParsersAction):
289297
default=80,
290298
)
291299

300+
deploy_parser.add_argument(
301+
"--host-network",
302+
action="store_true",
303+
help="use host network (default: False)",
304+
default=False,
305+
)
306+
292307
deploy_parser.add_argument(
293308
"--namespace",
294309
type=str,
@@ -325,6 +340,7 @@ def __init__(self, args: Namespace):
325340
self.backend = args.backend
326341
self.device = args.device
327342
self.port = args.port
343+
self.host_network = args.host_network
328344
self.namespace = args.namespace
329345
self.name = args.name
330346
self.image = args.image
@@ -386,7 +402,7 @@ def run(self):
386402
plan = WorkloadPlan(
387403
name=self.name,
388404
namespace=self.namespace,
389-
host_network=True,
405+
host_network=self.host_network,
390406
containers=[
391407
Container(
392408
image=self.image,
@@ -821,20 +837,15 @@ def format_workloads_table(sts: list[WorkloadStatus]) -> str:
821837
if not sts:
822838
return "No workloads found."
823839

824-
width = 100
825-
826840
headers = ["Name", "State", "Created At"]
827-
col_widths = [
828-
len(str(getattr(st, attr.lower().replace(" ", "_"))))
829-
for st in sts
830-
for attr in headers
831-
]
832-
col_widths = [max(w, len(h)) for w, h in zip(col_widths, headers, strict=False)]
833-
834-
total_width = sum(col_widths) + len(col_widths) * 3 + 1
835-
if total_width > width:
836-
scale = (width - len(col_widths) * 3 - 1) / sum(col_widths)
837-
col_widths = [int(w * scale) for w in col_widths]
841+
# Calculate max width for each column based on header and content
842+
col_widths = []
843+
for attr in headers:
844+
attr_key = attr.lower().replace(" ", "_")
845+
max_content_width = max(
846+
[len(str(getattr(st, attr_key))) for st in sts] + [len(attr)],
847+
)
848+
col_widths.append(max_content_width)
838849

839850
lines = []
840851
header_line = (
@@ -849,9 +860,9 @@ def format_workloads_table(sts: list[WorkloadStatus]) -> str:
849860

850861
for st in sts:
851862
row = [
852-
st.name.ljust(col_widths[0]),
853-
st.state.ljust(col_widths[1]),
854-
st.created_at.ljust(col_widths[2]),
863+
str(st.name).ljust(col_widths[0]),
864+
str(st.state).ljust(col_widths[1]),
865+
str(st.created_at).ljust(col_widths[2]),
855866
]
856867
line = "| " + " | ".join(row) + " |"
857868
lines.append(line)

gpustack_runtime/cmds/detector.py

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -80,63 +80,68 @@ def format_devices_table(devs: Devices) -> str:
8080
if not devs:
8181
return "No GPUs detected."
8282

83-
width = 100
83+
# Column headers
84+
col_headers = ["GPU", "Name", "Memory-Usage", "GPU-Util", "Temp", "CC"]
85+
# Gather all rows to determine max width for each column
86+
rows = []
87+
for dev in devs:
88+
row = [
89+
str(dev.index),
90+
dev.name if dev.name else "N/A",
91+
f"{dev.memory_used}MiB / {dev.memory}MiB",
92+
f"{dev.cores_utilization}%",
93+
f"{dev.temperature}C" if dev.temperature is not None else "N/A",
94+
dev.compute_capability if dev.compute_capability else "N/A",
95+
]
96+
rows.append(row)
97+
98+
# Calculate max width for each column
99+
col_widths = [len(header) for header in col_headers]
100+
for row in rows:
101+
for i, cell in enumerate(row):
102+
col_widths[i] = max(col_widths[i], len(str(cell)))
103+
104+
# Add padding
105+
col_widths = [w + 2 for w in col_widths]
106+
107+
# Calculate table width
108+
width = sum(col_widths) + len(col_widths) + 1
84109

85110
# Header section
86111
dev = devs[0]
87112
header_content = f"{dev.manufacturer.upper()} "
88113
header_content += (
89114
f"Driver Version: {dev.driver_version if dev.driver_version else 'N/A'} "
90115
)
91-
header_content += f"Runtime Version: {dev.runtime_version if dev.runtime_version else 'N/A'}".rjust(
92-
width - len(header_content) - 4,
116+
runtime_version_str = (
117+
f"Runtime Version: {dev.runtime_version if dev.runtime_version else 'N/A'}"
93118
)
94-
95119
header_lines = [
96120
"+" + "-" * (width - 2) + "+",
97-
f"| {header_content.ljust(width - 4)} |",
121+
f"| {header_content.ljust(width - 4 - len(runtime_version_str))}{runtime_version_str} |",
98122
"|" + "-" * (width - 2) + "|",
99123
]
100124

101-
# Column headers
102-
col_headers = ["GPU", "Name", "Memory-Usage", "GPU-Util", "Temp", "CC"]
103-
col_widths = [5, 31, 20, 10, 6, 6]
104-
105-
# Adjust column widths to fit total width
106-
total_current_width = sum(col_widths) + len(col_widths) * 3 - 1
107-
if total_current_width < width - 2:
108-
# Distribute extra space to the name column
109-
col_widths[1] += width - 2 - total_current_width
110-
111-
# Create column header line
125+
# Column header line
112126
col_header_line = "|"
113127
for i, header in enumerate(col_headers):
114-
col_header_line += f" {header.center(col_widths[i])} |"
128+
col_header_line += f" {header.center(col_widths[i] - 2)} |"
115129
header_lines.append(col_header_line)
116130

117131
# Separator line
118-
separator = "|" + "|".join(["-" * (w + 2) for w in col_widths]) + "|"
132+
separator = "|" + "|".join(["-" * w for w in col_widths]) + "|"
119133
header_lines.append(separator)
120134

121135
# Device rows
122136
device_lines = []
123-
for dev in devs:
124-
row_data: list[str] = [
125-
str(dev.index),
126-
dev.name if dev.name else "N/A",
127-
f"{dev.memory_used}MiB / {dev.memory}MiB",
128-
f"{dev.cores_utilization}%",
129-
f"{dev.temperature}C" if dev.temperature is not None else "N/A",
130-
dev.compute_capability if dev.compute_capability else "N/A",
131-
]
132-
137+
for row in rows:
133138
row_line = "|"
134-
for j, data in enumerate(row_data):
135-
# Truncate name if too long
136-
if j == 1 and len(data) > col_widths[j]:
137-
data = data[: col_widths[j] - 3] + "..." # noqa: PLW2901
138-
row_line += f" {data.ljust(col_widths[j])} |"
139-
139+
for j, data in enumerate(row):
140+
cell = str(data)
141+
# Truncate if too long
142+
if len(cell) > col_widths[j] - 2:
143+
cell = cell[: col_widths[j] - 5] + "..."
144+
row_line += f" {cell.ljust(col_widths[j] - 2)} |"
140145
device_lines.append(row_line)
141146

142147
# Footer section

gpustack_runtime/deployer/__types__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ class ContainerMountModeEnum(str, Enum):
277277
Read-write many mode.
278278
"""
279279

280+
def __str__(self):
281+
return self.value
282+
280283

281284
@dataclass
282285
class ContainerMount:
@@ -333,6 +336,9 @@ class ContainerPortProtocolEnum(str, Enum):
333336
SCTP protocol.
334337
"""
335338

339+
def __str__(self):
340+
return self.value
341+
336342

337343
@dataclass
338344
class ContainerPort:
@@ -518,6 +524,9 @@ class ContainerProfileEnum(str, Enum):
518524
Init profile.
519525
"""
520526

527+
def __str__(self):
528+
return self.value
529+
521530

522531
class ContainerRestartPolicyEnum(str, Enum):
523532
"""
@@ -537,6 +546,9 @@ class ContainerRestartPolicyEnum(str, Enum):
537546
Never restart the container.
538547
"""
539548

549+
def __str__(self):
550+
return self.value
551+
540552

541553
@dataclass
542554
class Container:
@@ -910,6 +922,9 @@ class WorkloadStatusStateEnum(str, Enum):
910922
The workload is inactive.
911923
"""
912924

925+
def __str__(self):
926+
return self.value
927+
913928

914929
WorkloadOperationToken = str
915930
"""

gpustack_runtime/deployer/docker.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ def parse_state(
182182
return WorkloadStatusStateEnum.UNHEALTHY
183183
if cr.status != "running" and not _has_restart_policy(cr):
184184
return WorkloadStatusStateEnum.PENDING
185+
health = cr.attrs["State"].get("Health", {})
186+
if health and health.get("Status") != "healthy":
187+
return WorkloadStatusStateEnum.UNHEALTHY
185188

186189
return WorkloadStatusStateEnum.RUNNING
187190

@@ -444,6 +447,7 @@ def _create_pause_container(
444447
if workload.host_network:
445448
create_options["network_mode"] = "host"
446449
else:
450+
create_options["hostname"] = workload.name
447451
port_mapping: dict[str, int] = {
448452
# <internal port>/<protocol>: <external port>
449453
f"{p.internal}/{p.protocol.lower()}": p.external or p.internal
@@ -732,9 +736,6 @@ def _create_containers(
732736
},
733737
}
734738

735-
if not workload.host_network:
736-
create_options["hostname"] = workload.name
737-
738739
if workload.pid_shared:
739740
create_options["pid_mode"] = pause_container_namespace
740741

gpustack_runtime/deployer/kuberentes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class KubernetesWorkloadServiceType(str, Enum):
5959
LoadBalancer: Exposes the service externally using a cloud provider's load balancer.
6060
"""
6161

62+
def __str__(self):
63+
return self.value
64+
6265

6366
@dataclass_json
6467
@dataclass

gpustack_runtime/detector/__types__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class ManufacturerEnum(str, Enum):
5050
Unknown Manufacturer
5151
"""
5252

53+
def __str__(self):
54+
return self.value
55+
5356

5457
_MANUFACTURER_BACKEND_MAPPING: dict[ManufacturerEnum, str] = {
5558
ManufacturerEnum.AMD: "rocm",

0 commit comments

Comments
 (0)