def getKernelOptions(kernelMemInMB): '''Create the list of options that get appended onto the "kernel" line of the grub.conf file. ''' disks = devices.DiskSet() rootPartition = disks.findPartitionContaining('/', searchVirtual=True) if not rootPartition: raise PartitionNotFound('/') devPartName = rootPartition.consoleDevicePath if not devPartName: # expected /dev/sda1 for the 1-disk case raise MissingConsoleDevicePath(rootPartition) rootPartUuid = getUuid(devPartName) # ro: mount "/" read-only in the initrd environment but when the init # scripts start up it magically gets remounted rw. options = 'ro' # root: tell the kernel where to find "/" options += ' root=UUID='+ rootPartUuid # mem: tell the kernel how much memory it can use options += ' mem='+ kernelMemInMB +'M' choices = userchoices.getBoot() if choices and choices['kernelParams']: options += ' '+ choices['kernelParams'] return options
def getOrderedDrives(self, allowUserOverride=True): '''Return a list of drives. The order will be the order that the BIOS puts them in, unless the user has specified a particular device to go first. This is primarily used to set up GRUB TODO: the scripted install "driveOrder" command only affects the order of at most one device. This is how I understand it should work. If that's the case, maybe we need to change the name from "driveOrder" to something else. ''' allDrives = self.disks.values() comparator = operator.attrgetter('biosBootOrder') allDrives.sort(key=comparator) # XXX - remove this at some point since mixing userchoices here # is bad. if allowUserOverride: bootOptions = userchoices.getBoot() if bootOptions: driveOrder = bootOptions['driveOrder'] if driveOrder: firstDrive = driveOrder[0] if firstDrive not in allDrives: raise InvalidDriveOrder(firstDrive) allDrives.remove(firstDrive) allDrives.insert(0, firstDrive) else: log.debug("No drive order specified. Set to default.") else: log.debug("Drive order set to default.") return allDrives
def _genBoot(): flags = "" choice = userchoices.getBoot() if choice['doNotInstall']: flags += " --location=none" else: flags += " --location=%s" % choice['location'] if choice['kernelParams']: flags += " --append='%s'" % shquote(choice['kernelParams']) if choice['password']: flagName = "--password" if choice['passwordType'] == userchoices.BOOT_PASSWORD_TYPE_MD5: flagName = "--md5pass" flags += " %s='%s'" % (flagName, shquote(choice['password'])) if choice['driveOrder']: flags += " --driveorder=%s" % ",".join( [disk.name for disk in choice['driveOrder']]) if choice['upgrade']: flags += " --upgrade" return "bootloader %s\n" % flags
def getKernelOptions(kernelMemInMB): '''Create the list of options that get appended onto the "kernel" line of the grub.conf file. ''' disks = devices.DiskSet() rootPartition = disks.findPartitionContaining('/', searchVirtual=True) if not rootPartition: raise PartitionNotFound('/') devPartName = rootPartition.consoleDevicePath if not devPartName: # expected /dev/sda1 for the 1-disk case raise MissingConsoleDevicePath(rootPartition) rootPartUuid = getUuid(devPartName) # ro: mount "/" read-only in the initrd environment but when the init # scripts start up it magically gets remounted rw. options = 'ro' # root: tell the kernel where to find "/" options += ' root=UUID=' + rootPartUuid # mem: tell the kernel how much memory it can use options += ' mem=' + kernelMemInMB + 'M' choices = userchoices.getBoot() if choices and choices['kernelParams']: options += ' ' + choices['kernelParams'] return options
def reviewBoot(values): choice = userchoices.getBoot() location = choice.get('location', userchoices.BOOT_LOC_MBR) if location == userchoices.BOOT_LOC_MBR: locationStr = 'Master Boot Record' elif location == userchoices.BOOT_LOC_PARTITION: locationStr = 'ESX partition' else: locationStr = 'Not installed' values['bootLocation'] = locationStr
def write(self, stringSubstitutionDict): choices = userchoices.getBoot() if choices and choices['doNotInstall']: log.info('Skipping the writing of the bootloader to disk') return self.__enter() cmd = cmd_grub % stringSubstitutionDict rc, stdout, stderr = execCommand(cmd) self.checkGrubOutput(stdout) self.__exit()
def getPasswordLine(): '''Create the (optional) "password" line of the grub.conf file. [password [--md5] PASSWD] ''' passwordLine = '' password = '' choices = userchoices.getBoot() if choices: password = choices['password'] if (password and choices['passwordType'] == userchoices.BOOT_PASSWORD_TYPE_MD5): passwordLine = 'password --md5 '+ password elif password: passwordLine = 'password '+ password return passwordLine
def getPasswordLine(): '''Create the (optional) "password" line of the grub.conf file. [password [--md5] PASSWD] ''' passwordLine = '' password = '' choices = userchoices.getBoot() if choices: password = choices['password'] if (password and choices['passwordType'] == userchoices.BOOT_PASSWORD_TYPE_MD5): passwordLine = 'password --md5 ' + password elif password: passwordLine = 'password ' + password return passwordLine
def copyGrubStageImages(): '''make sure all the "stage" images are stored on the boot partition. This replaces `/sbin/grub-install --just-copy` that was in anaconda ''' choices = userchoices.getBoot() if choices and choices['doNotInstall']: log.info('Skipping the writing of the bootloader to disk') return if not os.path.exists(grub_dir): os.makedirs(grub_dir) #makes directory for the stage images stageImgFilenames = glob.glob(grub_stage_img_dir + '*') if not stageImgFilenames: raise Exception('grub package directory (%s) was empty!' % grub_stage_img_dir) for fname in stageImgFilenames: basename = os.path.basename(fname) destination = grub_dir + basename shutil.copy(fname, destination)
def writeGrubConfFiles(stringSubstitutionDict): '''make grub config files''' # make sure the expected directories exist if not os.path.exists(grub_dir): os.makedirs(grub_dir) if not os.path.exists(os.path.dirname(sysconfig_grub_file)): os.makedirs(os.path.dirname(sysconfig_grub_file)) newEntry = grub_conf_entry % stringSubstitutionDict debugEntrySubstDict = stringSubstitutionDict.copy() debugEntrySubstDict['label'] = "Troubleshooting mode" debugEntrySubstDict['bootDirRelativeToGrub'] += "trouble/" debugEntrySubstDict['kernelOptions'] += " trouble" debugEntry = grub_conf_entry % debugEntrySubstDict choices = userchoices.getBoot() if (os.path.exists(grub_conf_file) and (userchoices.getUpgrade() or choices.get('upgrade', False))): # For an upgrade, we need to preserve all the settings in the file, # not just the titles. Otherwise, we lose things like password. grubFile = open(grub_conf_file) grubContents = grubFile.read() grubFile.close() grubContents = removeTitle(grubContents, newEntry.split('\n')[0]) grubContents = removeTitle(grubContents, debugEntry.split('\n')[0]) grubContents = grubContents.replace('VMware ESX Server', 'VMware ESX Server 3') grubContents = grubContents.replace( 'Service Console only', 'ESX Server 3 Service Console only') else: grubContents = grub_conf_header % stringSubstitutionDict grubContents = insertTitle(grubContents, debugEntry) grubContents = insertTitle(grubContents, newEntry) grubContents = changeSetting(grubContents, "default", "0") if userchoices.getUpgrade(): grubContents = writeUpgradeFiles(grubContents) # Write the whole file out first and then use rename to atomically install # it in the directory, we don't want to put a broken file in there during # an upgrade. tmpPath = os.tempnam(os.path.dirname(grub_conf_file), "grub.conf") fp = open(tmpPath, 'w') fp.write(grubContents) fp.close() os.chmod(tmpPath, 0600) os.rename(tmpPath, grub_conf_file) fp = open(device_map_file, 'w') fp.write(device_map % stringSubstitutionDict) fp.close() fp = open(sysconfig_grub_file, 'w') fp.write(sysconfig_grub % stringSubstitutionDict) fp.close()
def getStringSubstitutionDict(): label, version = getKernelLabelAndVersion() # Get the kernel mem to put in the boot command line. kernelMemInMB = vmkctl.MemoryInfoImpl().GetServiceConsoleReservedMem() upperMemInKB = str(kernelMemInMB*1024) disks = devices.DiskSet() if userchoices.getUpgrade(): # We reuse the boot partition from the old install. bootPath = os.path.join(consts.ESX3_INSTALLATION, "boot") else: bootPath = "/boot" slashBootPartition = disks.findPartitionContaining(bootPath) if not slashBootPartition: raise PartitionNotFound(bootPath) devPartName = slashBootPartition.consoleDevicePath if not devPartName: raise MissingConsoleDevicePath(slashBootPartition) slashBootPartUuid = getUuid(devPartName) diskIndex, partIndex = grubDiskAndPartitionIndicies(slashBootPartition) if diskIndex != 0: log.warn('Installing GRUB to the MBR of a disk that was not the first' ' disk reported by the BIOS. User must change their BIOS' ' settings if they want to boot from this disk') slashBootPartNum = partIndex grubInstallDevice = findGrubInstallDevice(slashBootPartition) # This code protects against instability with the /vmfs partition # going missing. We try to use the canonical path first, however if it # isn't there, use the /dev/sdX path and warn. The variable is used # in device.map. if os.path.exists(grubInstallDevice.path): installerDevDiskName = grubInstallDevice.path elif os.path.exists(grubInstallDevice.consoleDevicePath): log.warn('The normal path to the boot disk did not exist. ' 'Using console device path instead.') installerDevDiskName = grubInstallDevice.consoleDevicePath else: raise RuntimeError, "Couldn't find a place to write GRUB." # decide between installing to the MBR or the first partition bootChoices = userchoices.getBoot() if bootChoices and \ bootChoices['location'] == userchoices.BOOT_LOC_PARTITION: grubInstallLocation = '(hd0,%s)' % slashBootPartNum log.info('Installing GRUB to the first partition of %s ' % installerDevDiskName) else: grubInstallLocation = '(hd0)' log.info('Installing GRUB to the MBR of (%s)' % installerDevDiskName) # need to tell grub.conf where it will find the kernel and initrd # relative to the root of the partition it searches. if slashBootPartition.mountPoint in [ '/boot', os.path.join(consts.ESX3_INSTALLATION, "boot")]: bootDirRelativeToGrub = '/' elif slashBootPartition.mountPoint in ['/', consts.ESX3_INSTALLATION]: bootDirRelativeToGrub = '/boot/' kernelOptions = getKernelOptions(str(kernelMemInMB)) passwordLine = getPasswordLine() substitutes = dict( label = label, version = version, devPartName = devPartName, kernel_file = kernel_file, initrd_file = initrd_file, passwordLine = passwordLine, upperMemInKB = upperMemInKB, kernelMemInMB = kernelMemInMB, kernelOptions = kernelOptions, slashBootPartNum = slashBootPartNum, slashBootPartUuid = slashBootPartUuid, grubInstallLocation = grubInstallLocation, installerDevDiskName = installerDevDiskName, bootDirRelativeToGrub = bootDirRelativeToGrub, ) return substitutes
def getStringSubstitutionDict(): label, version = getKernelLabelAndVersion() # Get the kernel mem to put in the boot command line. kernelMemInMB = vmkctl.MemoryInfoImpl().GetServiceConsoleReservedMem() upperMemInKB = str(kernelMemInMB * 1024) disks = devices.DiskSet() if userchoices.getUpgrade(): # We reuse the boot partition from the old install. bootPath = os.path.join(consts.ESX3_INSTALLATION, "boot") else: bootPath = "/boot" slashBootPartition = disks.findPartitionContaining(bootPath) if not slashBootPartition: raise PartitionNotFound(bootPath) devPartName = slashBootPartition.consoleDevicePath if not devPartName: raise MissingConsoleDevicePath(slashBootPartition) slashBootPartUuid = getUuid(devPartName) diskIndex, partIndex = grubDiskAndPartitionIndicies(slashBootPartition) if diskIndex != 0: log.warn('Installing GRUB to the MBR of a disk that was not the first' ' disk reported by the BIOS. User must change their BIOS' ' settings if they want to boot from this disk') slashBootPartNum = partIndex grubInstallDevice = findGrubInstallDevice(slashBootPartition) # This code protects against instability with the /vmfs partition # going missing. We try to use the canonical path first, however if it # isn't there, use the /dev/sdX path and warn. The variable is used # in device.map. if os.path.exists(grubInstallDevice.path): installerDevDiskName = grubInstallDevice.path elif os.path.exists(grubInstallDevice.consoleDevicePath): log.warn('The normal path to the boot disk did not exist. ' 'Using console device path instead.') installerDevDiskName = grubInstallDevice.consoleDevicePath else: raise RuntimeError, "Couldn't find a place to write GRUB." # decide between installing to the MBR or the first partition bootChoices = userchoices.getBoot() if bootChoices and \ bootChoices['location'] == userchoices.BOOT_LOC_PARTITION: grubInstallLocation = '(hd0,%s)' % slashBootPartNum log.info('Installing GRUB to the first partition of %s ' % installerDevDiskName) else: grubInstallLocation = '(hd0)' log.info('Installing GRUB to the MBR of (%s)' % installerDevDiskName) # need to tell grub.conf where it will find the kernel and initrd # relative to the root of the partition it searches. if slashBootPartition.mountPoint in [ '/boot', os.path.join(consts.ESX3_INSTALLATION, "boot") ]: bootDirRelativeToGrub = '/' elif slashBootPartition.mountPoint in ['/', consts.ESX3_INSTALLATION]: bootDirRelativeToGrub = '/boot/' kernelOptions = getKernelOptions(str(kernelMemInMB)) passwordLine = getPasswordLine() substitutes = dict( label=label, version=version, devPartName=devPartName, kernel_file=kernel_file, initrd_file=initrd_file, passwordLine=passwordLine, upperMemInKB=upperMemInKB, kernelMemInMB=kernelMemInMB, kernelOptions=kernelOptions, slashBootPartNum=slashBootPartNum, slashBootPartUuid=slashBootPartUuid, grubInstallLocation=grubInstallLocation, installerDevDiskName=installerDevDiskName, bootDirRelativeToGrub=bootDirRelativeToGrub, ) return substitutes