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 { Alert } from "@patternfly/react-core/dist/esm/components/Alert/index.js";
11 : import { CardBody } from "@patternfly/react-core/dist/esm/components/Card/index.js";
12 :
13 : import { get_partitions, register_available_free_space } from "../utils.js";
14 : import { StorageCard, ChildrenTable, new_page, new_card } from "../pages.jsx";
15 : import { format_dialog } from "../block/format-dialog.jsx";
16 : import { make_block_page } from "../block/create-pages.jsx";
17 :
18 : import { make_partition_card, delete_partition } from "./partition.jsx";
19 :
20 113 : const _ = cockpit.gettext;
21 :
22 104 : function make_partition_pages(parent, block) {
23 104 : const block_ptable = client.blocks_ptable[block.path];
24 104 : let counter = 0;
25 :
26 18 : function make_free_space_page(parent, start, size, enable_dos_extended) {
27 18 : counter++;
28 18 : const card = new_card({
29 18 : page_name: _("Free space"),
30 18 : page_key: "free-space-" + counter,
31 18 : page_size: size,
32 18 : actions: [
33 18 : {
34 18 : title: _("Create partition"),
35 12 : action: () => format_dialog(client, block.path, start, size,
36 12 : enable_dos_extended),
37 18 : }
38 18 : ],
39 18 : });
40 18 : new_page(parent, card);
41 18 : }
42 :
43 2 : function make_extended_partition_page(parent, partition) {
44 2 : const card = new_card({
45 2 : page_name: _("Extended partition"),
46 2 : page_size: partition.size,
47 2 : actions: [
48 1 : { title: _("Delete"), action: () => delete_partition(partition.block, card), danger: true },
49 2 : ]
50 2 : });
51 2 : const page = new_page(parent, card);
52 2 : process_partitions(page, partition.partitions, false);
53 2 : }
54 :
55 104 : function process_partitions(parent, partitions, enable_dos_extended) {
56 104 : let i;
57 104 : let p;
58 104 : for (i = 0; i < partitions.length; i++) {
59 104 : p = partitions[i];
60 28 : if (p.type == 'free') {
61 28 : register_available_free_space(client, block, p);
62 28 : make_free_space_page(parent, p.start, p.size, enable_dos_extended);
63 28 : } else if (p.type == 'container')
64 13 : make_extended_partition_page(parent, p);
65 104 : else {
66 104 : const card = make_partition_card(null, p.block);
67 104 : make_block_page(parent, p.block, card);
68 104 : }
69 104 : }
70 104 : }
71 :
72 104 : process_partitions(parent, get_partitions(client, block),
73 104 : block_ptable.Type == 'dos');
74 104 : }
75 :
76 104 : export function make_partition_table_page(parent, block, next_card, partitionable) {
77 104 : const block_ptable = client.blocks_ptable[block.path];
78 :
79 104 : const parts_card = new_card({
80 104 : title: (block_ptable.Type
81 104 : ? cockpit.format(_("$0 partitions"), block_ptable.Type.toLocaleUpperCase())
82 12 : : _("Partitions")),
83 104 : next: next_card,
84 12 : component: partitionable ? PartitionsCard : UnexpectedPartitionsCard,
85 104 : props: { },
86 104 : });
87 :
88 104 : const p = new_page(parent, parts_card, { sorted: false });
89 104 : if (partitionable)
90 104 : make_partition_pages(p, block);
91 104 : }
92 :
93 14 : const PartitionsCard = ({ card }) => {
94 14 : return (
95 14 : <StorageCard card={card}>
96 14 : <ChildrenTable
97 14 : emptyCaption={_("No partitions found")}
98 14 : aria-label={_("Partitions")}
99 14 : page={card.page} />
100 14 : </StorageCard>
101 : );
102 14 : };
103 :
104 1 : const UnexpectedPartitionsCard = ({ card }) => {
105 1 : return (
106 1 : <StorageCard card={card}>
107 1 : <CardBody>
108 1 : <Alert isInline isPlain variant="info" title={_("Unexpected partitions")}>
109 1 : <p>{_("Partitions are not supported on this block device. If it is used as a disk for a virtual machine, the partitions must be managed by the operating system inside the virtual machine.")}</p>
110 1 : </Alert>
111 1 : </CardBody>
112 1 : </StorageCard>
113 : );
114 1 : };
|