Line data Source code
1 : /*
2 : * Copyright (C) 2023 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 113 : import cockpit from "cockpit";
7 113 : import React from "react";
8 : import client from "../client";
9 :
10 : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
11 : import { CardBody } from "@patternfly/react-core/dist/esm/components/Card/index.js";
12 : import { DescriptionList } from "@patternfly/react-core/dist/esm/components/DescriptionList/index.js";
13 :
14 : import { StorageCard, StorageDescription, new_card, register_crossref } from "../pages.jsx";
15 : import { std_format_action } from "../block/actions.jsx";
16 : import { std_lock_action } from "../crypto/actions.jsx";
17 : import { StorageUsageBar } from "../storage-controls.jsx";
18 :
19 113 : const _ = cockpit.gettext;
20 :
21 25 : export function make_lvm2_physical_volume_card(next, backing_block, content_block) {
22 25 : const block_pvol = client.blocks_pvol[content_block.path];
23 25 : const vgroup = block_pvol && client.vgroups[block_pvol.VolumeGroup];
24 :
25 25 : const pv_card = new_card({
26 25 : title: _("LVM2 physical volume"),
27 25 : location: {
28 24 : label: vgroup ? vgroup.Name : null,
29 24 : to: vgroup ? ["vg", vgroup.Name] : null,
30 25 : },
31 25 : next,
32 25 : page_size: (block_pvol
33 25 : ? <StorageUsageBar stats={[block_pvol.Size - block_pvol.FreeSize, block_pvol.Size]} short />
34 24 : : backing_block.Size),
35 25 : component: LVM2PhysicalVolumeCard,
36 25 : props: { backing_block, content_block },
37 25 : actions: [
38 25 : std_lock_action(backing_block, content_block),
39 25 : std_format_action(backing_block, content_block),
40 25 : ]
41 25 : });
42 :
43 1 : function pvol_remove() {
44 1 : return vgroup.RemoveDevice(block_pvol.path, true, {});
45 1 : }
46 :
47 0 : function pvol_empty_and_remove() {
48 0 : return (vgroup.EmptyDevice(block_pvol.path, {})
49 0 : .then(function() {
50 0 : vgroup.RemoveDevice(block_pvol.path, true, {});
51 0 : }));
52 0 : }
53 :
54 25 : if (vgroup) {
55 0 : const pvols = client.vgroups_pvols[vgroup.path] || [];
56 25 : let remove_action = null;
57 25 : let remove_excuse = null;
58 :
59 3 : if (vgroup.MissingPhysicalVolumes && vgroup.MissingPhysicalVolumes.length > 0) {
60 3 : remove_excuse = _("Volume group is missing physical volumes");
61 3 : } else if (pvols.length === 1) {
62 25 : remove_excuse = _("Last cannot be removed");
63 8 : } else if (block_pvol.FreeSize < block_pvol.Size) {
64 8 : if (block_pvol.Size <= vgroup.FreeSize)
65 5 : remove_action = pvol_empty_and_remove;
66 : else
67 7 : remove_excuse = _("Not enough free space");
68 8 : } else {
69 10 : remove_action = pvol_remove;
70 10 : }
71 :
72 25 : register_crossref({
73 25 : key: vgroup,
74 25 : card: pv_card,
75 25 : actions: [
76 25 : {
77 25 : title: _("Remove"),
78 25 : action: remove_action,
79 25 : excuse: remove_excuse,
80 25 : },
81 25 : ],
82 25 : size: <StorageUsageBar stats={[block_pvol.Size - block_pvol.FreeSize, block_pvol.Size]} short />,
83 25 : });
84 25 : }
85 :
86 25 : return pv_card;
87 25 : }
88 :
89 1 : export const LVM2PhysicalVolumeCard = ({ card, backing_block, content_block }) => {
90 1 : const block_pvol = client.blocks_pvol[content_block.path];
91 1 : const vgroup = block_pvol && client.vgroups[block_pvol.VolumeGroup];
92 :
93 1 : return (
94 1 : <StorageCard card={card}>
95 1 : <CardBody>
96 1 : <DescriptionList className="pf-m-horizontal-on-sm">
97 1 : <StorageDescription title={_("Volume group")}>
98 1 : {vgroup
99 1 : ? <Button variant="link" isInline role="link"
100 0 : onClick={() => cockpit.location.go(["vg", vgroup.Name])}>
101 1 : {vgroup.Name}
102 1 : </Button>
103 0 : : "-"
104 : }
105 1 : </StorageDescription>
106 1 : <StorageDescription title={_("UUID")} value={content_block.IdUUID} />
107 1 : { block_pvol &&
108 1 : <StorageDescription title={_("Usage")}>
109 1 : <StorageUsageBar key="s"
110 1 : stats={[block_pvol.Size - block_pvol.FreeSize,
111 1 : block_pvol.Size]} />
112 1 : </StorageDescription>
113 : }
114 1 : </DescriptionList>
115 1 : </CardBody>
116 1 : </StorageCard>);
117 1 : };
|