diff --git a/web/src/client/storage.js b/web/src/client/storage.js index ba74801644..3a35b45de3 100644 --- a/web/src/client/storage.js +++ b/web/src/client/storage.js @@ -241,10 +241,15 @@ class ProposalManager { * @property {string} encryptionMethod * @property {boolean} lvm * @property {string} spacePolicy + * @property {SpaceAction[]} spaceActions * @property {string[]} systemVGDevices * @property {Volume[]} volumes * @property {StorageDevice[]} installationDevices * + * @typedef {object} SpaceAction + * @property {string} device + * @property {string} action + * * @typedef {object} Volume * @property {string} mountPath * @property {string} fsType @@ -338,6 +343,13 @@ class ProposalManager { const systemDevices = await this.system.getDevices(); const buildResult = (proxy) => { + const buildSpaceAction = dbusSpaceAction => { + return { + device: dbusSpaceAction.Device.v, + action: dbusSpaceAction.Action.v + }; + }; + const buildAction = dbusAction => { return { text: dbusAction.Text.v, @@ -365,6 +377,7 @@ class ProposalManager { bootDevice: proxy.BootDevice, lvm: proxy.LVM, spacePolicy: proxy.SpacePolicy, + spaceActions: proxy.SpaceActions.map(buildSpaceAction), systemVGDevices: proxy.SystemVGDevices, encryptionPassword: proxy.EncryptionPassword, encryptionMethod: proxy.EncryptionMethod, @@ -388,7 +401,31 @@ class ProposalManager { * @param {ProposalSettings} settings * @returns {Promise} 0 on success, 1 on failure */ - async calculate({ bootDevice, encryptionPassword, encryptionMethod, lvm, spacePolicy, systemVGDevices, volumes }) { + async calculate(settings) { + const { + bootDevice, + encryptionPassword, + encryptionMethod, + lvm, + spacePolicy, + spaceActions, + systemVGDevices, + volumes + } = settings; + + const dbusSpaceActions = () => { + const dbusSpaceAction = (spaceAction) => { + return { + Device: { t: "s", v: spaceAction.device }, + Action: { t: "s", v: spaceAction.action } + }; + }; + + if (spacePolicy !== "custom") return; + + return spaceActions?.map(dbusSpaceAction); + }; + const dbusVolume = (volume) => { return removeUndefinedCockpitProperties({ MountPath: { t: "s", v: volume.mountPath }, @@ -401,18 +438,19 @@ class ProposalManager { }); }; - const settings = removeUndefinedCockpitProperties({ + const dbusSettings = removeUndefinedCockpitProperties({ BootDevice: { t: "s", v: bootDevice }, EncryptionPassword: { t: "s", v: encryptionPassword }, EncryptionMethod: { t: "s", v: encryptionMethod }, LVM: { t: "b", v: lvm }, SpacePolicy: { t: "s", v: spacePolicy }, + SpaceActions: { t: "aa{sv}", v: dbusSpaceActions() }, SystemVGDevices: { t: "as", v: systemVGDevices }, Volumes: { t: "aa{sv}", v: volumes?.map(dbusVolume) } }); const proxy = await this.proxies.proposalCalculator; - return proxy.Calculate(settings); + return proxy.Calculate(dbusSettings); } /** diff --git a/web/src/client/storage.test.js b/web/src/client/storage.test.js index 8c3826221f..6dc2c1437a 100644 --- a/web/src/client/storage.test.js +++ b/web/src/client/storage.test.js @@ -1,5 +1,5 @@ /* - * Copyright (c) [2022-2023] SUSE LLC + * Copyright (c) [2022-2024] SUSE LLC * * All Rights Reserved. * @@ -155,7 +155,17 @@ const contexts = { LVM: true, SystemVGDevices: ["/dev/sda", "/dev/sdb"], EncryptionPassword: "00000", - SpacePolicy: "delete", + SpacePolicy: "custom", + SpaceActions: [ + { + Device: { t: "s", v: "/dev/sda" }, + Action: { t: "s", v: "force_delete" } + }, + { + Device: { t: "s", v: "/dev/sdb" }, + Action: { t: "s", v: "resize" } + } + ], Volumes: [ { MountPath: { t: "s", v: "/" }, @@ -825,7 +835,11 @@ describe("#proposal", () => { lvm: true, systemVGDevices: ["/dev/sda", "/dev/sdb"], encryptionPassword: "00000", - spacePolicy: "delete", + spacePolicy: "custom", + spaceActions: [ + { device: "/dev/sda", action: "force_delete" }, + { device: "/dev/sdb", action: "resize" } + ], volumes: [ { mountPath: "/", @@ -895,6 +909,8 @@ describe("#proposal", () => { encryptionPassword: "12345", lvm: true, systemVGDevices: ["/dev/sdc"], + spacePolicy: "custom", + spaceActions: [{ device: "/dev/sda", action: "resize" }], volumes: [ { mountPath: "/test1", @@ -916,6 +932,16 @@ describe("#proposal", () => { EncryptionPassword: { t: "s", v: "12345" }, LVM: { t: "b", v: true }, SystemVGDevices: { t: "as", v: ["/dev/sdc"] }, + SpacePolicy: { t: "s", v: "custom" }, + SpaceActions: { + t: "aa{sv}", + v: [ + { + Device: { t: "s", v: "/dev/sda" }, + Action: { t: "s", v: "resize" } + } + ] + }, Volumes: { t: "aa{sv}", v: [ @@ -935,6 +961,17 @@ describe("#proposal", () => { } }); }); + + it("calculates a proposal without space actions if the policy is not custom", async () => { + await client.proposal.calculate({ + spacePolicy: "delete", + spaceActions: [{ device: "/dev/sda", action: "resize" }], + }); + + expect(cockpitProxies.proposalCalculator.Calculate).toHaveBeenCalledWith({ + SpacePolicy: { t: "s", v: "delete" } + }); + }); }); });