Skip to content

Commit a84608a

Browse files
committed
add gpu info
1 parent f794422 commit a84608a

10 files changed

Lines changed: 65 additions & 0 deletions

File tree

rock/actions/sandbox/response.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class SandboxStatusResponse(BaseModel):
5858
namespace: str | None = None
5959
cpus: float | None = None
6060
memory: str | None = None
61+
num_gpus: float | None = None
62+
accelerator_type: str | None = None
6163
disk: str | None = None
6264
disk_limit_rootfs: str | None = Field(default=None, deprecated="Use 'disk' instead")
6365
state: State | None = None

rock/actions/sandbox/sandbox_info.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class SandboxInfo(TypedDict, total=False):
2121
create_user_gray_flag: bool
2222
cpus: float
2323
memory: str
24+
num_gpus: float
25+
accelerator_type: str
2426
disk: str
2527
create_time: str
2628
start_time: str

rock/admin/proto/response.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class SandboxStatusResponse(BaseModel):
3434
namespace: str | None = None
3535
cpus: float | None = None
3636
memory: str | None = None
37+
num_gpus: float | None = None
38+
accelerator_type: str | None = None
3739
disk: str | None = None
3840
disk_limit_rootfs: str | None = Field(default=None, deprecated="Use 'disk' instead")
3941
start_time: str | None = None
@@ -64,6 +66,8 @@ def from_sandbox_info(cls, sandbox_info: "SandboxInfo") -> "SandboxStatusRespons
6466
namespace=sandbox_info.get("namespace"),
6567
cpus=sandbox_info.get("cpus"),
6668
memory=sandbox_info.get("memory"),
69+
num_gpus=sandbox_info.get("num_gpus"),
70+
accelerator_type=sandbox_info.get("accelerator_type"),
6771
disk=sandbox_info.get("disk"),
6872
disk_limit_rootfs=sandbox_info.get("disk"),
6973
start_time=sandbox_info.get("start_time"),

rock/sandbox/sandbox_manager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ async def start_async(
168168
"image": docker_deployment_config.image,
169169
"cpus": docker_deployment_config.cpus,
170170
"memory": docker_deployment_config.memory,
171+
"num_gpus": docker_deployment_config.num_gpus,
172+
"accelerator_type": docker_deployment_config.accelerator_type,
171173
}
172174
if docker_deployment_config.disk is not None:
173175
sandbox_info["disk"] = docker_deployment_config.disk
@@ -447,6 +449,8 @@ async def get_status(self, sandbox_id, include_all_states: bool = False) -> Sand
447449
namespace=sandbox_info.get("namespace"),
448450
cpus=sandbox_info.get("cpus"),
449451
memory=sandbox_info.get("memory"),
452+
num_gpus=sandbox_info.get("num_gpus"),
453+
accelerator_type=sandbox_info.get("accelerator_type"),
450454
disk=sandbox_info.get("disk"),
451455
disk_limit_rootfs=sandbox_info.get("disk"),
452456
start_time=sandbox_info.get("start_time"),

rock/sandbox/service/opensandbox_proxy_service.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ async def get_status(self, sandbox_id: str, include_all_states: bool = False) ->
250250
namespace=info.get("namespace"),
251251
cpus=info.get("cpus"),
252252
memory=info.get("memory"),
253+
num_gpus=info.get("num_gpus"),
254+
accelerator_type=info.get("accelerator_type"),
253255
disk=info.get("disk"),
254256
disk_limit_rootfs=info.get("disk"),
255257
start_time=info.get("start_time"),

rock/sandbox/service/sandbox_proxy_service.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,8 @@ async def get_status(self, sandbox_id: str, include_all_states: bool = False) ->
11351135
namespace=info.get("namespace"),
11361136
cpus=info.get("cpus"),
11371137
memory=info.get("memory"),
1138+
num_gpus=info.get("num_gpus"),
1139+
accelerator_type=info.get("accelerator_type"),
11381140
disk=info.get("disk"),
11391141
disk_limit_rootfs=info.get("disk"),
11401142
start_time=info.get("start_time"),

tests/unit/admin/proto/test_sandbox_response.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ def test_from_sandbox_info_with_none_disk(self):
118118
response = SandboxStatusResponse.from_sandbox_info(sandbox_info)
119119
assert response.disk is None
120120

121+
def test_from_sandbox_info_with_gpu(self):
122+
sandbox_info = {
123+
"sandbox_id": "test-sandbox",
124+
"num_gpus": 0.5,
125+
"accelerator_type": "A100",
126+
}
127+
128+
response = SandboxStatusResponse.from_sandbox_info(sandbox_info)
129+
130+
assert response.num_gpus == 0.5
131+
assert response.accelerator_type == "A100"
132+
121133

122134
# ---- actions/sandbox/response.SandboxStatusResponse tests ----
123135

@@ -148,3 +160,11 @@ def test_actions_status_response_auto_transition_fields(self):
148160

149161
assert response.auto_archive_time == "2026-01-01T00:10:00+00:00"
150162
assert response.auto_delete_time == "2026-01-01T00:20:00+00:00"
163+
164+
def test_actions_status_response_gpu_fields(self):
165+
from rock.actions.sandbox.response import SandboxStatusResponse as ActionStatusResponse
166+
167+
response = ActionStatusResponse(num_gpus=2, accelerator_type="H20")
168+
169+
assert response.num_gpus == 2
170+
assert response.accelerator_type == "H20"

tests/unit/sandbox/test_get_status_include_all_states.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,16 @@ async def test_get_status_sets_auto_stop_time_from_timeout(self, sandbox_manager
119119
result = await sandbox_manager.get_status("sandbox-1")
120120

121121
assert result.auto_stop_time == "2286-11-21T01:46:39+08:00"
122+
123+
@pytest.mark.asyncio
124+
async def test_get_status_returns_gpu_info(self, sandbox_manager, mock_operator, mock_meta_store):
125+
sandbox_info = _make_sandbox_info(state=State.RUNNING)
126+
sandbox_info["num_gpus"] = 0.5
127+
sandbox_info["accelerator_type"] = "A100"
128+
mock_meta_store.get = AsyncMock(return_value=sandbox_info)
129+
mock_operator.get_status = AsyncMock(return_value=_make_sandbox_info(state=State.RUNNING))
130+
131+
result = await sandbox_manager.get_status("sandbox-1")
132+
133+
assert result.num_gpus == 0.5
134+
assert result.accelerator_type == "A100"

tests/unit/sandbox/test_proxy_get_status.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,18 @@ async def test_running_sandbox_returns_phases_and_port_mapping(
134134
}
135135
assert result.port_mapping == {22555: 22555, 8080: 8080}
136136

137+
async def test_get_status_returns_gpu_info(self, proxy_service, mock_meta_store, mock_rpc_client):
138+
info = _make_meta_info(state=State.RUNNING)
139+
info.update(num_gpus=2, accelerator_type="H20")
140+
mock_meta_store.get.return_value = info
141+
mock_rpc_client.post.side_effect = Exception("connection refused")
142+
mock_rpc_client.get.side_effect = Exception("connection refused")
143+
144+
result = await proxy_service.get_status("sandbox-1")
145+
146+
assert result.num_gpus == 2
147+
assert result.accelerator_type == "H20"
148+
137149
async def test_pending_to_running_triggers_meta_update(self, proxy_service, mock_meta_store, mock_rpc_client):
138150
mock_meta_store.get.return_value = _make_meta_info(state=State.PENDING, host_ip="10.0.0.1")
139151
mock_rpc_client.post.side_effect = [

tests/unit/sandbox/test_proxy_get_status_route.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ async def test_get_status_success(self, client, mock_service):
4444
state=State.RUNNING,
4545
is_alive=True,
4646
host_ip="10.0.0.1",
47+
num_gpus=2,
48+
accelerator_type="H20",
4749
)
4850

4951
resp = await client.get("/get_status", params={"sandbox_id": "sandbox-1"})
@@ -53,6 +55,8 @@ async def test_get_status_success(self, client, mock_service):
5355
assert body["result"]["sandbox_id"] == "sandbox-1"
5456
assert body["result"]["state"] == State.RUNNING
5557
assert body["result"]["is_alive"] is True
58+
assert body["result"]["num_gpus"] == 2
59+
assert body["result"]["accelerator_type"] == "H20"
5660
mock_service.get_status.assert_awaited_once_with("sandbox-1", False)
5761

5862
async def test_get_status_passes_include_all_states(self, client, mock_service):

0 commit comments

Comments
 (0)