Skip to content

Commit 1b1c5d2

Browse files
authored
Merge pull request #671 from KKoukiou/cockpit-storage-free-space
storage: some cockpit-storage page improvements for RAID detection
2 parents 3e52ab6 + 03b4ea9 commit 1b1c5d2

6 files changed

+82
-13
lines changed

src/components/storage/CockpitStorageIntegration.jsx

+21-5
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ const CheckStorageDialog = ({
370370

371371
const useFreeSpace = useMemo(() => {
372372
const availability = checkUseFreeSpace({
373+
allowReclaim: false,
373374
diskFreeSpace,
374375
diskTotalSpace,
375376
requiredSize,
@@ -379,8 +380,18 @@ const CheckStorageDialog = ({
379380
return availability.available && !availability.hidden;
380381
}, [diskFreeSpace, diskTotalSpace, requiredSize, selectedDisks]);
381382

383+
const mdArrays = useMemo(() => {
384+
return Object.keys(devices).filter(device => devices[device].type.v === "mdarray");
385+
}, [devices]);
386+
const useEntireSoftwareDisk = useMemo(() => {
387+
return selectedDisks.every(disk => (
388+
mdArrays.includes(disk) &&
389+
getDeviceChildren({ device: disk, deviceData: devices }).every(child => devices[child].type.v !== "partition")
390+
));
391+
}, [devices, mdArrays, selectedDisks]);
392+
382393
const loading = !error && checkStep !== undefined;
383-
const storageRequirementsNotMet = !loading && (error || (!useConfiguredStorage && !useFreeSpace));
394+
const storageRequirementsNotMet = !loading && (error || (!useConfiguredStorage && !useFreeSpace && !useEntireSoftwareDisk));
384395

385396
useEffect(() => {
386397
const mode = useConfiguredStorage ? "use-configured-storage" : "use-free-space";
@@ -437,8 +448,6 @@ const CheckStorageDialog = ({
437448
return;
438449
}
439450

440-
const mdArrays = Object.keys(devices).filter(device => devices[device].type.v === "mdarray");
441-
442451
// In blivet we recognize two "types" of MD array:
443452
// * The array is directly on top of disks: in this case we consider the array to be a disk
444453
// (similar to a hardware RAID) and create the partition table on the array
@@ -455,6 +464,11 @@ const CheckStorageDialog = ({
455464
// Check if we have mdarrays that are not fitting in the above two scenarios
456465
// and show an error message
457466
const mdArraysNotSupported = mdArrays.filter(device => {
467+
// The user created a plain mdarray without any format to be used possible with 'Use entire disk'
468+
if (devices[device].formatData.type.v === "") {
469+
return false;
470+
}
471+
458472
if (
459473
devices[device].parents.v.every(parent => devices[parent].type.v === "disk") &&
460474
devices[device].formatData.type.v === "disklabel"
@@ -490,7 +504,7 @@ const CheckStorageDialog = ({
490504
} else {
491505
setCheckStep("prepare-partitioning");
492506
}
493-
}, [checkStep, devices, usableDevices, selectedDisks]);
507+
}, [checkStep, devices, mdArrays, usableDevices, selectedDisks]);
494508

495509
useEffect(() => {
496510
// If the required devices needed for manual partitioning are set up,
@@ -638,7 +652,9 @@ const CheckStorageDialog = ({
638652
{useConfiguredStorageReview}
639653
</Stack>
640654
)
641-
: _("Free space requirements met")}
655+
: (
656+
useEntireSoftwareDisk ? _("Use the RAID device for automatic partitioning") : _("Use free space")
657+
)}
642658
</HelperTextItem>}
643659
</HelperText>
644660
</>}

src/components/storage/scenarios/UseFreeSpace.jsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { helpUseFreeSpace } from "../HelpAutopartOptions.jsx";
2828

2929
const _ = cockpit.gettext;
3030

31-
export const checkUseFreeSpace = ({ diskFreeSpace, diskTotalSpace, requiredSize, selectedDisks }) => {
31+
export const checkUseFreeSpace = ({ allowReclaim = true, diskFreeSpace, diskTotalSpace, requiredSize, selectedDisks }) => {
3232
const availability = new AvailabilityState();
3333

3434
availability.hidden = false;
@@ -38,12 +38,16 @@ export const checkUseFreeSpace = ({ diskFreeSpace, diskTotalSpace, requiredSize,
3838
availability.hidden = diskFreeSpace === diskTotalSpace;
3939
}
4040
if (diskFreeSpace < requiredSize) {
41-
availability.enforceAction = true;
4241
availability.reason = _("Not enough free space on the selected disks.");
4342
availability.hint = cockpit.format(
4443
_("To use this option, resize or remove existing partitions to free up at least $0."),
4544
cockpit.format_bytes(requiredSize)
4645
);
46+
if (allowReclaim) {
47+
availability.enforceAction = true;
48+
} else {
49+
availability.available = false;
50+
}
4751
}
4852
return availability;
4953
};

test/check-storage-cockpit

+50-3
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,6 @@ class TestStorageCockpitIntegration(VirtInstallMachineCase, StorageCase):
467467
b.switch_to_top()
468468
s.return_to_installation("Invalid RAID configuration detected.")
469469

470-
471470
@nondestructive
472471
@disk_images([("", 15), ("", 15), ("", 15)])
473472
def testRAIDonDisks(self):
@@ -510,15 +509,20 @@ class TestStorageCockpitIntegration(VirtInstallMachineCase, StorageCase):
510509
# Exit the cockpit-storage iframe and return to installation
511510
b.switch_to_top()
512511
s.return_to_installation()
513-
s.return_to_installation()
512+
513+
with b.wait_timeout(60):
514+
disk = "MDRAID-SOMERAID"
515+
prefix="#cockpit-storage-integration-check-storage-dialog"
516+
r.check_disk_row(disk, "/boot", "SOMERAID2, RAID", "1.07 GB", False, prefix=prefix)
517+
r.check_disk_row(disk, "/", "SOMERAID3, RAID", "47.2 GB", False, prefix=prefix)
518+
514519
s.return_to_installation_confirm()
515520

516521
s.set_partitioning("use-configured-storage")
517522

518523
i.reach(i.steps.REVIEW)
519524

520525
def checkStorageReview(prefix=""):
521-
disk = "MDRAID-SOMERAID"
522526
with b.wait_timeout(30):
523527
r.check_disk(disk, "48.3 GB MDRAID-SOMERAID (MDRAID set (stripe))")
524528
r.check_disk_row(disk, "/boot", "SOMERAID2, RAID", "1.07 GB", False, prefix=prefix)
@@ -527,6 +531,49 @@ class TestStorageCockpitIntegration(VirtInstallMachineCase, StorageCase):
527531
# verify review screen
528532
checkStorageReview()
529533

534+
@nondestructive
535+
@disk_images([("", 15), ("", 15), ("", 15)])
536+
def testRAIDAutomatic(self):
537+
b = self.browser
538+
m = self.machine
539+
i = Installer(b, m)
540+
s = Storage(b, m)
541+
r = Review(b, m)
542+
543+
self.addCleanup(m.execute, "mdadm --zero-superblock /dev/vda /dev/vdb /dev/vdc")
544+
self.addCleanup(m.execute, "mdadm --stop /dev/md/SOMERAID")
545+
546+
i.open()
547+
i.reach(i.steps.INSTALLATION_METHOD)
548+
s.select_disks([("vdb", True), ("vda", True), ("vdc", True)])
549+
550+
s.modify_storage()
551+
s.confirm_entering_cockpit_storage()
552+
b.switch_to_frame("cockpit-storage")
553+
554+
# Create RAID device on vda, vdb, and vdc
555+
self.click_dropdown(self.card_header("Storage"), "Create MDRAID device")
556+
self.dialog_wait_open()
557+
self.dialog_set_val("level", "raid0")
558+
self.dialog_set_val("disks", {"vda": True, "vdb": True, "vdc": True})
559+
self.dialog_set_val("name", "SOMERAID")
560+
self.dialog_apply()
561+
self.dialog_wait_close()
562+
563+
# Exit the cockpit-storage iframe and return to installation
564+
b.switch_to_top()
565+
s.return_to_installation()
566+
s.return_to_installation_confirm()
567+
568+
s.check_partitioning_selected("erase-all")
569+
i.reach(i.steps.REVIEW)
570+
571+
disk = "MDRAID-SOMERAID"
572+
with b.wait_timeout(30):
573+
r.check_disk(disk, "48.3 GB MDRAID-SOMERAID (MDRAID set (stripe))")
574+
r.check_disk_row(disk, "/boot", "SOMERAID2, RAID", "1.07 GB", True, "xfs")
575+
r.check_disk_row(disk, "/", "SOMERAID3, LVM", "16.1 GB", True, "xfs")
576+
530577

531578
if __name__ == '__main__':
532579
test_main()

test/check-storage-mountpoints-raid-e2e

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from anacondalib import VirtInstallMachineCase, disk_images
1919
from installer import Installer
2020
from storage import Storage
21-
from testlib import test_main # pylint: disable=import-error
21+
from testlib import test_main, timeout # pylint: disable=import-error
2222

2323

2424
class TestStorageMountPointsRAID_E2E(VirtInstallMachineCase):
@@ -53,6 +53,7 @@ class TestStorageMountPointsRAID_E2E(VirtInstallMachineCase):
5353
""", timeout=90)
5454

5555
@disk_images([("", 15), ("", 15)])
56+
@timeout(900)
5657
def testLVMOnRAID(self):
5758
"""
5859
Test RAID1 on partition level with LVM. Both disks (vda, vdb) have:

test/check-storage-reclaim-e2e

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ from installer import Installer
2020
from operating_systems import DualBootHelper_E2E
2121
from review import Review
2222
from storage import Storage
23-
from testlib import test_main # pylint: disable=import-error
23+
from testlib import test_main, timeout # pylint: disable=import-error
2424

2525

2626
class TestStorageReclaim_E2E(DualBootHelper_E2E, VirtInstallMachineCase):
2727

2828
@disk_images([("debian-stable", 20)])
29+
@timeout(900)
2930
def testReclaimShrink(self):
3031
b = self.browser
3132
m = self.machine

test/helpers/storage.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def return_to_installation(self, error=None):
9090
def return_to_installation_confirm(self):
9191
# FIXME: testBtrfsTopLevelVolume fails sometimes on CI without this workaround
9292
try:
93-
with self.browser.wait_timeout(30):
93+
with self.browser.wait_timeout(60):
9494
self.browser.click("#cockpit-storage-integration-check-storage-dialog-continue")
9595
self.browser.wait_not_present("#cockpit-storage-integration-check-storage-dialog")
9696
except Error:

0 commit comments

Comments
 (0)