Skip to content

Commit

Permalink
WIP - storage redesign
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Oct 3, 2023
1 parent c746df5 commit 261de82
Show file tree
Hide file tree
Showing 20 changed files with 799 additions and 264 deletions.
144 changes: 138 additions & 6 deletions pkg/storaged/block-details.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,155 @@
import cockpit from "cockpit";
import React from "react";

import { Card, CardBody, CardTitle } from "@patternfly/react-core/dist/esm/components/Card/index.js";
import { Card, CardHeader, CardBody, CardTitle } from "@patternfly/react-core/dist/esm/components/Card/index.js";
import { DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm } from "@patternfly/react-core/dist/esm/components/DescriptionList/index.js";

import * as utils from "./utils.js";
import { StdDetailsLayout } from "./details.jsx";
import * as Content from "./content-views.jsx";
import { create_tabs } from "./content-views.jsx";
import { StorageButton } from "./storage-controls.jsx";

const _ = cockpit.gettext;

export function block_nav_parents(client, block) {
// XXX - terrible. The client should build a proper hierachical model.

const drive = client.drives[block.Drive];
const drive_block = drive && client.drives_block[drive.path];
if (drive && drive_block) {
return [
{
location: ["drive", utils.block_name(drive_block).replace(/^\/dev\//, "")],
title: utils.drive_name(drive)
}
];
}

const mdraid = client.mdraids[block.MDRaid];
if (mdraid) {
return [{ location: ["md", mdraid.UUID], title: "XXX - mdraid" }];
}

const lvol = client.blocks_lvm2[block.path] && client.lvols[client.blocks_lvm2[block.path].LogicalVolume];
const pool = lvol && client.lvols[lvol.Pool];
const vgroup = lvol && client.vgroups[lvol.VolumeGroup];

if (lvol && vgroup && pool) {
return [{ location: ["vg", vgroup.Name, pool.Name], title: pool.Name },
{ location: ["vg", vgroup.Name], title: vgroup.Name }
];
}

if (lvol && vgroup) {
return [{ location: ["vg", vgroup.Name], title: vgroup.Name }];
}

const stratis_fsys = client.blocks_stratis_fsys[block.path];
const stratis_pool = stratis_fsys && client.stratis_pools[stratis_fsys.Pool];
if (stratis_fsys && stratis_pool) {
return [{ location: ["pool", stratis_pool.Uuid], title: stratis_pool.Name }];
}

return [];
}

function content_description(client, block) {
let is_crypto = (block && block.IdUsage == 'crypto');
const content_block = is_crypto ? client.blocks_cleartext[block.path] : block;

const block_fsys = content_block && client.blocks_fsys[content_block.path];

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused variable block_fsys.
const block_lvm2 = block && client.blocks_lvm2[block.path];
const block_pvol = content_block && client.blocks_pvol[content_block.path];
const block_swap = content_block && client.blocks_swap[content_block.path];

const block_stratis_blockdev = block && client.blocks_stratis_blockdev[block.path];
const block_stratis_stopped_pool = block && client.blocks_stratis_stopped_pool[block.path];

const lvol = block_lvm2 && client.lvols[block_lvm2.LogicalVolume];

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused variable lvol.

const is_filesystem = (content_block && content_block.IdUsage == 'filesystem');
const is_stratis = ((content_block && content_block.IdUsage == "raid" && content_block.IdType == "stratis") ||
(block_stratis_blockdev && client.stratis_pools[block_stratis_blockdev.Pool]) ||
block_stratis_stopped_pool);

if (is_filesystem) {
return _("filesystem");
} else if ((content_block && content_block.IdUsage == "raid" && content_block.IdType == "LVM2_member") ||
(block_pvol && client.vgroups[block_pvol.VolumeGroup])) {
return _("LVM2 physical volume");
} else if (is_stratis) {
return _("Stratis blockdev");
} else if ((content_block && content_block.IdUsage == "raid") ||
(content_block && client.mdraids[content_block.MDRaidMember])) {
return _("RAID member");
} else if (content_block && client.legacy_vdo_overlay.find_by_backing_block(content_block)) {
return _("VDO backing device");
} else if (block_swap || (content_block && content_block.IdUsage == "other" && content_block.IdType == "swap")) {
return _("swap");
} else if (content_block) {
return _("unrecognized data");
} else
return "???";
}

function container_description(client, block) {
const drive = client.drives[block.Drive];
const drive_block = drive && client.drives_block[drive.path];
if (drive && drive_block) {
return _("drive");
}

const mdraid = client.mdraids[block.MDRaid];
if (mdraid) {
return _("MDRAID device");
}

const lvol = client.blocks_lvm2[block.path] && client.lvols[client.blocks_lvm2[block.path].LogicalVolume];
const pool = lvol && client.lvols[lvol.Pool];
const vgroup = lvol && client.vgroups[lvol.VolumeGroup];

if (lvol && vgroup && pool) {
return _("LVM2 thin provisioning pool");
}

if (lvol && vgroup) {
return _("LVM2 volume group");
}

const stratis_fsys = client.blocks_stratis_fsys[block.path];
const stratis_pool = stratis_fsys && client.stratis_pools[stratis_fsys.Pool];
if (stratis_fsys && stratis_pool) {
return _("Stratis pool");
}

return "thing";
}

export class BlockDetails extends React.Component {
render() {
const client = this.props.client;
const block = this.props.block;
const tabs = create_tabs(this.props.client, block, {});

const actions = tabs.actions;
tabs.menu_actions.forEach(a => {
if (!a.only_narrow)
actions.push(<StorageButton onClick={a.func}>{a.title}</StorageButton>);
});
tabs.menu_danger_actions.forEach(a => {
if (!a.only_narrow)
actions.push(<StorageButton kind="danger" onClick={a.func}>{a.title}</StorageButton>);
});

const header = (
<Card>
<CardTitle component="h2">{_("Block")}</CardTitle>
<CardHeader actions={{ actions }}>
<CardTitle component="h2">
{cockpit.format(_("A $0 on a $1"),
content_description(client, block),
container_description(client, block))}
</CardTitle>
</CardHeader>
<CardBody>
<DescriptionList className="pf-m-horizontal-on-sm">
<DescriptionListGroup>
Expand All @@ -47,12 +180,11 @@ export class BlockDetails extends React.Component {
<DescriptionListDescription>{ utils.block_name(block) }</DescriptionListDescription>
</DescriptionListGroup>
</DescriptionList>
{ tabs.renderers.map(t => <React.Fragment key={t.title}><br /><t.renderer {...t.data} /></React.Fragment>) }
</CardBody>
</Card>
);

const content = <Content.Block client={this.props.client} block={block} />;

return <StdDetailsLayout client={this.props.client} header={header} content={content} />;
return <StdDetailsLayout client={this.props.client} header={header} content={null} />;
}
}
20 changes: 20 additions & 0 deletions pkg/storaged/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,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
Loading

0 comments on commit 261de82

Please sign in to comment.