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 { CardBody } from "@patternfly/react-core/dist/esm/components/Card/index.js";
11 : import { DescriptionList } from "@patternfly/react-core/dist/esm/components/DescriptionList/index.js";
12 : import { useEvent } from "hooks";
13 :
14 : import { StorageCard, StorageDescription, new_card } from "../pages.jsx";
15 : import { std_format_action } from "../block/actions.jsx";
16 : import {
17 : fmt_size, decode_filename, encode_filename,
18 : parse_options, unparse_options, extract_option,
19 : } from "../utils.js";
20 : import { std_lock_action } from "../crypto/actions.jsx";
21 :
22 113 : const _ = cockpit.gettext;
23 :
24 1 : async function set_swap_noauto(block, noauto) {
25 1 : for (const conf of block.Configuration) {
26 1 : if (conf[0] == "fstab") {
27 1 : const options = parse_options(decode_filename(conf[1].opts.v));
28 1 : extract_option(options, "defaults");
29 1 : extract_option(options, "noauto");
30 1 : if (noauto)
31 1 : options.push("noauto");
32 1 : if (options.length == 0)
33 1 : options.push("defaults");
34 1 : const new_conf = [
35 1 : "fstab",
36 1 : Object.assign({ }, conf[1],
37 1 : {
38 1 : opts: {
39 1 : t: 'ay',
40 1 : v: encode_filename(unparse_options(options))
41 1 : }
42 1 : })
43 1 : ];
44 1 : await block.UpdateConfigurationItem(conf, new_conf, { });
45 1 : return;
46 1 : }
47 1 : }
48 :
49 1 : await block.AddConfigurationItem(
50 1 : ["fstab", {
51 1 : dir: { t: 'ay', v: encode_filename("none") },
52 1 : type: { t: 'ay', v: encode_filename("swap") },
53 0 : opts: { t: 'ay', v: encode_filename(noauto ? "noauto" : "defaults") },
54 1 : freq: { t: 'i', v: 0 },
55 1 : passno: { t: 'i', v: 0 },
56 1 : "track-parents": { t: 'b', v: true }
57 1 : }], { });
58 1 : }
59 :
60 3 : export function make_swap_card(next, backing_block, content_block) {
61 3 : const block_swap = client.blocks_swap[content_block.path];
62 :
63 1 : async function start() {
64 1 : await block_swap.Start({});
65 1 : await set_swap_noauto(content_block, false);
66 1 : }
67 :
68 1 : async function stop() {
69 1 : await block_swap.Stop({});
70 1 : await set_swap_noauto(content_block, true);
71 1 : }
72 :
73 3 : return new_card({
74 3 : title: _("Swap"),
75 3 : next,
76 3 : component: SwapCard,
77 3 : props: { block: content_block, block_swap },
78 3 : actions: [
79 3 : std_lock_action(backing_block, content_block),
80 3 : (block_swap && block_swap.Active
81 2 : ? { title: _("Stop"), action: stop }
82 3 : : null),
83 3 : (block_swap && !block_swap.Active
84 3 : ? { title: _("Start"), action: start }
85 3 : : null),
86 3 : std_format_action(backing_block, content_block),
87 3 : ]
88 3 : });
89 3 : }
90 :
91 2 : export const SwapCard = ({ card, block, block_swap }) => {
92 2 : const is_active = block_swap && block_swap.Active;
93 2 : let used;
94 :
95 2 : useEvent(client.swap_sizes, "changed");
96 :
97 2 : if (is_active) {
98 2 : const samples = client.swap_sizes.data[decode_filename(block.Device)];
99 2 : if (samples)
100 2 : used = fmt_size(samples[0] - samples[1]);
101 : else
102 2 : used = _("Unknown");
103 1 : } else {
104 1 : used = "-";
105 1 : }
106 :
107 2 : return (
108 2 : <StorageCard card={card}>
109 2 : <CardBody>
110 2 : <DescriptionList className="pf-m-horizontal-on-sm">
111 2 : <StorageDescription title={_("Used")} value={used} />
112 2 : </DescriptionList>
113 2 : </CardBody>
114 2 : </StorageCard>
115 : );
116 2 : };
|