@@ -66,13 +66,16 @@ def process():
66
66
leapp_efi_grubenv = os .path .join (EFI_MOUNTPOINT , LEAPP_EFIDIR_CANONICAL_PATH , 'grubenv' )
67
67
patch_efi_redhat_grubcfg_to_load_correct_grubenv ()
68
68
69
+ upgrade_bls_dir = modify_our_grubenv_to_have_separate_blsdir (leapp_efi_grubenv )
70
+
69
71
_set_bootnext (upgrade_boot_entry .boot_number )
70
72
71
73
efibootentry_fields = ['boot_number' , 'label' , 'active' , 'efi_bin_source' ]
72
74
api .produce (
73
75
ArmWorkaroundEFIBootloaderInfo (
74
76
original_entry = EFIBootEntry (** {f : getattr (current_boot_entry , f ) for f in efibootentry_fields }),
75
77
upgrade_entry = EFIBootEntry (** {f : getattr (upgrade_boot_entry , f ) for f in efibootentry_fields }),
78
+ upgrade_bls_dir = upgrade_bls_dir ,
76
79
)
77
80
)
78
81
@@ -231,3 +234,75 @@ def patch_efi_redhat_grubcfg_to_load_correct_grubenv():
231
234
shutil .copy (patched_grub2_cfg_path , leapp_grub_cfg_path )
232
235
233
236
237
+ def _list_grubenv_variables ():
238
+ try :
239
+ output_lines = run (['grub2-editenv' , 'list' ], split = True )['stdout' ]
240
+ except CalledProcessError :
241
+ raise StopActorExecutionError ('Failed to list grubenv variables used by the system' )
242
+
243
+ vars_with_values = {}
244
+ for line in output_lines :
245
+ var_with_value = line .lsplit ('=' )
246
+ if len (var_with_value ) <= 1 :
247
+ api .current_logger ().warning (
248
+ 'Skipping \' {}\' in grub2-editenv output, the line does not have the form <var>=<value>'
249
+ )
250
+ continue
251
+ vars_with_values [var_with_value [0 ]] = var_with_value [1 ]
252
+
253
+ return vars_with_values
254
+
255
+
256
+ def modify_our_grubenv_to_have_separate_blsdir (leapp_efi_grubenv_path ):
257
+ api .current_logger ().debug (
258
+ 'Setting up separate blsdir for the upgrade using grubenv: {}' .format (leapp_efi_grubenv_path )
259
+ )
260
+
261
+ grubenv_vars = _list_grubenv_variables ()
262
+ system_bls_dir = grubenv_vars .get ('blsdir' , '/boot/loader/entries' )
263
+
264
+ # Find our loader enty
265
+ try :
266
+ bls_entries = os .listdir (system_bls_dir )
267
+ except FileNotFoundError :
268
+ details = {
269
+ 'details' : 'Failed to list {}.' .format (system_bls_dir )
270
+ }
271
+ raise StopActorExecutionError ('Failed to set up bootloader for the upgrade.' , details = details )
272
+
273
+ leapp_bls_entry = None
274
+ for bls_entry in bls_entries :
275
+ if bls_entry .endswith ('upgrade.aarch64.conf' ):
276
+ leapp_bls_entry = bls_entry
277
+ break
278
+
279
+ if not leapp_bls_entry :
280
+ details = {
281
+ 'details' : 'Failed to identify BLS entry that belongs to leapp in {}' .format (system_bls_dir )
282
+ }
283
+ raise StopActorExecutionError ('Failed to set up bootloader for the upgrade.' )
284
+
285
+ # The 'blsdir' grubenv variable specifies location of bls directory relative to /boot
286
+ leapp_bls_dir_rel_to_boot = '/upgrade-loader/entries'
287
+ leapp_bls_dir = os .path .join ('/boot/' , leapp_bls_dir_rel_to_boot .lstrip ('/' ))
288
+ os .makedirs (leapp_bls_dir )
289
+ api .current_logger ().debug ('Successfully created upgrade BLS directory: {}' .format (leapp_bls_dir ))
290
+
291
+ leapp_bls_entry_fullpath = os .path .join (system_bls_dir , leapp_bls_entry )
292
+ bls_entry_dst = os .path .join (leapp_bls_dir , leapp_bls_entry )
293
+ api .current_logger ().debug (
294
+ 'Moving leapp\' s BLS entry ({}) into a separate BLS dir located at {}' .format (leapp_bls_entry , leapp_bls_dir )
295
+ )
296
+
297
+ shutil .move (leapp_bls_entry_fullpath , bls_entry_dst )
298
+
299
+ # Modify leapp's grubenv to define our own BLSDIR
300
+ try :
301
+ run (['grub2-editenv' , leapp_efi_grubenv_path , 'set' , 'blsdir="{}"' .format (leapp_bls_dir_rel_to_boot )])
302
+ except CalledProcessError as error :
303
+ details = {
304
+ 'details' : 'Failed to modify upgrade grubenv to contain a custom blsdir definition. Error {}' .format (error )
305
+ }
306
+ raise StopActorExecutionError ('Failed to set up bootloader for the upgrade.' , details = details )
307
+
308
+ return leapp_bls_dir
0 commit comments