Skip to content

Commit

Permalink
storage: Don't offer to mount while formatting in Anaconda mode
Browse files Browse the repository at this point in the history
It's the normal thing to do during installation.
  • Loading branch information
mvollmer committed Jan 9, 2024
1 parent db69adc commit 67a2b58
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 27 deletions.
23 changes: 17 additions & 6 deletions pkg/storaged/block/format-dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,20 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended,
else
at_boot = "local";

const action_title = create_partition ? _("Create and mount") : _("Format and mount");
const action_variant = { tag: "nomount", Title: create_partition ? _("Create only") : _("Format only") };
let action_variants = [
{ tag: null, Title: create_partition ? _("Create and mount") : _("Format and mount") },
{ tag: "nomount", Title: create_partition ? _("Create only") : _("Format only") }
];

const action_variants_for_empty = [
{ tag: null, Title: create_partition ? _("Create") : _("Format") }
];

if (client.in_anaconda_mode()) {
action_variants = [
{ tag: "nomount", Title: create_partition ? _("Create") : _("Format") }
];
}

const dlg = dialog_open({
Title: title,
Expand Down Expand Up @@ -402,16 +414,15 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended,
dlg.set_options("at_boot", { explanation: mount_explanation[vals.at_boot] });
else if (trigger == "type") {
if (dlg.get_value("type") == "empty") {
dlg.update_actions({ Variants: null, Title: _("Format") });
dlg.update_actions({ Variants: action_variants_for_empty });
} else {
dlg.update_actions({ Variants: [action_variant], Title: action_title });
dlg.update_actions({ Variants: action_variants });
}
}
},
Action: {
Title: action_title,
Variants: action_variants,
Danger: (create_partition ? null : _("Formatting erases all data on a storage device.")),
Variants: [action_variant],
wrapper: job_progress_wrapper(client, block.path, client.blocks_cleartext[block.path]?.path),
disable_on_error: usage.Teardown,
action: function (vals) {
Expand Down
40 changes: 27 additions & 13 deletions pkg/storaged/filesystem/utils.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,24 +147,35 @@ export const MountPoint = ({ fstab_config, forced_options, backing_block, conten
}

let extra_text = null;
if (!is_filesystem_mounted) {
if (client.in_anaconda_mode()) {
if (!old_dir)
extra_text = _("The filesystem has no permanent mount point.");
else
extra_text = _("The filesystem is not mounted.");
} else if (backing_block != content_block) {
if (!opt_never_auto)
extra_text = _("The filesystem will be unlocked and mounted on the next boot. This might require inputting a passphrase.");
extra_text = _("The filesystem has no assigned mount point.");
} else {
if (!is_filesystem_mounted) {
if (!old_dir)
extra_text = _("The filesystem has no permanent mount point.");
else
extra_text = _("The filesystem is not mounted.");
} else if (backing_block != content_block) {
if (!opt_never_auto)
extra_text = _("The filesystem will be unlocked and mounted on the next boot. This might require inputting a passphrase.");
}
}

if (!mount_point_text) {
mount_point_text = extra_text;
extra_text = null;
}

if (extra_text && mount_point_text)
if (extra_text)
extra_text = <><br />{extra_text}</>;

return (
<>
{ mount_point_text &&
<Flex>
{ mount_point_text &&
<FlexItem>{ mount_point_text }</FlexItem>
}
<FlexItem>
<StorageLink onClick={() => mounting_dialog(client,
content_block || backing_block,
Expand All @@ -174,7 +185,6 @@ export const MountPoint = ({ fstab_config, forced_options, backing_block, conten
</StorageLink>
</FlexItem>
</Flex>
}
{ extra_text }
</>);
};
Expand All @@ -185,9 +195,13 @@ export const mount_point_text = (mount_point, mounted) => {
mp_text = client.strip_mount_point_prefix(mount_point);
if (mp_text == false)
return null;
if (!mounted)
if (!mounted && !client.in_anaconda_mode())
mp_text = mp_text + " " + _("(not mounted)");
} else
mp_text = _("(not mounted)");
} else {
if (client.in_anaconda_mode())
mp_text = _("(no assigned mount point)");
else
mp_text = _("(not mounted)");
}
return mp_text;
};
15 changes: 13 additions & 2 deletions pkg/storaged/stratis/pool.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ function create_fs(pool) {
const forced_options = ["x-systemd.requires=stratis-fstab-setup@" + pool.Uuid + ".service"];
const managed_fsys_sizes = client.features.stratis_managed_fsys_sizes && !pool.Overprovisioning;

let action_variants;
if (!client.in_anaconda_mode()) {
action_variants = [
{ tag: null, Title: _("Create and mount") },
{ tag: "nomount", Title: _("Create only") },
];
} else {
action_variants = [
{ tag: "nomount", Title: _("Create") },
];
}

dialog_open({
Title: _("Create filesystem"),
Fields: [
Expand Down Expand Up @@ -137,8 +149,7 @@ function create_fs(pool) {
dlg.set_options("at_boot", { explanation: mount_explanation[vals.at_boot] });
},
Action: {
Title: _("Create and mount"),
Variants: [{ tag: "nomount", Title: _("Create only") }],
Variants: action_variants,
action: function (vals) {
return client.stratis_create_filesystem(pool, vals.name, vals.size)
.then(std_reply)
Expand Down
60 changes: 54 additions & 6 deletions test/verify/check-storage-anaconda
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ import testlib
@testlib.nondestructive
class TestStorageAnaconda(storagelib.StorageCase):

def enterAnacondaMode(self, config):
b = self.browser
b.call_js_func("window.localStorage.setItem", "cockpit_anaconda", json.dumps(config))
b.reload()
b.enter_page("/storage")

def testBasic(self):
m = self.machine
b = self.browser
Expand All @@ -38,9 +44,7 @@ class TestStorageAnaconda(storagelib.StorageCase):
}

self.login_and_go("/storage")
b.call_js_func("window.localStorage.setItem", "cockpit_anaconda", json.dumps(anaconda_config))
b.reload()
b.enter_page("/storage")
self.enterAnacondaMode(anaconda_config)

# There should be only one row, for our disk
b.wait(lambda: b.call_js_func('ph_count', self.card("Storage") + " tbody tr") == 1)
Expand Down Expand Up @@ -144,9 +148,7 @@ class TestStorageAnaconda(storagelib.StorageCase):
}

self.login_and_go("/storage")
b.call_js_func("window.localStorage.setItem", "cockpit_anaconda", json.dumps(anaconda_config))
b.reload()
b.enter_page("/storage")
self.enterAnacondaMode(anaconda_config)

# Create a Stratis pool
self.click_devices_dropdown("Create Stratis pool")
Expand Down Expand Up @@ -203,6 +205,52 @@ class TestStorageAnaconda(storagelib.StorageCase):
self.dialog_wait_close()
m.execute("! findmnt --fstab -n /sysroot")

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

disk = self.add_ram_disk()

anaconda_config = {
"mount_point_prefix": "/sysroot",
"available_devices": [disk],
}

self.login_and_go("/storage")
self.enterAnacondaMode(anaconda_config)

# Create a partition, there should be no "Create and mount" button
b.wait_text(self.card_row_col("Storage", 1, 3), "Unformatted data")
self.click_dropdown(self.card_row("Storage", 1), "Create partition table")
self.confirm()
b.wait_text(self.card_row_col("Storage", 2, 2), "Free space")

# Only one apply button in the Create Partition dialog
self.click_dropdown(self.card_row("Storage", 2), "Create partition")
self.dialog_wait_open()
self.dialog_set_val("type", "ext4")
b.wait(lambda: b.call_js_func('ph_count', "#dialog button.apply") == 1)
b.wait_text("#dialog button.apply", "Create")
self.dialog_apply()
self.dialog_wait_close()

# Page talks about assigned mount points instead of "not mounted".
b.wait_text(self.card_row_col("Storage", 2, 4), "(no assigned mount point)")

# Only one apply button in the Format dialog
self.click_dropdown(self.card_row("Storage", 2), "Format")
self.dialog_wait_open()
self.dialog_set_val("mount_point", "/boot")
self.dialog_set_val("type", "ext4")
b.wait(lambda: b.call_js_func('ph_count', "#dialog button.apply") == 1)
b.wait_text("#dialog button.apply", "Format")
self.dialog_apply()
self.dialog_wait_close()

# Filesystem is not mounted but page doesn't mention "not mounted".
m.execute(f"! findmnt {disk}")
b.wait_text(self.card_row_col("Storage", 2, 4), "/boot")


if __name__ == '__main__':
testlib.test_main()

0 comments on commit 67a2b58

Please sign in to comment.