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 : }
|