Beispiel #1
0
    def _validate_db_devs(self):
        # do not allow non-common VG to continue
        validators.has_common_vg(self.db_or_journal_devs)

        # find the common VG to calculate how much is available
        self.common_vg = self.get_common_vg(self.db_or_journal_devs)

        # find how many block.db LVs are possible from the common VG
        if self.common_vg:
            common_vg_size = disk.Size(gb=self.common_vg.free)
        else:
            common_vg_size = disk.Size(gb=0)

        # non-VG SSDs
        vg_members = set([d for d in self.db_or_journal_devs if d.is_lvm_member])
        self.blank_db_devs = set(self.db_or_journal_devs).difference(vg_members)
        self.total_blank_db_dev_size = disk.Size(b=0)
        for blank_db_dev in self.blank_db_devs:
            self.total_blank_db_dev_size += disk.Size(b=blank_db_dev.lvm_size.b)

        self.total_available_db_space = self.total_blank_db_dev_size + common_vg_size

        # If not configured, we default to 0, which is really "use as much as
        # possible" captured by the `else` condition
        if self.block_db_size.gb > 0:
            try:
                self.vg_extents = lvm.sizing(
                    self.total_available_db_space.b, size=self.block_db_size.b * self.osds_per_device
                )
            except SizeAllocationError:
                msg = "Not enough space in fast devices (%s) to create %s x %s block.db LV"
                raise RuntimeError(
                    msg % (self.total_available_db_space, self.osds_per_device, self.block_db_size)
                )
        else:
            self.vg_extents = lvm.sizing(
                self.total_available_db_space.b, parts=self.dbs_needed
            )

        # validate that number of block.db LVs possible are enough for number of
        # OSDs proposed
        if self.total_available_db_space.b == 0:
            msg = "No space left in fast devices to create block.db LVs"
            raise RuntimeError(msg)

        # bluestore_block_db_size was unset, so we must set this to whatever
        # size we get by dividing the total available space for block.db LVs
        # into the number of block.db LVs needed (i.e. "as large as possible")
        if self.block_db_size.b == 0:
            self.block_db_size = self.total_available_db_space / self.dbs_needed
            self.use_large_block_db = True

        total_dbs_possible = self.total_available_db_space / self.block_db_size

        if self.dbs_needed > total_dbs_possible:
            msg = "Not enough space (%s) to create %s x %s block.db LVs" % (
                self.total_available_db_space, self.dbs_needed, self.block_db_size,
            )
            raise RuntimeError(msg)
Beispiel #2
0
    def compute(self):
        """
        Go through the rules needed to properly size the lvs, return
        a dictionary with the result
        """
        osds = self.computed['osds']
        vgs = self.computed['vgs']
        for device in self.hdds:
            vgs.append({'devices': [device['path']], 'parts': 1})
            osd = {'data': {}, 'block.db': {}}
            osd['data']['path'] = device['path']
            osd['data']['size'] = device['size']
            osd['data']['parts'] = 1
            osd['data']['percentage'] = 100
            osd['data']['human_readable_size'] = str(disk.Size(b=device['size']))
            osds.append(osd)

        for device in self.ssds:
            # TODO: creates 2 OSDs per device, make this configurable (env var?)
            extents = lvm.sizing(device['size'], parts=2)
            vgs.append({'devices': [device['path']], 'parts': 2})
            for ssd in range(2):
                osd = {'data': {}, 'block.db': {}}
                osd['data']['path'] = device['path']
                osd['data']['size'] = extents['sizes']
                osd['data']['parts'] = extents['parts']
                osd['data']['percentage'] = 50
                osd['data']['human_readable_size'] = str(disk.Size(b=extents['sizes']))
                osds.append(osd)
Beispiel #3
0
    def report_pretty(self):
        vg_extents = lvm.sizing(self.total_ssd_size.b, parts=self.db_lvs)
        db_size = str(disk.Size(b=(vg_extents['sizes'])))

        string = ""
        string += templates.total_osds.format(total_osds=len(self.hdds))

        string += templates.ssd_volume_group.format(
            target='block.db',
            total_lv_size=str(self.total_ssd_size),
            total_lvs=vg_extents['parts'],
            block_lv_size=db_size,
            block_db_devices=', '.join([ssd.abspath for ssd in self.ssds]),
            lv_size=str(disk.Size(b=(vg_extents['sizes']))),
            total_osds=len(self.hdds))

        string += templates.osd_component_titles
        for osd in self.computed['osds']:
            string += templates.osd_header
            string += templates.osd_component.format(
                _type='[data]',
                path=osd['data']['path'],
                size=osd['data']['human_readable_size'],
                percent=osd['data']['percentage'])

            string += templates.osd_component.format(
                _type='[block.db]',
                path='(volume-group/lv)',
                size=osd['block.db']['human_readable_size'],
                percent=osd['block.db']['percentage'])

        print(string)
Beispiel #4
0
    def compute(self):
        """
        Go through the rules needed to properly size the lvs, return
        a dictionary with the result
        """
        osds = self.computed['osds']
        for device in self.hdds:
            for hdd in range(self.osds_per_device):
                osd = {'data': {}, 'block.db': {}}
                osd['data']['path'] = device.abspath
                osd['data']['size'] = device.sys_api['size'] / self.osds_per_device
                osd['data']['parts'] = self.osds_per_device
                osd['data']['percentage'] = 100 / self.osds_per_device
                osd['data']['human_readable_size'] = str(
                    disk.Size(b=device.sys_api['size']) / self.osds_per_device
                )
                osds.append(osd)

        for device in self.ssds:
            extents = lvm.sizing(device.sys_api['size'], parts=self.osds_per_device)
            for ssd in range(self.osds_per_device):
                osd = {'data': {}, 'block.db': {}}
                osd['data']['path'] = device.abspath
                osd['data']['size'] = extents['sizes']
                osd['data']['parts'] = extents['parts']
                osd['data']['percentage'] = 100 / self.osds_per_device
                osd['data']['human_readable_size'] = str(disk.Size(b=extents['sizes']))
                osds.append(osd)

        self.computed['changed'] = len(osds) > 0
Beispiel #5
0
    def report_pretty(self):
        vg_extents = lvm.sizing(self.total_ssd_size.b, parts=self.db_lvs)
        db_size = str(disk.Size(b=(vg_extents['sizes'])))

        string = ""
        string += templates.total_osds.format(
            total_osds=len(self.hdds)
        )

        string += templates.ssd_volume_group.format(
            target='block.db',
            total_lv_size=str(self.total_ssd_size),
            total_lvs=vg_extents['parts'],
            block_lv_size=db_size,
            block_db_devices=', '.join([ssd['path'] for ssd in self.ssds]),
            lv_size=str(disk.Size(b=(vg_extents['sizes']))),
            total_osds=len(self.hdds)
        )

        string += templates.osd_component_titles
        for osd in self.computed['osds']:
            string += templates.osd_header
            string += templates.osd_component.format(
                _type='[data]',
                path=osd['data']['path'],
                size=osd['data']['human_readable_size'],
                percent=osd['data']['percentage'])

            string += templates.osd_component.format(
                _type='[block.db]',
                path='(volume-group/lv)',
                size=osd['block.db']['human_readable_size'],
                percent=osd['block.db']['percentage'])

        print(string)
Beispiel #6
0
    def compute(self):
        """
        Go through the rules needed to properly size the lvs, return
        a dictionary with the result
        """
        osds = self.computed['osds']
        for device in self.hdds:
            for hdd in range(self.osds_per_device):
                osd = {'data': {}, 'block.db': {}}
                osd['data']['path'] = device.abspath
                osd['data']['size'] = device.lvm_size.b / self.osds_per_device
                osd['data']['parts'] = self.osds_per_device
                osd['data']['percentage'] = 100 / self.osds_per_device
                osd['data']['human_readable_size'] = str(
                    disk.Size(b=device.lvm_size.b) / self.osds_per_device
                )
                osds.append(osd)

        for device in self.ssds:
            extents = lvm.sizing(device.lvm_size.b, parts=self.osds_per_device)
            for ssd in range(self.osds_per_device):
                osd = {'data': {}, 'block.db': {}}
                osd['data']['path'] = device.abspath
                osd['data']['size'] = extents['sizes']
                osd['data']['parts'] = extents['parts']
                osd['data']['percentage'] = 100 / self.osds_per_device
                osd['data']['human_readable_size'] = str(disk.Size(b=extents['sizes']))
                osds.append(osd)

        self.computed['changed'] = len(osds) > 0
Beispiel #7
0
    def compute(self):
        """
        Go through the rules needed to properly size the lvs, return
        a dictionary with the result
        """
        osds = self.computed['osds']
        vgs = self.computed['vgs']
        for device in self.hdds:
            vgs.append({'devices': [device['path']], 'parts': 1})
            osd = {'data': {}, 'block.db': {}}
            osd['data']['path'] = device['path']
            osd['data']['size'] = device['size']
            osd['data']['parts'] = 1
            osd['data']['percentage'] = 100
            osd['data']['human_readable_size'] = str(
                disk.Size(b=device['size']))
            osds.append(osd)

        for device in self.ssds:
            # TODO: creates 2 OSDs per device, make this configurable (env var?)
            extents = lvm.sizing(device['size'], parts=2)
            vgs.append({'devices': [device['path']], 'parts': 2})
            for ssd in range(2):
                osd = {'data': {}, 'block.db': {}}
                osd['data']['path'] = device['path']
                osd['data']['size'] = extents['sizes']
                osd['data']['parts'] = extents['parts']
                osd['data']['percentage'] = 50
                osd['data']['human_readable_size'] = str(
                    disk.Size(b=extents['sizes']))
                osds.append(osd)
Beispiel #8
0
    def validate(self):
        """
        Ensure that the minimum requirements for this type of scenario is
        met, raise an error if the provided devices would not work
        """
        # validate minimum size for all devices
        validators.minimum_device_size(self.devices,
                                       osds_per_device=self.osds_per_device)

        # make sure that data devices do not have any LVs
        validators.no_lvm_membership(self.data_devs)

        # do not allow non-common VG to continue
        validators.has_common_vg(self.db_or_journal_devs)

        # find the common VG to calculate how much is available
        self.common_vg = self.get_common_vg(self.db_or_journal_devs)

        # find how many journals are possible from the common VG
        if self.common_vg:
            common_vg_size = disk.Size(b=self.common_vg.free)
        else:
            common_vg_size = disk.Size(gb=0)

        # non-VG SSDs
        vg_ssds = set([d for d in self.db_or_journal_devs if d.is_lvm_member])
        self.blank_journal_devs = set(
            self.db_or_journal_devs).difference(vg_ssds)
        self.total_blank_journal_dev_size = disk.Size(b=0)
        for blank_journal_dev in self.blank_journal_devs:
            self.total_blank_journal_dev_size += disk.Size(
                b=blank_journal_dev.lvm_size.b)

        self.total_available_journal_space = self.total_blank_journal_dev_size + common_vg_size

        try:
            self.vg_extents = lvm.sizing(self.total_available_journal_space.b,
                                         size=self.journal_size.b *
                                         self.osds_per_device)
        except SizeAllocationError:
            msg = "Not enough space in fast devices (%s) to create %s x %s journal LV"
            raise RuntimeError(msg % (self.total_available_journal_space,
                                      self.osds_per_device, self.journal_size))

        # validate that number of journals possible are enough for number of
        # OSDs proposed
        total_journals_possible = self.total_available_journal_space / self.journal_size
        if self.osds_per_device > total_journals_possible:
            msg = "Not enough space (%s) to create %s x %s journal LVs" % (
                self.total_available_journal_space, self.journals_needed,
                self.journal_size)
            raise RuntimeError(msg)

        if self.osd_ids:
            self._validate_osd_ids()
Beispiel #9
0
    def validate(self):
        """
        Ensure that the minimum requirements for this type of scenario is
        met, raise an error if the provided devices would not work
        """
        # validate minimum size for all devices
        validators.minimum_device_size(self.devices, osds_per_device=self.osds_per_device)

        # make sure that data devices do not have any LVs
        validators.no_lvm_membership(self.data_devs)

        # do not allow non-common VG to continue
        validators.has_common_vg(self.db_or_journal_devs)

        # find the common VG to calculate how much is available
        self.common_vg = self.get_common_vg(self.db_or_journal_devs)

        # find how many journals are possible from the common VG
        if self.common_vg:
            common_vg_size = disk.Size(gb=self.common_vg.free)
        else:
            common_vg_size = disk.Size(gb=0)

        # non-VG SSDs
        vg_ssds = set([d for d in self.db_or_journal_devs if d.is_lvm_member])
        self.blank_journal_devs = set(self.db_or_journal_devs).difference(vg_ssds)
        self.total_blank_journal_dev_size = disk.Size(b=0)
        for blank_journal_dev in self.blank_journal_devs:
            self.total_blank_journal_dev_size += disk.Size(b=blank_journal_dev.lvm_size.b)

        self.total_available_journal_space = self.total_blank_journal_dev_size + common_vg_size

        try:
            self.vg_extents = lvm.sizing(
                self.total_available_journal_space.b, size=self.journal_size.b * self.osds_per_device
            )
        except SizeAllocationError:
            msg = "Not enough space in fast devices (%s) to create %s x %s journal LV"
            raise RuntimeError(
                msg % (self.total_available_journal_space, self.osds_per_device, self.journal_size)
            )

        # validate that number of journals possible are enough for number of
        # OSDs proposed
        total_journals_possible = self.total_available_journal_space / self.journal_size
        if self.osds_per_device > total_journals_possible:
            msg = "Not enough space (%s) to create %s x %s journal LVs" % (
                self.total_available_journal_space, self.journals_needed, self.journal_size
            )
            raise RuntimeError(msg)

        if self.osd_ids:
            self._validate_osd_ids()
Beispiel #10
0
    def validate(self):
        """
        Ensure that the minimum requirements for this type of scenario is
        met, raise an error if the provided devices would not work
        """
        # validate minimum size for all devices
        validators.minimum_device_size(self.devices)

        # make sure that data devices do not have any LVs
        validators.no_lvm_membership(self.hdds)

        # do not allow non-common VG to continue
        validators.has_common_vg(self.ssds)

        # find the common VG to calculate how much is available
        self.common_vg = self.get_common_vg()

        # find how many journals are possible from the common VG
        if self.common_vg:
            common_vg_size = disk.Size(gb=self.common_vg.free)
        else:
            common_vg_size = disk.Size(gb=0)

        # non-VG SSDs
        self.vg_ssds = set([d for d in self.ssds if d.is_lvm_member])
        self.blank_ssds = set(self.ssds).difference(self.vg_ssds)
        self.total_blank_ssd_size = disk.Size(b=0)
        for blank_ssd in self.blank_ssds:
            self.total_blank_ssd_size += disk.Size(b=blank_ssd.sys_api['size'])

        self.total_available_journal_space = self.total_blank_ssd_size + common_vg_size

        try:
            self.vg_extents = lvm.sizing(self.total_available_journal_space.b,
                                         size=self.journal_size.b)
        # FIXME with real exception catching from sizing that happens when the
        # journal space is not enough
        except Exception:
            self.vg_extents = {'parts': 0, 'percentages': 0, 'sizes': 0}

        # validate that number of journals possible are enough for number of
        # OSDs proposed
        total_journals_possible = self.total_available_journal_space / self.journal_size
        if len(self.hdds) > total_journals_possible:
            msg = "Not enough %s journals (%s) can be created for %s OSDs" % (
                self.journal_size, total_journals_possible, len(self.hdds))
            raise RuntimeError(msg)
Beispiel #11
0
    def report_pretty(self):
        vg_extents = lvm.sizing(self.total_available_db_space.b, parts=self.dbs_needed)
        db_size = str(disk.Size(b=(vg_extents['sizes'])))

        string = ""
        if self.args.filtered_devices:
            string += templates.filtered_devices(self.args.filtered_devices)
        string += templates.total_osds.format(
            total_osds=len(self.hdds) * self.osds_per_device
        )

        string += templates.ssd_volume_group.format(
            target='block.db',
            total_lv_size=str(self.total_available_db_space),
            total_lvs=vg_extents['parts'] * self.osds_per_device,
            block_lv_size=db_size,
            block_db_devices=', '.join([ssd.abspath for ssd in self.ssds]),
            lv_size=self.block_db_size or str(disk.Size(b=(vg_extents['sizes']))),
            total_osds=len(self.hdds)
        )

        string += templates.osd_component_titles
        for osd in self.computed['osds']:
            string += templates.osd_header
            string += templates.osd_component.format(
                _type='[data]',
                path=osd['data']['path'],
                size=osd['data']['human_readable_size'],
                percent=osd['data']['percentage'])

            string += templates.osd_component.format(
                _type='[block.db]',
                path=osd['block.db']['path'],
                size=osd['block.db']['human_readable_size'],
                percent=osd['block.db']['percentage'])

        print(string)
Beispiel #12
0
    def validate(self):
        """
        HDDs represent data devices, and solid state devices are for block.db,
        make sure that the number of data devices would have enough LVs and
        those LVs would be large enough to accommodate a block.db
        """
        # validate minimum size for all devices
        validators.minimum_device_size(self.devices)

        # add all the size available in solid drives and divide it by the
        # expected number of osds, the expected output should be larger than
        # the minimum alllowed for block.db
        self.total_ssd_size = disk.Size(b=0)
        for ssd in self.ssds:
            self.total_ssd_size + disk.Size(b=ssd['size'])

        self.block_db_size = self.total_ssd_size / self.db_lvs
        self.vg_extents = lvm.sizing(self.total_ssd_size.b, parts=self.db_lvs)

        # min 2GB of block.db is allowed
        msg = 'Total solid size (%s) is not enough for block.db LVs larger than 2 GB'
        if self.block_db_size < disk.Size(gb=2):
            # use ad-hoc exception here
            raise RuntimeError(msg % self.total_ssd_size)
Beispiel #13
0
    def validate(self):
        """
        HDDs represent data devices, and solid state devices are for block.db,
        make sure that the number of data devices would have enough LVs and
        those LVs would be large enough to accommodate a block.db
        """
        # validate minimum size for all devices
        validators.minimum_device_size(self.devices)

        # add all the size available in solid drives and divide it by the
        # expected number of osds, the expected output should be larger than
        # the minimum alllowed for block.db
        self.total_ssd_size = disk.Size(b=0)
        for ssd in self.ssds:
            self.total_ssd_size + disk.Size(b=ssd['size'])

        self.block_db_size = self.total_ssd_size / self.db_lvs
        self.vg_extents = lvm.sizing(self.total_ssd_size.b, parts=self.db_lvs)

        # min 2GB of block.db is allowed
        msg = 'Total solid size (%s) is not enough for block.db LVs larger than 2 GB'
        if self.block_db_size < disk.Size(gb=2):
            # use ad-hoc exception here
            raise RuntimeError(msg % self.total_ssd_size)
Beispiel #14
0
    def report_pretty(self, filtered_devices):
        string = ""
        if filtered_devices:
            string += templates.filtered_devices(filtered_devices)
        string += templates.total_osds.format(total_osds=len(self.data_devs) *
                                              self.osds_per_device)

        if self.db_or_journal_devs:
            vg_extents = lvm.sizing(self.total_available_db_space.b,
                                    parts=self.dbs_needed)
            db_size = str(disk.Size(b=(vg_extents['sizes'])))

            string += templates.ssd_volume_group.format(
                target='block.db',
                total_lv_size=str(self.total_available_db_space),
                total_lvs=vg_extents['parts'] * self.osds_per_device,
                block_lv_size=db_size,
                block_db_devices=', '.join(
                    [ssd.abspath for ssd in self.db_or_journal_devs]),
                lv_size=self.block_db_size
                or str(disk.Size(b=(vg_extents['sizes']))),
                total_osds=len(self.data_devs))

        if self.wal_devs:
            wal_vg_extents = lvm.sizing(self.total_available_wal_space.b,
                                        parts=self.wals_needed)
            wal_size = str(disk.Size(b=(wal_vg_extents['sizes'])))
            string += templates.ssd_volume_group.format(
                target='block.wal',
                total_lv_size=str(self.total_available_wal_space),
                total_lvs=wal_vg_extents['parts'] * self.osds_per_device,
                block_lv_size=wal_size,
                block_db_devices=', '.join(
                    [dev.abspath for dev in self.wal_devs]),
                lv_size=self.block_wal_size
                or str(disk.Size(b=(wal_vg_extents['sizes']))),
                total_osds=len(self.data_devs))

        string += templates.osd_component_titles
        for osd in self.computed['osds']:
            string += templates.osd_header
            if 'osd_id' in osd:
                string += templates.osd_reused_id.format(id_=osd['osd_id'])
            string += templates.osd_component.format(
                _type='[data]',
                path=osd['data']['path'],
                size=osd['data']['human_readable_size'],
                percent=osd['data']['percentage'])

            if 'block.db' in osd:
                string += templates.osd_component.format(
                    _type='[block.db]',
                    path=osd['block.db']['path'],
                    size=osd['block.db']['human_readable_size'],
                    percent=osd['block.db']['percentage'])

            if 'block.wal' in osd:
                string += templates.osd_component.format(
                    _type='[block.wal]',
                    path=osd['block.wal']['path'],
                    size=osd['block.wal']['human_readable_size'],
                    percent=osd['block.wal']['percentage'])

        print(string)
Beispiel #15
0
    def validate(self):
        """
        HDDs represent data devices, and solid state devices are for block.db,
        make sure that the number of data devices would have enough LVs and
        those LVs would be large enough to accommodate a block.db
        """
        # validate minimum size for all devices
        validators.minimum_device_size(self.devices, osds_per_device=self.osds_per_device)

        # make sure that data devices do not have any LVs
        validators.no_lvm_membership(self.hdds)

        # do not allow non-common VG to continue
        validators.has_common_vg(self.ssds)

        # find the common VG to calculate how much is available
        self.common_vg = self.get_common_vg()

        # find how many block.db LVs are possible from the common VG
        if self.common_vg:
            common_vg_size = disk.Size(gb=self.common_vg.free)
        else:
            common_vg_size = disk.Size(gb=0)

        # non-VG SSDs
        self.vg_ssds = set([d for d in self.ssds if d.is_lvm_member])
        self.blank_ssds = set(self.ssds).difference(self.vg_ssds)
        self.total_blank_ssd_size = disk.Size(b=0)
        for blank_ssd in self.blank_ssds:
            self.total_blank_ssd_size += disk.Size(b=blank_ssd.sys_api['size'])

        self.total_available_db_space = self.total_blank_ssd_size + common_vg_size

        # If not configured, we default to 0, which is really "use as much as
        # possible" captured by the `else` condition
        if self.block_db_size.gb > 0:
            try:
                self.vg_extents = lvm.sizing(
                    self.total_available_db_space.b, size=self.block_db_size.b * self.osds_per_device
                )
            except SizeAllocationError:
                msg = "Not enough space in fast devices (%s) to create %s x %s block.db LV"
                raise RuntimeError(
                    msg % (self.total_available_db_space, self.osds_per_device, self.block_db_size)
                )
        else:
            self.vg_extents = lvm.sizing(
                self.total_available_db_space.b, parts=self.dbs_needed
            )

        # validate that number of block.db LVs possible are enough for number of
        # OSDs proposed
        if self.total_available_db_space.b == 0:
            msg = "No space left in fast devices to create block.db LVs"
            raise RuntimeError(msg)

        # bluestore_block_db_size was unset, so we must set this to whatever
        # size we get by dividing the total available space for block.db LVs
        # into the number of block.db LVs needed (i.e. "as large as possible")
        if self.block_db_size.b == 0:
            self.block_db_size = self.total_available_db_space / self.dbs_needed

        total_dbs_possible = self.total_available_db_space / self.block_db_size

        if self.dbs_needed > total_dbs_possible:
            msg = "Not enough space (%s) to create %s x %s block.db LVs" % (
                self.total_available_db_space, self.dbs_needed, self.block_db_size,
            )
            raise RuntimeError(msg)
Beispiel #16
0
    def validate(self):
        """
        HDDs represent data devices, and solid state devices are for block.db,
        make sure that the number of data devices would have enough LVs and
        those LVs would be large enough to accommodate a block.db
        """
        # validate minimum size for all devices
        validators.minimum_device_size(self.devices, osds_per_device=self.osds_per_device)

        # make sure that data devices do not have any LVs
        validators.no_lvm_membership(self.hdds)

        # do not allow non-common VG to continue
        validators.has_common_vg(self.ssds)

        # find the common VG to calculate how much is available
        self.common_vg = self.get_common_vg()

        # find how many block.db LVs are possible from the common VG
        if self.common_vg:
            common_vg_size = disk.Size(gb=self.common_vg.free)
        else:
            common_vg_size = disk.Size(gb=0)

        # non-VG SSDs
        self.vg_ssds = set([d for d in self.ssds if d.is_lvm_member])
        self.blank_ssds = set(self.ssds).difference(self.vg_ssds)
        self.total_blank_ssd_size = disk.Size(b=0)
        for blank_ssd in self.blank_ssds:
            self.total_blank_ssd_size += disk.Size(b=blank_ssd.lvm_size.b)

        self.total_available_db_space = self.total_blank_ssd_size + common_vg_size

        # If not configured, we default to 0, which is really "use as much as
        # possible" captured by the `else` condition
        if self.block_db_size.gb > 0:
            try:
                self.vg_extents = lvm.sizing(
                    self.total_available_db_space.b, size=self.block_db_size.b * self.osds_per_device
                )
            except SizeAllocationError:
                msg = "Not enough space in fast devices (%s) to create %s x %s block.db LV"
                raise RuntimeError(
                    msg % (self.total_available_db_space, self.osds_per_device, self.block_db_size)
                )
        else:
            self.vg_extents = lvm.sizing(
                self.total_available_db_space.b, parts=self.dbs_needed
            )

        # validate that number of block.db LVs possible are enough for number of
        # OSDs proposed
        if self.total_available_db_space.b == 0:
            msg = "No space left in fast devices to create block.db LVs"
            raise RuntimeError(msg)

        # bluestore_block_db_size was unset, so we must set this to whatever
        # size we get by dividing the total available space for block.db LVs
        # into the number of block.db LVs needed (i.e. "as large as possible")
        if self.block_db_size.b == 0:
            self.block_db_size = self.total_available_db_space / self.dbs_needed
            self.use_large_block_db = True

        total_dbs_possible = self.total_available_db_space / self.block_db_size

        if self.dbs_needed > total_dbs_possible:
            msg = "Not enough space (%s) to create %s x %s block.db LVs" % (
                self.total_available_db_space, self.dbs_needed, self.block_db_size,
            )
            raise RuntimeError(msg)
Beispiel #17
0
    def _validate_wal_devs(self):
        # do not allow non-common VG to continue
        validators.has_common_vg(self.wal_devs)

        # find the common VG to calculate how much is available
        self.common_wal_vg = self.get_common_vg(self.wal_devs)

        # find how many block.wal LVs are possible from the common VG
        if self.common_wal_vg:
            common_vg_size = disk.Size(gb=self.common_wal_vg.free)
        else:
            common_vg_size = disk.Size(gb=0)

        # non-VG SSDs
        vg_members = set([d for d in self.wal_devs if d.is_lvm_member])
        self.blank_wal_devs = set(self.wal_devs).difference(vg_members)
        self.total_blank_wal_dev_size = disk.Size(b=0)
        for blank_wal_dev in self.blank_wal_devs:
            self.total_blank_wal_dev_size += disk.Size(
                b=blank_wal_dev.lvm_size.b)

        self.total_available_wal_space = self.total_blank_wal_dev_size + common_vg_size

        # If not configured, we default to 0, which is really "use as much as
        # possible" captured by the `else` condition
        if self.block_wal_size.gb > 0:
            try:
                self.vg_extents = lvm.sizing(self.total_available_wal_space.b,
                                             size=self.block_wal_size.b *
                                             self.osds_per_device)
            except SizeAllocationError:
                msg = "Not enough space in fast devices (%s) to create %s x %s block.wal LV"
                raise RuntimeError(msg %
                                   (self.total_available_wal_space,
                                    self.osds_per_device, self.block_wal_size))
        else:
            self.wal_vg_extents = lvm.sizing(self.total_available_wal_space.b,
                                             parts=self.wals_needed)

        # validate that number of block.wal LVs possible are enough for number of
        # OSDs proposed
        if self.total_available_wal_space.b == 0:
            msg = "No space left in fast devices to create block.wal LVs"
            raise RuntimeError(msg)

        # bluestore_block_wal_size was unset, so we must set this to whatever
        # size we get by dividing the total available space for block.wal LVs
        # into the number of block.wal LVs needed (i.e. "as large as possible")
        if self.block_wal_size.b == 0:
            self.block_wal_size = self.total_available_wal_space / self.wals_needed
            self.use_large_block_wal = True

        total_wals_possible = self.total_available_wal_space / self.block_wal_size

        if self.wals_needed > total_wals_possible:
            msg = "Not enough space (%s) to create %s x %s block.wal LVs" % (
                self.total_available_wal_space,
                self.wals_needed,
                self.block_wal_size,
            )
            raise RuntimeError(msg)
Beispiel #18
0
    def report_pretty(self, filtered_devices):
        string = ""
        if filtered_devices:
            string += templates.filtered_devices(filtered_devices)
        string += templates.total_osds.format(
            total_osds=len(self.data_devs) * self.osds_per_device
        )

        if self.db_or_journal_devs:
            vg_extents = lvm.sizing(self.total_available_db_space.b, parts=self.dbs_needed)
            db_size = str(disk.Size(b=(vg_extents['sizes'])))

            string += templates.ssd_volume_group.format(
                target='block.db',
                total_lv_size=str(self.total_available_db_space),
                total_lvs=vg_extents['parts'] * self.osds_per_device,
                block_lv_size=db_size,
                block_db_devices=', '.join([ssd.abspath for ssd in
                                            self.db_or_journal_devs]),
                lv_size=self.block_db_size or str(disk.Size(b=(vg_extents['sizes']))),
                total_osds=len(self.data_devs)
            )

        if self.wal_devs:
            wal_vg_extents = lvm.sizing(self.total_available_wal_space.b,
                                        parts=self.wals_needed)
            wal_size = str(disk.Size(b=(wal_vg_extents['sizes'])))
            string += templates.ssd_volume_group.format(
                target='block.wal',
                total_lv_size=str(self.total_available_wal_space),
                total_lvs=wal_vg_extents['parts'] * self.osds_per_device,
                block_lv_size=wal_size,
                block_db_devices=', '.join([dev.abspath for dev in
                                            self.wal_devs]),
                lv_size=self.block_wal_size or str(disk.Size(b=(wal_vg_extents['sizes']))),
                total_osds=len(self.data_devs)
            )

        string += templates.osd_component_titles
        for osd in self.computed['osds']:
            string += templates.osd_header
            if 'osd_id' in osd:
                string += templates.osd_reused_id.format(
                    id_=osd['osd_id'])
            string += templates.osd_component.format(
                _type='[data]',
                path=osd['data']['path'],
                size=osd['data']['human_readable_size'],
                percent=osd['data']['percentage'])

            if 'block.db' in osd:
                string += templates.osd_component.format(
                    _type='[block.db]',
                    path=osd['block.db']['path'],
                    size=osd['block.db']['human_readable_size'],
                    percent=osd['block.db']['percentage'])

            if 'block.wal' in osd:
                string += templates.osd_component.format(
                    _type='[block.wal]',
                    path=osd['block.wal']['path'],
                    size=osd['block.wal']['human_readable_size'],
                    percent=osd['block.wal']['percentage'])

        print(string)