diff --git a/src/bios.rs b/src/bios.rs index a3fb23fc..481fff16 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -122,16 +122,22 @@ impl Component for Bios { } fn query_adopt(&self) -> Result> { - Ok(None) + crate::component::query_adopt_state() } - #[allow(unused_variables)] - fn adopt_update( - &self, - sysroot: &openat::Dir, - update: &ContentMetadata, - ) -> Result { - todo!(); + fn adopt_update(&self, _: &openat::Dir, update: &ContentMetadata) -> Result { + let Some(meta) = self.query_adopt()? else { + anyhow::bail!("Failed to find adoptable system") + }; + + let device = self.get_device()?; + let device = device.trim(); + self.run_grub_install("/", device)?; + Ok(InstalledContent { + meta: update.clone(), + filetree: None, + adopted_from: Some(meta.version), + }) } fn query_update(&self, sysroot: &openat::Dir) -> Result> { diff --git a/src/component.rs b/src/component.rs index 65be68d1..dfff20d5 100644 --- a/src/component.rs +++ b/src/component.rs @@ -144,6 +144,38 @@ pub(crate) fn get_component_update( } } +#[context("Querying adoptable state")] +pub(crate) fn query_adopt_state() -> Result> { + // This would be extended with support for other operating systems later + if let Some(coreos_aleph) = crate::coreos::get_aleph_version(Path::new("/"))? { + let meta = ContentMetadata { + timestamp: coreos_aleph.ts, + version: coreos_aleph.aleph.version, + }; + log::trace!("Adoptable: {:?}", &meta); + return Ok(Some(Adoptable { + version: meta, + confident: true, + })); + } else { + log::trace!("No CoreOS aleph detected"); + } + let ostree_deploy_dir = Path::new("/ostree/deploy"); + if ostree_deploy_dir.exists() { + let btime = ostree_deploy_dir.metadata()?.created()?; + let timestamp = chrono::DateTime::from(btime); + let meta = ContentMetadata { + timestamp, + version: "unknown".to_string(), + }; + return Ok(Some(Adoptable { + version: meta, + confident: true, + })); + } + Ok(None) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/efi.rs b/src/efi.rs index ed53e854..75c34f4c 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -179,7 +179,7 @@ fn string_from_utf16_bytes(slice: &[u8]) -> String { fn read_efi_var_utf16_string(name: &str) -> Option { let efivars = Path::new("/sys/firmware/efi/efivars"); if !efivars.exists() { - log::warn!("No efivars mount at {:?}", efivars); + log::trace!("No efivars mount at {:?}", efivars); return None; } let path = efivars.join(name); @@ -239,39 +239,13 @@ impl Component for Efi { log::trace!("No ESP detected"); return Ok(None); }; - // This would be extended with support for other operating systems later - if let Some(coreos_aleph) = crate::coreos::get_aleph_version(Path::new("/"))? { - let meta = ContentMetadata { - timestamp: coreos_aleph.ts, - version: coreos_aleph.aleph.version, - }; - log::trace!("EFI adoptable: {:?}", &meta); - return Ok(Some(Adoptable { - version: meta, - confident: true, - })); - } else { - log::trace!("No CoreOS aleph detected"); - } + // Don't adopt if the system is booted with systemd-boot or // systemd-stub since those will be managed with bootctl. if skip_systemd_bootloaders() { return Ok(None); } - let ostree_deploy_dir = Path::new("/ostree/deploy"); - if ostree_deploy_dir.exists() { - let btime = ostree_deploy_dir.metadata()?.created()?; - let timestamp = chrono::DateTime::from(btime); - let meta = ContentMetadata { - timestamp, - version: "unknown".to_string(), - }; - return Ok(Some(Adoptable { - version: meta, - confident: true, - })); - } - Ok(None) + crate::component::query_adopt_state() } /// Given an adoptable system and an update, perform the update. @@ -280,10 +254,8 @@ impl Component for Efi { sysroot: &openat::Dir, updatemeta: &ContentMetadata, ) -> Result { - let meta = if let Some(meta) = self.query_adopt()? { - meta - } else { - anyhow::bail!("Failed to find adoptable system"); + let Some(meta) = self.query_adopt()? else { + anyhow::bail!("Failed to find adoptable system") }; let esp = self.open_esp()?; diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index 0956bdfa..a3577533 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -84,6 +84,13 @@ if test -s out.txt; then fi ok update not avail +mount -o remount,rw /boot +rm -f /boot/bootupd-state.json +bootupctl adopt-and-update | tee out.txt +assert_file_has_content out.txt "Adopted and updated: BIOS: .*" +assert_file_has_content out.txt "Adopted and updated: EFI: .*" +ok adopt-and-update + tap_finish touch /run/testtmp/success sync