|
54 | 54 | from agent_env.store.ids import derive_id |
55 | 55 | from agent_env.store.image_store.image_contents import image_config, labels |
56 | 56 | from agent_env.store.image_store.oci_registry_credentials import names_registry |
57 | | -from agent_env.store.image_store.registry_api import NoSuchImageError, pin_digest, write_index |
| 57 | +from agent_env.store.image_store.image_store import ImageStore |
| 58 | +from agent_env.store.image_store.registry_api import pin_digest, pin_if_served, write_index |
58 | 59 | from agent_env.store.local_state import holding_locks |
59 | 60 | from agent_env.utils.docker.build import DockerBuildError |
60 | 61 |
|
@@ -176,7 +177,7 @@ def left(form: str, arch: str, record: dict | None) -> bool: |
176 | 177 | if status == "unverified": |
177 | 178 | return bool(boot.native_links(provider, arch, form, env.stored_id, env.computer.os.type)) |
178 | 179 | if form == "disk" and env.computer.os.type == "windows": |
179 | | - return not windows_disk.held(record["image"]) or windows_disk.expiring(record.get("expires")) |
| 180 | + return windows_disk.expiring(record.get("expires")) |
180 | 181 | if form != "vm_bundle": |
181 | 182 | return False |
182 | 183 | links = boot.native_links(provider, arch, form, env.stored_id) |
@@ -354,11 +355,11 @@ def _composed_vm_bundle(env: ComputerEnv, base: ComputerArtifact, driver: Comput |
354 | 355 |
|
355 | 356 | def _composed_windows_disk(env: ComputerEnv, base: ComputerArtifact, driver: ComputerDriverEnv, arch: str, |
356 | 357 | provider: SandboxProvider, progress: _Progress) -> dict: |
357 | | - """The Windows disk of ``arch`` composed with this machine's Docker and KVM (``windows_disk``), which keeps it: its |
358 | | - base installed from Microsoft's media first unless held, then the driver installed over ssh as a layer on it and |
359 | | - packed under a tag of its key; or one of that key reused, held here already. Then probed at full (gate 3), and |
360 | | - removed when that fails, so no deploy here boots it. All of it holds a lock of its tag, which keeps two composes of |
361 | | - one key from breaking each other: the other waits, then reuses it.""" |
| 358 | + """The Windows disk of ``arch``: one of its key the env's image store holds, reused; else composed with this |
| 359 | + machine's Docker and KVM (``windows_disk``), on its base, this machine's, the store's or installed from Microsoft's |
| 360 | + media, the driver installed over ssh as a layer on it, packed and pushed to the store under its key, as Linux disks |
| 361 | + are. Then probed at full (gate 3). All of it holds a lock of its key, which keeps two composes of one key on this |
| 362 | + machine from breaking each other: the other waits, then reuses it.""" |
362 | 363 | pair = f"disk/{arch}" |
363 | 364 | with (_attempting(env, "disk", arch) as attempt, |
364 | 365 | tempfile.TemporaryDirectory(prefix="agentenv-compose-") as work): |
@@ -387,33 +388,29 @@ def say(line: str) -> None: |
387 | 388 | progress.say(f"{pair}: {line}") |
388 | 389 |
|
389 | 390 | attempt.stage = "base" |
390 | | - iso = windows_disk.media(say) |
| 391 | + registry = windows_disk.Registry(_image_store(env), REPOSITORY) |
391 | 392 | disk_gb, user = base.forms.disk.min_disk_gb, base.session.user |
392 | | - made = windows_disk.base(_key(iso=windows_disk.sha256(iso), recipe=_digest(windows_disk.RECIPE), |
393 | | - disk_gb=disk_gb, user=user, form="windows-base", format=FORMAT), |
394 | | - iso, disk_gb, user, say) |
| 393 | + made = windows_disk.base(_key(recipe=_digest(windows_disk.RECIPE), disk_gb=disk_gb, user=user, |
| 394 | + form="windows-base", format=FORMAT), |
| 395 | + lambda: windows_disk.media(say), disk_gb, user, say, registry) |
395 | 396 | script = windows_disk.write(build, [part], settings, {"base": made.image, "layers": [part.folder]}) |
396 | | - key = attempt.key = _key(base=windows_disk.image_id(made.image), provision=script, context=_digest(context), |
| 397 | + expires = made.expires.isoformat(timespec="seconds") |
| 398 | + key = attempt.key = _key(base=made.image, base_expires=expires, provision=script, context=_digest(context), |
397 | 399 | build_settings=settings, form="disk", arch=arch, format=FORMAT) |
398 | | - image = f"agentenv-windows:{key[7:23]}" |
399 | 400 | attempt.stage = "build" |
400 | | - with holding_locks([f"windows-disk:{image}"], lambda: progress.at( |
401 | | - pair, "waiting", f"waiting for the compose or probe of {image} under way on this machine")): |
402 | | - if windows_disk.held(image): |
403 | | - progress.at(pair, "reusing", "reusing the disk of the same key, composed on this machine earlier") |
404 | | - result = {"status": "unverified", "key": key, "image": image, "reused": True, |
405 | | - "expires": made.expires.isoformat(timespec="seconds"), "built_at": now()} |
| 401 | + with holding_locks([f"windows-disk:{key}"], lambda: progress.at( |
| 402 | + pair, "waiting", "waiting for the compose of the same disk under way on this machine")): |
| 403 | + if (pinned := registry.served(windows_disk.disk_names(key).tag)) is not None: |
| 404 | + progress.at(pair, "reusing", "reusing the disk of the same key, composed earlier") |
| 405 | + result = {"status": "unverified", "key": key, "image": pinned, "reused": True, "expires": expires, |
| 406 | + "built_at": now()} |
406 | 407 | else: |
407 | 408 | progress.at(pair, "composing", "composing on this machine's Docker") |
408 | | - windows_disk.compose(made, build, image, {KEY_LABEL: key, windows_disk.EXPIRES_LABEL: |
409 | | - made.expires.isoformat(timespec="seconds")}, say) |
410 | | - result = {"status": "unverified", "key": key, "image": image, "reused": False, |
411 | | - "builder": "LocalSandboxProvider", "expires": made.expires.isoformat(timespec="seconds"), |
412 | | - "built_at": now()} |
413 | | - probed = _probed(env, driver, "disk", arch, result, provider, progress) |
414 | | - if probed["status"] == "failed": |
415 | | - windows_disk.remove(image) |
416 | | - return probed |
| 409 | + pinned = windows_disk.compose(made, build, key, |
| 410 | + {KEY_LABEL: key, windows_disk.EXPIRES_LABEL: expires}, say, registry) |
| 411 | + result = {"status": "unverified", "key": key, "image": pinned, "reused": False, |
| 412 | + "builder": "LocalSandboxProvider", "expires": expires, "built_at": now()} |
| 413 | + return _probed(env, driver, "disk", arch, result, provider, progress) |
417 | 414 | return attempt.result |
418 | 415 |
|
419 | 416 |
|
@@ -672,13 +669,19 @@ def _key(**inputs: Any) -> str: |
672 | 669 | return "sha256:" + hashlib.sha256(json.dumps(inputs, sort_keys=True).encode()).hexdigest() |
673 | 670 |
|
674 | 671 |
|
675 | | -def _stored(env: ComputerEnv, key: str) -> tuple[Any, str, str | None]: |
| 672 | +def _stored(env: ComputerEnv, key: str) -> tuple[ImageStore, str, str | None]: |
676 | 673 | """The env's image store, the ref there of the image of ``key``, and that ref pinned when the store serves one |
677 | 674 | already, for any env that built it.""" |
| 675 | + store = _image_store(env) |
| 676 | + ref = store.image_ref(REPOSITORY, key.removeprefix("sha256:")) |
| 677 | + return store, ref, pin_if_served(ref, store.auth(ref)) |
| 678 | + |
| 679 | + |
| 680 | +def _image_store(env: ComputerEnv) -> ImageStore: |
| 681 | + """The env's image store, with the repository its computers' images are kept in.""" |
678 | 682 | store = get_config().get_image_store_for(env.stored_id) |
679 | 683 | store.ensure_repository(REPOSITORY) |
680 | | - ref = store.image_ref(REPOSITORY, key.removeprefix("sha256:")) |
681 | | - return store, ref, _served(ref, store) |
| 684 | + return store |
682 | 685 |
|
683 | 686 |
|
684 | 687 | def _base_disk(base: ComputerArtifact, arch: str) -> tuple[str | None, str]: |
@@ -936,14 +939,6 @@ def _wants(layers: list[_Layer], protocol: bool) -> list[packages.Want]: |
936 | 939 | return wants |
937 | 940 |
|
938 | 941 |
|
939 | | -def _served(ref: str, store) -> str | None: |
940 | | - """``ref`` pinned to the digest the image store serves for it, or None when it serves none.""" |
941 | | - try: |
942 | | - return pin_digest(ref, store.auth(ref)) |
943 | | - except NoSuchImageError: |
944 | | - return None |
945 | | - |
946 | | - |
947 | 942 | def _computer(env: ComputerEnv, base: ComputerArtifact, built: dict[str, str], disks: dict[str, str], |
948 | 943 | bundles: dict[str, str]) -> dict | None: |
949 | 944 | """Write the env's computer over the images ``built``, by arch, joined into one index in the env's image store, signed |
|
0 commit comments