Skip to content

Commit

Permalink
WIP - unified overview
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Aug 24, 2023
1 parent 82a16df commit 74a0c8b
Show file tree
Hide file tree
Showing 17 changed files with 417 additions and 52 deletions.
22 changes: 21 additions & 1 deletion pkg/storaged/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ function is_multipath_master(block) {
}

function update_indices() {
let path, block, mdraid, vgroup, pvol, lvol, pool, blockdev, fsys, part, i;
let path, block, mdraid, vgroup, pvol, lvol, pool, blockdev, fsys, part, session, i;

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused variable session.

client.broken_multipath_present = false;
client.drives_multipath_blocks = { };
Expand Down Expand Up @@ -426,6 +426,26 @@ function update_indices() {
client.blocks_partitions[path].sort(function (a, b) { return a.Offset - b.Offset });
}

client.iscsi_sessions_drives = { };
client.drives_iscsi_session = { };
for (path in client.drives) {
const block = client.drives_block[path];
if (!block)
continue;
for (const session_path in client.iscsi_sessions) {
const session = client.iscsi_sessions[session_path];
for (i = 0; i < block.Symlinks.length; i++) {
console.log("??", block.Symlinks[i], session.data["target_name"]);
if (utils.decode_filename(block.Symlinks[i]).includes(session.data["target_name"])) {
client.drives_iscsi_session[path] = session;
if (!client.iscsi_sessions_drives[session_path])
client.iscsi_sessions_drives[session_path] = [];
client.iscsi_sessions_drives[session_path].push(client.drives[path]);
}
}
}
}

client.path_jobs = { };
function enter_job(job) {
if (!job.Objects || !job.Objects.length)
Expand Down
47 changes: 36 additions & 11 deletions pkg/storaged/content-views.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { BlockVolTab, PoolVolTab, VDOPoolTab } from "./lvol-tabs.jsx";
import { PartitionTab } from "./part-tab.jsx";
import { SwapTab } from "./swap-tab.jsx";
import { UnrecognizedTab } from "./unrecognized-tab.jsx";
import { vgroup_rename, vgroup_delete } from "./vgroup-details.jsx";

const _ = cockpit.gettext;

Expand Down Expand Up @@ -144,13 +145,21 @@ function create_tabs(client, target, options) {
const tab_menu_danger_actions = [];

function add_action(title, func) {
tab_actions.push(<StorageButton onlyWide key={title} onClick={func}>{title}</StorageButton>);
tab_menu_actions.push({ title, func, only_narrow: true });
if (options.unified) {
tab_menu_actions.push({ title, func });
} else {
tab_actions.push(<StorageButton onlyWide key={title} onClick={func}>{title}</StorageButton>);
tab_menu_actions.push({ title, func, only_narrow: true });
}
}

function add_danger_action(title, func) {
tab_actions.push(<StorageButton onlyWide key={title} onClick={func}>{title}</StorageButton>);
tab_menu_danger_actions.push({ title, func, only_narrow: true });
if (options.unified) {
tab_menu_danger_actions.push({ title, func });
} else {
tab_actions.push(<StorageButton onlyWide key={title} onClick={func}>{title}</StorageButton>);
tab_menu_danger_actions.push({ title, func, only_narrow: true });
}
}

function add_menu_action(title, func) {
Expand All @@ -164,6 +173,11 @@ function create_tabs(client, target, options) {
const tabs = [];

function add_tab(name, renderer, for_content, associated_warnings) {
// No tabs on the unified overview
// XXX - what about warnings?
if (options.unified)
return;

let tab_warnings = [];
if (associated_warnings)
tab_warnings = warnings.filter(w => associated_warnings.indexOf(w.warning) >= 0);
Expand Down Expand Up @@ -513,6 +527,9 @@ function block_description(client, block, options) {
if (cleartext && !omit_encrypted_label)
type = cockpit.format(_("$0 (encrypted)"), type);

if (options.unified)
link = null;

return {
type,
used_for,
Expand Down Expand Up @@ -578,7 +595,7 @@ function append_row(client, rows, level, key, name, desc, tabs, job_object, opti
];

rows.push({
props: { key, className: "content-level-" + level },
props: { key, className: "content-level-" + level, go: options.go },
columns: cols,
expandedContent: tabs.renderers.length > 0 ? <ListingPanel tabRenderers={tabs.renderers} /> : null
});
Expand Down Expand Up @@ -680,7 +697,8 @@ function append_device(client, rows, level, block, options) {

export function block_content_rows(client, block, options) {
const rows = [];
append_device(client, rows, 0, block, options);
append_device(client, rows, options.level || 0, block,
{ go: () => utils.go_to_block(client, block.path), ...options });
return rows;
}

Expand Down Expand Up @@ -749,8 +767,8 @@ export function block_menu_items(client, block, options) {
}

return [
<StorageMenuItem key="create" onClick={onClick}>
{_("Initialize")}
<StorageMenuItem danger key="disk-format" onClick={onClick}>
{_("Create partition table")}
</StorageMenuItem>
];
}
Expand Down Expand Up @@ -849,12 +867,13 @@ function append_logical_volume(client, rows, level, lvol, options) {
export function vgroup_content_rows(client, vgroup, options) {
const rows = [];

const go = () => cockpit.location.go(["vg", vgroup.Name]);
const isVDOPool = lvol => Object.keys(client.vdo_vols).some(v => client.vdo_vols[v].VDOPool == lvol.path);

(client.vgroups_lvols[vgroup.path] || []).forEach(lvol => {
// Don't display VDO pool volumes as separate entities; they are an internal implementation detail and have no actions
if (lvol.ThinPool == "/" && lvol.Origin == "/" && !isVDOPool(lvol))
append_logical_volume(client, rows, 0, lvol, options);
append_logical_volume(client, rows, options.level || 0, lvol, { go, ...options });
});
return rows;
}
Expand Down Expand Up @@ -1021,9 +1040,15 @@ export function vgroup_menu_items(client, vgroup, options) {
}

return [
<StorageMenuItem key="create" onClick={onClick}>
<StorageMenuItem key="vgroup-create" onClick={onClick}>
{_("Create logical volume")}
</StorageMenuItem>
</StorageMenuItem>,
<StorageMenuItem key="vgroup-rename" onClick={() => vgroup_rename(client, vgroup)}>
{_("Rename volume group")}
</StorageMenuItem>,
<StorageMenuItem key="vgroup-rename" danger onClick={() => vgroup_delete(client, vgroup)}>
{_("Delete volume group")}
</StorageMenuItem>,
];
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/storaged/drives-panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { fmt_size, drive_name, decode_filename, block_name } from "./utils.js";
const _ = cockpit.gettext;
const C_ = cockpit.gettext;

export function drive_rows(client) {
export function drive_rows(client, options) {
function cmp_drive(path_a, path_b) {
return client.drives[path_a].SortKey.localeCompare(client.drives[path_b].SortKey);
}
Expand Down
35 changes: 33 additions & 2 deletions pkg/storaged/iscsi-panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { CheckIcon, EditIcon, PlusIcon, TrashIcon } from "@patternfly/react-icon

import { SidePanel } from "./side-panel.jsx";
import { } from "./utils.js";
import { StorageButton } from "./storage-controls.jsx";
import { StorageButton, StorageMenuItem } from "./storage-controls.jsx";
import { dialog_open, TextInput, PassInput, SelectRow } from "./dialog.jsx";

const _ = cockpit.gettext;
Expand Down Expand Up @@ -186,6 +186,22 @@ function iscsi_change_name(client) {
});
}

export function iscsi_menu_items(client, options) {
if (!client.features.iscsi)
return [];

return [
<StorageMenuItem key="edit"
onClick={() => iscsi_change_name(client)}>
{_("Change iSCSI initiator name")}
</StorageMenuItem>,
<StorageMenuItem key="add"
onClick={() => iscsi_discover(client)}>
{_("Add iSCSI portal")}
</StorageMenuItem>,
];
}

export function iscsi_rows(client, options) {
function cmp_session(path_a, path_b) {
const a = client.iscsi_sessions[path_a];
Expand Down Expand Up @@ -218,15 +234,30 @@ export function iscsi_rows(client, options) {
actions,
kind: "array",
name: session.data.target_name || "",
type: _("iSCSI portal"),
key: path,
detail: session.data.persistent_address + ":" + session.data.persistent_port
detail: session.data.persistent_address + ":" + session.data.persistent_port,
location: session.data.persistent_address + ":" + session.data.persistent_port,
portal: session
};
}

return Object.keys(client.iscsi_sessions).sort(cmp_session)
.map(make_session);
}

export function portal_menu_items(client, session, options) {
function iscsi_remove() {
return session.Logout({ 'node.startup': { t: 's', v: "manual" } });
}

return [
<StorageMenuItem danger onClick={iscsi_remove}>
{_("Disconnect")}
</StorageMenuItem>
];
}

export class IscsiPanel extends React.Component {
constructor() {
super();
Expand Down
22 changes: 21 additions & 1 deletion pkg/storaged/mdraid-details.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import * as utils from "./utils.js";
import { StdDetailsLayout } from "./details.jsx";
import { SidePanel } from "./side-panel.jsx";
import { Block } from "./content-views.jsx";
import { StorageButton } from "./storage-controls.jsx";
import { StorageButton, StorageMenuItem } from "./storage-controls.jsx";
import {
dialog_open, SelectSpaces, BlockingMessage, TeardownMessage,
init_active_usage_processes
Expand Down Expand Up @@ -249,6 +249,26 @@ function mdraid_delete(client, mdraid) {
});
}

export function mdraid_menu_items(client, mdraid, options) {
/* Older versions of Udisks/storaged don't have a Running property */
let running = mdraid.Running;
if (running === undefined)
running = mdraid.ActiveDevices && mdraid.ActiveDevices.length > 0;

return [
(running
? <StorageMenuItem key="mdraid-stop" onClick={() => mdraid_stop(client, mdraid)}>
{_("Stop RAID device")}
</StorageMenuItem>
: <StorageMenuItem key="mdraid-start" onClick={() => mdraid_start(client, mdraid)}>
{_("Start RAID device")}
</StorageMenuItem>),
<StorageMenuItem key="mdraid-delete" danger onClick={() => mdraid_delete(client, mdraid)}>
{_("Delete RAID device")}
</StorageMenuItem>,
];
}


export class MDRaidDetails extends React.Component {
render() {
Expand Down
6 changes: 5 additions & 1 deletion pkg/storaged/mdraids-panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ function mdraid_row(client, path) {
name: mdraid_name(mdraid),
devname: block && block_name(block),
detail: fmt_size(mdraid.Size) + " " + _("RAID device"),
type: _("RAID device"),
size: mdraid.Size,
job_path: path,
key: path,
go: () => cockpit.location.go(["mdraid", mdraid.UUID])
go: () => cockpit.location.go(["mdraid", mdraid.UUID]),
block,
mdraid
};
}

Expand Down
12 changes: 11 additions & 1 deletion pkg/storaged/nfs-details.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
import * as format from "./format-dialog.jsx";

import { StdDetailsLayout } from "./details.jsx";
import { StorageButton, StorageUsageBar } from "./storage-controls.jsx";
import { StorageButton, StorageUsageBar, StorageMenuItem } from "./storage-controls.jsx";

const _ = cockpit.gettext;

Expand Down Expand Up @@ -273,6 +273,16 @@ function remove(client, entry) {
});
}

export function nfs_content_menu_items(client, entry) {
return [
entry.mounted
? <StorageMenuItem key="nfs-unmount" onClick={() => unmount(client, entry)}>{_("Unmount")}</StorageMenuItem>
: <StorageMenuItem key="nfs-mount" onClick={() => mount(client, entry)}>{_("Mount")}</StorageMenuItem>,
<StorageMenuItem key="nfs-edit" onClick={() => edit(client, entry)}>{_("Edit")}</StorageMenuItem>,
<StorageMenuItem key="nfs-remove" danger onClick={() => remove(client, entry)}>{_("Remove")}</StorageMenuItem>,
];
}

export class NFSDetails extends React.Component {
render() {
const client = this.props.client;
Expand Down
Loading

0 comments on commit 74a0c8b

Please sign in to comment.