Esempio n. 1
0
def hostAction(context):
    subDict = getStringSubstitutionDict()
    log.debug('Dumping bootloader variables...')
    safeDict = subDict.copy()
    del safeDict['passwordLine']
    log.debug(str(safeDict))

    makeBackups()

    if userchoices.getUpgrade():
        discoverLocation(subDict)
        subDict = getStringSubstitutionDict()

    context.cb.pushStatusGroup(5)
    context.cb.pushStatus('Copying the GRUB images')
    copyGrubStageImages()
    context.cb.popStatus()

    context.cb.pushStatus('Writing the GRUB config files')
    writeGrubConfFiles(subDict)
    context.cb.popStatus()

    context.cb.pushStatus('Making the initial ramdisk')
    makeInitialRamdisk(subDict)
    context.cb.popStatus()

    context.cb.pushStatus('Writing GRUB to the Master Boot Record')
    w = MBRWriter()
    w.write(subDict)
    context.cb.popStatus()
    context.cb.popStatusGroup()

    sanityCheck(subDict)
Esempio n. 2
0
def doit(context, stepListType='install'):
    '''Executes the steps needed to do the actual install or upgrade.'''

    if stepListType == 'install':
        if userchoices.getUpgrade():
            steps = _upgradeSteps()
        else:
            steps = _installSteps()
    elif stepListType == 'loadDrivers':
        steps = _loadDriverSteps()

    assert steps

    try:
        context.cb.pushStatusGroup(sum([step[0] for step in steps]))
        for portion, desc, msgID, func in steps:
            context.cb.pushStatus(desc, portion, msgID=msgID)
            func(context)
            context.cb.popStatus()
        context.cb.popStatusGroup()

        if stepListType == 'install':
            log.info("installation complete")
        elif stepListType == 'loadDrivers':
            log.info("driver loading complete")
    except exception.InstallCancelled:
        pass

    return
Esempio n. 3
0
def doit(context, stepListType='install'):
    '''Executes the steps needed to do the actual install or upgrade.'''

    if stepListType == 'install':
        if userchoices.getUpgrade():
            steps = _upgradeSteps()
        else:
            steps = _installSteps()
    elif stepListType == 'loadDrivers':
        steps = _loadDriverSteps()

    assert steps

    try:
        context.cb.pushStatusGroup(sum([step[0] for step in steps]))
        for portion, desc, msgID, func in steps:
            context.cb.pushStatus(desc, portion, msgID=msgID)
            func(context)
            context.cb.popStatus()
        context.cb.popStatusGroup()
        
        if stepListType == 'install':
            log.info("installation complete")
        elif stepListType == 'loadDrivers':
            log.info("driver loading complete")
    except exception.InstallCancelled:
        pass

    return
Esempio n. 4
0
def hostAction(context):
    subDict = getStringSubstitutionDict()
    log.debug('Dumping bootloader variables...')
    safeDict = subDict.copy()
    del safeDict['passwordLine']
    log.debug(str(safeDict))

    makeBackups()

    if userchoices.getUpgrade():
        discoverLocation(subDict)
        subDict = getStringSubstitutionDict()

    context.cb.pushStatusGroup(5)
    context.cb.pushStatus('Copying the GRUB images')
    copyGrubStageImages()
    context.cb.popStatus()

    context.cb.pushStatus('Writing the GRUB config files')
    writeGrubConfFiles(subDict)
    context.cb.popStatus()

    context.cb.pushStatus('Making the initial ramdisk')
    makeInitialRamdisk(subDict)
    context.cb.popStatus()

    context.cb.pushStatus('Writing GRUB to the Master Boot Record')
    w = MBRWriter()
    w.write(subDict)
    context.cb.popStatus()
    context.cb.popStatusGroup()

    sanityCheck(subDict)
Esempio n. 5
0
    def _runtimeActions(self):
        errors = []
        warnings = []

        if userchoices.getActivateNetwork() and userchoices.getCosNICs() and \
           not networking.connected() and not userchoices.getUpgrade():
            try:
                networking.cosConnectForInstaller()
            except Exception, ex:
                log.exception(str(ex))
                warnings.append("warning: could not bring up network -- %s\n" %
                                str(ex))
Esempio n. 6
0
def hostActionMountFileSystems(context):
    # XXX - we only use one virtual device for now
    virtualDevs = userchoices.getVirtualDevices()
    assert len(virtualDevs) == 1 or len(virtualDevs) == 0

    requests = allUserPartitionRequests()
    requests.sort(sortByMountPoint=True)

    for request in requests:
        # skip vmfs partitions since they can't be mounted
        if not request.mountPoint:
            continue

        mountPoint = os.path.normpath(consts.HOST_ROOT + request.mountPoint)

        if not os.path.exists(mountPoint):
            os.makedirs(mountPoint)

        log.debug("Mounting %s -> %s" % \
                  (request.consoleDevicePath, mountPoint))
        request.fsType.mount(request.consoleDevicePath, mountPoint)

        if request.clearContents:
            # Clear out the contents of the drive.  Removing the files might be
            # preferable to a reformat since we preserve the UUID.
            for name in os.listdir(mountPoint):
                path = os.path.join(mountPoint, name)
                if os.path.isdir(path):
                    shutil.rmtree(path)
                else:
                    os.remove(path)

    if userchoices.getUpgrade():
        upgradeMounts = [(consts.ESX3_INSTALLATION,
                          userchoices.getRootUUID()['uuid'])]

        if userchoices.isCombinedBootAndRootForUpgrade():
            log.debug("Linking boot")
            # No /boot partition, need to create a link to the old one.
            os.symlink(
                os.path.join(consts.ESX3_INSTALLATION.lstrip('/'), "boot"),
                os.path.join(consts.HOST_ROOT, "boot"))
        else:
            upgradeMounts.append(("/boot", userchoices.getBootUUID()['uuid']))

        for partMountPoint, uuid in upgradeMounts:
            mountPoint = os.path.normpath(consts.HOST_ROOT + partMountPoint)
            if not os.path.exists(mountPoint):
                os.makedirs(mountPoint)

            log.debug("Mounting %s -> %s" % (uuid, mountPoint))
            rc = util.mount(uuid, mountPoint, isUUID=True)
            assert rc == 0  # TODO: handle errors
Esempio n. 7
0
    def _runtimeActions(self):
        errors = []
        warnings = []

        if userchoices.getActivateNetwork() and userchoices.getCosNICs() and \
           not networking.connected() and not userchoices.getUpgrade():
            try:
                networking.cosConnectForInstaller()
            except Exception, ex:
                log.exception(str(ex))
                warnings.append("warning: could not bring up network -- %s\n" %
                                str(ex))
Esempio n. 8
0
class Scui:
    '''Class used to do a scripted install.'''
    def __init__(self, script):
        # Setup error handling stuff first so any errors during driver loading
        # or the main bits gets handled correctly.

        global tty6Handler

        sys.excepthook = lambda type, value, tb: \
                         exception.handleException(self, (type, value, tb),
                                                   traceInDetails=False)

        try:
            # The scui uses logging to write out user-visible output so we need
            # another logger for tty6 (which stdout is redirected to by
            # weasel.py).
            tty6Handler = logging.StreamHandler(sys.stdout)
            tty6Handler.setFormatter(formatterForHuman)
            tty6Handler.setLevel(LOGLEVEL_HUMAN)
            log.addHandler(tty6Handler)
        except IOError:
            #Could not open for writing.  Probably not the root user
            pass

        self._execute(script)

    @applychoices.ensureDriversAreLoaded
    def _execute(self, script):
        from preparser import ScriptedInstallPreparser
        from scriptedinstallutil import Result

        errors = None
        installCompleted = False

        try:
            self.sip = ScriptedInstallPreparser(script)

            (result, errors, warnings) = self.sip.parseAndValidate()
            if warnings:
                log.warn("\n".join(warnings))
            if errors:
                log.error("\n".join(errors))
                userchoices.setReboot(False)
            if result != Result.FAIL:
                # Bring up whatever is needed for the install to happen.  For
                # example, get the network going for non-local installs.
                errors, warnings = self._runtimeActions()

                if warnings:
                    log.warn("\n".join(warnings))
                if errors:
                    log.error("\n".join(errors))
                    userchoices.setReboot(False)

                if not errors:
                    if userchoices.getDebug():
                        log.info(userchoices.dumpToString())

                    if userchoices.getDryrun():
                        log.log(LOGLEVEL_HUMAN, "dry run specified, stopping.")
                    else:
                        context = applychoices.Context(
                            applychoices.ProgressCallback(
                                applychoices.StdoutProgressDelegate()))
                        applychoices.doit(context)
                        installCompleted = True

                media.runtimeActionEjectMedia()
        except IOError, e:
            log.error("error: cannot open file -- %s\n" % str(e))

        if not installCompleted:
            log.error("installation aborted")

        if not installCompleted or not userchoices.getReboot():
            msg = "Press <enter> to reboot..."
            if userchoices.getUpgrade():
                msg = "The machine will reboot automatically or\n" \
                    "press <enter> to reboot immediately..."
            raw_input(msg)
Esempio n. 9
0
def sanityCheckPartitionRequests(partRequestSetList=None, checkSizing=False):
    '''Check the partition requests to make sure the expected requests (e.g.
    "/boot" and "/") are there.

    The given list of PartitionRequestSets is checked against the following
    constraints:
      * There is a "/boot" partition that is on a physical partition and is
        greater than or equal to 100MB in size.
      * There is a "/" partition and it greater than or equal to 100MB in size.

    The return value is a pair containing any error messages and warnings.

    >>> from devices import DiskSet
    >>> ds = DiskSet()
    >>> prs = PartitionRequestSet(ds.values()[0])
    >>> prs.append(PartitionRequest("/boot", minimumSize=100))
    >>> # There is no root partition, we should get an error.
    ... sanityCheckPartitionRequests([prs])
    (['no root partition found.'], [])
    >>> prs.append(PartitionRequest("/", minimumSize=100))
    >>> sanityCheckPartitionRequests([prs])
    ([], [])
    '''

    if partRequestSetList is None:
        partRequestSetList = _allUserPartitionRequestSets()

    errors = []

    bootRequest = None
    rootRequest = None

    if checkSizing and partRequestSetList:
        # Download the package data so we can figure out the minimum partition
        # sizes
        weaselConfig = systemsettings.WeaselConfig()
        packagesXML = packages.getPackagesXML(weaselConfig.packageGroups)
        packageData = packages.PackageData(packagesXML.fullInstallDepot)

        fileSizes = packageData.fileDict
    else:
        fileSizes = {}

    swapSize = 0
    for reqSet in partRequestSetList:
        clearChoice = userchoices.getClearPartitions()
        if reqSet.device and reqSet.device.deviceExists and \
                reqSet.deviceName not in clearChoice.get('drives', []):
            errors.append(
                '%s needs to have its partitions cleared before it can be '
                'repartitioned.' % reqSet.device.name)

        minSize = reqSet.getMinimumSize()
        if reqSet.device and minSize > reqSet.device.getSizeInMegabytes():
            errors.append(
                'partition sizes for %s are too large (%d MB > %d MB).' %
                (reqSet.device.name, minSize,
                 reqSet.device.getSizeInMegabytes()))

        sizeDict = reqSet.findMinimumRequestSizes(fileSizes)
        for req in reqSet:
            if isinstance(req.fsType, fsset.swapFileSystem):
                swapSize += req.minimumSize
                continue

            if not req.mountPoint:
                continue

            if req.mountPoint.startswith('/') and \
                    req.minimumSize < sizeDict[req.mountPoint]:
                errors.append('The "%s" partition needs to be at least %d '
                              'megabytes in size.' %
                              (req.mountPoint, sizeDict[req.mountPoint]))

            if (not isinstance(reqSet.device, devices.VirtualDiskDev)
                    and req.mountPoint == '/boot'):
                bootRequest = req

            if req.mountPoint == '/':
                rootRequest = req

            # TODO: Check for anything starting with '/etc' or '/boot'.
            if req.mountPoint in INVALID_MOUNTPOINTS:
                errors.append('%s cannot be on a separate partition.' %
                              req.mountPoint)

    if swapSize == 0:
        errors.append('A swap partition is required to use ESX.')
    elif swapSize < 256:
        errors.append('Swap space must be at least 256MB in size.')

    if userchoices.getUpgrade():
        if not userchoices.getBootUUID():
            # TODO: deal with no boot partition, everything in root...
            errors.append('no "/boot" partition specified for upgrade.')
    elif not bootRequest:
        errors.append('no "/boot" partition found.')
    elif bootRequest.minimumSize < (BOOT_MINIMUM_SIZE - PARTITION_FUDGE_SIZE):
        errors.append('"/boot" partition must be at least %dMB in size.' %
                      BOOT_MINIMUM_SIZE)

    if not rootRequest:
        errors.append("A '/' (root) partition was not specified for the "
                      "Service Console virtual disk.  The Service Console "
                      "can not boot without a '/' partition.")

    return errors
Esempio n. 10
0
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()
Esempio n. 11
0
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
Esempio n. 12
0
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()
Esempio n. 13
0
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