Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Dec 18, 2024
1 parent de59abd commit 046c281
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 134 deletions.
22 changes: 16 additions & 6 deletions web/src/api/storage/types/config-model.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/

/**
* Alias used to reference a device.
*/
export type Alias = string;
export type FilesystemType =
| "bcachefs"
| "btrfs"
Expand All @@ -29,18 +34,25 @@ export type PartitionId = "linux" | "swap" | "lvm" | "raid" | "esp" | "prep" | "
* Config model
*/
export interface Config {
boot?: Boot;
drives?: Drive[];
}
export interface Boot {
configure: boolean;
device?: BootDevice;
}
export interface BootDevice {
default: boolean;
name?: string;
}
export interface Drive {
name: string;
alias?: string;
alias?: Alias;
mountPath?: string;
filesystem?: Filesystem;
spacePolicy?: SpacePolicy;
ptableType?: PtableType;
partitions?: Partition[];
boot?: string;
volumeGroups: string[];
}
export interface Filesystem {
default: boolean;
Expand All @@ -49,15 +61,13 @@ export interface Filesystem {
}
export interface Partition {
name?: string;
alias?: string;
alias?: Alias;
id?: PartitionId;
mountPath?: string;
filesystem?: Filesystem;
size?: Size;
delete?: boolean;
// TODO: ignore
deleteIfNeeded?: boolean;
// TODO: ignore
resize?: boolean;
resizeIfNeeded?: boolean;
}
Expand Down
10 changes: 5 additions & 5 deletions web/src/components/overview/StorageSection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import { StorageSection } from "~/components/overview";
import * as ConfigModel from "~/api/storage/types/config-model";

const mockDevices = [
{ name: "/dev/sda", size: 536870912000, volumeGroups: [] },
{ name: "/dev/sdb", size: 697932185600, volumeGroups: [] },
{ name: "/dev/sda", size: 536870912000 },
{ name: "/dev/sdb", size: 697932185600 },
];

const mockConfig = { drives: [] as ConfigModel.Drive[] };
Expand All @@ -54,7 +54,7 @@ describe("when the configuration does not include any device", () => {

describe("when the configuration contains one drive", () => {
beforeEach(() => {
mockConfig.drives = [{ name: "/dev/sda", spacePolicy: "delete", volumeGroups: [] }];
mockConfig.drives = [{ name: "/dev/sda", spacePolicy: "delete" }];
});

it("renders the proposal summary", async () => {
Expand Down Expand Up @@ -105,8 +105,8 @@ describe("when the configuration contains one drive", () => {
describe("when the configuration contains several drives", () => {
beforeEach(() => {
mockConfig.drives = [
{ name: "/dev/sda", spacePolicy: "delete", volumeGroups: [] },
{ name: "/dev/sdb", spacePolicy: "delete", volumeGroups: [] },
{ name: "/dev/sda", spacePolicy: "delete" },
{ name: "/dev/sdb", spacePolicy: "delete" },
];
});

Expand Down
2 changes: 1 addition & 1 deletion web/src/components/storage/BootConfigField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { STORAGE as PATHS } from "~/routes/paths";
const Link = ({ isBold = false }: { isBold?: boolean }) => {
const text = _("Change boot options");

return <RouterLink to={PATHS.bootingPartition}>{isBold ? <b>{text}</b> : text}</RouterLink>;
return <RouterLink to={PATHS.bootDevice}>{isBold ? <b>{text}</b> : text}</RouterLink>;
};

export type BootConfig = {
Expand Down
64 changes: 35 additions & 29 deletions web/src/components/storage/BootSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ import { DevicesFormSelect } from "~/components/storage";
import { Page } from "~/components/core";
import { deviceLabel } from "~/components/storage/utils";
import { StorageDevice } from "~/types/storage";
import { useAvailableDevices, useProposalMutation, useProposalResult } from "~/queries/storage";
import { useAvailableDevices } from "~/queries/storage";
import textStyles from "@patternfly/react-styles/css/utilities/Text/text";
import { sprintf } from "sprintf-js";
import { _ } from "~/i18n";
import { useBoot } from "~/queries/storage/config-model";

// FIXME: improve classNames
// FIXME: improve and rename to BootSelectionDialog
Expand All @@ -39,50 +40,49 @@ const BOOT_AUTO_ID = "boot-auto";
const BOOT_MANUAL_ID = "boot-manual";
const BOOT_DISABLED_ID = "boot-disabled";

type BootSelectionState = {
load: boolean;
selectedOption?: string;
configureBoot?: boolean;
bootDevice?: StorageDevice;
defaultBootDevice?: StorageDevice;
availableDevices?: StorageDevice[];
};

/**
* Allows the user to select the boot configuration.
*/
export default function BootSelectionDialog() {
type BootSelectionState = {
load: boolean;
selectedOption?: string;
configureBoot?: boolean;
bootDevice?: StorageDevice;
defaultBootDevice?: StorageDevice;
availableDevices?: StorageDevice[];
};

const [state, setState] = useState<BootSelectionState>({ load: false });
const { settings } = useProposalResult();
const availableDevices = useAvailableDevices();
const updateProposal = useProposalMutation();
const navigate = useNavigate();
const boot = useBoot();

useEffect(() => {
if (state.load) return;

let selectedOption: string;
const { bootDevice, configureBoot, defaultBootDevice } = settings;

if (!configureBoot) {
if (!boot.configure) {
selectedOption = BOOT_DISABLED_ID;
} else if (configureBoot && bootDevice === "") {
} else if (boot.isDefault) {
selectedOption = BOOT_AUTO_ID;
} else {
selectedOption = BOOT_MANUAL_ID;
}

const findDevice = (name: string) => availableDevices.find((d) => d.name === name);
const bootDevice = availableDevices.find((d) => d.name === boot.deviceName);
const defaultBootDevice = boot.isDefault ? bootDevice : undefined;

setState({
load: true,
bootDevice: findDevice(bootDevice) || findDevice(defaultBootDevice) || availableDevices[0],
configureBoot,
defaultBootDevice: findDevice(defaultBootDevice),
bootDevice: bootDevice || availableDevices[0],
configureBoot: boot.configure,
defaultBootDevice,
availableDevices,
selectedOption,
});
}, [availableDevices, settings, state.load]);
}, [availableDevices, boot, state.load]);

if (!state.load) return;

Expand All @@ -92,12 +92,18 @@ export default function BootSelectionDialog() {
// const formData = new FormData(e.target);
// const mode = formData.get("bootMode");
// const device = formData.get("bootDevice");
const newSettings = {
configureBoot: state.selectedOption !== BOOT_DISABLED_ID,
bootDevice: state.selectedOption === BOOT_MANUAL_ID ? state.bootDevice.name : undefined,
};

await updateProposal.mutateAsync({ ...settings, ...newSettings });
switch (state.selectedOption) {
case BOOT_DISABLED_ID:
boot.disable();
break;
case BOOT_AUTO_ID:
boot.setDefault();
break;
default:
boot.setDevice(state.bootDevice?.name);
}

navigate("..");
};

Expand Down Expand Up @@ -126,20 +132,20 @@ partitions in the appropriate disk.",
setState({ ...state, selectedOption: e.target.value });
};

const setBootDevice = (v) => {
const changeBootDevice = (v) => {
setState({ ...state, bootDevice: v });
};

return (
<Page>
<Page.Header>
<h2>{_("Select booting partition")}</h2>
<h2>{_("Boot options")}</h2>
<p className={textStyles.color_400}>{description}</p>
</Page.Header>

<Page.Content>
<Form id="bootSelectionForm" onSubmit={onSubmit}>
<Page.Section>
<Page.Section aria-label={_("Select a boot option")}>
<FormGroup isStack>
<Radio
name="bootMode"
Expand Down Expand Up @@ -183,7 +189,7 @@ partitions in the appropriate disk.",
name="bootDevice"
devices={state?.availableDevices || []}
selectedDevice={state.bootDevice}
onChange={setBootDevice}
onChange={changeBootDevice}
isDisabled={state.selectedOption !== BOOT_MANUAL_ID}
/>
</Stack>
Expand Down
7 changes: 6 additions & 1 deletion web/src/components/storage/ConfigEditorMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { _ } from "~/i18n";
import { useHref } from "react-router-dom";
import {
Expand All @@ -31,8 +32,10 @@ import {
DropdownItem,
Divider,
} from "@patternfly/react-core";
import { STORAGE as PATHS } from "~/routes/paths";

export default function ConfigEditorMenu() {
const navigate = useNavigate();
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);

Expand All @@ -58,7 +61,9 @@ export default function ConfigEditorMenu() {
<DropdownItem key="vg">{_("Add LVM volume group")}</DropdownItem>
<DropdownItem key="raid">{_("Add MD RAID")}</DropdownItem>
<Divider />
<DropdownItem key="boot">{_("Change boot options")}</DropdownItem>
<DropdownItem key="boot" onClick={() => navigate(PATHS.bootDevice)}>
{_("Change boot options")}
</DropdownItem>
<DropdownItem key="reinstall">{_("Reinstall an existing system")}</DropdownItem>
<Divider />
<DropdownItem key="iscsi-link" to={useHref("/storage/iscsi")}>
Expand Down
Loading

0 comments on commit 046c281

Please sign in to comment.