Skip to content

Commit

Permalink
Merge pull request #4837 from KKoukiou/webui-show-partitions
Browse files Browse the repository at this point in the history
webui: show partitions of local standard disks
  • Loading branch information
KKoukiou authored Jun 15, 2023
2 parents 30e4f3a + 1e15ed5 commit 5a3f544
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 10 deletions.
24 changes: 24 additions & 0 deletions ui/webui/src/apis/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,19 @@ export const getDiskFreeSpace = ({ diskNames }) => {
);
};

/**
* @param {string} disk Name A disk name
*
* @returns {Promise} Resolves the device format data
*/
export const getFormatData = ({ diskName }) => {
return new StorageClient().client.call(
"/org/fedoraproject/Anaconda/Modules/Storage/DeviceTree",
"org.fedoraproject.Anaconda.Modules.Storage.DeviceTree.Viewer",
"GetFormatData", [diskName]
);
};

/**
* @param {int} requiredSpace A required space in bytes
*
Expand Down Expand Up @@ -125,6 +138,17 @@ export const getDiskTotalSpace = ({ diskNames }) => {
);
};

/**
* @returns {Promise} Resolves all devices in a device tree
*/
export const getDevices = () => {
return new StorageClient().client.call(
"/org/fedoraproject/Anaconda/Modules/Storage/DeviceTree",
"org.fedoraproject.Anaconda.Modules.Storage.DeviceTree.Viewer",
"GetDevices", []
);
};

/**
* @returns {Promise} Resolves a list with disk names
*/
Expand Down
22 changes: 22 additions & 0 deletions ui/webui/src/components/app.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import "global-variables";

// Copied from cockpit/pkg/lib/page.scss instead of including it in its entirety:
// Let PF4 handle the scrolling through page component otherwise we might get double scrollbar
html:not(.index-page) body {
Expand All @@ -15,3 +17,23 @@ html:not(.index-page) body {
#installation-wizard .pf-c-wizard__main-body {
flex: 1 1 auto;
}

// Nested tables showing partitions in the local standards disks table should not fill space in larger screens
@media (min-width: $pf-global--breakpoint--lg) {
.ct-table .pf-c-table__expandable-row-content {
display: flex;
}
.ct-table .ct-table {
flex: 75% 0 0;
}
}

// Nested tables showing partitions in the local standards disks table don't need borders for last row
.ct-table .ct-table tr:last-child {
border: none;
}

// Nested tables showing partitions in the local standards disks table don't need extra padding
.ct-table .pf-c-table__expandable-row-content {
padding: 0;
}
56 changes: 47 additions & 9 deletions ui/webui/src/components/storage/InstallationDestination.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import {
Tooltip,
} from "@patternfly/react-core";

import { HelpIcon } from "@patternfly/react-icons";
import { HelpIcon, LockIcon } from "@patternfly/react-icons";

import { EmptyStatePanel } from "cockpit-components-empty-state.jsx";
import { ListingTable } from "cockpit-components-table.jsx";
Expand All @@ -54,9 +54,11 @@ import {
applyPartitioning,
createPartitioning,
getAllDiskSelection,
getDevices,
getDeviceData,
getDiskFreeSpace,
getDiskTotalSpace,
getFormatData,
getRequiredDeviceSize,
getUsableDisks,
partitioningConfigureWithTask,
Expand Down Expand Up @@ -203,7 +205,12 @@ const LocalStandardDisks = ({ idPrefix, setIsFormValid, onAddErrorNotification }

useEffect(() => {
let usableDisks;
getUsableDisks()
let devices;
getDevices()
.then(ret => {
devices = ret[0];
return getUsableDisks();
})
.then(res => {
usableDisks = res[0];
return getAllDiskSelection();
Expand All @@ -218,7 +225,7 @@ const LocalStandardDisks = ({ idPrefix, setIsFormValid, onAddErrorNotification }
setDisks(usableDisks.reduce((acc, cur) => ({ ...acc, [cur]: defaultDisks.includes(cur) }), {}));

// Show disks data
usableDisks.forEach(disk => {
devices.forEach(disk => {
let deviceData = {};
const diskNames = [disk];

Expand All @@ -235,6 +242,10 @@ const LocalStandardDisks = ({ idPrefix, setIsFormValid, onAddErrorNotification }
}, console.error)
.then(total => {
deviceData.total = cockpit.variant(String, total[0]);
return getFormatData({ diskName: disk });
}, console.error)
.then(formatData => {
deviceData.formatData = formatData[0];
setDeviceData(d => ({ ...d, [disk]: deviceData }));
}, console.error);
});
Expand All @@ -258,7 +269,8 @@ const LocalStandardDisks = ({ idPrefix, setIsFormValid, onAddErrorNotification }
setSelectedDisks({ drives: selected }).catch(onAddErrorNotification);
}, [disks, onAddErrorNotification, selectedDisksCnt, setIsFormValid]);

if (totalDisksCnt === 0) {
const loading = Object.keys(disks).some(disk => !deviceData[disk]);
if (loading) {
return <EmptyStatePanel loading />;
}

Expand Down Expand Up @@ -333,18 +345,44 @@ const LocalStandardDisks = ({ idPrefix, setIsFormValid, onAddErrorNotification }
},
];

const localDisksRows = Object.keys(disks).map(disk => (
{
const expandedContent = (disk) => (
<ListingTable
variant="compact"
columns={[_("Partition"), _("Type"), _("Size")]}
rows={deviceData[disk]?.children?.v.map(child => {
const partition = deviceData[child];
const path = {
title: (
<Flex spaceItems={{ default: "spaceItemsSm" }}>
<FlexItem>{partition.path.v}</FlexItem>
{partition.formatData.type.v === "luks" && <FlexItem><LockIcon /></FlexItem>}
</Flex>
)
};
const size = { title: cockpit.format_bytes(partition.total.v) };
const type = { title: partition.formatData.description.v };

return ({ columns: [path, type, size] });
})}
/>
);

const localDisksRows = Object.keys(disks).map(disk => {
const hasPartitions = deviceData[disk]?.children?.v.length && deviceData[disk]?.children?.v.every(partition => deviceData[partition]);

return ({
selected: !!disks[disk],
hasPadding: true,
props: { key: disk, id: disk },
columns: [
{ title: disk },
{ title: deviceData[disk] && deviceData[disk].description.v },
{ title: cockpit.format_bytes(deviceData[disk] && deviceData[disk].total.v) },
{ title: cockpit.format_bytes(deviceData[disk] && deviceData[disk].free.v) },
]
}
));
],
...(hasPartitions && { expandedContent: expandedContent(disk) }),
});
});

const rescanningDisksColumns = localDisksColumns.map(col => ({ ...col, sortable: false }));

Expand Down
36 changes: 36 additions & 0 deletions ui/webui/test/check-storage
Original file line number Diff line number Diff line change
Expand Up @@ -281,5 +281,41 @@ class TestStorageExtraDisks(anacondalib.VirtInstallMachineCase):
s.check_disk_selected(disk)


def testStoragePartitions(self):
b = self.browser
m = self.machine

m.add_disk(size=2)
disk="/dev/vdb"
m.execute(f'parted -s {disk} mktable gpt')
m.execute(f'parted -s {disk} mkpart primary ext4 0% 20%')
m.execute(f"echo einszweidrei | cryptsetup luksFormat {disk}1")

m.execute(f'parted -s {disk} mkpart primary ext4 20% 60%')
m.execute(f'mkfs.ext4 {disk}2')

i = Installer(b, m)
s = Storage(b, m)

i.open()
i.next()

s.rescan_disks()

s.check_disk_visible("vda")
s.check_disk_expandable("vda", False)
s.check_disk_visible("vdb", False)
s.check_disk_expandable("vdb", True)

s.set_expand_disk_row("vdb", True)
s.check_disk_partition("vdb", "/dev/vdb1", "Encrypted (LUKS)", "429 MB")
s.check_disk_partition("vdb", "/dev/vdb2", "ext4", "859 MB")

b.assert_pixels(
"#app",
"storage-step-basic-partitions",
wait_animations=False,
)

if __name__ == '__main__':
test_main()
23 changes: 23 additions & 0 deletions ui/webui/test/helpers/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ def check_disk_visible(self, disk, visible=True):
else:
self.browser.wait_not_present(f"#{disk}")

def check_disk_expandable(self, disk, expandable=True):
if expandable:
self.browser.wait_visible(f"#{disk} .pf-c-table__toggle")
else:
self.browser.wait_not_present(f"#{disk} .pf-c-table__toggle")

@log_step(snapshot_before=True)
def check_disk_capacity(self, disk, total=None, free=None):
if total:
Expand Down Expand Up @@ -208,3 +214,20 @@ def unlock_storage_on_boot(self, password):
def open_storage_options_help_drawer(self):
self.browser.click(".pf-c-wizard__main-body #learn-more-about-storage-options")
self.browser.wait_visible(".pf-c-drawer__panel-main")

def set_expand_disk_row(self, disk, expanded=True):
if not expanded:
self.browser.wait_visible(f"#{disk} + .pf-c-table__expandable-row.pf-m-expanded")
else:
self.browser._wait_present(f"#{disk} + .pf-c-table__expandable-row[hidden]")

self.browser.click(f"#{disk} > .pf-c-table__toggle button")

if not expanded:
self.browser._wait_present(f"#{disk} + .pf-c-table__expandable-row[hidden]")
else:
self.browser.wait_visible(f"#{disk} + .pf-c-table__expandable-row.pf-m-expanded")

def check_disk_partition(self, disk, partition, fs_type, size):
self.browser.wait_in_text(f"#{disk} + .pf-c-table__expandable-row.pf-m-expanded tr:contains('{partition}') td[data-label=Type]", fs_type)
self.browser.wait_in_text(f"#{disk} + .pf-c-table__expandable-row.pf-m-expanded tr:contains('{partition}') td[data-label=Size]", size)

0 comments on commit 5a3f544

Please sign in to comment.