Skip to content

Commit 481e604

Browse files
committed
Add composefs-ostree and some basic CLI tools
Based on ideas from #141 This is an initial version of ostree support. This allows pulling from local and remote ostree repos, which will create a set of regular file content objects, as well as a blob containing all the remaining ostree objects. From the blob we can create an image. When pulling a commit, a base blob (i.e. "the previous version" can be specified. Any objects in that base blob will not be downloaded. If a name is given for the pulled commit, then pre-existing blobs with the same name will automatically be used as a base blob. This is an initial version and there are several things missing: * Pull operations are completely serial * There is no support for ostree summary files * There is no support for ostree delta files * There is no caching of local file availability (other than base blob) * Local ostree repos only support archive mode * There is no GPG validation on ostree pull Signed-off-by: Alexander Larsson <[email protected]>
1 parent d576157 commit 481e604

File tree

10 files changed

+1794
-17
lines changed

10 files changed

+1794
-17
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ composefs = { version = "0.3.0", path = "crates/composefs", default-features = f
1919
composefs-oci = { version = "0.3.0", path = "crates/composefs-oci", default-features = false }
2020
composefs-boot = { version = "0.3.0", path = "crates/composefs-boot", default-features = false }
2121
composefs-http = { version = "0.3.0", path = "crates/composefs-http", default-features = false }
22+
composefs-ostree = { version = "0.3.0", path = "crates/composefs-ostree", default-features = false }
2223

2324
[profile.dev.package.sha2]
2425
# this is *really* slow otherwise

crates/cfsctl/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ rust-version.workspace = true
1111
version.workspace = true
1212

1313
[features]
14-
default = ['pre-6.15', 'oci']
14+
default = ['pre-6.15', 'oci','ostree']
1515
http = ['composefs-http']
1616
oci = ['composefs-oci']
17+
ostree = ['composefs-ostree']
1718
rhel9 = ['composefs/rhel9']
1819
'pre-6.15' = ['composefs/pre-6.15']
1920

@@ -24,6 +25,7 @@ composefs = { workspace = true }
2425
composefs-boot = { workspace = true }
2526
composefs-oci = { workspace = true, optional = true }
2627
composefs-http = { workspace = true, optional = true }
28+
composefs-ostree = { workspace = true, optional = true }
2729
env_logger = { version = "0.11.0", default-features = false }
2830
hex = { version = "0.4.0", default-features = false }
2931
rustix = { version = "1.0.0", default-features = false, features = ["fs", "process"] }

crates/cfsctl/src/main.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,33 @@ enum OciCommand {
9292
},
9393
}
9494

95+
#[cfg(feature = "ostree")]
96+
#[derive(Debug, Subcommand)]
97+
enum OstreeCommand {
98+
PullLocal {
99+
repo_path: PathBuf,
100+
ostree_ref: String,
101+
name: Option<String>,
102+
#[clap(long)]
103+
base_name: Option<String>,
104+
},
105+
Pull {
106+
repo_url: String,
107+
ostree_ref: String,
108+
name: Option<String>,
109+
#[clap(long)]
110+
base_name: Option<String>,
111+
},
112+
CreateImage {
113+
commit_name: String,
114+
#[clap(long)]
115+
image_name: Option<String>,
116+
},
117+
Inspect {
118+
commit_name: String,
119+
},
120+
}
121+
95122
#[derive(Debug, Subcommand)]
96123
enum Command {
97124
/// Take a transaction lock on the repository.
@@ -114,6 +141,12 @@ enum Command {
114141
#[clap(subcommand)]
115142
cmd: OciCommand,
116143
},
144+
/// Commands for dealing with OSTree commits
145+
#[cfg(feature = "ostree")]
146+
Ostree {
147+
#[clap(subcommand)]
148+
cmd: OstreeCommand,
149+
},
117150
/// Mounts a composefs, possibly enforcing fsverity of the image
118151
Mount {
119152
/// the name of the image to mount, either a sha256 digest or prefixed with 'ref/'
@@ -311,6 +344,54 @@ async fn main() -> Result<()> {
311344
create_dir_all(state.join("etc/work"))?;
312345
}
313346
},
347+
#[cfg(feature = "ostree")]
348+
Command::Ostree { cmd: ostree_cmd } => match ostree_cmd {
349+
OstreeCommand::PullLocal {
350+
ref repo_path,
351+
ref ostree_ref,
352+
name,
353+
base_name,
354+
} => {
355+
let verity = composefs_ostree::pull_local(
356+
&Arc::new(repo),
357+
repo_path,
358+
ostree_ref,
359+
name.as_deref(),
360+
base_name.as_deref(),
361+
)
362+
.await?;
363+
364+
println!("verity {}", verity.to_hex());
365+
}
366+
OstreeCommand::Pull {
367+
ref repo_url,
368+
ref ostree_ref,
369+
name,
370+
base_name,
371+
} => {
372+
let verity = composefs_ostree::pull(
373+
&Arc::new(repo),
374+
repo_url,
375+
ostree_ref,
376+
name.as_deref(),
377+
base_name.as_deref(),
378+
)
379+
.await?;
380+
381+
println!("verity {}", verity.to_hex());
382+
}
383+
OstreeCommand::CreateImage {
384+
ref commit_name,
385+
ref image_name,
386+
} => {
387+
let mut fs = composefs_ostree::create_filesystem(&repo, commit_name)?;
388+
let image_id = fs.commit_image(&repo, image_name.as_deref())?;
389+
println!("{}", image_id.to_id());
390+
}
391+
OstreeCommand::Inspect { ref commit_name } => {
392+
composefs_ostree::inspect(&repo, commit_name)?;
393+
}
394+
},
314395
Command::ComputeId {
315396
ref path,
316397
bootable,

crates/composefs-ostree/Cargo.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[package]
2+
name = "composefs-ostree"
3+
description = "ostree support for composefs"
4+
keywords = ["composefs", "ostree"]
5+
6+
edition.workspace = true
7+
license.workspace = true
8+
readme.workspace = true
9+
repository.workspace = true
10+
rust-version.workspace = true
11+
version.workspace = true
12+
13+
[dependencies]
14+
anyhow = { version = "1.0.87", default-features = false }
15+
composefs = { workspace = true }
16+
configparser = { version = "3.1.0", features = [] }
17+
flate2 = { version = "1.1.2", default-features = true }
18+
gvariant = { version = "0.5.0", default-features = true}
19+
hex = { version = "0.4.0", default-features = false, features = ["std"] }
20+
rustix = { version = "1.0.0", default-features = false, features = ["fs", "mount", "process", "std"] }
21+
sha2 = { version = "0.10.1", default-features = false }
22+
zerocopy = { version = "0.8.0", default-features = false, features = ["derive", "std"] }
23+
reqwest = { version = "0.12.15", features = ["zstd"] }
24+
25+
[dev-dependencies]
26+
similar-asserts = "1.7.0"
27+
28+
[lints]
29+
workspace = true

0 commit comments

Comments
 (0)