@@ -10,7 +10,9 @@ use camino::Utf8Path;
1010use cap_std_ext:: cap_std;
1111use cap_std_ext:: cap_std:: fs:: Dir ;
1212use composefs:: dumpfile;
13- use composefs:: fsverity:: { Algorithm , FsVerityHashValue } ;
13+ use composefs:: erofs:: format:: FormatVersion ;
14+ use composefs:: fsverity:: FsVerityHashValue ;
15+ use composefs:: repository:: RepositoryConfig ;
1416use composefs_boot:: BootOps as _;
1517use composefs_ctl:: composefs;
1618use composefs_ctl:: composefs_boot;
@@ -20,21 +22,26 @@ use crate::store::ComposefsRepository;
2022
2123/// Creates a temporary composefs repository for computing digests.
2224///
25+ /// The `erofs_version` controls which EROFS format the digest is computed for:
26+ /// use `FormatVersion::V1` to get a `composefs.digest.v1=` karg (V1 EROFS, C-tool
27+ /// compatible) or `FormatVersion::V2` for the legacy `composefs=` karg.
28+ ///
2329/// Returns the TempDir guard (must be kept alive for the repo to remain valid)
2430/// and the repository wrapped in Arc.
2531#[ fn_error_context:: context( "Creating new temp composefs repo" ) ]
26- pub ( crate ) fn new_temp_composefs_repo ( ) -> Result < ( TempDir , Arc < ComposefsRepository > ) > {
32+ pub ( crate ) fn new_temp_composefs_repo (
33+ erofs_version : FormatVersion ,
34+ ) -> Result < ( TempDir , Arc < ComposefsRepository > ) > {
2735 let td_guard = tempfile:: tempdir_in ( "/var/tmp" ) ?;
2836 let td_path = td_guard. path ( ) ;
2937 let td_dir = Dir :: open_ambient_dir ( td_path, cap_std:: ambient_authority ( ) ) ?;
3038
3139 td_dir. create_dir ( "repo" ) ?;
3240 let repo_dir = td_dir. open_dir ( "repo" ) ?;
33- let ( mut repo, _created) =
34- ComposefsRepository :: init_path ( & repo_dir, "." , Algorithm :: SHA512 , false )
35- . context ( "Init cfs repo" ) ?;
36- // We don't need to hard require verity on the *host* system, we're just computing a checksum here
37- repo. set_insecure ( ) ;
41+ let mut config = RepositoryConfig :: new ( composefs:: fsverity:: Algorithm :: SHA512 ) . set_insecure ( ) ;
42+ config. erofs_formats = composefs:: erofs:: format:: FormatConfig :: single ( erofs_version) ;
43+ let ( repo, _created) =
44+ ComposefsRepository :: init_path ( & repo_dir, "." , config) . context ( "Init cfs repo" ) ?;
3845 Ok ( ( td_guard, Arc :: new ( repo) ) )
3946}
4047
@@ -58,13 +65,14 @@ pub(crate) fn new_temp_composefs_repo() -> Result<(TempDir, Arc<ComposefsReposit
5865#[ fn_error_context:: context( "Computing composefs digest" ) ]
5966pub ( crate ) async fn compute_composefs_digest (
6067 path : & Utf8Path ,
68+ erofs_version : FormatVersion ,
6169 write_dumpfile_to : Option < & Utf8Path > ,
6270) -> Result < String > {
6371 if path. as_str ( ) == "/" {
6472 anyhow:: bail!( "Cannot operate on active root filesystem; mount separate target instead" ) ;
6573 }
6674
67- let ( _td_guard, repo) = new_temp_composefs_repo ( ) ?;
75+ let ( _td_guard, repo) = new_temp_composefs_repo ( erofs_version ) ?;
6876
6977 // Read filesystem from path, transform for boot, compute digest
7078 let dirfd: OwnedFd = rustix:: fs:: open (
@@ -81,7 +89,7 @@ pub(crate) async fn compute_composefs_digest(
8189 . await
8290 . context ( "Reading container root" ) ?;
8391 fs. transform_for_boot ( & repo) . context ( "Preparing for boot" ) ?;
84- let id = fs. compute_image_id ( ) ;
92+ let id = fs. compute_image_id ( erofs_version ) ;
8593 let digest = id. to_hex ( ) ;
8694
8795 if let Some ( dumpfile_path) = write_dumpfile_to {
@@ -135,7 +143,9 @@ mod tests {
135143
136144 // Compute the digest
137145 let path = Utf8Path :: from_path ( td. path ( ) ) . unwrap ( ) ;
138- let digest = compute_composefs_digest ( path, None ) . await . unwrap ( ) ;
146+ let digest = compute_composefs_digest ( path, FormatVersion :: V2 , None )
147+ . await
148+ . unwrap ( ) ;
139149
140150 // Verify it's a valid hex string of expected length (SHA-512 = 128 hex chars)
141151 assert_eq ! (
@@ -150,7 +160,9 @@ mod tests {
150160 ) ;
151161
152162 // Verify consistency - computing twice on the same filesystem produces the same result
153- let digest2 = compute_composefs_digest ( path, None ) . await . unwrap ( ) ;
163+ let digest2 = compute_composefs_digest ( path, FormatVersion :: V2 , None )
164+ . await
165+ . unwrap ( ) ;
154166 assert_eq ! (
155167 digest, digest2,
156168 "Digest should be consistent across multiple computations"
@@ -159,7 +171,7 @@ mod tests {
159171
160172 #[ tokio:: test]
161173 async fn test_compute_composefs_digest_rejects_root ( ) {
162- let result = compute_composefs_digest ( Utf8Path :: new ( "/" ) , None ) . await ;
174+ let result = compute_composefs_digest ( Utf8Path :: new ( "/" ) , FormatVersion :: V2 , None ) . await ;
163175 assert ! ( result. is_err( ) ) ;
164176 let err = result. unwrap_err ( ) ;
165177 let found = err. chain ( ) . any ( |e| {
0 commit comments