Skip to content

Commit 94d9949

Browse files
committed
to-disk: Add metadata + caching for disk images
Closes: #17 Signed-off-by: Colin Walters <[email protected]>
1 parent aa85398 commit 94d9949

File tree

8 files changed

+1095
-372
lines changed

8 files changed

+1095
-372
lines changed

Cargo.lock

Lines changed: 460 additions & 336 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/integration-tests/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ fn main() {
172172
tests::to_disk::test_to_disk_qcow2();
173173
Ok(())
174174
}),
175+
Trial::test("to_disk_caching", || {
176+
tests::to_disk::test_to_disk_caching();
177+
Ok(())
178+
}),
175179
Trial::test("libvirt_list_functionality", || {
176180
tests::libvirt_verb::test_libvirt_list_functionality();
177181
Ok(())

crates/integration-tests/src/tests/to_disk.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,110 @@ pub fn test_to_disk_qcow2() {
215215
"qcow2 installation successful - disk contains expected partitions, is in qcow2 format, and bootc reported completion"
216216
);
217217
}
218+
219+
/// Test disk image caching functionality
220+
pub fn test_to_disk_caching() {
221+
let bck = get_bck_command().unwrap();
222+
223+
// Create a temporary disk image file
224+
let temp_dir = TempDir::new().expect("Failed to create temp directory");
225+
let disk_path = Utf8PathBuf::try_from(temp_dir.path().join("test-disk-cache.img"))
226+
.expect("temp path is not UTF-8");
227+
228+
println!("Testing disk image caching with: {}", disk_path);
229+
230+
// First run: Create the disk image
231+
println!("=== First run: Creating initial disk image ===");
232+
let output1 = Command::new("timeout")
233+
.args([
234+
"600s", // 10 minute timeout for installation
235+
&bck,
236+
"to-disk",
237+
"--label",
238+
INTEGRATION_TEST_LABEL,
239+
"quay.io/centos-bootc/centos-bootc:stream10",
240+
disk_path.as_str(),
241+
])
242+
.output()
243+
.expect("Failed to run bcvk to-disk (first time)");
244+
245+
let stdout1 = String::from_utf8_lossy(&output1.stdout);
246+
let stderr1 = String::from_utf8_lossy(&output1.stderr);
247+
248+
println!("First run output:");
249+
println!("stdout:\n{}", stdout1);
250+
println!("stderr:\n{}", stderr1);
251+
252+
// Check that the first run completed successfully
253+
assert!(
254+
output1.status.success(),
255+
"First to-disk run failed with exit code: {:?}. stdout: {}, stderr: {}",
256+
output1.status.code(),
257+
stdout1,
258+
stderr1
259+
);
260+
261+
// Verify the disk was created and has content
262+
let metadata1 =
263+
std::fs::metadata(&disk_path).expect("Failed to get disk metadata after first run");
264+
assert!(metadata1.len() > 0, "Disk image is empty after first run");
265+
266+
// Verify installation completed successfully
267+
assert!(
268+
stdout1.contains("Installation complete") || stderr1.contains("Installation complete"),
269+
"No 'Installation complete' message found in first run output"
270+
);
271+
272+
// Second run: Should reuse the cached disk
273+
println!("=== Second run: Should reuse cached disk image ===");
274+
let output2 = Command::new(&bck)
275+
.args([
276+
"to-disk",
277+
"--label",
278+
INTEGRATION_TEST_LABEL,
279+
"quay.io/centos-bootc/centos-bootc:stream10",
280+
disk_path.as_str(),
281+
])
282+
.output()
283+
.expect("Failed to run bcvk to-disk (second time)");
284+
285+
let stdout2 = String::from_utf8_lossy(&output2.stdout);
286+
let stderr2 = String::from_utf8_lossy(&output2.stderr);
287+
288+
println!("Second run output:");
289+
println!("stdout:\n{}", stdout2);
290+
println!("stderr:\n{}", stderr2);
291+
292+
// Check that the second run completed successfully
293+
assert!(
294+
output2.status.success(),
295+
"Second to-disk run failed with exit code: {:?}. stdout: {}, stderr: {}",
296+
output2.status.code(),
297+
stdout2,
298+
stderr2
299+
);
300+
301+
// Verify cache was used (should see reusing message)
302+
assert!(
303+
stdout2.contains("Reusing existing cached disk image"),
304+
"Second run should have reused cached disk, but cache reuse message not found. stdout: {}, stderr: {}",
305+
stdout2, stderr2
306+
);
307+
308+
// Verify the disk metadata didn't change (file wasn't recreated)
309+
let metadata2 =
310+
std::fs::metadata(&disk_path).expect("Failed to get disk metadata after second run");
311+
assert_eq!(
312+
metadata1.len(),
313+
metadata2.len(),
314+
"Disk size changed between runs, indicating it was recreated instead of reused"
315+
);
316+
317+
// Verify the second run was much faster (no installation should have occurred)
318+
assert!(
319+
!stdout2.contains("Installation complete") && !stderr2.contains("Installation complete"),
320+
"Second run should not have performed installation, but found 'Installation complete' message"
321+
);
322+
323+
println!("Disk image caching test successful - cache was properly reused on second run");
324+
}

crates/kit/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ publish = false
66

77
[dependencies]
88
base64 = "0.22"
9-
cap-std-ext = { version = "4" }
9+
# For some recent APIs, TODO switch back to published version
10+
cap-std-ext = { git = "https://github.com/coreos/cap-std-ext", rev = "cfdb25d51ffc697e70aa0d8d3cefe9ec2133bd0a" }
1011
chrono = { version = "0.4", features = ["serde"] }
1112
const_format = { workspace = true }
1213
color-eyre = { workspace = true }
@@ -47,6 +48,7 @@ comfy-table = "7.1"
4748
strum = { version = "0.26", features = ["derive"] }
4849
quick-xml = "0.36"
4950
oci-spec = "0.8.2"
51+
sha2 = "0.10"
5052

5153
[dev-dependencies]
5254
similar-asserts = "1.5"

0 commit comments

Comments
 (0)