diff --git a/pkg/storaged/block/actions.jsx b/pkg/storaged/block/actions.jsx index 0128cbf1c266..0d32ae06467d 100644 --- a/pkg/storaged/block/actions.jsx +++ b/pkg/storaged/block/actions.jsx @@ -22,6 +22,7 @@ import client from "../client"; import { format_disk } from "./format-disk-dialog.jsx"; import { format_dialog } from "./format-dialog.jsx"; +import { format_swap_dialog } from "../swap/format-dialog.jsx"; import { erase_dialog } from "./erase-dialog.jsx"; const _ = cockpit.gettext; @@ -34,14 +35,6 @@ export function block_actions(block, kind) { const actions = []; if (client.blocks_available[block.path]) { - if (kind != "crypto") { - actions.push({ - title: _("Add encryption"), - action: () => format_dialog(block, { add_encryption: true }), - excuse, - }); - } - if (kind == "part") { actions.push({ title: _("Create partitions"), @@ -62,7 +55,16 @@ export function block_actions(block, kind) { actions.push({ title: _("Format as filesystem"), action: () => format_dialog(block), - primary: true, + excuse, + }); + actions.push({ + title: _("Format as swap"), + action: () => format_swap_dialog(block), + excuse, + }); + actions.push({ + title: _("Add encryption"), + action: () => format_dialog(block, { add_encryption: true }), excuse, }); } diff --git a/pkg/storaged/block/format-dialog.jsx b/pkg/storaged/block/format-dialog.jsx index 3b3f11c98473..364cf1984860 100644 --- a/pkg/storaged/block/format-dialog.jsx +++ b/pkg/storaged/block/format-dialog.jsx @@ -94,7 +94,7 @@ function find_root_fsys_block() { export function format_dialog(block, options) { const { free_spaces, enable_dos_extended, add_encryption } = options || { }; - const is_already_encrypted = options.is_encrypted; + const is_already_encrypted = options?.is_encrypted; const block_part = client.blocks_part[block.path]; const block_ptable = client.blocks_ptable[block.path] || client.blocks_ptable[block_part?.Table]; const content_block = block.IdUsage == "crypto" ? client.blocks_cleartext[block.path] : block; @@ -110,7 +110,7 @@ export function format_dialog(block, options) { title = cockpit.format(_("Format $0 as filesystem"), block_name(block)); function is_filesystem(vals) { - return !add_encryption && vals.type != "empty" && vals.type != "dos-extended" && vals.type != "biosboot" && vals.type != "swap"; + return !add_encryption && vals.type != "empty" && vals.type != "dos-extended" && vals.type != "biosboot"; } function add_fsys(storaged_name, entry) { @@ -129,7 +129,6 @@ export function format_dialog(block, options) { add_fsys("btrfs", { value: "btrfs", title: "BTRFS" }); add_fsys("vfat", { value: "vfat", title: "VFAT" }); add_fsys("ntfs", { value: "ntfs", title: "NTFS" }); - add_fsys("swap", { value: "swap", title: "Swap" }); if (client.in_anaconda_mode()) { if (block_ptable && block_ptable.Type == "gpt" && !client.anaconda.efi) add_fsys(true, { value: "biosboot", title: "BIOS boot partition" }); @@ -357,8 +356,6 @@ export function format_dialog(block, options) { if (trigger == "type") { if (dlg.get_value("type") == "empty") { dlg.update_actions({ Variants: action_variants_for_empty }); - } else if (dlg.get_value("type") == "swap") { - dlg.update_actions({ Variants: action_variants_for_swap }); } else { dlg.update_actions({ Variants: action_variants }); } @@ -385,12 +382,6 @@ export function format_dialog(block, options) { partition_type = "21686148-6449-6e6f-744e-656564454649"; } - if (type == "swap") { - partition_type = (block_ptable && block_ptable.Type == "dos" - ? "0x82" - : "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f"); - } - const options = { 'tear-down': { t: 'b', v: true } }; @@ -471,17 +462,6 @@ export function format_dialog(block, options) { } } - if (type == "swap") { - config_items.push(["fstab", { - dir: { t: 'ay', v: encode_filename("none") }, - type: { t: 'ay', v: encode_filename("swap") }, - opts: { t: 'ay', v: encode_filename(mount_now ? "defaults" : "noauto") }, - freq: { t: 'i', v: 0 }, - passno: { t: 'i', v: 0 }, - "track-parents": { t: 'b', v: true } - }]); - } - if (config_items.length > 0) options["config-items"] = { t: 'a(sa{sv})', v: config_items }; @@ -545,10 +525,6 @@ export function format_dialog(block, options) { const block_fsys = await client.wait_for(() => block_fsys_for_block(path)); await client.mount_at(client.blocks[block_fsys.path], mount_point); } - if (type == "swap" && mount_now) { - const block_swap = await client.wait_for(() => block_swap_for_block(path)); - await block_swap.Start({}); - } if (is_encrypted(vals) && vals.type != "empty" && !mount_now && !client.in_anaconda_mode()) { const block_crypto = await client.wait_for(() => block_crypto_for_block(path)); await block_crypto.Lock({ }); diff --git a/pkg/storaged/swap/format-dialog.jsx b/pkg/storaged/swap/format-dialog.jsx new file mode 100644 index 000000000000..f963140f6ae5 --- /dev/null +++ b/pkg/storaged/swap/format-dialog.jsx @@ -0,0 +1,98 @@ +/* + * This file is part of Cockpit. + * + * Copyright (C) 2024 Red Hat, Inc. + * + * Cockpit is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * Cockpit is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Cockpit; If not, see . + */ + +import cockpit from "cockpit"; +import client from "../client.js"; + +import { + encode_filename, block_name, get_active_usage, teardown_active_usage, +} from "../utils.js"; + +import { + dialog_open, + BlockingMessage, TeardownMessage, + init_active_usage_processes +} from "../dialog.jsx"; + +import { job_progress_wrapper } from "../jobs-panel.jsx"; + +const _ = cockpit.gettext; + +export function format_swap_dialog(block) { + const usage = get_active_usage(client, block.path, _("format"), _("delete")); + + if (usage.Blocking) { + dialog_open({ + Title: cockpit.format(_("$0 is in use"), block_name(block)), + Body: BlockingMessage(usage) + }); + return; + } + + dialog_open({ + Title: cockpit.format(_("Format $0 as swap"), block_name(block)), + Teardown: TeardownMessage(usage), + Action: { + Variants: [ + { Title: _("Format and start") }, + { variant: "nostart", Title: _("Format only") } + ], + wrapper: job_progress_wrapper(client, block.path), + disable_on_error: usage.Teardown, + action: async function (vals) { + const config_items = [ + ["fstab", { + dir: { t: 'ay', v: encode_filename("none") }, + type: { t: 'ay', v: encode_filename("swap") }, + opts: { t: 'ay', v: encode_filename(vals.variant == "nostart" ? "noauto" : "defaults") }, + freq: { t: 'i', v: 0 }, + passno: { t: 'i', v: 0 }, + "track-parents": { t: 'b', v: true } + }] + ]; + + const options = { + 'tear-down': { t: 'b', v: true }, + 'config-items': { t: 'a(sa{sv})', v: config_items }, + }; + + await teardown_active_usage(client, usage); + await block.Format("swap", options); + + const block_part = client.blocks_part[block.path]; + if (block_part) { + const block_ptable = client.blocks_ptable[block_part.Table]; + const partition_type = + (block_ptable && block_ptable.Type == "dos" + ? "0x82" + : "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f"); + await block_part.SetType(partition_type, {}); + } + + if (vals.varian != "nostart") { + const block_swap = await client.wait_for(() => client.blocks_swap[block.path]); + await block_swap.Start({}); + } + } + }, + Inits: [ + init_active_usage_processes(client, usage), + ] + }); +}