LCOV - code coverage report
Current view: top level - pkg/storaged - anaconda.jsx Coverage Total Hit
Test: cockpit Lines: 96.7 % 121 117
Test Date: 2026-07-17 14:32:59

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2023 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6              : import client from "./client.js";
       7              : 
       8              : import { decode_filename } from "./utils.js";
       9              : import { parse_subvol_from_options } from "./btrfs/utils.jsx";
      10              : 
      11            2 : function parse_parent_from_options(options) {
      12            2 :     const parent_match = options.match(/x-parent=(?<parent>[\w\\-]+)/);
      13            2 :     if (parent_match) {
      14            2 :         return parent_match.groups.parent;
      15            2 :     } else
      16            0 :         return null;
      17            2 : }
      18              : 
      19            2 : function uuid_equal(a, b) {
      20            2 :     return a.replace("-", "").toUpperCase() == b.replace("-", "").toUpperCase();
      21            2 : }
      22              : 
      23           11 : function device_name(block) {
      24              :     // Prefer symlinks in /dev/stratis/.
      25           11 :     return (block.Symlinks.map(decode_filename).find(n => n.indexOf("/dev/stratis/") == 0) ||
      26           11 :             decode_filename(block.PreferredDevice));
      27           11 : }
      28              : 
      29           18 : export function remember_passphrase(block, passphrase) {
      30           18 :     if (!client.in_anaconda_mode())
      31           18 :         return;
      32              : 
      33            3 :     if (!window.isSecureContext)
      34            3 :         return;
      35              : 
      36            3 :     try {
      37            3 :         const passphrases = JSON.parse(window.sessionStorage.getItem("cockpit_passphrases")) || { };
      38           18 :         passphrases[device_name(block)] = passphrase;
      39           18 :         window.sessionStorage.setItem("cockpit_passphrases", JSON.stringify(passphrases));
      40            0 :     } catch {
      41            0 :         console.warn("Can't record passphrases");
      42            0 :     }
      43           18 : }
      44              : 
      45          112 : export function export_mount_point_mapping() {
      46          112 :     if (!client.in_anaconda_mode())
      47          112 :         return;
      48              : 
      49           11 :     function tab_info(config, for_parent) {
      50           11 :         let dir;
      51           11 :         let subvols;
      52              : 
      53           11 :         for (const c of config) {
      54           11 :             if (c[0] == "fstab") {
      55           11 :                 const o = decode_filename(c[1].opts.v);
      56            3 :                 if (for_parent && !uuid_equal(parse_parent_from_options(o), for_parent))
      57           11 :                     continue;
      58              : 
      59           11 :                 const d = client.strip_mount_point_prefix(decode_filename(c[1].dir.v));
      60            6 :                 if (d) {
      61            6 :                     const sv = parse_subvol_from_options(o);
      62            2 :                     if (sv) {
      63            2 :                         if (sv.pathname) {
      64            2 :                             if (!subvols)
      65            2 :                                 subvols = { };
      66            2 :                             subvols[sv.pathname] = { dir: d };
      67            2 :                         }
      68            1 :                     } else if (!dir) {
      69            5 :                         dir = d;
      70            5 :                     }
      71            6 :                 }
      72           11 :             }
      73           11 :         }
      74              : 
      75           11 :         if (dir || subvols)
      76            6 :             return {
      77            6 :                 type: "filesystem",
      78            6 :                 dir,
      79            6 :                 subvolumes: subvols
      80            6 :             };
      81              : 
      82           11 :         for (const c of config) {
      83            2 :             if (c[0] == "crypttab") {
      84            2 :                 const o = decode_filename(c[1].options.v);
      85            2 :                 if (for_parent && !uuid_equal(parse_parent_from_options(o), for_parent))
      86            2 :                     continue;
      87              : 
      88            2 :                 const device = decode_filename(c[1].device.v);
      89            2 :                 let content_info;
      90            2 :                 if (device.startsWith("UUID=")) {
      91            2 :                     content_info = tab_info(config, device.substring(5));
      92            2 :                 }
      93              : 
      94            2 :                 return {
      95            2 :                     type: "crypto",
      96            2 :                     content: content_info,
      97            2 :                 };
      98            2 :             }
      99           11 :         }
     100           11 :     }
     101              : 
     102           11 :     function block_info(block) {
     103           11 :         if (block.IdUsage == "filesystem") {
     104           11 :             return tab_info(block.Configuration);
     105           11 :         } else if (block.IdUsage == "other" && block.IdType == "swap") {
     106           11 :             return {
     107           11 :                 type: "swap",
     108           11 :             };
     109            4 :         } else if (block.IdUsage == "crypto") {
     110            4 :             const cleartext_block = client.blocks_cleartext[block.path];
     111              : 
     112            4 :             let content_info;
     113            4 :             if (cleartext_block)
     114            4 :                 content_info = block_info(cleartext_block);
     115            4 :             else {
     116            4 :                 const block_crypto = client.blocks_crypto[block.path];
     117            4 :                 if (block_crypto)
     118            4 :                     content_info = tab_info(block_crypto.ChildConfiguration, block.IdUUID);
     119            4 :             }
     120              : 
     121            3 :             if (content_info) {
     122            3 :                 return {
     123            3 :                     type: "crypto",
     124            3 :                     cleartext_device: cleartext_block && device_name(cleartext_block),
     125            3 :                     content: content_info,
     126            3 :                 };
     127            3 :             }
     128            4 :         }
     129           11 :     }
     130              : 
     131           23 :     const mpm = { };
     132           23 :     for (const p in client.blocks) {
     133           23 :         const b = client.blocks[p];
     134           23 :         mpm[device_name(b)] = block_info(b);
     135           23 :     }
     136              : 
     137              :     // Add inactive logical volumes
     138           14 :     for (const vg_p in client.vgroups) {
     139           14 :         const vg = client.vgroups[vg_p];
     140           13 :         for (const lv of client.vgroups_lvols[vg_p] || []) {
     141           14 :             const b = client.lvols_block[lv.path];
     142           14 :             const dev_name = "/dev/" + vg.Name + "/" + lv.Name;
     143           14 :             if (!b && !mpm[dev_name]) {
     144           14 :                 const info = tab_info(lv.ChildConfiguration, lv.UUID);
     145           14 :                 if (info)
     146           14 :                     mpm[dev_name] = info;
     147           14 :             }
     148           14 :         }
     149           14 :     }
     150              : 
     151           23 :     window.sessionStorage.setItem("cockpit_mount_points", JSON.stringify(mpm));
     152          112 : }
        

Generated by: LCOV version 2.0-1