Example #1
0
    def test_create_volume_dfn(self):
        rsc_dfn = self.execute_with_single_resp(
            ['resource-definition', 'create', 'rscvlm'])
        self.assert_api_succuess(rsc_dfn)

        vlm_dfn = self.execute_with_single_resp(
            ['volume-definition', 'create', 'rscvlm', '128MiB'])
        self.assert_api_succuess(vlm_dfn)
        self.assert_volume_def(
            'rscvlm', 0, None,
            SizeCalc.convert_round_up(128, SizeCalc.UNIT_MiB,
                                      SizeCalc.UNIT_KiB))

        vlm_dfn = self.execute_with_single_resp(
            ['volume-definition', 'create', 'rscvlm', '0'])
        self.assertTrue(vlm_dfn.is_error())
        self.assertEqual(
            self.signed_mask(MASK_VLM_DFN | MASK_CRT | FAIL_INVLD_VLM_SIZE),
            vlm_dfn.ret_code)

        vlm_dfn = self.execute_with_single_resp([
            'volume-definition', 'create', 'rscvlm', '--vlmnr', '3', '256Mib'
        ])
        self.assert_api_succuess(vlm_dfn)
        self.assertEqual(MASK_VLM_DFN | MASK_CRT | CREATED, vlm_dfn.ret_code)
        self.assert_volume_def(
            'rscvlm', 3, None,
            SizeCalc.convert_round_up(256, SizeCalc.UNIT_MiB,
                                      SizeCalc.UNIT_KiB))

        with self.assertRaises(SystemExit):
            self.execute_with_single_resp(
                ['volume-definition', 'create', 'rscvlm', '1Gi'])
Example #2
0
    def parse_opts(cls, new_args, object_name):
        modify = {}
        deletes = []
        for arg in new_args:
            is_unset = arg.startswith(cls.unsetprefix)
            value = new_args[arg]
            prop_name = arg[len(cls.unsetprefix) + 1:] if is_unset else arg
            if prop_name.startswith(
                    "drbd-") and prop_name[5:] in cls.CLASH_OPTIONS:
                prop_name = prop_name[5:]
            option = cls.drbd_options[object_name][prop_name]

            key = option['key']
            if is_unset:
                deletes.append(key)
            else:
                if DrbdOptions._is_byte_unit(option):
                    unit = SizeCalc.UNIT_KiB if option.get(
                        'unit_prefix') == 'k' else SizeCalc.UNIT_B
                    value = SizeCalc.auto_convert(value, unit)
                    if option['min'] <= value <= option['max']:
                        value = str(value)
                    else:
                        raise ArgumentError(
                            prop_name +
                            " value {v}{u} is out of range [{mi}-{ma}]".format(
                                v=value,
                                u=SizeCalc.unit_to_str(unit),
                                mi=str(option['min']) +
                                option.get('unit_prefix', ''),
                                ma=str(option['max']) +
                                option.get('unit_prefix', '')))
                modify[key] = str(value)

        return modify, deletes
Example #3
0
    def test_size_calc_convert(self):
        self.assertEqual(10485760,
                         SizeCalc.auto_convert("10M", SizeCalc.UNIT_B))
        self.assertEqual(10485760,
                         SizeCalc.auto_convert("10MiB", SizeCalc.UNIT_B))
        self.assertEqual(10000000,
                         SizeCalc.auto_convert("10MB", SizeCalc.UNIT_B))

        self.assertEqual(3221225472,
                         SizeCalc.auto_convert("3Gib", SizeCalc.UNIT_B))
        self.assertEqual(3145728,
                         SizeCalc.auto_convert("3Gib", SizeCalc.UNIT_KiB))
    def parse_opts(cls, new_args, object_name):
        modify = {}
        deletes = []
        for arg in new_args:
            value = new_args[arg]
            is_unset = arg.startswith(cls.unsetprefix)
            prop_name = arg[len(cls.unsetprefix) + 1:] if is_unset else arg
            option = cls.drbd_options[object_name][prop_name]

            key = option['key']
            if is_unset:
                deletes.append(key)
            else:
                if 'bytes' in option and option['unit'] == 'bytes':
                    value = SizeCalc.auto_convert(value, SizeCalc.UNIT_B)
                    if option['min'] < value < option['max']:
                        value = str(value)
                    else:
                        raise argparse.ArgumentTypeError(
                            prop_name +
                            " value {v} is out of range [{mi}-{ma}]".format(
                                v=value, mi=option['min'], ma=option['max']))
                modify[key] = str(value)

        return modify, deletes
Example #5
0
    def parse_size_str(cls, size_str, default_unit="GiB"):
        if size_str is None:
            return None
        m = re.match(r'(\d+)(\D*)', size_str)

        size = 0
        try:
            size = int(m.group(1))
        except AttributeError:
            sys.stderr.write('Size is not a valid number\n')
            sys.exit(ExitCode.ARGPARSE_ERROR)

        unit_str = m.group(2)
        if unit_str == "":
            unit_str = default_unit
        try:
            _, unit = SizeCalc.UNITS_MAP[unit_str.lower()]
        except KeyError:
            sys.stderr.write('"%s" is not a valid unit!\n' % unit_str)
            sys.stderr.write('Valid units: %s\n' % SizeCalc.UNITS_LIST_STR)
            sys.exit(ExitCode.ARGPARSE_ERROR)

        _, unit = SizeCalc.UNITS_MAP[unit_str.lower()]

        if unit != SizeCalc.UNIT_KiB:
            size = SizeCalc.convert_round_up(size, unit, SizeCalc.UNIT_KiB)

        return size
Example #6
0
    def show(cls, args, lstmsg):
        tbl = linstor_client.Table(utf8=not args.no_utf8, colors=not args.no_color, pastable=args.pastable)

        vlm_dfn_hdrs = list(cls._vlm_dfn_headers)
        if args.external_name:
            vlm_dfn_hdrs.insert(1, linstor_client.TableHeader("External"))
        for hdr in vlm_dfn_hdrs:
            tbl.add_header(hdr)

        tbl.set_groupby(args.groupby if args.groupby else [tbl.header_name(0)])
        for rsc_dfn in lstmsg.resource_definitions:
            for vlmdfn in rsc_dfn.volume_definitions:
                state = tbl.color_cell("ok", Color.DARKGREEN)
                if FLAG_DELETE in vlmdfn.flags:
                    state = tbl.color_cell("DELETING", Color.RED)
                elif FLAG_RESIZE in vlmdfn.flags:
                    state = tbl.color_cell("resizing", Color.DARKPINK)

                drbd_data = vlmdfn.drbd_data
                tbl.add_row([
                    rsc_dfn.name,
                    vlmdfn.number,
                    drbd_data.minor if drbd_data else "",
                    SizeCalc.approximate_size_string(vlmdfn.size),
                    "+" if FLAG_GROSS_SIZE in vlmdfn.flags else "",
                    state
                ])
        tbl.show()
Example #7
0
    def show(cls, args, lstmsg):
        tbl = linstor_client.Table(utf8=not args.no_utf8,
                                   colors=not args.no_color,
                                   pastable=args.pastable)
        tbl.add_column("ResourceName")
        tbl.add_column("SnapshotName")
        tbl.add_column("NodeNames")
        tbl.add_column("Volumes")
        tbl.add_column("State",
                       color=Output.color(Color.DARKGREEN, args.no_color))
        for snapshot_dfn in lstmsg.snapshots:
            if FLAG_DELETE in snapshot_dfn.flags:
                state_cell = tbl.color_cell("DELETING", Color.RED)
            elif FLAG_FAILED_DEPLOYMENT in snapshot_dfn.flags:
                state_cell = tbl.color_cell("Failed", Color.RED)
            elif FLAG_FAILED_DISCONNECT in snapshot_dfn.flags:
                state_cell = tbl.color_cell("Satellite disconnected",
                                            Color.RED)
            elif FLAG_SUCCESSFUL in snapshot_dfn.flags:
                state_cell = tbl.color_cell("Successful", Color.DARKGREEN)
            else:
                state_cell = tbl.color_cell("Incomplete", Color.DARKBLUE)

            tbl.add_row([
                snapshot_dfn.resource_name, snapshot_dfn.name,
                ", ".join([node_name for node_name in snapshot_dfn.nodes]),
                ", ".join([
                    str(snapshot_vlm_dfn.number) + ": " +
                    SizeCalc.approximate_size_string(snapshot_vlm_dfn.size)
                    for snapshot_vlm_dfn in
                    snapshot_dfn.snapshot_volume_definitions
                ]), state_cell
            ])
        tbl.show()
Example #8
0
    def _show_query_max_volume(self, args, lstmsg):
        """
        DEPRECATED will be removed
        :param args:
        :param lstmsg:
        :return:
        """
        print(
            Output.color_str("DEPRECATED:", Color.YELLOW, args.no_color) +
            " use `linstor controller query-max-volume-size`")
        tbl = linstor_client.Table(utf8=not args.no_utf8,
                                   colors=not args.no_color,
                                   pastable=args.pastable)
        tbl.add_column("StoragePool")
        tbl.add_column("MaxVolumeSize", just_txt='>')
        tbl.add_column("Provisioning")
        tbl.add_column("Nodes")

        def limited_string(obj_list):
            limit = 40
            s = ""
            list_length = len(obj_list)
            for i in range(0, len(obj_list)):
                obj = obj_list[i]
                s += obj + (", " if i != list_length - 1 else "")
                if len(s) > limit:
                    s = s[:limit - 3] + "..."

            return s

        storage_pool_dfns = self.get_linstorapi().storage_pool_dfn_list(
        )[0].storage_pool_definitions

        for candidate in lstmsg.candidates:
            max_vlm_size = SizeCalc.approximate_size_string(
                candidate.max_volume_size)

            storage_pool_props = [
                x for x in storage_pool_dfns
                if x.name == candidate.storage_pool
            ][0].properties
            max_oversubscription_ratio_props = \
                [x for x in storage_pool_props if x.key == KEY_STOR_POOL_DFN_MAX_OVERSUBSCRIPTION_RATIO]
            max_oversubscription_ratio_prop = max_oversubscription_ratio_props[0].value \
                if max_oversubscription_ratio_props \
                else lstmsg.default_max_oversubscription_ratio
            max_oversubscription_ratio = float(max_oversubscription_ratio_prop)

            tbl.add_row([
                candidate.storage_pool, max_vlm_size,
                "Thin, oversubscription ratio " +
                str(max_oversubscription_ratio)
                if candidate.all_thin else "Thick",
                limited_string(candidate.node_names)
            ])
        tbl.show()
Example #9
0
    def show(self, args, lstmsg):
        tbl = linstor_client.Table(utf8=not args.no_utf8,
                                   colors=not args.no_color,
                                   pastable=args.pastable)
        for hdr in self._stor_pool_headers:
            tbl.add_header(hdr)

        storage_pool_resp = lstmsg  # type: StoragePoolListResponse

        tbl.set_groupby(args.groupby if args.
                        groupby else [self._stor_pool_headers[0].name])

        errors = []
        for storpool in storage_pool_resp.storage_pools:
            driver_device = linstor.StoragePoolDriver.storage_props_to_driver_pool(
                storpool.provider_kind, storpool.properties)

            free_capacity = ""
            total_capacity = ""
            if not storpool.is_diskless() and storpool.free_space is not None:
                free_capacity = SizeCalc.approximate_size_string(
                    storpool.free_space.free_capacity)
                total_capacity = SizeCalc.approximate_size_string(
                    storpool.free_space.total_capacity)

            for error in storpool.reports:
                if error not in errors:
                    errors.append(error)

            state_str, state_color = self.get_replies_state(storpool.reports)
            tbl.add_row([
                storpool.name, storpool.node_name, storpool.provider_kind,
                driver_device, free_capacity, total_capacity,
                storpool.supports_snapshots(),
                tbl.color_cell(state_str,
                               state_color), storpool.free_space_mgr_name
                if ':' not in storpool.free_space_mgr_name else ''
            ])
        tbl.show()
        for err in errors:
            Output.handle_ret(err,
                              warn_as_error=args.warn_as_error,
                              no_color=args.no_color)
Example #10
0
    def show(cls, args, lstmsg):
        tbl = linstor_client.Table(utf8=not args.no_utf8,
                                   colors=not args.no_color,
                                   pastable=args.pastable)
        tbl.add_column("ResourceName")
        tbl.add_column("SnapshotName")
        tbl.add_column("NodeNames")
        tbl.add_column("Volumes")
        tbl.add_column("CreatedOn")
        tbl.add_column("State",
                       color=Output.color(Color.DARKGREEN, args.no_color))
        for snapshot_dfn in lstmsg.snapshots:
            if FLAG_DELETE in snapshot_dfn.flags:
                state_cell = tbl.color_cell("DELETING", Color.RED)
            elif FLAG_FAILED_DEPLOYMENT in snapshot_dfn.flags:
                state_cell = tbl.color_cell("Failed", Color.RED)
            elif FLAG_FAILED_DISCONNECT in snapshot_dfn.flags:
                state_cell = tbl.color_cell("Satellite disconnected",
                                            Color.RED)
            elif FLAG_SUCCESSFUL in snapshot_dfn.flags:
                in_backup_restore = False
                in_backup_create = False
                if FLAG_BACKUP in snapshot_dfn.flags and FLAG_SHIPPING in snapshot_dfn.flags:
                    for snap in snapshot_dfn.snapshots:
                        in_backup_create |= FLAG_BACKUP_SOURCE in snap.flags
                        in_backup_restore |= FLAG_BACKUP_TARGET in snap.flags
                if in_backup_create:
                    state_cell = tbl.color_cell("Shipping", Color.YELLOW)
                elif in_backup_restore:
                    state_cell = tbl.color_cell("Restoring", Color.YELLOW)
                else:
                    state_cell = tbl.color_cell("Successful", Color.DARKGREEN)
            else:
                state_cell = tbl.color_cell("Incomplete", Color.DARKBLUE)

            snapshot_date = ""
            if snapshot_dfn.snapshots and snapshot_dfn.snapshots[
                    0].create_datetime:
                snapshot_date = str(
                    snapshot_dfn.snapshots[0].create_datetime)[:19]

            tbl.add_row([
                snapshot_dfn.resource_name, snapshot_dfn.name,
                ", ".join([node_name for node_name in snapshot_dfn.nodes]),
                ", ".join([
                    str(snapshot_vlm_dfn.number) + ": " +
                    SizeCalc.approximate_size_string(snapshot_vlm_dfn.size)
                    for snapshot_vlm_dfn in
                    snapshot_dfn.snapshot_volume_definitions
                ]), snapshot_date, state_cell
            ])
        tbl.show()
Example #11
0
    def make_volume_node(cls, vlm):
        """

        :param responses.Volume vlm:
        :return:
        """
        volume_node = TreeNode('volume' + str(vlm.number), '', Color.DARKGREEN)
        volume_node.set_description('minor number: ' + str(vlm.drbd_data.drbd_volume_definition.minor)
                                    if vlm.drbd_data else '')
        volume_node.add_description(
            ', size: ' + str(SizeCalc.approximate_size_string(vlm.allocated_size))
        )
        return volume_node
Example #12
0
def resize_disk(resource, target_vm, disk_id, new_size):
    """

    :param Resource resource:
    :param vm.Vm target_vm:
    :param str disk_id:
    :param int new_size: new size in mega bytes
    :return:
    """
    util.log_info("Resizing resource {r} new size: {s}MiB".format(
        r=resource.name, s=new_size))
    resource.volumes[0].size = SizeCalc.convert(new_size, SizeCalc.UNIT_MiB,
                                                SizeCalc.UNIT_B)

    resize_if_qcow2(resource, target_vm, disk_id, new_size)
Example #13
0
    def _show_query_max_volume(self, args, lstmsg):
        tbl = linstor_client.Table(utf8=not args.no_utf8,
                                   colors=not args.no_color,
                                   pastable=args.pastable)
        tbl.add_column("StoragePool")
        tbl.add_column("MaxVolumeSize", just_txt='>')
        tbl.add_column("Provisioning")
        tbl.add_column("Nodes")

        def limited_string(obj_list):
            limit = 40
            s = ""
            list_length = len(obj_list)
            for i in range(0, len(obj_list)):
                obj = obj_list[i]
                s += obj + (", " if i != list_length - 1 else "")
                if len(s) > limit:
                    s = s[:limit - 3] + "..."

            return s

        storage_pool_dfns = self.get_linstorapi().storage_pool_dfn_list(
        )[0].storage_pool_definitions

        for candidate in lstmsg.candidates:
            max_vlm_size = SizeCalc.approximate_size_string(
                candidate.max_volume_size)

            storage_pool_props = [
                x for x in storage_pool_dfns
                if x.name == candidate.storage_pool
            ][0].properties
            max_oversubscription_ratio = float(
                storage_pool_props.get(
                    KEY_STOR_POOL_DFN_MAX_OVERSUBSCRIPTION_RATIO,
                    lstmsg.default_max_oversubscription_ratio))

            tbl.add_row([
                candidate.storage_pool, max_vlm_size,
                "Thin, oversubscription ratio " +
                str(max_oversubscription_ratio)
                if candidate.all_thin else "Thick",
                limited_string(candidate.node_names)
            ])
        tbl.show()
Example #14
0
    def show_volumes(cls, args, lstmsg):
        """

        :param args:
        :param responses.ResourceResponse lstmsg: resource response data to display
        :return: None
        """
        tbl = Table(utf8=not args.no_utf8,
                    colors=not args.no_color,
                    pastable=args.pastable)
        tbl.add_column("Node")
        tbl.add_column("Resource")
        tbl.add_column("StoragePool")
        tbl.add_column("VolNr", just_txt='>')
        tbl.add_column("MinorNr", just_txt='>')
        tbl.add_column("DeviceName")
        tbl.add_column("Allocated", just_txt='>')
        tbl.add_column("InUse",
                       color=Output.color(Color.DARKGREEN, args.no_color))
        tbl.add_column("State",
                       color=Output.color(Color.DARKGREEN, args.no_color),
                       just_txt='>')

        rsc_state_lkup = {
            x.node_name + x.name: x
            for x in lstmsg.resource_states
        }

        reports = []
        for rsc in lstmsg.resources:
            if not args.all and apiconsts.FLAG_TIE_BREAKER in rsc.flags:
                continue  # skip tie breaker resources

            if apiconsts.FLAG_RSC_INACTIVE in rsc.flags:
                continue  # do not show non existing volumes for inactive resources

            rsc_state = rsc_state_lkup.get(rsc.node_name + rsc.name)
            rsc_usage = ""
            if rsc_state and rsc_state.in_use is not None:
                if rsc_state.in_use:
                    rsc_usage = tbl.color_cell("InUse", Color.GREEN)
                else:
                    rsc_usage = "Unused"
            for vlm in rsc.volumes:
                vlm_state = cls.get_volume_state(
                    rsc_state.volume_states, vlm.number) if rsc_state else None
                state_txt, color = cls.volume_state_cell(
                    vlm_state, rsc.flags, vlm.flags)
                has_errors = any([x.is_error() for x in vlm.reports])
                conn_failed = (rsc.layer_data.drbd_resource
                               and any(not v.connected
                                       for k, v in rsc.layer_data.
                                       drbd_resource.connections.items()))
                if conn_failed:
                    color = Color.RED

                state = tbl.color_cell(state_txt,
                                       color) if color else state_txt
                if has_errors:
                    state = tbl.color_cell("Error", Color.RED)
                for x in vlm.reports:
                    reports.append(x)
                vlm_drbd_data = vlm.drbd_data
                tbl.add_row([
                    rsc.node_name, rsc.name, vlm.storage_pool_name,
                    str(vlm.number),
                    str(vlm_drbd_data.drbd_volume_definition.minor)
                    if vlm_drbd_data else "", vlm.device_path,
                    SizeCalc.approximate_size_string(vlm.allocated_size)
                    if vlm.allocated_size else "", rsc_usage, state
                ])

        tbl.show()
        for x in reports:
            Output.handle_ret(x,
                              args.no_color,
                              warn_as_error=args.warn_as_error)
Example #15
0
 def assertSizeUnit(self, val, exp_size, exp_unit):
     size, unit = SizeCalc.parse_unit(val)
     self.assertEqual(exp_size, size)
     self.assertEqual(exp_unit, unit)
Example #16
0
    def show_backups_info(cls, args, lstmsg):
        rsc_tbl = Table(utf8=not args.no_utf8,
                        colors=not args.no_color,
                        pastable=args.pastable)

        rsc_tbl.add_column("Resource")
        rsc_tbl.add_column("Snapshot")
        rsc_tbl.add_column("Full Backup")
        rsc_tbl.add_column("Latest Backup")
        rsc_tbl.add_column("Backup Count")
        rsc_tbl.add_column("Download Size")
        rsc_tbl.add_column("Allocated Size")

        # table will only have a single row
        row = [
            lstmsg.rsc, lstmsg.snap, lstmsg.full, lstmsg.latest, lstmsg.count
        ]
        row += [
            SizeCalc.approximate_size_string(lstmsg.dl_size),
            SizeCalc.approximate_size_string(lstmsg.alloc_size)
        ]
        rsc_tbl.add_row(row)
        rsc_tbl.show()

        stor_pool_tbl = Table(utf8=not args.no_utf8,
                              colors=not args.no_color,
                              pastable=args.pastable)

        stor_pool_tbl.add_column("Origin StorPool (Type)")
        if args.target_node:
            stor_pool_tbl.add_column("Target Pool")
            stor_pool_tbl.add_column("Remaining Free Space")
        stor_pool_tbl.add_column("Volume to Download")
        stor_pool_tbl.add_column("Type")
        stor_pool_tbl.add_column("Download Size")
        stor_pool_tbl.add_column("Allocated Size")
        stor_pool_tbl.add_column("Usable Size")

        for stor_pool in lstmsg.storpools:
            row = [stor_pool.name + " (" + stor_pool.provider_kind + ")"]
            if args.target_node:
                row += [
                    stor_pool.target_name,
                ]
                if stor_pool.remaining_space < 0:
                    row += [
                        stor_pool_tbl.color_cell(
                            "-" + SizeCalc.approximate_size_string(
                                -stor_pool.remaining_space), Color.RED)
                    ]
                else:
                    row += [
                        SizeCalc.approximate_size_string(
                            stor_pool.remaining_space)
                    ]

            vlm_to_dl_cell = []
            type_cell = []
            dl_size_cell = []
            alloc_size_cell = []
            usable_size_cell = []
            for volume in stor_pool.volumes:
                vlm_to_dl_cell += [volume.name if volume.name else "-"]
                type_cell += [volume.layer_type]
                dl_size_cell += [
                    SizeCalc.approximate_size_string(volume.dl_size)
                    if volume.dl_size else "-"
                ]
                alloc_size_cell += [
                    SizeCalc.approximate_size_string(volume.alloc_size)
                    if volume.alloc_size else "-"
                ]
                usable_size_cell += [
                    SizeCalc.approximate_size_string(volume.usable_size)
                    if volume.usable_size else "-"
                ]
            row += [
                "\n".join(vlm_to_dl_cell), "\n".join(type_cell),
                "\n".join(dl_size_cell), "\n".join(alloc_size_cell),
                "\n".join(usable_size_cell)
            ]
            stor_pool_tbl.add_row(row)

        stor_pool_tbl.show()