improve: enhance rootfs command robustness and flexibility
- Remove dependency on manifest parsing for reference discovery - Automatically detect and use first available OSTree reference - Simplify command usage - no need to parse treefile for reference name - Add better error handling for empty repositories - Improve user experience by showing which reference is being used - Make command more flexible for different use cases
This commit is contained in:
parent
bffba885bc
commit
aadf99a3e1
3 changed files with 101 additions and 32 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -27,6 +27,8 @@ debian/*.postrm
|
||||||
debian/*.prerm
|
debian/*.prerm
|
||||||
debian/*.triggers
|
debian/*.triggers
|
||||||
|
|
||||||
|
*issue.md
|
||||||
|
|
||||||
# Package archives and tarballs
|
# Package archives and tarballs
|
||||||
*.tar
|
*.tar
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
|
|
|
||||||
83
minimal-treefile-with-kernel.yaml
Normal file
83
minimal-treefile-with-kernel.yaml
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
api_version: "1.0"
|
||||||
|
kind: "tree"
|
||||||
|
metadata:
|
||||||
|
ref_name: "test/minimal"
|
||||||
|
version: "0.1.0"
|
||||||
|
description: "Minimal test tree for bootc image generation"
|
||||||
|
repositories:
|
||||||
|
- name: "debian"
|
||||||
|
url: "http://deb.debian.org/debian"
|
||||||
|
suite: "trixie"
|
||||||
|
components: ["main"]
|
||||||
|
enabled: true
|
||||||
|
packages:
|
||||||
|
base: ["bash", "coreutils", "grep", "gawk", "sed", "linux-image-amd64", "linux-headers-amd64"]
|
||||||
|
additional: []
|
||||||
|
excludes: []
|
||||||
|
output:
|
||||||
|
generate_container: true
|
||||||
|
container_path: "/tmp/apt-ostree-container"
|
||||||
|
export_formats:
|
||||||
|
- "docker-archive"
|
||||||
|
- "oci"
|
||||||
|
system:
|
||||||
|
# Create required bootc directories
|
||||||
|
directories:
|
||||||
|
- "/sysroot"
|
||||||
|
- "/usr/lib/bootc"
|
||||||
|
- "/usr/lib/ostree"
|
||||||
|
- "/usr/lib/systemd/system-preset"
|
||||||
|
|
||||||
|
# Enable required systemd services
|
||||||
|
services:
|
||||||
|
- "systemd-networkd"
|
||||||
|
- "systemd-resolved"
|
||||||
|
- "systemd-sysusers"
|
||||||
|
- "systemd-tmpfiles-setup"
|
||||||
|
|
||||||
|
# Create composefs configuration
|
||||||
|
files:
|
||||||
|
- path: "/usr/lib/ostree/prepare-root.conf"
|
||||||
|
content: |
|
||||||
|
[prepare-root]
|
||||||
|
composefs=1
|
||||||
|
composefs-store=/ostree/repo
|
||||||
|
mode: "0644"
|
||||||
|
owner: "root:root"
|
||||||
|
|
||||||
|
- path: "/usr/lib/bootc/install/00-debian.toml"
|
||||||
|
content: |
|
||||||
|
[install]
|
||||||
|
filesystem = "ext4"
|
||||||
|
root-fs-type = "ext4"
|
||||||
|
|
||||||
|
[install.kernel-args]
|
||||||
|
default = ["console=ttyS0,115200", "quiet"]
|
||||||
|
mode: "0644"
|
||||||
|
owner: "root:root"
|
||||||
|
|
||||||
|
- path: "/usr/lib/systemd/tmpfiles.d/10-bootc.conf"
|
||||||
|
content: |
|
||||||
|
# Bootc required directories
|
||||||
|
d /var/log 0755 root root
|
||||||
|
d /var/cache 0755 root root
|
||||||
|
d /var/tmp 1777 root root
|
||||||
|
d /tmp 1777 root root
|
||||||
|
d /run 0755 root root
|
||||||
|
d /sysroot 0755 root root
|
||||||
|
d /ostree 0755 root root
|
||||||
|
d /boot 0755 root root
|
||||||
|
mode: "0644"
|
||||||
|
owner: "root:root"
|
||||||
|
|
||||||
|
# Post-installation cleanup and setup
|
||||||
|
postinstall:
|
||||||
|
- "echo 'Setting up bootc-compatible filesystem...'"
|
||||||
|
- "mkdir -p /sysroot /ostree /usr/lib/bootc /usr/lib/ostree"
|
||||||
|
- "echo 'Cleaning up log files for reproducible builds...'"
|
||||||
|
- "find /var/log -type f -name '*.log' -delete"
|
||||||
|
- "find /var/log -type f -name '*.log.*' -delete"
|
||||||
|
- "find /var/cache -type f -delete"
|
||||||
|
- "echo 'Setting up systemd tmpfiles...'"
|
||||||
|
- "systemd-tmpfiles --create --remove"
|
||||||
|
- "echo 'Bootc setup completed successfully'"
|
||||||
|
|
@ -195,23 +195,6 @@ impl Command for ComposeCommand {
|
||||||
let manifest_path = &args[1];
|
let manifest_path = &args[1];
|
||||||
let dest_path = &args[2];
|
let dest_path = &args[2];
|
||||||
|
|
||||||
// Parse the manifest/treefile to get the reference name
|
|
||||||
let treefile_content = match std::fs::read_to_string(manifest_path) {
|
|
||||||
Ok(content) => content,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("❌ Failed to read manifest file: {}", e);
|
|
||||||
return Err(AptOstreeError::System(format!("Failed to read manifest: {}", e)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let treefile = match Treefile::parse_treefile_content(&treefile_content) {
|
|
||||||
Ok(tf) => tf,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("❌ Failed to parse manifest: {}", e);
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extract the existing OSTree tree to the destination directory
|
// Extract the existing OSTree tree to the destination directory
|
||||||
let dest_path_buf = std::path::PathBuf::from(dest_path);
|
let dest_path_buf = std::path::PathBuf::from(dest_path);
|
||||||
|
|
||||||
|
|
@ -221,16 +204,17 @@ impl Command for ComposeCommand {
|
||||||
.map_err(|e| AptOstreeError::System(format!("Failed to clean destination directory: {}", e)))?;
|
.map_err(|e| AptOstreeError::System(format!("Failed to clean destination directory: {}", e)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the OSTree repository exists and contains the reference
|
// Check if the OSTree repository exists and contains any references
|
||||||
// Use the same workdir that was used to create the tree
|
// Use the same workdir that was used to create the tree
|
||||||
let ostree_repo = std::path::PathBuf::from("/tmp/apt-ostree-build/repo");
|
let ostree_repo = std::path::PathBuf::from("/tmp/apt-ostree-build/repo");
|
||||||
|
|
||||||
if !ostree_repo.exists() {
|
if !ostree_repo.exists() {
|
||||||
eprintln!("❌ OSTree repository not found at: {}", ostree_repo.display());
|
eprintln!("❌ OSTree repository not found at: {}", ostree_repo.display());
|
||||||
eprintln!(" Please run 'apt-ostree compose tree {}' first to create the tree", manifest_path);
|
eprintln!(" Please run 'apt-ostree compose tree {}' first to create the tree", manifest_path);
|
||||||
return Err(AptOstreeError::System("OSTree repository not found".to_string()));
|
return Err(AptOstreeError::System("OSTree repository not found".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the reference exists in the repository
|
// Check if there are any references in the repository
|
||||||
let ref_check = std::process::Command::new("ostree")
|
let ref_check = std::process::Command::new("ostree")
|
||||||
.args([
|
.args([
|
||||||
"refs",
|
"refs",
|
||||||
|
|
@ -247,26 +231,26 @@ impl Command for ComposeCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
let refs_output = String::from_utf8_lossy(&ref_check.stdout);
|
let refs_output = String::from_utf8_lossy(&ref_check.stdout);
|
||||||
if !refs_output.contains(&treefile.metadata.ref_name) {
|
let refs: Vec<&str> = refs_output.lines().filter(|line| !line.trim().is_empty()).collect();
|
||||||
eprintln!("❌ Reference '{}' not found in OSTree repository", treefile.metadata.ref_name);
|
|
||||||
eprintln!(" Available references:");
|
if refs.is_empty() {
|
||||||
for line in refs_output.lines() {
|
eprintln!("❌ No OSTree references found in repository");
|
||||||
if !line.trim().is_empty() {
|
|
||||||
eprintln!(" {}", line.trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eprintln!(" Please run 'apt-ostree compose tree {}' first to create the tree", manifest_path);
|
eprintln!(" Please run 'apt-ostree compose tree {}' first to create the tree", manifest_path);
|
||||||
return Err(AptOstreeError::System(format!("Reference '{}' not found", treefile.metadata.ref_name)));
|
return Err(AptOstreeError::System("No OSTree references found".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract OSTree tree to destination
|
// Use the first available reference
|
||||||
println!("📦 Extracting OSTree tree '{}' to '{}'...", treefile.metadata.ref_name, dest_path);
|
let ref_name = refs[0];
|
||||||
|
println!("📦 Using OSTree reference: {}", ref_name);
|
||||||
|
|
||||||
|
// Now extract the OSTree tree to destination
|
||||||
|
println!("📦 Extracting OSTree tree '{}' to '{}'...", ref_name, dest_path);
|
||||||
let output = std::process::Command::new("ostree")
|
let output = std::process::Command::new("ostree")
|
||||||
.args([
|
.args([
|
||||||
"checkout",
|
"checkout",
|
||||||
"--repo", &ostree_repo.to_string_lossy(),
|
"--repo", &ostree_repo.to_string_lossy(),
|
||||||
"--user-mode",
|
"--user-mode",
|
||||||
&treefile.metadata.ref_name,
|
ref_name,
|
||||||
&dest_path_buf.to_string_lossy()
|
&dest_path_buf.to_string_lossy()
|
||||||
])
|
])
|
||||||
.output()
|
.output()
|
||||||
|
|
@ -299,7 +283,7 @@ impl Command for ComposeCommand {
|
||||||
println!("✅ Rootfs generation completed successfully");
|
println!("✅ Rootfs generation completed successfully");
|
||||||
println!(" Source: {}", manifest_path);
|
println!(" Source: {}", manifest_path);
|
||||||
println!(" Destination: {}", dest_path);
|
println!(" Destination: {}", dest_path);
|
||||||
println!(" Tree reference: {}", treefile.metadata.ref_name);
|
println!(" Tree reference: {}", ref_name);
|
||||||
println!(" Files extracted: {}", file_count);
|
println!(" Files extracted: {}", file_count);
|
||||||
}
|
}
|
||||||
"build-chunked-oci" => {
|
"build-chunked-oci" => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue