Пример #1
0
    def scan_device(self, path):
        device_metadata = {'path': None, 'uuid': None}
        if not path:
            return device_metadata
        if self.is_encrypted:
            encryption_metadata = encryption.legacy_encrypted(path)
            device_metadata['path'] = encryption_metadata['device']
            device_metadata['uuid'] = disk.get_partuuid(
                encryption_metadata['device'])
            return device_metadata
        # cannot read the symlink if this is tmpfs
        if os.path.islink(path):
            device = os.readlink(path)
        else:
            device = path
        lvm_device = lvm.get_lv_from_argument(device)
        if lvm_device:
            device_uuid = lvm_device.lv_uuid
        else:
            device_uuid = disk.get_partuuid(device)

        device_metadata['uuid'] = device_uuid
        device_metadata['path'] = device

        return device_metadata
Пример #2
0
 def get_ptuuid(self, argument):
     uuid = disk.get_partuuid(argument)
     if not uuid:
         terminal.error('blkid could not detect a PARTUUID for device: %s' %
                        argument)
         raise RuntimeError('unable to use device')
     return uuid
Пример #3
0
    def zap(self, args):
        device = args.device
        lv = api.get_lv_from_argument(device)
        if lv:
            # we are zapping a logical volume
            path = lv.lv_path
        else:
            # we are zapping a partition
            #TODO: ensure device is a partition
            path = device

        mlogger.info("Zapping: %s", path)

        # check if there was a pv created with the
        # name of device
        pv = api.get_pv(pv_name=device)
        if pv:
            vg_name = pv.vg_name
            lv = api.get_lv(vg_name=vg_name)

        dmcrypt = False
        dmcrypt_uuid = None
        if lv:
            osd_path = "/var/lib/ceph/osd/{}-{}".format(lv.tags['ceph.cluster_name'], lv.tags['ceph.osd_id'])
            dmcrypt_uuid = lv.lv_uuid
            dmcrypt = lv.encrypted
            if system.path_is_mounted(osd_path):
                mlogger.info("Unmounting %s", osd_path)
                system.unmount(osd_path)
        else:
            # we're most likely dealing with a partition here, check to
            # see if it was encrypted
            partuuid = disk.get_partuuid(device)
            if encryption.status("/dev/mapper/{}".format(partuuid)):
                dmcrypt_uuid = partuuid
                dmcrypt = True

        if dmcrypt and dmcrypt_uuid:
            dmcrypt_path = "/dev/mapper/{}".format(dmcrypt_uuid)
            mlogger.info("Closing encrypted path %s", dmcrypt_path)
            encryption.dmcrypt_close(dmcrypt_path)

        if args.destroy and pv:
            logger.info("Found a physical volume created from %s, will destroy all it's vgs and lvs", device)
            vg_name = pv.vg_name
            mlogger.info("Destroying volume group %s because --destroy was given", vg_name)
            api.remove_vg(vg_name)
            mlogger.info("Destroying physical volume %s because --destroy was given", device)
            api.remove_pv(device)
        elif args.destroy and not pv:
            mlogger.info("Skipping --destroy because no associated physical volumes are found for %s", device)

        wipefs(path)
        zap_data(path)

        if lv and not pv:
            # remove all lvm metadata
            lv.clear_tags()

        terminal.success("Zapping successful for: %s" % path)
Пример #4
0
    def zap(self, args):
        for device in args.devices:
            if disk.is_mapper_device(device):
                terminal.error(
                    "Refusing to zap the mapper device: {}".format(device))
                raise SystemExit(1)
            lv = api.get_lv_from_argument(device)
            if lv:
                # we are zapping a logical volume
                path = lv.lv_path
                self.unmount_lv(lv)
            else:
                # we are zapping a partition
                #TODO: ensure device is a partition
                path = device
                # check to if it is encrypted to close
                partuuid = disk.get_partuuid(device)
                if encryption.status("/dev/mapper/{}".format(partuuid)):
                    dmcrypt_uuid = partuuid
                    self.dmcrypt_close(dmcrypt_uuid)

            mlogger.info("Zapping: %s", path)

            # check if there was a pv created with the
            # name of device
            pvs = api.PVolumes()
            pvs.filter(pv_name=device)
            vgs = set([pv.vg_name for pv in pvs])
            for pv in pvs:
                vg_name = pv.vg_name
                lv = None
                if pv.lv_uuid:
                    lv = api.get_lv(vg_name=vg_name, lv_uuid=pv.lv_uuid)

                if lv:
                    self.unmount_lv(lv)

            if args.destroy:
                for vg_name in vgs:
                    mlogger.info(
                        "Destroying volume group %s because --destroy was given",
                        vg_name)
                    api.remove_vg(vg_name)
                mlogger.info(
                    "Destroying physical volume %s because --destroy was given",
                    device)
                api.remove_pv(device)

            wipefs(path)
            zap_data(path)

            if lv and not pvs:
                # remove all lvm metadata
                lv.clear_tags()

        terminal.success("Zapping successful for: %s" %
                         ", ".join(args.devices))
Пример #5
0
    def zap(self, args):
        for device in args.devices:
            if disk.is_mapper_device(device):
                terminal.error("Refusing to zap the mapper device: {}".format(device))
                raise SystemExit(1)
            lv = api.get_lv_from_argument(device)
            if lv:
                # we are zapping a logical volume
                path = lv.lv_path
                self.unmount_lv(lv)
            else:
                # we are zapping a partition
                #TODO: ensure device is a partition
                path = device
                # check to if it is encrypted to close
                partuuid = disk.get_partuuid(device)
                if encryption.status("/dev/mapper/{}".format(partuuid)):
                    dmcrypt_uuid = partuuid
                    self.dmcrypt_close(dmcrypt_uuid)

            mlogger.info("Zapping: %s", path)

            # check if there was a pv created with the
            # name of device
            pvs = api.PVolumes()
            pvs.filter(pv_name=device)
            vgs = set([pv.vg_name for pv in pvs])
            for pv in pvs:
                vg_name = pv.vg_name
                lv = None
                if pv.lv_uuid:
                    lv = api.get_lv(vg_name=vg_name, lv_uuid=pv.lv_uuid)

                if lv:
                    self.unmount_lv(lv)

            if args.destroy:
                for vg_name in vgs:
                    mlogger.info("Destroying volume group %s because --destroy was given", vg_name)
                    api.remove_vg(vg_name)
                if not lv:
                    mlogger.info("Destroying physical volume %s because --destroy was given", device)
                    api.remove_pv(device)

            wipefs(path)
            zap_data(path)

            if lv and not pvs:
                # remove all lvm metadata
                lv.clear_tags()

        terminal.success("Zapping successful for: %s" % ", ".join(args.devices))
Пример #6
0
    def scan_device(self, path):
        device_metadata = {'path': None, 'uuid': None}
        if not path:
            return device_metadata
        if self.is_encrypted:
            encryption_metadata = encryption.legacy_encrypted(path)
            device_metadata['path'] = encryption_metadata['device']
            device_metadata['uuid'] = disk.get_partuuid(encryption_metadata['device'])
            return device_metadata
        # cannot read the symlink if this is tmpfs
        if os.path.islink(path):
            device = os.readlink(path)
        else:
            device = path
        lvm_device = lvm.get_lv_from_argument(device)
        if lvm_device:
            device_uuid = lvm_device.lv_uuid
        else:
            device_uuid = disk.get_partuuid(device)

        device_metadata['uuid'] = device_uuid
        device_metadata['path'] = device

        return device_metadata
Пример #7
0
 def get_ptuuid(self, argument):
     uuid = disk.get_partuuid(argument)
     if not uuid:
         terminal.error('blkid could not detect a PARTUUID for device: %s' % argument)
         raise RuntimeError('unable to use device')
     return uuid
Пример #8
0
    def scan_encrypted(self, directory=None):
        device = self.encryption_metadata['device']
        lockbox = self.encryption_metadata['lockbox']
        encryption_type = self.encryption_metadata['type']
        osd_metadata = {}
        # Get the PARTUUID of the device to make sure have the right one and
        # that maps to the data device
        device_uuid = disk.get_partuuid(device)
        dm_path = '/dev/mapper/%s' % device_uuid
        # check if this partition is already mapped
        device_status = encryption.status(device_uuid)

        # capture all the information from the lockbox first, reusing the
        # directory scan method
        if self.device_mounts.get(lockbox):
            lockbox_path = self.device_mounts.get(lockbox)[0]
            lockbox_metadata = self.scan_directory(lockbox_path)
            # ceph-disk stores the fsid as osd-uuid in the lockbox, thanks ceph-disk
            dmcrypt_secret = encryption.get_dmcrypt_key(
                None,  # There is no ID stored in the lockbox
                lockbox_metadata['osd-uuid'],
                os.path.join(lockbox_path, 'keyring')
            )
        else:
            with system.tmp_mount(lockbox) as lockbox_path:
                lockbox_metadata = self.scan_directory(lockbox_path)
                # ceph-disk stores the fsid as osd-uuid in the lockbox, thanks ceph-disk
                dmcrypt_secret = encryption.get_dmcrypt_key(
                    None,  # There is no ID stored in the lockbox
                    lockbox_metadata['osd-uuid'],
                    os.path.join(lockbox_path, 'keyring')
                )

        if not device_status:
            # Note how both these calls need b64decode. For some reason, the
            # way ceph-disk creates these keys, it stores them in the monitor
            # *undecoded*, requiring this decode call again. The lvm side of
            # encryption doesn't need it, so we are assuming here that anything
            # that `simple` scans, will come from ceph-disk and will need this
            # extra decode call here
            dmcrypt_secret = base64.b64decode(dmcrypt_secret)
            if encryption_type == 'luks':
                encryption.luks_open(dmcrypt_secret, device, device_uuid)
            else:
                encryption.plain_open(dmcrypt_secret, device, device_uuid)

        # If we have a directory, use that instead of checking for mounts
        if directory:
            osd_metadata = self.scan_directory(directory)
        else:
            # Now check if that mapper is mounted already, to avoid remounting and
            # decrypting the device
            dm_path_mount = self.device_mounts.get(dm_path)
            if dm_path_mount:
                osd_metadata = self.scan_directory(dm_path_mount[0])
            else:
                with system.tmp_mount(dm_path, encrypted=True) as device_path:
                    osd_metadata = self.scan_directory(device_path)

        osd_metadata['encrypted'] = True
        osd_metadata['encryption_type'] = encryption_type
        osd_metadata['lockbox.keyring'] = parse_keyring(lockbox_metadata['keyring'])
        return osd_metadata
Пример #9
0
    def scan_encrypted(self, directory=None):
        device = self.encryption_metadata['device']
        lockbox = self.encryption_metadata['lockbox']
        encryption_type = self.encryption_metadata['type']
        osd_metadata = {}
        # Get the PARTUUID of the device to make sure have the right one and
        # that maps to the data device
        device_uuid = disk.get_partuuid(device)
        dm_path = '/dev/mapper/%s' % device_uuid
        # check if this partition is already mapped
        device_status = encryption.status(device_uuid)

        # capture all the information from the lockbox first, reusing the
        # directory scan method
        if self.device_mounts.get(lockbox):
            lockbox_path = self.device_mounts.get(lockbox)[0]
            lockbox_metadata = self.scan_directory(lockbox_path)
            # ceph-disk stores the fsid as osd-uuid in the lockbox, thanks ceph-disk
            dmcrypt_secret = encryption.get_dmcrypt_key(
                None,  # There is no ID stored in the lockbox
                lockbox_metadata['osd-uuid'],
                os.path.join(lockbox_path, 'keyring')
            )
        else:
            with system.tmp_mount(lockbox) as lockbox_path:
                lockbox_metadata = self.scan_directory(lockbox_path)
                # ceph-disk stores the fsid as osd-uuid in the lockbox, thanks ceph-disk
                dmcrypt_secret = encryption.get_dmcrypt_key(
                    None,  # There is no ID stored in the lockbox
                    lockbox_metadata['osd-uuid'],
                    os.path.join(lockbox_path, 'keyring')
                )

        if not device_status:
            # Note how both these calls need b64decode. For some reason, the
            # way ceph-disk creates these keys, it stores them in the monitor
            # *undecoded*, requiring this decode call again. The lvm side of
            # encryption doesn't need it, so we are assuming here that anything
            # that `simple` scans, will come from ceph-disk and will need this
            # extra decode call here
            dmcrypt_secret = base64.b64decode(dmcrypt_secret)
            if encryption_type == 'luks':
                encryption.luks_open(dmcrypt_secret, device, device_uuid)
            else:
                encryption.plain_open(dmcrypt_secret, device, device_uuid)

        # If we have a directory, use that instead of checking for mounts
        if directory:
            osd_metadata = self.scan_directory(directory)
        else:
            # Now check if that mapper is mounted already, to avoid remounting and
            # decrypting the device
            dm_path_mount = self.device_mounts.get(dm_path)
            if dm_path_mount:
                osd_metadata = self.scan_directory(dm_path_mount[0])
            else:
                with system.tmp_mount(dm_path, encrypted=True) as device_path:
                    osd_metadata = self.scan_directory(device_path)

        osd_metadata['encrypted'] = True
        osd_metadata['encryption_type'] = encryption_type
        osd_metadata['lockbox.keyring'] = parse_keyring(lockbox_metadata['keyring'])
        return osd_metadata
Пример #10
0
    def zap(self, args):
        device = args.device
        if disk.is_mapper_device(device):
            terminal.error(
                "Refusing to zap the mapper device: {}".format(device))
            raise SystemExit(1)
        lv = api.get_lv_from_argument(device)
        if lv:
            # we are zapping a logical volume
            path = lv.lv_path
        else:
            # we are zapping a partition
            #TODO: ensure device is a partition
            path = device

        mlogger.info("Zapping: %s", path)

        # check if there was a pv created with the
        # name of device
        pv = api.get_pv(pv_name=device)
        if pv:
            vg_name = pv.vg_name
            lv = api.get_lv(vg_name=vg_name)

        dmcrypt = False
        dmcrypt_uuid = None
        if lv:
            if lv.tags.get('ceph.cluster_name') and lv.tags.get('ceph.osd_id'):
                lv_path = "/var/lib/ceph/osd/{}-{}".format(
                    lv.tags['ceph.cluster_name'], lv.tags['ceph.osd_id'])
            else:
                lv_path = lv.path
            dmcrypt_uuid = lv.lv_uuid
            dmcrypt = lv.encrypted
            if system.path_is_mounted(lv_path):
                mlogger.info("Unmounting %s", lv_path)
                system.unmount(lv_path)
        else:
            # we're most likely dealing with a partition here, check to
            # see if it was encrypted
            partuuid = disk.get_partuuid(device)
            if encryption.status("/dev/mapper/{}".format(partuuid)):
                dmcrypt_uuid = partuuid
                dmcrypt = True

        if dmcrypt and dmcrypt_uuid:
            dmcrypt_path = "/dev/mapper/{}".format(dmcrypt_uuid)
            mlogger.info("Closing encrypted path %s", dmcrypt_path)
            encryption.dmcrypt_close(dmcrypt_path)

        if args.destroy and pv:
            logger.info(
                "Found a physical volume created from %s, will destroy all it's vgs and lvs",
                device)
            vg_name = pv.vg_name
            mlogger.info(
                "Destroying volume group %s because --destroy was given",
                vg_name)
            api.remove_vg(vg_name)
            mlogger.info(
                "Destroying physical volume %s because --destroy was given",
                device)
            api.remove_pv(device)
        elif args.destroy and not pv:
            mlogger.info(
                "Skipping --destroy because no associated physical volumes are found for %s",
                device)

        wipefs(path)
        zap_data(path)

        if lv and not pv:
            # remove all lvm metadata
            lv.clear_tags()

        terminal.success("Zapping successful for: %s" % path)