|
25 | 25 | //! // One-time install (no-op if already present). |
26 | 26 | //! pyhl::install(&pyhl::InstallOptions { |
27 | 27 | //! home, |
28 | | -//! source: pyhl::InstallSource::Ghcr, |
| 28 | +//! source: pyhl::InstallSource::Ghcr { tag: None }, // None = :latest |
29 | 29 | //! mounts: &[], |
30 | 30 | //! network: None, |
31 | 31 | //! listen_ports: None, |
@@ -104,8 +104,9 @@ pub struct InstallOptions<'a> { |
104 | 104 | /// Where `install` pulls its kernel and CPIO from. |
105 | 105 | #[derive(Debug)] |
106 | 106 | pub enum InstallSource<'a> { |
107 | | - /// Pull the default published image from GHCR via docker/podman. |
108 | | - Ghcr, |
| 107 | + /// Pull the published image from GHCR via docker/podman. |
| 108 | + /// `tag`: `None` pulls `:latest`; `Some("v0.3.1")` pins a release. |
| 109 | + Ghcr { tag: Option<&'a str> }, |
109 | 110 | /// Copy from a local python-agent-driver build tree. |
110 | 111 | LocalDir(&'a Path), |
111 | 112 | /// Explicit files — useful for custom image pipelines. |
@@ -164,18 +165,16 @@ pub fn install(opts: &InstallOptions<'_>) -> Result<InstallReport> { |
164 | 165 | kernel.to_path_buf(), |
165 | 166 | initrd.to_path_buf(), |
166 | 167 | ), |
167 | | - InstallSource::Ghcr => { |
| 168 | + InstallSource::Ghcr { tag } => { |
| 169 | + let kernel_image = ghcr_image_ref(GHCR_KERNEL_REPO, *tag); |
| 170 | + let initrd_image = ghcr_image_ref(GHCR_INITRD_REPO, *tag); |
168 | 171 | let scratch = home.join(".pyhl.download"); |
169 | 172 | fs::create_dir_all(&scratch)?; |
170 | 173 | let k = scratch.join("kernel"); |
171 | 174 | let i = scratch.join("initrd.cpio"); |
172 | | - extract_from_ghcr(GHCR_KERNEL_IMAGE, "/kernel", &k)?; |
173 | | - extract_from_ghcr(GHCR_INITRD_IMAGE, "/initrd.cpio", &i)?; |
174 | | - ( |
175 | | - format!("ghcr: {GHCR_KERNEL_IMAGE} + {GHCR_INITRD_IMAGE}"), |
176 | | - k, |
177 | | - i, |
178 | | - ) |
| 175 | + extract_from_ghcr(&kernel_image, "/kernel", &k)?; |
| 176 | + extract_from_ghcr(&initrd_image, "/initrd.cpio", &i)?; |
| 177 | + (format!("ghcr: {kernel_image} + {initrd_image}"), k, i) |
179 | 178 | } |
180 | 179 | }; |
181 | 180 |
|
@@ -394,13 +393,18 @@ pub fn discover_source_artifacts(dir: &Path) -> Result<(PathBuf, PathBuf)> { |
394 | 393 | // through InstallSource::Ghcr. |
395 | 394 | // --------------------------------------------------------------------------- |
396 | 395 |
|
397 | | -/// OCI image references published by `.github/workflows/publish-examples.yml`. |
398 | | -/// Both images are FROM-scratch payloads: kernel image has a single /kernel, |
399 | | -/// initrd image has a single /initrd.cpio. |
400 | | -pub const GHCR_KERNEL_IMAGE: &str = |
401 | | - "ghcr.io/hyperlight-dev/hyperlight-unikraft/python-agent-driver-kernel:latest"; |
402 | | -pub const GHCR_INITRD_IMAGE: &str = |
403 | | - "ghcr.io/hyperlight-dev/hyperlight-unikraft/python-agent-driver-initrd:latest"; |
| 396 | +/// GHCR repository base (without tag) for the kernel image. |
| 397 | +pub const GHCR_KERNEL_REPO: &str = |
| 398 | + "ghcr.io/hyperlight-dev/hyperlight-unikraft/python-agent-driver-kernel"; |
| 399 | +/// GHCR repository base (without tag) for the initrd image. |
| 400 | +pub const GHCR_INITRD_REPO: &str = |
| 401 | + "ghcr.io/hyperlight-dev/hyperlight-unikraft/python-agent-driver-initrd"; |
| 402 | + |
| 403 | +/// Build a full OCI image reference from a repo base and an optional tag. |
| 404 | +/// `None` resolves to `:latest`. |
| 405 | +pub fn ghcr_image_ref(repo: &str, tag: Option<&str>) -> String { |
| 406 | + format!("{}:{}", repo, tag.unwrap_or("latest")) |
| 407 | +} |
404 | 408 |
|
405 | 409 | /// Pull a single file out of an OCI image hosted on GHCR. Uses whichever |
406 | 410 | /// of `docker` / `podman` is on `$PATH`. The published images are |
|
0 commit comments