diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index 03eeb22172..2a8605fc6e 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -420,10 +420,13 @@ pub(crate) struct InstallComposefsOpts { impl InstallComposefsOpts { /// Check that the options fit together, once `composefs_backend` says /// whether the composefs backend is used (passed, or selected by the image). + /// `config_stateroot` comes from the install configuration and only counts + /// when `--stateroot` isn't passed. pub(crate) fn validate( &self, bootloader: Option<&Bootloader>, stateroot: Option<&str>, + config_stateroot: Option<&str>, ) -> Result<()> { if self.composefs_backend { anyhow::ensure!( @@ -436,6 +439,12 @@ impl InstallComposefsOpts { "--stateroot {stateroot} is not supported with the composefs backend, which only uses {default}" ); } + if let (None, Some(stateroot)) = (stateroot, config_stateroot.filter(|&s| s != default)) + { + anyhow::bail!( + "stateroot {stateroot} in the install configuration is not supported with the composefs backend, which only uses {default}" + ); + } } else { anyhow::ensure!( !self.allow_missing_verity, @@ -1817,9 +1826,16 @@ async fn prepare_install( )?; tracing::debug!("Composefs default: {composefs_default}"); composefs_options.composefs_backend |= composefs_required || composefs_default; + // An image may set a stateroot in its install configuration for its ostree + // installs, so only check it when the image can't be installed with ostree. + let config_stateroot = install_config + .as_ref() + .and_then(|c| c.stateroot.as_deref()) + .filter(|_| composefs_required || composefs_default); composefs_options.validate( config_opts.bootloader.as_ref(), config_opts.stateroot.as_deref(), + config_stateroot, )?; composefs_options.validate_bound_images(config_opts.bound_images, &rootfs)?; @@ -3202,7 +3218,7 @@ mod tests { uki_addon, }; assert_eq!( - opts.validate(bootloader.as_ref(), stateroot).is_ok(), + opts.validate(bootloader.as_ref(), stateroot, None).is_ok(), valid, "{opts:?} {bootloader:?} {stateroot:?}" ); @@ -3213,9 +3229,25 @@ mod tests { ..Default::default() }; assert_eq!( - opts.validate(None, Some("myroot")).unwrap_err().to_string(), + opts.validate(None, Some("myroot"), None) + .unwrap_err() + .to_string(), "--stateroot myroot is not supported with the composefs backend, which only uses default" ); + + assert!(opts.validate(None, None, Some("default")).is_ok()); + assert!(opts.validate(None, Some("default"), Some("myroot")).is_ok()); + assert!( + InstallComposefsOpts::default() + .validate(None, None, Some("myroot")) + .is_ok() + ); + assert_eq!( + opts.validate(None, None, Some("myroot")) + .unwrap_err() + .to_string(), + "stateroot myroot in the install configuration is not supported with the composefs backend, which only uses default" + ); } #[test]