@@ -25,6 +25,13 @@ use std::fs::{self, File};
25
25
use std:: io:: { BufRead , BufReader , BufWriter , Write } ;
26
26
use std:: path:: { Path , PathBuf } ;
27
27
28
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
29
+ pub ( crate ) enum Bootloader {
30
+ Grub2 ,
31
+ #[ cfg( feature = "systemd-boot" ) ]
32
+ SystemdBoot ,
33
+ }
34
+
28
35
pub ( crate ) enum ConfigMode {
29
36
None ,
30
37
Static ,
@@ -81,6 +88,25 @@ pub(crate) fn install(
81
88
anyhow:: bail!( "No components specified" ) ;
82
89
}
83
90
91
+ // If Grub2 binaries are present, use Grub2
92
+ // Else if systemd-boot EFI binaries are present, use SystemdBoot
93
+ // Else fall back to Grub2
94
+ let bootloader = if has_grub ( & source_root) {
95
+ Bootloader :: Grub2
96
+ } else if has_systemd_boot ( & source_root) {
97
+ #[ cfg( feature = "systemd-boot" ) ]
98
+ {
99
+ Bootloader :: SystemdBoot
100
+ }
101
+ #[ cfg( not( feature = "systemd-boot" ) ) ]
102
+ {
103
+ anyhow:: bail!( "systemd-boot support is not enabled in this build" ) ;
104
+ }
105
+ } else {
106
+ log:: warn!( "No bootloader binaries found, defaulting to Grub2" ) ;
107
+ Bootloader :: Grub2
108
+ } ;
109
+
84
110
let mut state = SavedState :: default ( ) ;
85
111
let mut installed_efi_vendor = None ;
86
112
for & component in target_components. iter ( ) {
@@ -93,20 +119,51 @@ pub(crate) fn install(
93
119
continue ;
94
120
}
95
121
122
+ #[ cfg( feature = "systemd-boot" ) ]
123
+ if bootloader == Bootloader :: SystemdBoot && component. name ( ) == "BIOS" {
124
+ log:: warn!( "Skip installing BIOS component when using systemd-boot" ) ;
125
+ continue ;
126
+ }
127
+
128
+ let update_firmware = match bootloader {
129
+ Bootloader :: Grub2 => update_firmware,
130
+ #[ cfg( feature = "systemd-boot" ) ]
131
+ Bootloader :: SystemdBoot => false ,
132
+ } ;
133
+
96
134
let meta = component
97
- . install ( & source_root, dest_root, device, update_firmware)
135
+ . install (
136
+ & source_root,
137
+ dest_root,
138
+ device,
139
+ update_firmware,
140
+ & bootloader,
141
+ )
98
142
. with_context ( || format ! ( "installing component {}" , component. name( ) ) ) ?;
99
143
log:: info!( "Installed {} {}" , component. name( ) , meta. meta. version) ;
100
144
state. installed . insert ( component. name ( ) . into ( ) , meta) ;
101
- // Yes this is a hack...the Component thing just turns out to be too generic.
102
- if let Some ( vendor) = component. get_efi_vendor ( & source_root) ? {
103
- assert ! ( installed_efi_vendor. is_none( ) ) ;
104
- installed_efi_vendor = Some ( vendor) ;
145
+
146
+ match bootloader {
147
+ Bootloader :: Grub2 => {
148
+ // Yes this is a hack...the Component thing just turns out to be too generic.
149
+ if let Some ( vendor) = component. get_efi_vendor ( & source_root) ? {
150
+ assert ! ( installed_efi_vendor. is_none( ) ) ;
151
+ installed_efi_vendor = Some ( vendor) ;
152
+ }
153
+ }
154
+ #[ cfg( feature = "systemd-boot" ) ]
155
+ _ => { }
105
156
}
106
157
}
107
158
let sysroot = & openat:: Dir :: open ( dest_root) ?;
108
159
109
- match configs. enabled_with_uuid ( ) {
160
+ // If systemd-boot is enabled, do not run grubconfigs::install
161
+ let configs_with_uuid = match bootloader {
162
+ Bootloader :: Grub2 => configs. enabled_with_uuid ( ) ,
163
+ #[ cfg( feature = "systemd-boot" ) ]
164
+ _ => None ,
165
+ } ;
166
+ match configs_with_uuid {
110
167
Some ( uuid) => {
111
168
let meta = get_static_config_meta ( ) ?;
112
169
state. static_configs = Some ( meta) ;
@@ -715,6 +772,16 @@ fn strip_grub_config_file(
715
772
Ok ( ( ) )
716
773
}
717
774
775
+ /// Determine whether the necessary bootloader files are present for GRUB.
776
+ fn has_grub ( source_root : & openat:: Dir ) -> bool {
777
+ source_root. open_file ( bios:: GRUB_BIN ) . is_ok ( )
778
+ }
779
+
780
+ /// Determine whether the necessary bootloader files are present for systemd-boot.
781
+ fn has_systemd_boot ( source_root : & openat:: Dir ) -> bool {
782
+ source_root. open_file ( efi:: SYSTEMD_BOOT_EFI ) . is_ok ( )
783
+ }
784
+
718
785
#[ cfg( test) ]
719
786
mod tests {
720
787
use super :: * ;
0 commit comments