Skip to content

Commit

Permalink
storage: Move some fstab/crypttab to utils.js
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Sep 28, 2023
1 parent 515b6bc commit 8fcf63f
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 114 deletions.
39 changes: 3 additions & 36 deletions pkg/storaged/content-views.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
init_active_usage_processes
} from "./dialog.jsx";
import * as utils from "./utils.js";
import { set_crypto_auto_option } from "./utils.js";

import React from "react";
import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core/dist/esm/components/Card/index.js';
Expand All @@ -38,13 +39,11 @@ import { ListingTable } from "cockpit-components-table.jsx";
import { ListingPanel } from 'cockpit-components-listing-panel.jsx';
import { StorageButton, StorageBarMenu, StorageMenuItem, StorageUsageBar } from "./storage-controls.jsx";
import * as PK from "packagekit.js";
import {
format_dialog, parse_options, extract_option, unparse_options
} from "./format-dialog.jsx";
import { format_dialog } from "./format-dialog.jsx";
import { job_progress_wrapper } from "./jobs-panel.jsx";

import { FilesystemTab, is_mounted, mounting_dialog, get_fstab_config } from "./fsys-tab.jsx";
import { CryptoTab, edit_config } from "./crypto-tab.jsx";
import { CryptoTab } from "./crypto-tab.jsx";
import { get_existing_passphrase, unlock_with_type } from "./crypto-keyslots.jsx";
import { BlockVolTab, PoolVolTab, VDOPoolTab } from "./lvol-tabs.jsx";
import { PartitionTab } from "./part-tab.jsx";
Expand Down Expand Up @@ -75,38 +74,6 @@ function next_default_logical_volume_name(client, vgroup, prefix) {
return name;
}

export function set_crypto_options(block, readonly, auto, nofail, netdev) {
return edit_config(block, (config, commit) => {
const opts = config.options ? parse_options(utils.decode_filename(config.options.v)) : [];
if (readonly !== null) {
extract_option(opts, "readonly");
if (readonly)
opts.push("readonly");
}
if (auto !== null) {
extract_option(opts, "noauto");
if (!auto)
opts.push("noauto");
}
if (nofail !== null) {
extract_option(opts, "nofail");
if (nofail)
opts.push("nofail");
}
if (netdev !== null) {
extract_option(opts, "_netdev");
if (netdev)
opts.push("_netdev");
}
config.options = { t: 'ay', v: utils.encode_filename(unparse_options(opts)) };
return commit();
});
}

export function set_crypto_auto_option(block, flag) {
return set_crypto_options(block, null, flag, null, null);
}

function create_tabs(client, target, options) {
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
Expand Down
6 changes: 2 additions & 4 deletions pkg/storaged/crypto-keyslots.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,9 @@ import {
dialog_open,
SelectOneRadio, TextInput, PassInput, Skip
} from "./dialog.jsx";
import { decode_filename, encode_filename, get_block_mntopts, block_name, for_each_async, get_children } from "./utils.js";
import { decode_filename, encode_filename, get_block_mntopts, block_name, for_each_async, get_children, parse_options, unparse_options, edit_crypto_config } from "./utils.js";
import { fmt_to_fragments } from "utils.jsx";
import { StorageButton } from "./storage-controls.jsx";
import { parse_options, unparse_options } from "./format-dialog.jsx";
import { edit_config } from "./crypto-tab.jsx";

import clevis_luks_passphrase_sh from "./clevis-luks-passphrase.sh";

Expand Down Expand Up @@ -384,7 +382,7 @@ function ensure_crypto_option(steps, progress, client, block, option) {

const new_crypto_options = crypto_options.concat([option]);
progress(cockpit.format(_("Adding \"$0\" to encryption options"), option), null);
return edit_config(block, (config, commit) => {
return edit_crypto_config(block, (config, commit) => {
config.options = { t: 'ay', v: encode_filename(unparse_options(new_crypto_options)) };
return commit();
});
Expand Down
34 changes: 3 additions & 31 deletions pkg/storaged/crypto-tab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import { DescriptionList, DescriptionListDescription, DescriptionListGroup, Desc
import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex/index.js";
import cockpit from "cockpit";
import { dialog_open, TextInput, PassInput } from "./dialog.jsx";
import { encode_filename, decode_filename, block_name } from "./utils.js";
import { parse_options, unparse_options, extract_option } from "./format-dialog.jsx";
import { encode_filename, decode_filename, block_name, parse_options, unparse_options, extract_option, edit_crypto_config } from "./utils.js";
import { is_mounted } from "./fsys-tab.jsx";

import React from "react";
Expand Down Expand Up @@ -50,33 +49,6 @@ function parse_tag_mtime(tag) {
return null;
}

export function edit_config(block, modify) {
let old_config, new_config;

function commit() {
new_config[1]["track-parents"] = { t: 'b', v: true };
if (old_config)
return block.UpdateConfigurationItem(old_config, new_config, { });
else
return block.AddConfigurationItem(new_config, { });
}

return block.GetSecretConfiguration({}).then(
function (items) {
old_config = items.find(c => c[0] == "crypttab");
new_config = ["crypttab", old_config ? Object.assign({ }, old_config[1]) : { }];

// UDisks insists on always having a "passphrase-contents" field when
// adding a crypttab entry, but doesn't include one itself when returning
// an entry without a stored passphrase.
//
if (!new_config[1]['passphrase-contents'])
new_config[1]['passphrase-contents'] = { t: 'ay', v: encode_filename("") };

return modify(new_config[1], commit);
});
}

export class CryptoTab extends React.Component {
constructor() {
super();
Expand Down Expand Up @@ -141,7 +113,7 @@ export class CryptoTab extends React.Component {
this.monitor_slots(block);

function edit_stored_passphrase() {
edit_config(block, function (config, commit) {
edit_crypto_config(block, function (config, commit) {
dialog_open({
Title: _("Stored passphrase"),
Fields: [
Expand Down Expand Up @@ -188,7 +160,7 @@ export class CryptoTab extends React.Component {
const content_block = client.blocks_cleartext[block.path];
const is_fsys = fsys_config || (content_block && content_block.IdUsage == "filesystem");

edit_config(block, function (config, commit) {
edit_crypto_config(block, function (config, commit) {
dialog_open({
Title: _("Encryption options"),
Fields: [
Expand Down
35 changes: 6 additions & 29 deletions pkg/storaged/format-dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import cockpit from "cockpit";
import * as utils from "./utils.js";
import { edit_crypto_config, parse_options, unparse_options, extract_option } from "./utils.js";

import React from "react";
import { FormHelperText } from "@patternfly/react-core/dist/esm/components/Form/index.js";
Expand All @@ -33,35 +34,11 @@ import {
} from "./dialog.jsx";

import { get_fstab_config, is_valid_mount_point } from "./fsys-tab.jsx";
import { edit_config } from "./crypto-tab.jsx";
import { init_existing_passphrase, unlock_with_type } from "./crypto-keyslots.jsx";
import { job_progress_wrapper } from "./jobs-panel.jsx";

const _ = cockpit.gettext;

export function parse_options(options) {
if (options)
return (options.split(",")
.map(function (s) { return s.trim() })
.filter(function (s) { return s != "" }));
else
return [];
}

export function unparse_options(split) {
return split.join(",");
}

export function extract_option(split, opt) {
const index = split.indexOf(opt);
if (index >= 0) {
split.splice(index, 1);
return true;
} else {
return false;
}
}

export function initial_tab_options(client, block, for_fstab) {
const options = { };

Expand Down Expand Up @@ -530,11 +507,11 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended,
return block_ptable.CreatePartitionAndFormat(start, vals.size, "", "", { },
vals.type, options);
} else if (keep_keys) {
return (edit_config(block,
(config, commit) => {
config.options = new_crypto_options;
return commit();
})
return (edit_crypto_config(block,
(config, commit) => {
config.options = new_crypto_options;
return commit();
})
.then(() => maybe_unlock())
.then(content_block => {
return content_block.Format(vals.type, options);
Expand Down
9 changes: 3 additions & 6 deletions pkg/storaged/fsys-tab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,14 @@ import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex/ind

import cockpit from "cockpit";
import * as utils from "./utils.js";
import { parse_options, unparse_options, extract_option, set_crypto_options, set_crypto_auto_option } from "./utils.js";

import {
dialog_open, TextInput, PassInput, CheckBoxes, SelectOne,
StopProcessesMessage, stop_processes_danger_message
} from "./dialog.jsx";
import { StorageButton, StorageLink } from "./storage-controls.jsx";
import {
initial_tab_options, parse_options, unparse_options, extract_option,
mount_explanation
} from "./format-dialog.jsx";
import { set_crypto_options, set_crypto_auto_option } from "./content-views.jsx";
import { initial_tab_options, mount_explanation } from "./format-dialog.jsx";
import { init_existing_passphrase, unlock_with_type } from "./crypto-keyslots.jsx";

import client from "./client.js";
Expand Down Expand Up @@ -78,7 +75,7 @@ export function get_fstab_config(block, also_child_config) {
return [];
}

export function find_blocks_for_mount_point(client, mount_point, self) {
function find_blocks_for_mount_point(client, mount_point, self) {
const blocks = [];

function is_self(b) {
Expand Down
14 changes: 7 additions & 7 deletions pkg/storaged/nfs-details.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ import {
dialog_open, TextInput, ComboBox, CheckBoxes,
StopProcessesMessage, stop_processes_danger_message
} from "./dialog.jsx";
import * as format from "./format-dialog.jsx";

import { StdDetailsLayout } from "./details.jsx";
import { StorageButton, StorageUsageBar } from "./storage-controls.jsx";
import { parse_options, unparse_options, extract_option } from "./utils.js";

const _ = cockpit.gettext;

Expand Down Expand Up @@ -80,10 +80,10 @@ function get_exported_directories(server) {

export function nfs_fstab_dialog(client, entry) {
const mount_options = entry ? entry.fields[3] : "defaults";
const split_options = format.parse_options(mount_options == "defaults" ? "" : mount_options);
const opt_auto = !format.extract_option(split_options, "noauto");
const opt_ro = format.extract_option(split_options, "ro");
const extra_options = format.unparse_options(split_options);
const split_options = parse_options(mount_options == "defaults" ? "" : mount_options);
const opt_auto = !extract_option(split_options, "noauto");
const opt_ro = extract_option(split_options, "ro");
const extra_options = unparse_options(split_options);

function mounting_options(vals) {
let opts = [];
Expand All @@ -92,8 +92,8 @@ export function nfs_fstab_dialog(client, entry) {
if (vals.mount_options.ro)
opts.push("ro");
if (vals.mount_options.extra !== false)
opts = opts.concat(format.parse_options(vals.mount_options.extra));
return format.unparse_options(opts);
opts = opts.concat(parse_options(vals.mount_options.extra));
return unparse_options(opts);
}

function show(busy) {
Expand Down
82 changes: 82 additions & 0 deletions pkg/storaged/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,88 @@ export function compare_versions(a, b) {
return a_ints.length - b_ints.length;
}

export function parse_options(options) {
if (options)
return (options.split(",")
.map(function (s) { return s.trim() })
.filter(function (s) { return s != "" }));
else
return [];
}

export function unparse_options(split) {
return split.join(",");
}

export function extract_option(split, opt) {
const index = split.indexOf(opt);
if (index >= 0) {
split.splice(index, 1);
return true;
} else {
return false;
}
}

export function edit_crypto_config(block, modify) {
let old_config, new_config;

function commit() {
new_config[1]["track-parents"] = { t: 'b', v: true };
if (old_config)
return block.UpdateConfigurationItem(old_config, new_config, { });
else
return block.AddConfigurationItem(new_config, { });
}

return block.GetSecretConfiguration({}).then(
function (items) {
old_config = items.find(c => c[0] == "crypttab");
new_config = ["crypttab", old_config ? Object.assign({ }, old_config[1]) : { }];

// UDisks insists on always having a "passphrase-contents" field when
// adding a crypttab entry, but doesn't include one itself when returning
// an entry without a stored passphrase.
//
if (!new_config[1]['passphrase-contents'])
new_config[1]['passphrase-contents'] = { t: 'ay', v: encode_filename("") };

return modify(new_config[1], commit);
});
}

export function set_crypto_options(block, readonly, auto, nofail, netdev) {
return edit_crypto_config(block, (config, commit) => {
const opts = config.options ? parse_options(decode_filename(config.options.v)) : [];
if (readonly !== null) {
extract_option(opts, "readonly");
if (readonly)
opts.push("readonly");
}
if (auto !== null) {
extract_option(opts, "noauto");
if (!auto)
opts.push("noauto");
}
if (nofail !== null) {
extract_option(opts, "nofail");
if (nofail)
opts.push("nofail");
}
if (netdev !== null) {
extract_option(opts, "_netdev");
if (netdev)
opts.push("_netdev");
}
config.options = { t: 'ay', v: encode_filename(unparse_options(opts)) };
return commit();
});
}

export function set_crypto_auto_option(block, flag) {
return set_crypto_options(block, null, flag, null, null);
}

export let hostnamed = cockpit.dbus("org.freedesktop.hostname1").proxy();

// for unit tests
Expand Down

0 comments on commit 8fcf63f

Please sign in to comment.