def FindBootKernels(cls): Tools.Print("Scanning " + config.kernelDirectory + " ...") # Check to see if our boot directory exists before starting if not os.path.exists(config.kernelDirectory): Tools.Print("The " + config.kernelDirectory + " directory doesn't exist. Creating ...") os.mkdir(config.kernelDirectory) if os.path.exists(config.kernelDirectory): Tools.Warn("Please place your kernels inside " + config.kernelDirectory + "/<version>, configure " + ConfigLoader.GetConfigFilePath() + ", and then re-run the program. \n\nExample:\n\n" + config.kernelDirectory + "/3.12.12-KS.01/{vmlinuz, initrd}") quit(1) else: Tools.Fail(config.kernelDirectory + " directory doesn't exist") cmd = 'ls ' + config.kernelDirectory results = check_output(["ls", config.kernelDirectory], universal_newlines=True).strip() # Add kernels to out kernel set if results: for i in results.split("\n"): cls._bootKernels.append(i) else: Tools.Fail("No kernels found in " + config.kernelDirectory + ". A directory for each kernel you want must exist " + "in that location.\n\nExample:\n\n" + config.kernelDirectory + "/3.13.5-KS.01/\n" + config.kernelDirectory + "/3.14.27-KS.01/\n")
def CreateOutputDirectory(cls, vParentDirectory): if not os.path.exists(vParentDirectory): os.makedirs(vParentDirectory) if not os.path.exists(vParentDirectory): Tools.Fail("Unable to create the " + vParentDirectory + " directory ...")
def ScanFstab(cls): cmd = 'cat /etc/fstab | grep /boot[[:blank:]] | awk \'{print $1, $2, $3, $4, $5, $6}\'' results = check_output(cmd, shell=True, universal_newlines=True).strip() if results: # Split the /boot line so we can store it splits = results.split(" ") # Save fstab /boot drive info for x in splits: cls._fstabValues.append(x.strip()) else: Tools.Fail("/boot line could not be found in /etc/fstab")
def StripHead(cls, vPath): if vPath: splinters = vPath.split("/") srange = len(splinters) if srange >= 3: news = "" for i in range(len(splinters))[2:]: news = news + "/" + splinters[i] return news elif srange == 2: # if two then that means we will be looking in that folder specifically for kernels # so just return / return "/" else: Tools.Fail("The value to strip is empty ...")
def WriteEntries(cls): outputFile = "" driveLayout = Scanner.GetDriveLayout() isOutput = Tools.IsOutputSet() if isOutput: outputFile = Tools.GetOutputFile() # Check to see if the directory for this file exists. If it doesn't # create any directories leading up to the output file so that we don't # get a "FileNotFoundError" later on outputFileFullPath = os.path.abspath(outputFile) outputFileParentDir = os.path.dirname(outputFileFullPath) if not os.path.exists(outputFileParentDir): cls.CreateOutputDirectory(outputFileParentDir) elif not isOutput and config.bootloader == "grub2": outputFile = "grub.cfg" elif not isOutput and config.bootloader == "extlinux": outputFile = "extlinux.conf" # Check to see what's the bootloader before we start adding # all the entries, depending the bootloader we can cleanly start # adding generic information like default kernel, timeouts, etc position = Scanner.FindDefaultKernel() if position != -1: if config.bootloader == "grub2": Tools.Print("Generating GRUB 2 configuration ...") bootdrive = Scanner.GetGrub2BootDrive() if os.path.exists(outputFile): if Tools.IsForceSet(): dossier = open(outputFile, "w") else: Tools.Fail("Target file: " + outputFile + " already exists. Pass -f to overwrite.") else: dossier = open(outputFile, "w") dossier.write("set timeout=" + str(config.timeout) + "\n") dossier.write("set default=" + str(position) + "\n") dossier.write("\n") # Write the modules that need to be inserted depending # drive style. For whole disk zfs, none will be returned # since a person can partition the drive manually and use msdos, # or they can let zfs format their drive automatically with # gpt. This ambiguity will be the reason both grub modules will # be inserted. if driveLayout == "gpt": dossier.write("insmod part_gpt\n") elif driveLayout == "msdos": dossier.write("insmod part_msdos\n") elif driveLayout == "none": dossier.write("insmod part_gpt\n") dossier.write("insmod part_msdos\n") if config.efi: dossier.write("insmod efi_gop\n") dossier.write("insmod efi_uga\n") dossier.write("insmod fat\n") if config.wholeDiskZfs: dossier.write("insmod zfs\n") if config.goodyBag: for candy in config.goodyBag: dossier.write("insmod " + candy + "\n") if not config.wholeDiskZfs: dossier.write("\nset root='" + bootdrive + "'\n") dossier.write("\n") dossier.close() elif config.bootloader == "extlinux": Tools.Print("Generating extlinux configuration ...") # Gets the name of the default kernel defaultKernelLabel = Scanner.GetKernel(position)[0] if os.path.exists(outputFile): if Tools.IsForceSet(): dossier = open(outputFile, "w") else: Tools.Fail("Target file: " + outputFile + " already exists. Pass -f to overwrite.") else: dossier = open(outputFile, "w") dossier.write("TIMEOUT " + str(int(config.timeout * 10)) + "\n") if not config.extlinuxAutoBoot: dossier.write("UI " + config.extlinuxUi + "\n") dossier.write("\n") dossier.write("DEFAULT " + defaultKernelLabel + str(position) + "\n\n") dossier.write("MENU TITLE " + config.extlinuxMenuTitle + "\n") dossier.write("MENU COLOR title " + config.extlinuxTitleColor + "\n") dossier.write("MENU COLOR border " + config.extlinuxBorderColor + "\n") dossier.write("MENU COLOR unsel " + config.extlinuxUnselectedColor + "\n") dossier.write("\n") dossier.close() else: Tools.Fail("The bootloader defined in " + ConfigLoader.GetConfigFilePath() + " is not supported.") else: Tools.Fail("The default kernel entry in " + ConfigLoader.GetConfigFilePath() + " was not found in " + config.kernelDirectory) # Add all our desired kernels for kernel in Scanner.GetCommonKernels(): # Get the position so that we can create the labels correctly position = Scanner.GetKernelIndexInCommonList(kernel) Tools.Warn("Adding: " + kernel[0] + " - " + kernel[1]) cs = cls.StripHead(config.kernelDirectory) kernelPath = cs + "/" + kernel[1] # Depending the bootloader we have specified, generate # its appropriate configuration. if config.bootloader == "grub2": # Open it in append mode since the header was previously # created before. dossier = open(outputFile, "a") dossier.write("menuentry \"" + kernel[0] + " - " + kernel[1] + "\" {\n") if config.wholeDiskZfs: dossier.write("\tlinux " + bootdrive + "/@" + kernelPath + "/" + kernel[3] + " " + kernel[5] + "\n") if config.useInitrd: dossier.write("\tinitrd " + bootdrive + "/@" + kernelPath + "/" + kernel[4] + "\n") else: dossier.write("\tlinux " + kernelPath + "/" + kernel[3] + " " + kernel[5] + "\n") if config.useInitrd: dossier.write("\tinitrd " + kernelPath + "/" + kernel[4] + "\n") dossier.write("}\n\n") dossier.close() elif config.bootloader == "extlinux": dossier = open(outputFile, "a") dossier.write("LABEL " + kernel[0] + str(position) + "\n") dossier.write("\tMENU LABEL " + kernel[0] + " - " + kernel[1] + "\n") dossier.write("\tLINUX " + kernelPath + "/" + kernel[3] + "\n") if config.useInitrd: dossier.write("\tINITRD " + kernelPath + "/" + kernel[4] + "\n") dossier.write("\tAPPEND " + kernel[5] + "\n") dossier.write("\n") dossier.close() # Append anything else the user wants automatically added if config.append and config.appendStuff: Tools.Print("Appending additional information ...") if config.bootloader == "grub2": dossier = open(outputFile, "a") dossier.write(config.appendStuff) dossier.close() elif config.bootloader == "extlinux": dossier = open(outputFile, "a") dossier.write(config.appendStuff) dossier.close() # Check to make sure that the file was created successfully. # If so let the user know.. if os.path.isfile(outputFile): Tools.Success("'" + outputFile + "' has been created!") else: Tools.Fail( "Either the file couldn't be created or the specified bootloader isn't supported." )
def GetGrub2BootDrive(cls): # If we are using 'whole disk zfs', then we won't have a /boot entry # in /etc/fstab. So instead we will format the zfs_boot variable and # return it ready to be used in grub2 if config.wholeDiskZfs: match = re.search('(/[a-zA-Z0-9_/]+)', config.wholeDiskZfsBootPool) if match: return match.group() Tools.Fail( "Could not parse the 'wholeDiskZfsBootPool' variable correctly." ) # Properly processes the boot drive field in order for us to get # a value that we can properly parse for the grub.cfg. # This is so that if the user is using UUIDs as a /boot entry in # /etc/fstab, we can handle that situation correctly. match = re.search('/dev/(.*)', cls._bootDrive) if match: # Possibilities: # sd[a-z][0+] # vd[a-z][0+] # md[0+] # mapper/vg-root # vg/root # --- Handle sdX or vdX drives --- m1 = re.search('[s|v]d(\w+)', match.group(1)) if m1: # Complete value, will be completed as function progresses completedValue = "(hd" # Process the letter part and convert it to a grub compatible format; a = (hd0) alph = re.search('\w', m1.group(1)) if alph: # Find the number in the alphabet of this letter alphindex = cls.GetAlphabeticalIndex(alph.group(0)) # Add this number to the final string completedValue = completedValue + str(alphindex) # Process the number part of the drive numberPartOfDrive = re.search('\d', m1.group(1)) if numberPartOfDrive: # add layout completedValue = completedValue + "," + cls._driveLayout # add number part completedValue = completedValue + numberPartOfDrive.group( 0) # close the value and return it completedValue = completedValue + ")" return completedValue # --- Handle md# --- m1 = re.search('md(\d+)', match.group(1)) if m1: return "(md/" + m1.group(1) + ")" # --- LVM: mapper/<volume_group>-<logical_volume> --- m1 = re.search('mapper/(\w.-\w+)', match.group(1)) if m1: return "(lvm/" + m1.group(1) + ")" # --- LVM: <volume_group>/<logical_volume> --- m1 = re.search('(\w+)/(\w+)', match.group(1)) if m1: return "(lvm/" + m1.group(1) + "-" + m1.group(2) + ")" # We've failed :( Tools.Fail("Unable to generate the boot drive entry.")