Exemple #1
0
    def _ata_erase(self, block_device):
        security_lines = self._get_ata_security_lines(block_device)

        # If secure erase isn't supported return False so erase_block_device
        # can try another mechanism. Below here, if secure erase is supported
        # but fails in some way, error out (operators of hardware that supports
        # secure erase presumably expect this to work).
        if 'supported' not in security_lines:
            return False

        if 'enabled' in security_lines:
            raise errors.BlockDeviceEraseError(
                ('Block device {0} already has '
                 'a security password set').format(block_device.name))

        if 'not frozen' not in security_lines:
            raise errors.BlockDeviceEraseError(
                ('Block device {0} is frozen '
                 'and cannot be erased').format(block_device.name))

        utils.execute('hdparm', '--user-master', 'u', '--security-set-pass',
                      'NULL', block_device.name)
        utils.execute('hdparm', '--user-master', 'u', '--security-erase',
                      'NULL', block_device.name)

        # Verify that security is now 'not enabled'
        security_lines = self._get_ata_security_lines(block_device)
        if 'not enabled' not in security_lines:
            raise errors.BlockDeviceEraseError(
                ('An unknown error occurred '
                 'erasing block device {0}').format(block_device.name))

        return True
    def erase_devices_metadata(self, node, ports):
        """Attempt to erase the disk devices metadata.

        :param node: Ironic node object
        :param ports: list of Ironic port objects
        :raises BlockDeviceEraseError: when there's an error erasing the
                block device
        """
        block_devices = self.list_block_devices()
        erase_errors = {}
        for dev in block_devices:
            if self._is_virtual_media_device(dev):
                LOG.info("Skipping the erase of virtual media device %s",
                         dev.name)
                continue

            try:
                disk_utils.destroy_disk_metadata(dev.name, node['uuid'])
            except processutils.ProcessExecutionError as e:
                LOG.error(
                    'Failed to erase the metadata on device "%(dev)s". '
                    'Error: %(error)s', {
                        'dev': dev.name,
                        'error': e
                    })
                erase_errors[dev.name] = e

        if erase_errors:
            excpt_msg = (
                'Failed to erase the metadata on the device(s): %s' %
                '; '.join(
                    ['"%s": %s' % (k, v) for k, v in erase_errors.items()]))
            raise errors.BlockDeviceEraseError(excpt_msg)
Exemple #3
0
    def erase_block_device(self, block_device):
        if self._ata_erase(block_device):
            return

        # NOTE(russell_h): Support for additional generic erase methods should
        # be added above this raise, in order of precedence.
        raise errors.BlockDeviceEraseError(
            ('Unable to erase block device '
             '{0}: device is unsupported.').format(block_device.name))
    def _erase_lsi_warpdrive(self, block_device):
        if not self._is_warpdrive(block_device):
            return False

        # NOTE(JayF): Start timing here, so any devices short circuited
        # don't produce invalidly-short metrics.
        with metrics.instrument_context(__name__, 'erase_lsi_warpdrive'):
            device = self._get_warpdrive_card(block_device)
            result = utils.execute(DDOEMCLI, '-c', device['id'], '-format',
                    '-op', '-level', 'nom', '-s')
            if 'WarpDrive format successfully completed.' not in result[0]:
                raise errors.BlockDeviceEraseError(('Erasing LSI card failed: '
                    '{0}').format(result[0]))

        return True
Exemple #5
0
 def test_error_classes(self):
     cases = [
         (errors.InvalidContentError(DETAILS), SAME_DETAILS),
         (errors.NotFound(), SAME_CL_DETAILS),
         (errors.CommandExecutionError(DETAILS), SAME_DETAILS),
         (errors.InvalidCommandError(DETAILS), SAME_DETAILS),
         (errors.InvalidCommandParamsError(DETAILS), SAME_DETAILS),
         (errors.RequestedObjectNotFoundError('type_descr',
                                              'obj_id'), DIFF_CL_DETAILS),
         (errors.IronicAPIError(DETAILS), SAME_DETAILS),
         (errors.HeartbeatError(DETAILS), SAME_DETAILS),
         (errors.LookupNodeError(DETAILS), SAME_DETAILS),
         (errors.LookupAgentIPError(DETAILS), SAME_DETAILS),
         (errors.LookupAgentInterfaceError(DETAILS), SAME_DETAILS),
         (errors.ImageDownloadError('image_id', DETAILS), DIFF_CL_DETAILS),
         (errors.ImageChecksumError('image_id', '/foo/image_id',
                                    'incorrect',
                                    'correct'), DIFF_CL_DETAILS),
         (errors.ImageWriteError('device', 'exit_code', 'stdout',
                                 'stderr'), DIFF_CL_DETAILS),
         (errors.ConfigDriveTooLargeError('filename',
                                          'filesize'), DIFF_CL_DETAILS),
         (errors.ConfigDriveWriteError('device', 'exit_code', 'stdout',
                                       'stderr'), DIFF_CL_DETAILS),
         (errors.SystemRebootError('exit_code', 'stdout',
                                   'stderr'), DIFF_CL_DETAILS),
         (errors.BlockDeviceEraseError(DETAILS), SAME_DETAILS),
         (errors.BlockDeviceError(DETAILS), SAME_DETAILS),
         (errors.VirtualMediaBootError(DETAILS), SAME_DETAILS),
         (errors.UnknownNodeError(), DEFAULT_DETAILS),
         (errors.UnknownNodeError(DETAILS), SAME_DETAILS),
         (errors.HardwareManagerNotFound(), DEFAULT_DETAILS),
         (errors.HardwareManagerNotFound(DETAILS), SAME_DETAILS),
         (errors.HardwareManagerMethodNotFound('method'), DIFF_CL_DETAILS),
         (errors.IncompatibleHardwareMethodError(), DEFAULT_DETAILS),
         (errors.IncompatibleHardwareMethodError(DETAILS), SAME_DETAILS),
     ]
     for (obj, check_details) in cases:
         self._test_class(obj, check_details)
    def _ata_erase(self, block_device):
        security_lines = self._get_ata_security_lines(block_device)

        # If secure erase isn't supported return False so erase_block_device
        # can try another mechanism. Below here, if secure erase is supported
        # but fails in some way, error out (operators of hardware that supports
        # secure erase presumably expect this to work).
        if 'supported' not in security_lines:
            return False

        if 'enabled' in security_lines:
            # Attempt to unlock the drive in the event it has already been
            # locked by a previous failed attempt.
            try:
                utils.execute('hdparm', '--user-master', 'u',
                              '--security-unlock', 'NULL', block_device.name)
                security_lines = self._get_ata_security_lines(block_device)
            except processutils.ProcessExecutionError as e:
                raise errors.BlockDeviceEraseError(
                    'Security password set '
                    'failed for device '
                    '%(name)s: %(err)s' % {
                        'name': block_device.name,
                        'err': e
                    })

        if 'enabled' in security_lines:
            raise errors.BlockDeviceEraseError(
                ('Block device {} already has a security password set').format(
                    block_device.name))

        if 'not frozen' not in security_lines:
            raise errors.BlockDeviceEraseError(
                ('Block device {} is frozen and cannot be erased').format(
                    block_device.name))

        try:
            utils.execute('hdparm', '--user-master', 'u',
                          '--security-set-pass', 'NULL', block_device.name)
        except processutils.ProcessExecutionError as e:
            raise errors.BlockDeviceEraseError('Security password set '
                                               'failed for device '
                                               '%(name)s: %(err)s' % {
                                                   'name': block_device.name,
                                                   'err': e
                                               })

        # Use the 'enhanced' security erase option if it's supported.
        erase_option = '--security-erase'
        if 'not supported: enhanced erase' not in security_lines:
            erase_option += '-enhanced'

        try:
            utils.execute('hdparm', '--user-master', 'u', erase_option, 'NULL',
                          block_device.name)
        except processutils.ProcessExecutionError as e:
            raise errors.BlockDeviceEraseError('Erase failed for device '
                                               '%(name)s: %(err)s' % {
                                                   'name': block_device.name,
                                                   'err': e
                                               })

        # Verify that security is now 'not enabled'
        security_lines = self._get_ata_security_lines(block_device)
        if 'not enabled' not in security_lines:
            raise errors.BlockDeviceEraseError(
                ('An unknown error occurred erasing block device {}').format(
                    block_device.name))

        return True
Exemple #7
0
    def _ata_erase(self, block_device):
        security_lines = self._get_ata_security_lines(block_device)

        # If secure erase isn't supported return False so erase_block_device
        # can try another mechanism. Below here, if secure erase is supported
        # but fails in some way, error out (operators of hardware that supports
        # secure erase presumably expect this to work).
        if 'supported' not in security_lines:
            return False

        # At this point, we could be SEC1,2,4,5,6

        if 'not frozen' not in security_lines:
            # In SEC2 or 6
            raise errors.BlockDeviceEraseError(
                ('Block device {} is frozen and cannot be erased').format(
                    block_device.name))

        # At this point, we could be in SEC1,4,5

        # Attempt to unlock the drive in the event it has already been
        # locked by a previous failed attempt. We try the empty string as
        # versions of hdparm < 9.51, interpreted NULL as the literal string,
        # "NULL", as opposed to the empty string.
        unlock_passwords = ['NULL', '']
        for password in unlock_passwords:
            if 'not locked' in security_lines:
                break
            try:
                utils.execute('hdparm', '--user-master', 'u',
                              '--security-unlock', password, block_device.name)
            except processutils.ProcessExecutionError as e:
                LOG.info(
                    'Security unlock failed for device '
                    '%(name)s using password "%(password)s": %(err)s', {
                        'name': block_device.name,
                        'password': password,
                        'err': e
                    })
            security_lines = self._get_ata_security_lines(block_device)

        # If the unlock failed we will still be in SEC4, otherwise, we will be
        # in SEC1 or SEC5

        if 'not locked' not in security_lines:
            # In SEC4
            raise errors.BlockDeviceEraseError(
                ('Block device {} already has a security password set').format(
                    block_device.name))

        # At this point, we could be in SEC1 or 5
        if 'not enabled' in security_lines:
            # SEC1. Try to transition to SEC5 by setting empty user
            # password.
            try:
                utils.execute('hdparm', '--user-master', 'u',
                              '--security-set-pass', 'NULL', block_device.name)
            except processutils.ProcessExecutionError as e:
                error_msg = ('Security password set failed for device '
                             '{name}: {err}').format(name=block_device.name,
                                                     err=e)
                raise errors.BlockDeviceEraseError(error_msg)

        # Use the 'enhanced' security erase option if it's supported.
        erase_option = '--security-erase'
        if 'not supported: enhanced erase' not in security_lines:
            erase_option += '-enhanced'

        try:
            utils.execute('hdparm', '--user-master', 'u', erase_option, 'NULL',
                          block_device.name)
        except processutils.ProcessExecutionError as e:
            raise errors.BlockDeviceEraseError('Erase failed for device '
                                               '%(name)s: %(err)s' % {
                                                   'name': block_device.name,
                                                   'err': e
                                               })

        # Verify that security is now 'not enabled'
        security_lines = self._get_ata_security_lines(block_device)
        if 'not enabled' not in security_lines:
            # Not SEC1 - fail
            raise errors.BlockDeviceEraseError(
                ('An unknown error occurred erasing block device {}').format(
                    block_device.name))

        # In SEC1 security state
        return True