LCOV - code coverage report
Current view: top level - pkg/systemd/overview-cards - systemInformationCard.jsx Coverage Total Hit
Test: cockpit Lines: 85.7 % 105 90
Test Date: 2026-07-17 14:32:59

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2019 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5           94 : import React from 'react';
       6              : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
       7              : import { Card, CardBody, CardFooter, CardTitle } from "@patternfly/react-core/dist/esm/components/Card/index.js";
       8              : 
       9           94 : import cockpit from "cockpit";
      10              : import * as machine_info from "machine-info.js";
      11              : import * as timeformat from "timeformat";
      12              : 
      13              : import "./systemInformationCard.scss";
      14              : 
      15           94 : const _ = cockpit.gettext;
      16              : 
      17           94 : export class SystemInformationCard extends React.Component {
      18           93 :     constructor(props) {
      19           93 :         super(props);
      20              : 
      21           93 :         this.state = {
      22           93 :             machineID: null,
      23           93 :             model: null,
      24           93 :             assetTag: null,
      25           93 :             systemUptime: null,
      26           93 :         };
      27           93 :         this.getSystemUptime = this.getSystemUptime.bind(this);
      28           93 :     }
      29              : 
      30           93 :     componentDidMount() {
      31           93 :         this.getDMIInfo();
      32           93 :         this.getMachineId();
      33           93 :         this.getSystemUptime();
      34              : 
      35           93 :         this.uptimeTimer = setInterval(this.getSystemUptime, 60000);
      36           93 :     }
      37              : 
      38            0 :     componentWillUnmount() {
      39            0 :         clearInterval(this.uptimeTimer); // not-covered: callers currently never unmount this
      40            0 :     }
      41              : 
      42           93 :     getMachineId() {
      43           93 :         const machine_id = cockpit.file("/etc/machine-id");
      44              : 
      45           93 :         machine_id.read()
      46           93 :                 .then(machineID => this.setState({ machineID }))
      47            0 :                 .catch(ex => console.error("Error reading machine id", ex.toString())) // not-covered: OS error
      48           93 :                 .finally(machine_id.close);
      49           93 :     }
      50              : 
      51           93 :     getDMIInfo() {
      52           93 :         machine_info.dmi_info()
      53           85 :                 .then(fields => {
      54           85 :                     let vendor = fields.sys_vendor;
      55           85 :                     let name = fields.product_name;
      56           17 :                     if (!vendor || !name) {
      57           17 :                         vendor = fields.board_vendor;
      58           17 :                         name = fields.board_name;
      59           17 :                     }
      60           85 :                     if (!vendor || !name)
      61           17 :                         this.setState({ model: null });
      62              :                     else
      63           85 :                         this.setState({ model: vendor + " " + name });
      64              : 
      65           85 :                     this.setState({ assetTag: fields.product_serial || fields.chassis_serial });
      66           85 :                 })
      67            0 :                 .catch(ex => {
      68              :                     // try DeviceTree
      69            0 :                     machine_info.devicetree_info() // not-covered: coverage only runs on x86_64
      70            0 :                             .then(fields => this.setState({ assetTag: fields.serial, model: fields.model }))
      71            0 :                             .catch(dmiex => {
      72            0 :                                 console.debug("couldn't read dmi info: " + ex.toString());
      73            0 :                                 console.debug("couldn't read DeviceTree info: " + dmiex.toString());
      74            0 :                                 this.setState({ assetTag: null, model: null });
      75            0 :                             });
      76            0 :                 });
      77           93 :     }
      78              : 
      79           93 :     getSystemUptime() {
      80           93 :         cockpit.file("/proc/uptime").read()
      81           93 :                 .then(content => {
      82           93 :                     const uptime = parseFloat(content.split(' ')[0]);
      83           93 :                     const bootTime = new Date().valueOf() - uptime * 1000;
      84           93 :                     this.setState({ systemUptime: timeformat.distanceToNow(bootTime) });
      85           93 :                 })
      86            0 :                 .catch(ex => console.error("Error reading system uptime", ex.toString())); // not-covered: OS error
      87           93 :     }
      88              : 
      89           93 :     render() {
      90           93 :         return (
      91           93 :             <Card className="system-information">
      92           93 :                 <CardTitle>{_("System information")}</CardTitle>
      93           93 :                 <CardBody>
      94           93 :                     <table className="pf-v6-c-table pf-m-grid-md pf-m-compact">
      95           93 :                         <tbody className="pf-v6-c-table__tbody">
      96           85 :                             {this.state.model && <tr className="pf-v6-c-table__tr">
      97           85 :                                 <th className="pf-v6-c-table__th" scope="row">{_("Model")}</th>
      98           85 :                                 <td className="pf-v6-c-table__td">
      99           85 :                                     <div id="system_information_hardware_text">{this.state.model}</div>
     100           85 :                                 </td>
     101           85 :                             </tr>}
     102           17 :                             {this.state.assetTag && <tr className="pf-v6-c-table__tr">
     103           17 :                                 <th className="pf-v6-c-table__th" scope="row">{_("Asset tag")}</th>
     104           17 :                                 <td className="pf-v6-c-table__td">
     105           17 :                                     <div id="system_information_asset_tag_text">{this.state.assetTag}</div>
     106           17 :                                 </td>
     107           17 :                             </tr>}
     108           93 :                             <tr className="pf-v6-c-table__tr">
     109           93 :                                 <th className="pf-v6-c-table__th system-information-machine-id" scope="row">{_("Machine ID")}</th>
     110           93 :                                 <td className="pf-v6-c-table__td">
     111           93 :                                     <div id="system_machine_id">{this.state.machineID}</div>
     112           93 :                                 </td>
     113           93 :                             </tr>
     114           93 :                             <tr className="pf-v6-c-table__tr">
     115           93 :                                 <th className="pf-v6-c-table__th system-information-uptime" scope="row">{_("Up since")}</th>
     116           93 :                                 <td className="pf-v6-c-table__td">
     117           93 :                                     <div id="system_uptime">{this.state.systemUptime}</div>
     118           93 :                                 </td>
     119           93 :                             </tr>
     120           93 :                         </tbody>
     121           93 :                     </table>
     122           93 :                 </CardBody>
     123           93 :                 <CardFooter>
     124            0 :                     <Button isInline variant="link" component="a" onClick={ev => { ev.preventDefault(); cockpit.jump("/system/hwinfo", cockpit.transport.host) }}>
     125           93 :                         {_("View hardware details")}
     126           93 :                     </Button>
     127           93 :                 </CardFooter>
     128           93 :             </Card>
     129              :         );
     130           93 :     }
     131           94 : }
        

Generated by: LCOV version 2.0-1