Find the kernel in a container image root directory. This function first attempts to find a UKI in `/boot/EFI/Linux/*.efi`. If that doesn't exist, it falls back to looking for a traditional kernel layout with `/usr/lib/modules/ /vmlinuz`. Returns `None` if no kernel is found.
(root: &Dir)
| 71 | /// |
| 72 | /// Returns `None` if no kernel is found. |
| 73 | pub(crate) fn find_kernel(root: &Dir) -> Result<Option<KernelInternal>> { |
| 74 | // First, try to find a UKI |
| 75 | if let Some(uki_path) = find_uki_path(root)? { |
| 76 | let version = uki_path.file_stem().unwrap_or(uki_path.as_str()).to_owned(); |
| 77 | |
| 78 | let mut uki = root.open(&uki_path).context("Opening UKI")?; |
| 79 | |
| 80 | // Best effort to check for composefs=?verity in the UKI cmdline |
| 81 | let cmdline = composefs_boot::uki::get_section_buffered(&mut uki, ".cmdline"); |
| 82 | |
| 83 | let cmdline = match cmdline { |
| 84 | Ok(cmdline) => { |
| 85 | let cmdline_str = std::str::from_utf8(&cmdline)?; |
| 86 | Some(Cmdline::from(cmdline_str.to_owned())) |
| 87 | } |
| 88 | |
| 89 | Err(uki_error) => match uki_error { |
| 90 | composefs_boot::uki::UkiError::MissingSection(_) => { |
| 91 | // TODO(Johan-Liebert1): Check this when we have full UKI Addons support |
| 92 | // The cmdline might be in an addon, so don't allow missing verity |
| 93 | None |
| 94 | } |
| 95 | |
| 96 | e => anyhow::bail!("Failed to read UKI cmdline: {e:?}"), |
| 97 | }, |
| 98 | }; |
| 99 | |
| 100 | return Ok(Some(KernelInternal { |
| 101 | kernel: Kernel { |
| 102 | version, |
| 103 | unified: true, |
| 104 | }, |
| 105 | k_type: KernelType::Uki { |
| 106 | path: uki_path, |
| 107 | cmdline, |
| 108 | }, |
| 109 | })); |
| 110 | } |
| 111 | |
| 112 | // Fall back to checking for a traditional kernel via ostree_ext |
| 113 | if let Some(modules_dir) = ostree_ext::bootabletree::find_kernel_dir_fs(root)? { |
| 114 | let version = modules_dir |
| 115 | .file_name() |
| 116 | .ok_or_else(|| anyhow::anyhow!("kernel dir should have a file name: {modules_dir}"))? |
| 117 | .to_owned(); |
| 118 | let vmlinuz = modules_dir.join("vmlinuz"); |
| 119 | let initramfs = modules_dir.join("initramfs.img"); |
| 120 | return Ok(Some(KernelInternal { |
| 121 | kernel: Kernel { |
| 122 | version, |
| 123 | unified: false, |
| 124 | }, |
| 125 | k_type: KernelType::Vmlinuz { |
| 126 | path: vmlinuz, |
| 127 | initramfs, |
| 128 | }, |
| 129 | })); |
| 130 | } |