🏡 index : quine-global-labs/mirror-cockpit-project-cockpit.git

/*
 * Copyright (C) 2023 Red Hat, Inc.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */

import cockpit from "cockpit";
import React from "react";
import client from "../client";

import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
import { CardBody } from "@patternfly/react-core/dist/esm/components/Card/index.js";
import { DescriptionList } from "@patternfly/react-core/dist/esm/components/DescriptionList/index.js";

import { StorageCard, StorageDescription, new_card, register_crossref } from "../pages.jsx";
import { std_format_action } from "../block/actions.jsx";
import { std_lock_action } from "../crypto/actions.jsx";
import { StorageUsageBar } from "../storage-controls.jsx";

const _ = cockpit.gettext;

export function make_lvm2_physical_volume_card(next, backing_block, content_block) {
    const block_pvol = client.blocks_pvol[content_block.path];
    const vgroup = block_pvol && client.vgroups[block_pvol.VolumeGroup];

    const pv_card = new_card({
        title: _("LVM2 physical volume"),
        location: {
            label: vgroup ? vgroup.Name : null,
            to: vgroup ? ["vg", vgroup.Name] : null,
        },
        next,
        page_size: (block_pvol
            ? <StorageUsageBar stats={[block_pvol.Size - block_pvol.FreeSize, block_pvol.Size]} short />
            : backing_block.Size),
        component: LVM2PhysicalVolumeCard,
        props: { backing_block, content_block },
        actions: [
            std_lock_action(backing_block, content_block),
            std_format_action(backing_block, content_block),
        ]
    });

    function pvol_remove() {
        return vgroup.RemoveDevice(block_pvol.path, true, {});
    }

    function pvol_empty_and_remove() {
        return (vgroup.EmptyDevice(block_pvol.path, {})
                .then(function() {
                    vgroup.RemoveDevice(block_pvol.path, true, {});
                }));
    }

    if (vgroup) {
        const pvols = client.vgroups_pvols[vgroup.path] || [];
        let remove_action = null;
        let remove_excuse = null;

        if (vgroup.MissingPhysicalVolumes && vgroup.MissingPhysicalVolumes.length > 0) {
            remove_excuse = _("Volume group is missing physical volumes");
        } else if (pvols.length === 1) {
            remove_excuse = _("Last cannot be removed");
        } else if (block_pvol.FreeSize < block_pvol.Size) {
            if (block_pvol.Size <= vgroup.FreeSize)
                remove_action = pvol_empty_and_remove;
            else
                remove_excuse = _("Not enough free space");
        } else {
            remove_action = pvol_remove;
        }

        register_crossref({
            key: vgroup,
            card: pv_card,
            actions: [
                {
                    title: _("Remove"),
                    action: remove_action,
                    excuse: remove_excuse,
                },
            ],
            size: <StorageUsageBar stats={[block_pvol.Size - block_pvol.FreeSize, block_pvol.Size]} short />,
        });
    }

    return pv_card;
}

export const LVM2PhysicalVolumeCard = ({ card, backing_block, content_block }) => {
    const block_pvol = client.blocks_pvol[content_block.path];
    const vgroup = block_pvol && client.vgroups[block_pvol.VolumeGroup];

    return (
        <StorageCard card={card}>
            <CardBody>
                <DescriptionList className="pf-m-horizontal-on-sm">
                    <StorageDescription title={_("Volume group")}>
                        {vgroup
                            ? <Button variant="link" isInline role="link"
                                   onClick={() => cockpit.location.go(["vg", vgroup.Name])}>
                                {vgroup.Name}
                            </Button>
                            : "-"
                        }
                    </StorageDescription>
                    <StorageDescription title={_("UUID")} value={content_block.IdUUID} />
                    { block_pvol &&
                    <StorageDescription title={_("Usage")}>
                        <StorageUsageBar key="s"
                                           stats={[block_pvol.Size - block_pvol.FreeSize,
                                               block_pvol.Size]} />
                    </StorageDescription>
                    }
                </DescriptionList>
            </CardBody>
        </StorageCard>);
};