예제 #1
0
class ReplaceBackupDeviceCommand(RdmcCommandBase):
    """ Main replacebackupdevice command class """
    def __init__(self, rdmcObj):
        RdmcCommandBase.__init__(self, \
        name='replacebackupdevice', \
        usage="replacebackupdevice OLD-ID NEW-ID\n"\
            "\n\tReplace a Scalable Persistent Memory backup storage device.\n"\
            "\tSpecify devices by ID, e.g. '1@1' from the show backup device command.\n"\
            "\n\tThis operation initializes all backup storage devices."\
            "\n\tData on any existing logical NVDIMMs will be lost. Back up all data first.\n"\
            "\n\texample: replacebackupdevice 1@1 2@1", \
        summary='Replace a backup storage device.', \
        aliases=['spmem-replaced', 'spmreplaced'], \
        optparser=OptionParser())

        self._rdmc = rdmcObj
        self._helpers = Helpers()
        self._rest_helpers = RestHelpers(self._rdmc)
        self._validator = LogicalNvdimmValidator()
        self._chif_lib = self._helpers.gethprestchifhandle()

    def run(self, line):
        """ Runs the command.

        :param line: command line input
        :type line: string
        """
        try:
            (_, args) = self._parse_arglist(line)
        except:
            if ("-h" in line) or ("--help" in line):
                return ReturnCodes.SUCCESS
            else:
                raise InvalidCommandLineErrorOPTS("")

        if not args or len(args) != 2:
            self.print_help()
            sys.stdout.write("\n")
            raise InvalidCommandLineError(u"OLD-ID and NEW-ID must be specified")

        if len(args) != len(set(args)):
            raise InvalidCommandLineError(u"Duplicate device IDs specified")

        if not self._chif_lib:
            self._helpers.failNoChifLibrary()

        scalable_pmem_config = ScalablePersistentMemoryConfig(self._rest_helpers,\
                                                 self._validator, self._chif_lib)
        scalable_pmem_config.refresh()

        # pre-validation
        self._helpers.validateFeatureIsSupported(scalable_pmem_config)
        self._helpers.validateFeatureEnabledByUser(scalable_pmem_config)

        try:
            old_drive, new_drive = scalable_pmem_config.drives.findDrives(args)
        except ValueError as excp:
            raise InvalidCommandLineError(u"Invalid device ID: {}".format(excp))

        self.replace_drive(scalable_pmem_config, old_drive, new_drive)

        scalable_pmem_config.refresh()
        self._helpers.displayDrivesConfiguration(scalable_pmem_config)

        return ReturnCodes.SUCCESS

    def replace_drive(self, scalable_pmem_config, old_drive, new_drive):
        """ Replaces a backup storage drive.

        :param scalable_pmem_config: the Scalable Persistent Memory configuration
        :param old_drive: the drive to be replaced
        :param new_drive: the replacement drive
        """
        backup_drives = scalable_pmem_config.drives.selectedDrives

        if old_drive not in backup_drives:
            raise NoChangesFoundOrMadeError(u"Device {} is not configured "\
                            "for backup storage".format(old_drive.generatedId))

        if new_drive in backup_drives:
            raise NoChangesFoundOrMadeError(u"Device {} is already configured " \
                            "for backup storage".format(new_drive.generatedId))

        backup_drives.remove(old_drive)
        backup_drives.append(new_drive)

        config_data = scalable_pmem_config.config_resource

        # new backup storage drives must adhere to the drive policy requirements
        is_valid, error_msg = self._validator.checkLogicalNvdimmDrivePolicies(\
                                                    config_data, backup_drives)
        if not is_valid:
            raise NoChangesFoundOrMadeError(error_msg)

        # new backup storage drives must support the current logical NVDIMM configuration
        max_pmem = self._validator.calculateMaxPmemGiB(self._chif_lib, \
                                                    config_data, backup_drives)
        allocated_pmem = scalable_pmem_config.regions.totalSizeGiB

        if allocated_pmem > max_pmem:
            raise NoChangesFoundOrMadeError(u"The new backup storage devices must support "
                                            u"the current logical NVDIMM configuration.")

        if old_drive.currentMode == Drive.MODE_NVDIMM and scalable_pmem_config.\
                                                    hasActiveConfiguredRegions:
            # actual drive replacement occurring with data at risk
            if self._rdmc.interactive:
                sys.stdout.write(u"\nAll backup storage devices will be initialized upon restart."
                                 u"\nData on any existing logical NVDIMMs will be lost.\n")

                uinput = raw_input(u"\nConfirm changes [y/N]? ")
                if uinput.lower() != 'y':
                    raise NoChangesFoundOrMadeError(u"No changes have been made")

        self._rest_helpers.setDrives(new_drives=[new_drive], old_drives=[old_drive])
class EnableScalablePmemCommand(RdmcCommandBase):
    """ Enable Scalable Pmem command """
    def __init__(self, rdmcObj):
        RdmcCommandBase.__init__(self, \
            name='enablescalablepmem', \
            usage='enablescalablepmem [OPTIONS]\n\n' \
                '\tEnables or disables the Scalable Persistent Memory feature.\n'\
                '\n\texample: enablescalablepmem', \
            summary='Enable or disable the Scalable Persistent Memory feature.', \
            aliases=['spmem-enable', 'spmemen'], \
            optparser=OptionParser())
        self.definearguments(self.parser)
        self._rdmc = rdmcObj
        self._helpers = Helpers()
        self._restHelpers = RestHelpers(self._rdmc)
        self._chif_lib = self._helpers.gethprestchifhandle()

    def enableOrDisableFeature(self, enable):
        """ Enables or disables the feature

        :param enable: a flag whether to enable or disable the feature
        :type enable: boolean
        """

        validator = LogicalNvdimmValidator()

        scalable_pmem_config = ScalablePersistentMemoryConfig(self._restHelpers,\
                                                     validator, self._chif_lib)
        scalable_pmem_config.refresh()

        # pre-validation
        self._helpers.validateFeatureIsSupported(scalable_pmem_config)
        self._helpers.validateFunctionalityIsEnabled(scalable_pmem_config)

        if enable is False:
            # If user disables Scalable PMEM, revert any pending changes to
            # prevent data or configuration loss
            if self._rdmc.interactive:
                message = u"Warning: disabling Scalable Persistent Memory will "\
                                    "revert any pending configuration changes.\n"
                self._helpers.confirmChanges(message=message)
            self._restHelpers.revertSettings()

        patchAttributes = {
            "FeatureEnabled" : enable
        }
        _ = self._restHelpers.patchScalablePmemSettingAttributes(patchAttributes)

        sys.stdout.write(u"\nThe Scalable Persistent Memory feature has been "\
                    "set to: {}\n".format("Enabled" if enable else "Disabled"))

        self._helpers.noticeRestartRequired(scalable_pmem_config)

        sys.stdout.write("\n\n")

    def run(self, line):
        """ Wrapper function for the Remove logical NVDIMM command

        :param line: command line input
        :type line: string.
        """
        LOGGER.info("Scalable PMEM: {}".format(self.name))
        try:
            (options, _) = self._parse_arglist(line)
        except:
            if ("-h" in line) or ("--help" in line):
                return ReturnCodes.SUCCESS
            else:
                raise InvalidCommandLineErrorOPTS("")

        if len(args):
            InvalidCommandLineError("This command takes no parameters.")

        LOGGER.info("Options: {}".format(options))

        if not self._chif_lib:
            self._helpers.failNoChifLibrary()

        enable = True
        if options.enableFeature is False:
            enable = False

        self.enableOrDisableFeature(enable)

        #Return code
        return ReturnCodes.SUCCESS

    def definearguments(self, customparser):
        """ Define arguments for the command

        :param customparser: command line input
        :type customparser: parser.
        """

        customparser.add_option(
            '--disable',
            action="store_false",
            dest="enableFeature",
            help="Disable the Scalable Persistent Memory feature. Warning: "\
                                "any pending configuration changes will be lost."
        )
class ShowLogicalNVDIMMDrivesCommand(RdmcCommandBase):
    """ Main showbackupdevices command class """
    def __init__(self, rdmcObj):
        RdmcCommandBase.__init__(self, \
            name='showbackupdevices', \
            usage='showbackupdevices\n\n\tDisplay the devices supported for use '\
            'as Scalable Persistent Memory\n\tbackup storage.\n\n\texample: '\
            'showbackupdevices', \
            summary='Display backup storage devices.', \
            aliases=['spmem-showdrives', 'spmemsd', 'showscalablepmemdrives'], \
            optparser=OptionParser())
        self._rdmc = rdmcObj
        self._helpers = Helpers()
        self._chif_lib = self._helpers.gethprestchifhandle()

    def showDriveData(self):
        """ Main showlogicalnvdimmdrives command worker function

        :param options: command options
        :type options: options.
        """

        helpers = Helpers()
        restHelpers = RestHelpers(self._rdmc)
        validator = LogicalNvdimmValidator()

        scalable_pmem_config = ScalablePersistentMemoryConfig(restHelpers, \
                                                    validator, self._chif_lib)
        scalable_pmem_config.refresh()

        # pre-validation
        self._helpers.validateFeatureIsSupported(scalable_pmem_config)

        helpers.writeHeader2(
            u"Scalable Persistent Memory Backup Storage Devices")
        helpers.displayDrivesConfiguration(scalable_pmem_config)
        sys.stdout.write(u"\n")

    def run(self, line):
        """ Wrapper function for showlogicalnvdimmdrives command main function

        :param line: command line input
        :type line: string.
        """
        LOGGER.info("Scalable PMEM: {}".format(self.name))
        try:
            (options, args) = self._parse_arglist(line)
        except:
            if ("-h" in line) or ("--help" in line):
                return ReturnCodes.SUCCESS
            else:
                raise InvalidCommandLineErrorOPTS("")

        if args:
            raise InvalidCommandLineError("No argument is required.")

        LOGGER.info("Options: {}".format(options))

        if not self._chif_lib:
            self._helpers.failNoChifLibrary()

        self.showDriveData()

        #Return code
        return ReturnCodes.SUCCESS