diff --git a/rafs/src/metadata/mod.rs b/rafs/src/metadata/mod.rs index 0c12fc3dd88..9136bbbed66 100644 --- a/rafs/src/metadata/mod.rs +++ b/rafs/src/metadata/mod.rs @@ -656,6 +656,15 @@ impl From for u32 { } } +impl std::fmt::Display for RafsVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RafsVersion::V5 => write!(f, "5"), + RafsVersion::V6 => write!(f, "6"), + } + } +} + impl RafsVersion { /// Check whether it's RAFS v5. pub fn is_v5(&self) -> bool { diff --git a/src/bin/nydus-image/main.rs b/src/bin/nydus-image/main.rs index fbc25f4bb12..1b9a89037f8 100644 --- a/src/bin/nydus-image/main.rs +++ b/src/bin/nydus-image/main.rs @@ -74,6 +74,10 @@ pub struct OutputSerializer { blobs: Vec, /// Performance trace info for current build. trace: serde_json::Map, + /// RAFS filesystem version (5 or 6). + fs_version: String, + /// Chunk compression algorithm. + compressor: String, } impl OutputSerializer { @@ -81,6 +85,8 @@ impl OutputSerializer { matches: &ArgMatches, build_output: BuildOutput, build_info: &BuildTimeInfo, + compressor: compress::Algorithm, + fs_version: RafsVersion, ) -> Result<()> { let output_json: Option = matches .get_one::("output-json") @@ -100,6 +106,8 @@ impl OutputSerializer { bootstrap: build_output.bootstrap_path.unwrap_or_default(), blobs: build_output.blobs, trace, + fs_version: fs_version.to_string(), + compressor: compressor.to_string(), }; serde_json::to_writer_pretty(w, &output) @@ -114,6 +122,8 @@ impl OutputSerializer { build_info: &BuildTimeInfo, blob_ids: Vec, bootstrap: &Path, + compressor: compress::Algorithm, + fs_version: RafsVersion, ) -> Result<()> { let output_json: Option = matches .get_one::("output-json") @@ -133,6 +143,8 @@ impl OutputSerializer { bootstrap: bootstrap.display().to_string(), blobs: blob_ids, trace, + fs_version: fs_version.to_string(), + compressor: compressor.to_string(), }; serde_json::to_writer(w, &output).context("failed to write result to output file")?; @@ -1179,7 +1191,7 @@ impl Command { event_tracer!("euid", "{}", geteuid()); event_tracer!("egid", "{}", getegid()); info!("successfully built RAFS filesystem: \n{}", build_output); - OutputSerializer::dump(matches, build_output, build_info) + OutputSerializer::dump(matches, build_output, build_info, compressor, version) } fn chunkdict_save(matches: &ArgMatches) -> Result<()> { @@ -1271,6 +1283,9 @@ impl Command { ctx.configuration = config.clone(); let parent_bootstrap_path = Self::get_parent_bootstrap(matches)?; + let meta = RafsSuper::load_from_file(&source_bootstrap_paths[0], config.clone(), false)? + .0 + .meta; let output = Merger::merge( &mut ctx, @@ -1285,7 +1300,13 @@ impl Command { chunk_dict_path, config, )?; - OutputSerializer::dump(matches, output, build_info) + OutputSerializer::dump( + matches, + output, + build_info, + meta.get_compressor(), + meta.version.try_into().unwrap(), + ) } fn compact(matches: &ArgMatches, build_info: &BuildTimeInfo) -> Result<()> { @@ -1319,10 +1340,12 @@ impl Command { let config = serde_json::from_reader(file) .with_context(|| format!("invalid config file {}", config_file_path))?; + let version = rs.meta.version.try_into().unwrap(); + let compressor = rs.meta.get_compressor(); if let Some(build_output) = BlobCompactor::compact(rs, dst_bootstrap, chunk_dict, backend, &config)? { - OutputSerializer::dump(matches, build_output, build_info)?; + OutputSerializer::dump(matches, build_output, build_info, compressor, version)?; } Ok(()) } @@ -1380,7 +1403,7 @@ impl Command { .set_blob_accessible(matches.get_one::("bootstrap").is_none()); let mut validator = Validator::new(bootstrap_path, config)?; - let blobs = validator + let (blobs, compressor, fs_version) = validator .check(verbose) .with_context(|| format!("failed to check bootstrap {:?}", bootstrap_path))?; @@ -1400,7 +1423,14 @@ impl Command { blob_ids.push(blob.blob_id().to_string()); } - OutputSerializer::dump_for_check(matches, build_info, blob_ids, bootstrap_path)?; + OutputSerializer::dump_for_check( + matches, + build_info, + blob_ids, + bootstrap_path, + compressor, + fs_version, + )?; Ok(()) } diff --git a/src/bin/nydus-image/validator.rs b/src/bin/nydus-image/validator.rs index 3df6a771836..95e8355c277 100644 --- a/src/bin/nydus-image/validator.rs +++ b/src/bin/nydus-image/validator.rs @@ -10,8 +10,9 @@ use std::sync::Arc; use anyhow::{Context, Result}; use nydus_api::ConfigV2; use nydus_builder::Tree; -use nydus_rafs::metadata::RafsSuper; +use nydus_rafs::metadata::{RafsSuper, RafsVersion}; use nydus_storage::device::BlobInfo; +use nydus_utils::compress; pub struct Validator { sb: RafsSuper, @@ -24,7 +25,10 @@ impl Validator { Ok(Self { sb }) } - pub fn check(&mut self, verbosity: bool) -> Result>> { + pub fn check( + &mut self, + verbosity: bool, + ) -> Result<(Vec>, compress::Algorithm, RafsVersion)> { let err = "failed to load bootstrap for validator"; let tree = Tree::from_bootstrap(&self.sb, &mut ()).context(err)?; @@ -39,7 +43,13 @@ impl Validator { Ok(()) }; tree.walk_dfs_pre(pre)?; - - Ok(self.sb.superblock.get_blob_infos()) + let compressor = self.sb.meta.get_compressor(); + let rafs_version: RafsVersion = self.sb.meta.version.try_into().unwrap(); + + Ok(( + self.sb.superblock.get_blob_infos(), + compressor, + rafs_version, + )) } }