11# oci-utils
22#
3- # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
3+ # Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
44# Licensed under the Universal Permissive License v 1.0 as shown
55# at http://oss.oracle.com/licenses/upl.
66
3030from oci_utils .migrate import terminal_dimension
3131from oci_utils .migrate .exception import OciMigrateException
3232from oci_utils .migrate .migrate_tools import get_config_data
33+ from pprint import pformat
3334
3435_logger = logging .getLogger ('oci-utils.imgdevice' )
3536
@@ -433,7 +434,8 @@ def handle_image(self):
433434 self .update_image ()
434435 return True
435436 except Exception as e :
436- _logger .critical (' Image %s handling failed: %s' , self .image_info ['img_name' ], str (e ), exc_info = True )
437+ _logger .debug (' Image %s handling failed: %s' , self .image_info ['img_name' ], str (e ), exc_info = True )
438+ _logger .critical ('\n Image %s handling failed: %s' , self .image_info ['img_name' ], str (e ))
437439 return False
438440 finally :
439441 _ , nbcols = terminal_dimension ()
@@ -958,8 +960,7 @@ def find_uuid_partition(uuid_part):
958960 """
959961 part_p = 'na'
960962 mount_p = 'na'
961- for partition , partdata in list (
962- self .image_info ['partitions' ].items ()):
963+ for partition , partdata in list (self .image_info ['partitions' ].items ()):
963964 if self .skip_partition (partdata ):
964965 _logger .debug ('Skipping %s' , partition )
965966 elif 'ID_FS_UUID' in list (partdata .keys ()):
@@ -1072,6 +1073,7 @@ def find_mapper_partition(mapper_part):
10721073 def get_grub_data (self , loopdir ):
10731074 """
10741075 Collect data related to boot and grub.
1076+
10751077 Parameters:
10761078 ----------
10771079 loopdir: str
@@ -1107,9 +1109,39 @@ def find_grub_config_file():
11071109 _logger .debug ('No grub config file in %s' , grubroot )
11081110 return grub_path
11091111
1112+ def find_boot_loader_entries_dir ():
1113+ """
1114+ Verify if the directory /boot/loader/entries exists and contains files.
1115+
1116+ Returns
1117+ -------
1118+ str: the path of the boot loader entries.
1119+ """
1120+ _logger .debug ('__ Looking for /boot/loader/entries' )
1121+ boot_loader_entries = os .path .join (loopdir , 'boot/loader/entries' )
1122+ if os .path .exists (boot_loader_entries ):
1123+ if os .listdir (boot_loader_entries ):
1124+ return boot_loader_entries
1125+ return None
1126+
1127+ def find_grubenv_dir ():
1128+ """
1129+ Verify if the grubenv file exists.
1130+
1131+ Returns
1132+ -------
1133+ str: the path of the grubenv file.
1134+ """
1135+ _logger .debug ('__ Looking for /boot/grub2/grubenv' )
1136+ grubenvpath = os .path .join (loopdir , 'boot/grub2/grubenv' )
1137+ if os .path .exists (grubenvpath ):
1138+ return grubenvpath
1139+ return None
1140+
11101141 def find_efi_boot_config ():
11111142 """
11121143 Find out if the image is using BIOS or UEFI boot.
1144+
11131145 Returns
11141146 -------
11151147 str: [BIOS|UEFI]
@@ -1146,57 +1178,113 @@ def find_efi_boot_config():
11461178 raise OciMigrateException ('No grub config file found in %s' % self ._fn )
11471179 result_msg (msg = 'Grub config file: %s' % grub_cfg_path , result = False )
11481180 #
1181+ # verify if a boot loader entries is present
1182+ boot_loader_entries_path = find_boot_loader_entries_dir ()
1183+ grub_env_path = find_grubenv_dir ()
1184+ #
11491185 # investigate boot type
11501186 self .image_info ['boot_type' ] = find_efi_boot_config ()
11511187 result_msg (msg = 'Image boot type: %s' % self .image_info ['boot_type' ])
11521188 #
11531189 # get grub config contents
11541190 grubdata = list ()
11551191 grub2 = False
1192+ grubby = True if boot_loader_entries_path else False
11561193 grubentry = dict ()
11571194 grubefi = dict ()
11581195 kernelversion = '0'
11591196 kernellist = list ()
11601197 _logger .debug ('Initialised grub structure' )
1161- try :
1162- #
1163- # check for grub2 data
1164- mentry = False
1165- with open (grub_cfg_path , 'r' ) as f :
1166- for ffsline in f :
1167- fsline = ffsline .strip ()
1168- fsline_split = re .split ('[ "]' , fsline )
1169- if bool (fsline .split ()):
1170- _logger .debug ('%s' , fsline )
1171- if fsline_split [0 ] == 'menuentry' :
1172- mentry = True
1173- grub2 = True
1174- if grubentry :
1175- grubdata .append (grubentry )
1176- grubentry = {'menuentry' : [fsline ]}
1177- _logger .debug ('grub line: %s' , fsline )
1178- elif fsline_split [0 ] == 'search' :
1179- if mentry :
1180- grubentry ['menuentry' ].append (fsline )
1181- _logger .debug ('Grub line: %s' , grubentry ['menuentry' ])
1198+
1199+ if not grubby :
1200+ try :
1201+ #
1202+ # check for grub2 data
1203+ mentry = False
1204+ with open (grub_cfg_path , 'r' ) as f :
1205+ for ffsline in f :
1206+ fsline = ffsline .strip ()
1207+ fsline_split = re .split ('[ "]' , fsline )
1208+ if bool (fsline .split ()):
1209+ _logger .debug ('%s' , fsline )
1210+ if fsline_split [0 ] == 'menuentry' :
1211+ mentry = True
1212+ grub2 = True
1213+ if grubentry :
1214+ grubdata .append (grubentry )
1215+ grubentry = {'menuentry' : [fsline ]}
1216+ _logger .debug ('grub line: %s' , fsline )
1217+ elif fsline_split [0 ] == 'search' :
1218+ if mentry :
1219+ grubentry ['menuentry' ].append (fsline )
1220+ _logger .debug ('Grub line: %s' , grubentry ['menuentry' ])
1221+ else :
1222+ _logger .debug ('Not a menuentry, skipping %s' , fsline )
1223+ elif fsline_split [0 ] == 'set' :
1224+ if 'default_kernelopts' in fsline_split [1 ]:
1225+ grubefi = {'grubefi' : [fsline ]}
1226+ _logger .debug ('efi line: %s' , fsline )
11821227 else :
1183- _logger .debug ('Not a menuentry, skipping %s' , fsline )
1184- elif fsline_split [0 ] == 'set' :
1185- if 'default_kernelopts' in fsline_split [1 ]:
1186- grubefi = {'grubefi' : [fsline ]}
1187- _logger .debug ('efi line: %s' , fsline )
1188- else :
1189- _logger .debug ('Skipping %s' , fsline )
1190- if bool (grubentry ):
1191- grubdata .append (grubentry )
1192- if bool (grubefi ):
1193- grubdata .append (grubefi )
1194- except Exception as e :
1195- _logger .error (' Errors during reading %s: %s' , grub_cfg_path , str (e ))
1196- raise OciMigrateException ('Errors during reading %s:' % grub_cfg_path ) from e
1197- if grub2 :
1228+ _logger .debug ('Skipping %s' , fsline )
1229+ if bool (grubentry ):
1230+ grubdata .append (grubentry )
1231+ if bool (grubefi ):
1232+ grubdata .append (grubefi )
1233+ except Exception as e :
1234+ _logger .error (' Errors during reading %s: %s' , grub_cfg_path , str (e ))
1235+ raise OciMigrateException ('Errors during reading %s:' % grub_cfg_path ) from e
1236+
1237+ if grubby :
1238+ _logger .debug ('Found /boot/loader/entries' )
1239+ result_msg (msg = 'Found /boot/loader/entries directory.' , result = False )
1240+ #
1241+ # find all kernels defined in loader entries directory.
1242+ kernellist = system_tools .get_grubby_kernels (boot_loader_entries_path )
1243+ _logger .debug ('Kernels defined in boot laoder entries: %s' , kernellist )
1244+ if grub_env_path :
1245+ kernelversion = system_tools .get_grubby_default_kernel (grub_env_path )
1246+ _logger .debug ('Default kernel: %s' , kernelversion )
1247+ kernelopts = ''
1248+ try :
1249+ # find kernel options
1250+ with open (grub_cfg_path , 'r' ) as f :
1251+ for ffsline in f :
1252+ fsline = ffsline .strip ()
1253+ fsline_split = re .split ('[ "]' , fsline )
1254+ if bool (fsline .split ()):
1255+ if fsline_split [0 ] == 'set' :
1256+ if 'kernelopts' in fsline_split [1 ]:
1257+ kernelopts = ' ' .join (fsline_split [1 :])
1258+ break
1259+ for _ , _ , files in os .walk (boot_loader_entries_path ):
1260+ for name in files :
1261+ with open (os .path .join (boot_loader_entries_path , name ), 'r' ) as f :
1262+ for ffsline in f :
1263+ fsline = ffsline .strip ()
1264+ if len (fsline ) > 0 :
1265+ _logger .debug ('%s' , fsline )
1266+ if fsline .split ()[0 ] == 'title' :
1267+ if grubentry :
1268+ grubdata .append (grubentry )
1269+ grubentry = {'title' : [fsline ]}
1270+ _logger .debug ('grub line: %s' , fsline )
1271+ elif fsline .split ()[0 ] == 'linux' :
1272+ grubentry ['title' ].append (fsline )
1273+ _logger .debug ('grub line: %s' , grubentry ['title' ])
1274+ else :
1275+ _logger .debug ('skipping %s' , fsline )
1276+ if grubentry :
1277+ if kernelopts :
1278+ grubentry ['title' ].append (kernelopts )
1279+ grubdata .append (grubentry )
1280+
1281+ except Exception as e :
1282+ _logger .error (' Errors during reading %s: %s' , boot_loader_entries_path , str (e ))
1283+ raise OciMigrateException ('Errors during reading %s:' % boot_loader_entries_path ) from e
1284+
1285+ elif grub2 :
11981286 _logger .debug ('Found grub2 configuration file.' )
1199- result_msg (msg = 'Found grub2 configuration file' , result = False )
1287+ result_msg (msg = 'Found grub2 configuration file. ' , result = False )
12001288 #
12011289 # find all kernels defined in grub(1) config file.
12021290 kernellist = system_tools .get_grub2_kernels (grub_cfg_path )
@@ -1237,6 +1325,9 @@ def find_efi_boot_config():
12371325 _logger .error (' Errors during reading %s: %s' , grub_cfg_path , str (e ))
12381326 raise OciMigrateException ('Errors during reading %s:' % grub_cfg_path ) from e
12391327
1328+ _logger .debug ('grubdata:\n %s' , pformat (grubdata , indent = 4 ))
1329+ _logger .debug ('kernellist\n %s' , pformat (kernellist , indent = 4 ))
1330+ _logger .debug ('kernelversion\n %s' , kernelversion )
12401331 return grubdata , kernelversion , kernellist
12411332
12421333 def get_os_release (self ):
@@ -1459,23 +1550,25 @@ def generic_prereq_check(self):
14591550 msg = 'grub2 line ->%s<- specifies boot partition via UUID.' % le )
14601551 elif l_split [0 ] == 'kernel' :
14611552 grub_l += 1
1462- if len ([a for a in l_split
1463- if any (b in a for b in ['root=UUID=' , 'root=/dev/mapper/' ])]) == 0 :
1464- _logger .debug ('grub line ->%s<- does not specify boot partition via '
1465- 'UUID nor LVM2.' , le )
1553+ if len ([a for a in l_split if any (b in a for b in ['root=UUID=' , 'root=/dev/mapper/' ])]) == 0 :
1554+ _logger .debug ('grub line ->%s<- does not specify boot partition via UUID nor LVM2.' , le )
14661555 grub_fail += 1
14671556 else :
1468- result_msg (msg = 'grub line ->%s<- specifies boot partition via UUID or LVM2.'
1469- % le , result = True )
1557+ result_msg (msg = 'grub line ->%s<- specifies boot partition via UUID or LVM2.' % le ,)
14701558 elif 'default_kernelopts' in l_split [1 ]:
14711559 grub_l += 1
1472- if len ([a for a in l_split
1473- if any (b in a for b in ['root=UUID=' , 'root=/dev/mapper/' ])]) == 0 :
1560+ if len ([a for a in l_split if any (b in a for b in ['root=UUID=' , 'root=/dev/mapper/' ])]) == 0 :
1561+ _logger .debug ('grub line ->%s<- does not specify boot partition via UUID nor LVM2.' , le )
1562+ grub_fail += 1
1563+ else :
1564+ result_msg (msg = 'grub line ->%s<- specifies boot partition via UUID or LVM2.' % le )
1565+ elif l_split [0 ] == 'kernelopts=' :
1566+ grub_l += 1
1567+ if len ([a for a in l_split if any (b in a for b in ['root=UUID=' , 'root=/dev/mapper/' ])]) == 0 :
14741568 _logger .debug ('grub line ->%s<- does not specify boot partition via UUID nor LVM2.' , le )
14751569 grub_fail += 1
14761570 else :
1477- result_msg (msg = 'grub line ->%s<- specifies boot partition via UUID or LVM2.'
1478- % le , result = True )
1571+ result_msg (msg = 'grub line ->%s<- specifies boot partition via UUID or LVM2.' % le )
14791572 else :
14801573 _logger .debug ('skipping %s' , l_split )
14811574 if grub_l == 0 :
@@ -1486,6 +1579,7 @@ def generic_prereq_check(self):
14861579 failmsg += '\n - grub config file does not guarantee booting using UUID or LVM2.'
14871580 else :
14881581 _logger .debug ('Grub config file ok.' )
1582+ result_msg (msg = 'Grub config file ok.' , result = True )
14891583 else :
14901584 passed_requirement = False
14911585 failmsg += '\n - Grub config file not found.'
0 commit comments