LCOV - code coverage report
Current view: top level - pkg/networkmanager - bridge.jsx Coverage Total Hit
Test: cockpit Lines: 94.0 % 100 94
Test Date: 2026-07-17 07:33:01

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2021 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6           37 : import React, { useState, useContext } from 'react';
       7           37 : import cockpit from 'cockpit';
       8              : import { Checkbox } from "@patternfly/react-core/dist/esm/components/Checkbox/index.js";
       9              : import { FormGroup } from "@patternfly/react-core/dist/esm/components/Form/index.js";
      10              : import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput/index.js";
      11              : 
      12              : import { MemberInterfaceChoices, NetworkModal, Name, dialogSave } from './dialogs-common.jsx';
      13              : import { ModelContext } from './model-context.jsx';
      14              : import { useDialogs } from "dialogs.jsx";
      15              : 
      16              : import { v4 as uuidv4 } from 'uuid';
      17              : import {
      18              :     member_connection_for_interface,
      19              :     member_interface_choices,
      20              : } from './interfaces.js';
      21              : 
      22           37 : const _ = cockpit.gettext;
      23              : 
      24            2 : export const BridgeDialog = ({ connection, dev, settings }) => {
      25            2 :     const Dialogs = useDialogs();
      26            2 :     const idPrefix = "network-bridge-settings";
      27            2 :     const model = useContext(ModelContext);
      28            2 :     const memberChoicesInit = {};
      29              : 
      30            2 :     member_interface_choices(model, connection).forEach((iface) => {
      31            2 :         memberChoicesInit[iface.Name] = !!member_connection_for_interface(connection, iface);
      32            2 :     });
      33              : 
      34            2 :     const [dialogError, setDialogError] = useState(undefined);
      35            2 :     const [iface, setIface] = useState(settings.connection.interface_name);
      36            2 :     const [stp, setStp] = useState(!!settings.bridge.stp);
      37            0 :     const [priority, setPriority] = useState(settings.bridge.priority || 10);
      38            0 :     const [forwardDelay, setForwardDelay] = useState(settings.bridge.forward_delay || 10);
      39            0 :     const [helloTime, setHelloTime] = useState(settings.bridge.hello_time || 10);
      40            0 :     const [maxAge, setMaxAge] = useState(settings.bridge.max_age || 10);
      41            2 :     const [memberChoices, setMemberChoices] = useState(memberChoicesInit);
      42              : 
      43            2 :     const onSubmit = (ev) => {
      44            2 :         const createSettingsObj = () => ({
      45            2 :             ...settings,
      46            2 :             connection: {
      47            2 :                 ...settings.connection,
      48            2 :                 id: iface,
      49            2 :                 interface_name: iface,
      50            2 :             },
      51            2 :             bridge: {
      52            2 :                 ...settings.bridge,
      53            2 :                 stp,
      54            1 :                 ...(stp && { priority, forward_delay: forwardDelay, hello_time: helloTime, max_age: maxAge }),
      55            2 :                 interface_name: iface,
      56            2 :             }
      57            2 :         });
      58              : 
      59            2 :         dialogSave({
      60            2 :             model,
      61            2 :             dev,
      62            2 :             connection,
      63            2 :             members: memberChoices,
      64            2 :             membersInit: memberChoicesInit,
      65            2 :             settings: createSettingsObj(),
      66            2 :             setDialogError,
      67            2 :             onClose: Dialogs.close,
      68            2 :         });
      69              : 
      70              :         // Prevent dialog from closing because of <form> onsubmit event
      71            2 :         if (ev)
      72            2 :             ev.preventDefault();
      73              : 
      74            2 :         return false;
      75            2 :     };
      76              : 
      77            2 :     return (
      78            2 :         <NetworkModal dialogError={dialogError}
      79            2 :                       idPrefix="network-bridge-settings"
      80            2 :                       onSubmit={onSubmit}
      81            1 :                       title={!connection ? _("Add bridge") : _("Edit bridge settings")}
      82            2 :                       isCreateDialog={!connection}
      83              :         >
      84            2 :             <>
      85            2 :                 <Name idPrefix={idPrefix} iface={iface} setIface={setIface} />
      86            2 :                 <FormGroup label={_("Ports")} fieldId={idPrefix + "-interface-members-list"} hasNoPaddingTop>
      87            2 :                     <MemberInterfaceChoices idPrefix={idPrefix} memberChoices={memberChoices} setMemberChoices={setMemberChoices} model={model} group={connection} />
      88            2 :                 </FormGroup>
      89            2 :                 <FormGroup label={_("Options")} fieldId={idPrefix + "-stp-enabled-input"} hasNoPaddingTop>
      90            1 :                     <Checkbox id={idPrefix + "-stp-enabled-input"} isChecked={stp} onChange={(_, s) => setStp(s)} label={_("Spanning tree protocol (STP)")} />
      91            1 :                     {stp && <>
      92            1 :                         <FormGroup fieldId="network-bridge-stp-settings-priority-input" label={_("STP priority")}>
      93            1 :                             <TextInput id="network-bridge-stp-settings-priority-input" className="network-number-field" value={priority} onChange={(_event, value) => setPriority(Number.parseInt(value))} />
      94            1 :                         </FormGroup>
      95            1 :                         <FormGroup fieldId="network-bridge-stp-settings-forward-delay-input" label={_("STP forward delay")}>
      96            0 :                             <TextInput id="network-bridge-stp-settings-forward-delay-input" className="network-number-field" value={forwardDelay} onChange={(_event, value) => setForwardDelay(Number.parseInt(value))} />
      97            1 :                         </FormGroup>
      98            1 :                         <FormGroup fieldId="network-bridge-stp-settings-hello-time-input" label={_("STP hello time")}>
      99            1 :                             <TextInput id="network-bridge-stp-settings-hello-time-input" className="network-number-field" value={helloTime} onChange={(_event, value) => setHelloTime(Number.parseInt(value))} />
     100            1 :                         </FormGroup>
     101            1 :                         <FormGroup fieldId="network-bridge-stp-settings-max-age-input" label={_("STP maximum message age")}>
     102            0 :                             <TextInput id="network-bridge-stp-settings-max-age-input" className="network-number-field" value={maxAge} onChange={(_event, value) => setMaxAge(Number.parseInt(value))} />
     103            1 :                         </FormGroup>
     104            1 :                     </>}
     105            2 :                 </FormGroup>
     106            2 :             </>
     107            2 :         </NetworkModal>
     108              :     );
     109            2 : };
     110              : 
     111           35 : export const getGhostSettings = ({ newIfaceName }) => {
     112           35 :     return (
     113           35 :         {
     114           35 :             connection: {
     115           35 :                 id: newIfaceName,
     116           35 :                 autoconnect: true,
     117           35 :                 type: "bridge",
     118           35 :                 uuid: uuidv4(),
     119           35 :                 interface_name: newIfaceName
     120           35 :             },
     121           35 :             bridge: {
     122           35 :                 interface_name: newIfaceName,
     123           35 :                 stp: false,
     124           35 :                 priority: 32768,
     125           35 :                 forward_delay: 15,
     126           35 :                 hello_time: 2,
     127           35 :                 max_age: 20,
     128           35 :                 ageing_time: 300
     129           35 :             }
     130           35 :         }
     131              :     );
     132           35 : };
        

Generated by: LCOV version 2.0-1