Skip to content

Commit 462ea90

Browse files
committed
addressed great pr feedback
1 parent e2ea0b8 commit 462ea90

1 file changed

Lines changed: 8 additions & 63 deletions

File tree

examples/devbox_snapshots.py

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
from runloop_api_client import AsyncRunloopSDK
3535
from runloop_api_client.lib.polling import PollingConfig
3636
from runloop_api_client.sdk.async_devbox import AsyncDevbox
37-
from runloop_api_client.sdk.async_snapshot import AsyncSnapshot
3837

3938
from ._harness import run_as_cli, unique_name, wrap_recipe
4039
from .example_types import ExampleCheck, RecipeOutput, RecipeContext
@@ -55,45 +54,6 @@ async def recipe(ctx: RecipeContext) -> RecipeOutput:
5554

5655
resources_created: list[str] = []
5756

58-
source_devbox: AsyncDevbox | None = None
59-
clone_a: AsyncDevbox | None = None
60-
clone_b: AsyncDevbox | None = None
61-
snapshot: AsyncSnapshot | None = None
62-
local_file_path: Path | None = None
63-
64-
source_needs_cleanup = False
65-
clone_a_needs_cleanup = False
66-
clone_b_needs_cleanup = False
67-
snapshot_needs_cleanup = False
68-
69-
async def cleanup_source() -> None:
70-
if source_needs_cleanup and source_devbox is not None:
71-
await source_devbox.shutdown()
72-
73-
async def cleanup_clone_a() -> None:
74-
if clone_a_needs_cleanup and clone_a is not None:
75-
await clone_a.shutdown()
76-
77-
async def cleanup_clone_b() -> None:
78-
if clone_b_needs_cleanup and clone_b is not None:
79-
await clone_b.shutdown()
80-
81-
async def cleanup_snapshot() -> None:
82-
if snapshot_needs_cleanup and snapshot is not None:
83-
await snapshot.delete()
84-
85-
def cleanup_local_file() -> None:
86-
if local_file_path is not None:
87-
local_file_path.unlink(missing_ok=True)
88-
89-
# Cleanup runs in LIFO order, so register these handlers up front in reverse
90-
# dependency order: clones, then source devbox, then snapshot, then local file.
91-
cleanup.add("local-file:snapshot-demo", cleanup_local_file)
92-
cleanup.add("snapshot:baseline", cleanup_snapshot)
93-
cleanup.add("devbox:source", cleanup_source)
94-
cleanup.add("devbox:clone-a", cleanup_clone_a)
95-
cleanup.add("devbox:clone-b", cleanup_clone_b)
96-
9757
uploaded_contents = "uploaded-from-local-file"
9858
baseline_contents = "baseline-after-upload-and-mutation"
9959
source_contents = "source-devbox-after-isolated-mutation"
@@ -103,23 +63,23 @@ def cleanup_local_file() -> None:
10363
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as tmp_file:
10464
tmp_file.write(uploaded_contents)
10565
local_file_path = Path(tmp_file.name)
66+
cleanup.add("local-file:snapshot-demo", lambda: local_file_path.unlink(missing_ok=True))
10667

10768
source_devbox = await sdk.devbox.create(
10869
name=unique_name("snapshot-source"),
10970
launch_parameters={
11071
"resource_size_request": "X_SMALL",
11172
},
11273
)
113-
source_needs_cleanup = True
74+
cleanup.add(f"devbox:{source_devbox.id}", source_devbox.shutdown)
11475
resources_created.append(f"devbox:{source_devbox.id}")
11576

11677
await source_devbox.file.upload(path=FILE_PATH, file=local_file_path)
11778
uploaded_readback = await read_file_contents(source_devbox)
11879

11980
await source_devbox.file.write(file_path=FILE_PATH, contents=baseline_contents)
12081

121-
suspend_response = await source_devbox.suspend()
122-
suspended_info = suspend_response
82+
suspended_info = await source_devbox.suspend()
12383
if suspended_info.status != "suspended":
12484
suspended_info = await source_devbox.await_suspended(polling_config=POLLING_CONFIG)
12585

@@ -131,7 +91,7 @@ def cleanup_local_file() -> None:
13191
commit_message="Capture the shared baseline after suspend and resume.",
13292
polling_config=POLLING_CONFIG,
13393
)
134-
snapshot_needs_cleanup = True
94+
cleanup.add(f"snapshot:{snapshot.id}", snapshot.delete)
13595
resources_created.append(f"snapshot:{snapshot.id}")
13696

13797
clone_a = await snapshot.create_devbox(
@@ -140,17 +100,19 @@ def cleanup_local_file() -> None:
140100
"resource_size_request": "X_SMALL",
141101
},
142102
)
143-
clone_a_needs_cleanup = True
103+
cleanup.add(f"devbox:{clone_a.id}", clone_a.shutdown)
144104
resources_created.append(f"devbox:{clone_a.id}")
145105

106+
# clone_a used snapshot.create_devbox(); clone_b uses sdk.devbox.create_from_snapshot()
107+
# to demonstrate both entry points for restoring a devbox from a snapshot.
146108
clone_b = await sdk.devbox.create_from_snapshot(
147109
snapshot.id,
148110
name=unique_name("snapshot-clone-b"),
149111
launch_parameters={
150112
"resource_size_request": "X_SMALL",
151113
},
152114
)
153-
clone_b_needs_cleanup = True
115+
cleanup.add(f"devbox:{clone_b.id}", clone_b.shutdown)
154116
resources_created.append(f"devbox:{clone_b.id}")
155117

156118
clone_a_baseline_readback = await read_file_contents(clone_a)
@@ -164,18 +126,6 @@ def cleanup_local_file() -> None:
164126
clone_a_isolated_readback = await read_file_contents(clone_a)
165127
clone_b_isolated_readback = await read_file_contents(clone_b)
166128

167-
await clone_b.shutdown()
168-
clone_b_needs_cleanup = False
169-
170-
await clone_a.shutdown()
171-
clone_a_needs_cleanup = False
172-
173-
await source_devbox.shutdown()
174-
source_needs_cleanup = False
175-
176-
await snapshot.delete()
177-
snapshot_needs_cleanup = False
178-
179129
return RecipeOutput(
180130
resources_created=resources_created,
181131
checks=[
@@ -229,11 +179,6 @@ def cleanup_local_file() -> None:
229179
),
230180
details=(f"values={[source_isolated_readback, clone_a_isolated_readback, clone_b_isolated_readback]}"),
231181
),
232-
ExampleCheck(
233-
name="snapshot can be deleted after the demo finishes",
234-
passed=not snapshot_needs_cleanup,
235-
details=f"deleted={not snapshot_needs_cleanup}",
236-
),
237182
],
238183
)
239184

0 commit comments

Comments
 (0)