LCOV - code coverage report
Current view: top level - pkg/networkmanager - networkmanager.jsx Coverage Total Hit
Test: cockpit Lines: 99.1 % 108 107
Test Date: 2026-06-01 17:00:21

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2021 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : import '../lib/patternfly/patternfly-6-cockpit.scss';
       6              : import "./network-anaconda.scss";
       7           35 : import cockpit from "cockpit";
       8              : import 'cockpit-dark-theme'; // once per page
       9           35 : import React, { useRef } from 'react';
      10           35 : import { createRoot } from "react-dom/client";
      11              : 
      12              : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
      13              : import { ExclamationCircleIcon } from "@patternfly/react-icons";
      14              : 
      15              : import { EmptyStatePanel } from "cockpit-components-empty-state.jsx";
      16              : import { ModelContext } from './model-context.jsx';
      17              : import { NetworkInterfacePage } from './network-interface.jsx';
      18              : import { NetworkPage } from './network-main.jsx';
      19              : import { UsageMonitor } from './helpers.js';
      20              : 
      21              : import * as service from 'service.js';
      22              : import { init as initDialogs, NetworkManagerModel } from './interfaces.js';
      23              : import { superuser } from 'superuser';
      24              : import { PlotState } from 'plot';
      25              : 
      26              : import { useObject, useEvent, usePageLocation } from "hooks";
      27              : import { WithDialogs } from "dialogs.jsx";
      28              : import { AnacondaNetworkPage } from './anaconda-main';
      29              : 
      30           35 : const _ = cockpit.gettext;
      31              : 
      32           35 : const App = () => {
      33           35 :     const nmService = useObject(() => service.proxy("NetworkManager"),
      34           35 :                                 null,
      35           35 :                                 []);
      36           35 :     useEvent(nmService, "changed");
      37              : 
      38           35 :     const model = useObject(() => new NetworkManagerModel(), null, []);
      39           35 :     useEvent(model, "changed");
      40              : 
      41           35 :     const nmRunning_ref = useRef(undefined);
      42           35 :     useEvent(model.client, "owner", (event, owner) => { nmRunning_ref.current = owner !== null });
      43              : 
      44           35 :     const { path } = usePageLocation();
      45              : 
      46           35 :     useEvent(superuser, "changed");
      47              : 
      48           35 :     const usage_monitor = useObject(() => new UsageMonitor(), null, []);
      49           35 :     const plot_state_main = useObject(() => new PlotState(), null, []);
      50           35 :     const plot_state_iface = useObject(() => new PlotState(), null, []);
      51              : 
      52            9 :     if (model.curtain == 'testing' || model.curtain == 'restoring') {
      53            9 :         return <EmptyStatePanel loading title={model.curtain == 'testing' ? _("Testing connection") : _("Restoring connection")} />;
      54            9 :     }
      55              : 
      56           35 :     if (model.ready === undefined)
      57           35 :         return <EmptyStatePanel loading />;
      58              : 
      59              :     /* Show EmptyStatePanel when nm is not running */
      60            7 :     if (!nmRunning_ref.current) {
      61            7 :         if (nmService.enabled) {
      62            7 :             return (
      63            7 :                 <div id="networking-nm-crashed">
      64            7 :                     <EmptyStatePanel icon={ ExclamationCircleIcon }
      65            7 :                                      title={ _("NetworkManager is not running") }
      66            6 :                                      action={nmService.exists ? _("Start service") : null}
      67            7 :                                      onAction={ nmService.start }
      68            7 :                                      secondary={
      69            7 :                                          <Button component="a"
      70            7 :                                                  variant="secondary"
      71            1 :                                                  onClick={() => cockpit.jump("/system/services#/NetworkManager.service", cockpit.transport.host)}>
      72            7 :                                              {_("Troubleshoot…")}
      73            7 :                                          </Button>
      74            7 :                                      } />
      75            7 :                 </div>
      76              :             );
      77            7 :         } else if (!nmService.exists) {
      78            7 :             return (
      79            7 :                 <div id="networking-nm-not-found">
      80            7 :                     <EmptyStatePanel icon={ ExclamationCircleIcon }
      81            7 :                                      title={ _("NetworkManager is not installed") } />
      82              : 
      83            7 :                 </div>
      84              :             );
      85            7 :         } else {
      86            7 :             return (
      87            7 :                 <div id="networking-nm-disabled">
      88            7 :                     <EmptyStatePanel icon={ ExclamationCircleIcon }
      89            7 :                                      title={ _("Network devices and graphs require NetworkManager") }
      90            6 :                                      action={nmService.exists ? _("Enable service") : null}
      91            1 :                                      onAction={() => {
      92            1 :                                          nmService.enable();
      93            1 :                                          nmService.start();
      94            1 :                                      }} />
      95              : 
      96            7 :                 </div>
      97              :             );
      98            7 :         }
      99            7 :     }
     100              : 
     101           35 :     const interfaces = model.list_interfaces();
     102              : 
     103           35 :     const anaconda_mode = JSON.parse(window.sessionStorage.getItem("cockpit_anaconda"));
     104              : 
     105            6 :     if (anaconda_mode) {
     106            0 :         const iface = path.length == 1 ? interfaces.find(iface => iface.Name == path[0]) : undefined;
     107              : 
     108            6 :         return (
     109            6 :             <ModelContext.Provider value={model}>
     110            6 :                 <WithDialogs key="networking-anaconda">
     111            6 :                     <AnacondaNetworkPage privileged={superuser.allowed}
     112            6 :                                          operationInProgress={model.operationInProgress}
     113            6 :                                          usage_monitor={usage_monitor}
     114            6 :                                          interfaces={interfaces}
     115            6 :                                          iface={iface} />
     116            6 :                 </WithDialogs>
     117            6 :             </ModelContext.Provider>
     118              :         );
     119            6 :     }
     120              : 
     121              :     /* At this point NM is running and the model is ready */
     122           34 :     if (path.length == 0) {
     123           34 :         return (
     124           34 :             <ModelContext.Provider value={model}>
     125           34 :                 <WithDialogs key="networking">
     126           34 :                     <NetworkPage privileged={superuser.allowed}
     127           34 :                                  operationInProgress={model.operationInProgress}
     128           34 :                                  usage_monitor={usage_monitor}
     129           34 :                                  plot_state={plot_state_main}
     130           34 :                                  interfaces={interfaces} />
     131           34 :                 </WithDialogs>
     132           34 :             </ModelContext.Provider>
     133              :         );
     134           31 :     } else if (path.length == 1) {
     135           29 :         const iface = interfaces.find(iface => iface.Name == path[0]);
     136              : 
     137           32 :         if (iface) {
     138           32 :             return (
     139           32 :                 <ModelContext.Provider value={model}>
     140           32 :                     <WithDialogs key="networking-interface">
     141           32 :                         <NetworkInterfacePage privileged={superuser.allowed}
     142           32 :                                               operationInProgress={model.operationInProgress}
     143           32 :                                               usage_monitor={usage_monitor}
     144           32 :                                               plot_state={plot_state_iface}
     145           32 :                                               interfaces={interfaces}
     146           32 :                                               iface={iface} />
     147           32 :                     </WithDialogs>
     148           32 :                 </ModelContext.Provider>
     149              :             );
     150           32 :         }
     151           32 :     }
     152              : 
     153            7 :     return null;
     154           35 : };
     155              : 
     156           35 : function init() {
     157           35 :     initDialogs();
     158           35 :     const root = createRoot(document.getElementById("network-page"));
     159           35 :     root.render(<App />);
     160           35 : }
     161              : 
     162           35 : document.addEventListener("DOMContentLoaded", init);
        

Generated by: LCOV version 2.0-1