LCOV - code coverage report
Current view: top level - pkg/storaged/mdraid - mdraid-disk.jsx Coverage Total Hit
Test: cockpit Lines: 98.9 % 92 91
Test Date: 2026-07-03 14:25:32

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2023 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6          113 : import cockpit from "cockpit";
       7          113 : import React from "react";
       8              : import client from "../client";
       9              : 
      10              : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
      11              : import { CardBody } from "@patternfly/react-core/dist/esm/components/Card/index.js";
      12              : import { DescriptionList } from "@patternfly/react-core/dist/esm/components/DescriptionList/index.js";
      13              : 
      14              : import { StorageCard, StorageDescription, new_card, register_crossref } from "../pages.jsx";
      15              : import { std_format_action } from "../block/actions.jsx";
      16              : import { block_short_name, fmt_size, mdraid_name } from "../utils.js";
      17              : import { std_lock_action } from "../crypto/actions.jsx";
      18              : 
      19          113 : const _ = cockpit.gettext;
      20              : 
      21            7 : export function make_mdraid_disk_card(next, backing_block, content_block) {
      22            7 :     const mdraid = client.mdraids[content_block.MDRaidMember];
      23            7 :     const mdraid_block = mdraid && client.mdraids_block[mdraid.path];
      24              : 
      25            7 :     const disk_card = new_card({
      26            7 :         title: _("MDRAID disk"),
      27            7 :         next,
      28            7 :         location: {
      29            6 :             label: mdraid_block ? block_short_name(mdraid_block) : (mdraid ? mdraid_name(mdraid) : null),
      30            7 :             to: mdraid ? ["mdraid", mdraid.UUID] : null,
      31            7 :         },
      32            7 :         component: MDRaidDiskCard,
      33            7 :         props: { backing_block, content_block, mdraid },
      34            7 :         actions: [
      35            7 :             std_lock_action(backing_block, content_block),
      36            7 :             std_format_action(backing_block, content_block),
      37            7 :         ]
      38            7 :     });
      39              : 
      40            7 :     if (mdraid) {
      41            1 :         const members = client.mdraids_members[mdraid.path] || [];
      42            7 :         let n_spares = 0;
      43            7 :         let n_recovering = 0;
      44            6 :         mdraid.ActiveDevices.forEach(function(as) {
      45            3 :             if (as[2].indexOf("spare") >= 0) {
      46            3 :                 if (as[1] < 0)
      47            3 :                     n_spares += 1;
      48              :                 else
      49            3 :                     n_recovering += 1;
      50            3 :             }
      51            6 :         });
      52              : 
      53            6 :         const active_state = mdraid.ActiveDevices.find(as => as[0] == content_block.path);
      54              : 
      55            6 :         const state_text = (state) => {
      56            6 :             return {
      57            6 :                 faulty: _("Failed"),
      58            6 :                 in_sync: _("In sync"),
      59            3 :                 spare: active_state[1] < 0 ? _("Spare") : _("Recovering"),
      60            6 :                 write_mostly: _("Write-mostly"),
      61            6 :                 blocked: _("Blocked")
      62            1 :             }[state] || cockpit.format(_("Unknown ($0)"), state);
      63            6 :         };
      64              : 
      65            7 :         const slot = active_state && active_state[1] >= 0 && active_state[1].toString();
      66            7 :         let states = active_state && active_state[2].map(state_text).join(", ");
      67              : 
      68            7 :         if (slot)
      69            7 :             states = cockpit.format(_("Slot $0"), slot) + ", " + states;
      70              : 
      71            7 :         const is_in_sync = (active_state && active_state[2].indexOf("in_sync") >= 0);
      72            4 :         const is_recovering = (active_state && active_state[2].indexOf("spare") >= 0 && active_state[1] >= 0);
      73              : 
      74            7 :         let remove_excuse = null;
      75            7 :         if (!mdraid_block)
      76            6 :             remove_excuse = _("The MDRAID device must be running");
      77            7 :         else if ((is_in_sync && n_recovering > 0) || is_recovering)
      78            4 :             remove_excuse = _("MDRAID device is recovering");
      79            7 :         else if (is_in_sync && n_spares < 1)
      80            6 :             remove_excuse = _("Need a spare disk");
      81            6 :         else if (members.length <= 1)
      82            4 :             remove_excuse = _("Last disk can not be removed");
      83              : 
      84            7 :         let remove_action = null;
      85            7 :         if (mdraid.Level != "raid0")
      86            7 :             remove_action = {
      87            7 :                 title: _("Remove"),
      88            2 :                 action: () => mdraid.RemoveDevice(content_block.path, { wipe: { t: 'b', v: true } }),
      89            7 :                 excuse: remove_excuse
      90            7 :             };
      91              : 
      92            7 :         register_crossref({
      93            7 :             key: mdraid,
      94            7 :             card: disk_card,
      95            7 :             actions: [
      96            7 :                 remove_action
      97            7 :             ],
      98            7 :             size: fmt_size(content_block.Size),
      99            7 :             extra: states,
     100            7 :         });
     101            7 :     }
     102              : 
     103            7 :     return disk_card;
     104            7 : }
     105              : 
     106            2 : export const MDRaidDiskCard = ({ card, backing_block, content_block, mdraid }) => {
     107            2 :     return (
     108            2 :         <StorageCard card={card}>
     109            2 :             <CardBody>
     110            2 :                 <DescriptionList className="pf-m-horizontal-on-sm">
     111            2 :                     <StorageDescription title={_("MDRAID device")}>
     112            2 :                         {mdraid
     113            2 :                             ? <Button variant="link" isInline role="link"
     114            1 :                                    onClick={() => cockpit.location.go(["mdraid", mdraid.UUID])}>
     115            2 :                                 {mdraid_name(mdraid)}
     116            2 :                             </Button>
     117            0 :                             : "-"
     118              :                         }
     119            2 :                     </StorageDescription>
     120            2 :                 </DescriptionList>
     121            2 :             </CardBody>
     122            2 :         </StorageCard>
     123              :     );
     124            2 : };
        

Generated by: LCOV version 2.0-1