diff --git a/builder/src/merge.rs b/builder/src/merge.rs index 56b0c8d3a94..6357b322661 100644 --- a/builder/src/merge.rs +++ b/builder/src/merge.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use anyhow::{anyhow, bail, ensure, Context, Result}; use hex::FromHex; use nydus_api::ConfigV2; -use nydus_rafs::metadata::{RafsSuper, RafsVersion}; +use nydus_rafs::metadata::{MergeError, RafsSuper, RafsVersion}; use nydus_storage::device::{BlobFeatures, BlobInfo}; use nydus_utils::crypt; @@ -83,6 +83,7 @@ impl Merger { target: ArtifactStorage, chunk_dict: Option, config_v2: Arc, + expected_fs_version: Option, ) -> Result { if sources.is_empty() { bail!("source bootstrap list is empty , at least one bootstrap is required"); @@ -127,7 +128,13 @@ impl Merger { sources.len(), ); } - + if let Some(expected_version) = expected_fs_version { + ensure!( + expected_version == 5 || expected_version == 6, + "invalid fs version, expected v5 or v6, found {}", + expected_version + ) + } let mut tree: Option = None; let mut blob_mgr = BlobManager::new(ctx.digester); let mut blob_idx_map = HashMap::new(); @@ -171,6 +178,14 @@ impl Merger { .check_compatibility(&rs.meta)?; fs_version = RafsVersion::try_from(rs.meta.version) .context("failed to get RAFS version number")?; + if let Some(expected_version) = expected_fs_version { + if expected_version != u32::from(fs_version) { + bail!(MergeError::InconsisentFsVersion(format!( + "Unexpected fs version, expected {:?}, actual {:?}", + expected_fs_version, fs_version + ))) + } + } ctx.compressor = rs.meta.get_compressor(); ctx.digester = rs.meta.get_digester(); // If any RAFS filesystems are encrypted, the merged boostrap will be marked as encrypted. diff --git a/src/bin/nydus-image/main.rs b/src/bin/nydus-image/main.rs index 093ee58ae16..c40c6cbf331 100644 --- a/src/bin/nydus-image/main.rs +++ b/src/bin/nydus-image/main.rs @@ -1228,6 +1228,14 @@ impl Command { .map(|item| item.trim().to_string()) .collect() }); + let expected_fs_version: Option = matches + .get_one::("expected-fs-version") + .map(|value| { + value + .parse::() + .expect("invalid number in --expected-fs-version option") + }); + let target_bootstrap_path = Self::get_bootstrap_storage(matches)?; let chunk_dict_path = if let Some(arg) = matches.get_one::("chunk-dict") { Some(parse_chunk_dict_arg(arg)?) @@ -1259,6 +1267,7 @@ impl Command { target_bootstrap_path, chunk_dict_path, config, + expected_fs_version, )?; OutputSerializer::dump(matches, output, build_info) }