5.5 KiB
Phase 3: Complete harmony_assets, Refactor Consumers
Goal
Make harmony_assets the single way to manage downloadable binaries and images across Harmony. Eliminate k3d::DownloadableAsset duplication, implement Url::Url in OPNsense infra, remove LFS-tracked files from git.
Current State
harmony_assetsexists withAsset,LocalCache,LocalStore,S3Store(behind feature flag). CLI withupload,download,checksum,verifycommands. No tests. Zero consumers.k3d/src/downloadable_asset.rshas the same functionality with full test coverage (httptest mock server, checksum verification, cache hit, 404 handling, checksum failure).Url::Urlvariant inharmony_types/src/net.rsexists but istodo!()in OPNsense TFTP and HTTP infra layers.- OKD modules hardcode
./data/...paths (bootstrap_02_bootstrap.rs:84-88,ipxe.rs:73). data/directory contains ~3GB of LFS-tracked files (OKD binaries, PXE images, SCOS images).
Tasks
3.1 Port k3d tests to harmony_assets
The k3d crate has 5 well-written tests in downloadable_asset.rs. Port them to test harmony_assets::LocalStore:
// harmony_assets/tests/local_store.rs (or in src/ as unit tests)
#[tokio::test]
async fn test_fetch_downloads_and_verifies_checksum() {
// Start httptest server serving a known file
// Create Asset with URL pointing to mock server
// Fetch via LocalStore
// Assert file exists at expected cache path
// Assert checksum matches
}
#[tokio::test]
async fn test_fetch_returns_cached_file_when_present() {
// Pre-populate cache with correct file
// Fetch — assert no HTTP request made (mock server not hit)
}
#[tokio::test]
async fn test_fetch_fails_on_404() { ... }
#[tokio::test]
async fn test_fetch_fails_on_checksum_mismatch() { ... }
#[tokio::test]
async fn test_fetch_with_progress_callback() {
// Assert progress callback is called with (bytes_received, total_size)
}
Add httptest to [dev-dependencies] of harmony_assets.
3.2 Refactor k3d to use harmony_assets
Replace k3d/src/downloadable_asset.rs with calls to harmony_assets:
// k3d/src/lib.rs — in download_latest_release()
use harmony_assets::{Asset, LocalCache, LocalStore, ChecksumAlgo};
let asset = Asset::new(
binary_url,
checksum,
ChecksumAlgo::SHA256,
K3D_BIN_FILE_NAME.to_string(),
);
let cache = LocalCache::new(self.base_dir.clone());
let store = LocalStore::new();
let path = store.fetch(&asset, &cache, None).await
.map_err(|e| format!("Failed to download k3d: {}", e))?;
Delete k3d/src/downloadable_asset.rs. Update k3d's Cargo.toml to depend on harmony_assets.
3.3 Define asset metadata as config structs
Following plan.md Phase 2, create typed config for OKD assets using harmony_config:
// harmony/src/modules/okd/config.rs
#[derive(Config, Serialize, Deserialize, JsonSchema, InteractiveParse)]
struct OkdInstallerConfig {
pub openshift_install_url: String,
pub openshift_install_sha256: String,
pub scos_kernel_url: String,
pub scos_kernel_sha256: String,
pub scos_initramfs_url: String,
pub scos_initramfs_sha256: String,
pub scos_rootfs_url: String,
pub scos_rootfs_sha256: String,
}
First run prompts for URLs/checksums (or uses compiled-in defaults). Values persist to SQLite. Can be overridden via env vars or OpenBao.
3.4 Implement Url::Url in OPNsense infra layer
In harmony/src/infra/opnsense/http.rs and tftp.rs, implement the Url::Url(url) match arm:
// Instead of SCP-ing files to OPNsense:
// SSH into OPNsense, run: fetch -o /usr/local/http/{path} {url}
// (FreeBSD-native HTTP client, no extra deps on OPNsense)
This eliminates the manual scp workaround and the inquire::Confirm prompts in ipxe.rs:126 and bootstrap_02_bootstrap.rs:230.
3.5 Refactor OKD modules to use assets + config
In bootstrap_02_bootstrap.rs:
openshift-install: ResolveOkdInstallerConfigfromharmony_config, download viaharmony_assets, invoke from cache.- SCOS images: Pass
Url::Url(scos_kernel_url)etc. toStaticFilesHttpScore. OPNsense fetches from S3 directly. - Remove
ocandkubectlfromdata/okd/bin/(never used by code).
In ipxe.rs:
- Replace the folder-to-serve SCP workaround with individual
Url::Urlentries. - Remove the
inquire::ConfirmSCP prompts.
3.6 Upload assets to S3
- Upload all current
data/binaries to Ceph S3 bucket with path scheme:harmony-assets/okd/v{version}/openshift-install,harmony-assets/pxe/centos-stream-9/install.img, etc. - Set public-read ACL or configure presigned URL generation.
- Record S3 URLs and SHA256 checksums as defaults in the config structs.
3.7 Remove LFS, clean git
- Remove all LFS-tracked files from the repo.
- Update
.gitattributesto remove LFS filters. - Keep
data/in.gitignore(it becomes a local cache directory). - Optionally use
git filter-repoor BFG to strip LFS objects from history (required before Phase 4 GitHub publish).
Deliverables
harmony_assetshas tests ported from k3d pattern (5+ tests with httptest)k3d::DownloadableAssetreplaced byharmony_assetsusageOkdInstallerConfigstruct usingharmony_configUrl::Urlimplemented in OPNsense HTTP and TFTP infra- OKD bootstrap refactored to use lazy-download pattern
- Assets uploaded to S3 with documented URLs/checksums
- LFS removed, git history cleaned
- Repo size small enough for GitHub (~code + templates only)