ferrix_app/pages/
kernel.rs

1/* kernel.rs
2 *
3 * Copyright 2025 Michail Krasnov <mskrasnov07@ya.ru>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21//! Kernel page
22
23use crate::{
24    Message, fl,
25    load_state::DataLoadingState,
26    pages::{InfoRow, fmt_val, hdr_name, kv_info_table, text_fmt_val},
27};
28use ferrix_lib::sys::{KModules, Kernel, Module};
29
30use iced::{
31    Length, Padding,
32    widget::{column, container, scrollable, table, text},
33};
34use serde::Serialize;
35
36#[derive(Debug, Clone, Serialize)]
37pub struct KernelData {
38    pub kernel: Kernel,
39    pub mods: KModules,
40}
41
42impl KernelData {
43    pub fn new() -> anyhow::Result<Self> {
44        Ok(Self {
45            kernel: Kernel::new()?,
46            mods: KModules::new()?,
47        })
48    }
49}
50
51fn modules_table<'a>(rows: &'a [Module]) -> table::Table<'a, Message> {
52    let columns = [
53        table::column(hdr_name(fl!("kmod-name")), |row: &'a Module| {
54            text(&row.name).wrapping(text::Wrapping::WordOrGlyph)
55        })
56        .width(Length::FillPortion(1)),
57        table::column(hdr_name(fl!("kmod-size")), |row: &'a Module| {
58            text_fmt_val(row.size.round(2))
59        }),
60        table::column(hdr_name(fl!("kmod-instances")), |row: &'a Module| {
61            text(row.instances)
62        }),
63        table::column(hdr_name(fl!("kmod-depends")), |row: &'a Module| {
64            text(if &row.dependencies == "-" {
65                ""
66            } else {
67                &row.dependencies
68            })
69            .wrapping(text::Wrapping::WordOrGlyph)
70        })
71        .width(Length::FillPortion(3)),
72        table::column(hdr_name(fl!("kmod-state")), |row: &'a Module| {
73            text(&row.state).style(if &row.state == "Live" {
74                text::success
75            } else {
76                text::default
77            })
78        }),
79        table::column(hdr_name(fl!("kmod-addrs")), |row: &'a Module| {
80            text(&row.memory_addrs)
81        }),
82    ];
83
84    table(columns, rows).padding(2).width(Length::Fill)
85}
86
87pub fn kernel_page<'a>(
88    kernel_data: &'a DataLoadingState<KernelData>,
89) -> container::Container<'a, Message> {
90    match kernel_data {
91        DataLoadingState::Loaded(kernel_data) => {
92            let kern = &kernel_data.kernel;
93            let summary_rows = vec![
94                InfoRow::new(fl!("kernel-summary"), kern.uname.clone()),
95                InfoRow::new(fl!("kernel-cmdline"), kern.cmdline.clone()),
96                InfoRow::new(fl!("kernel-arch"), kern.arch.clone()),
97                InfoRow::new(fl!("kernel-version"), kern.version.clone()),
98                InfoRow::new(fl!("kernel-build"), kern.build_info.clone()),
99                InfoRow::new(fl!("kernel-pid-max"), fmt_val(Some(kern.pid_max))),
100                InfoRow::new(fl!("kernel-threads-max"), fmt_val(Some(kern.threads_max))),
101                InfoRow::new(fl!("kernel-user-evs"), fmt_val(kern.user_events_max)),
102                InfoRow::new(fl!("kernel-avail-enthropy"), fmt_val(kern.enthropy_avail)),
103            ];
104
105            let kern_summary_data =
106                column![container(kv_info_table(summary_rows)).style(container::rounded_box)]
107                    .spacing(5);
108
109            let kern_modules =
110                container(modules_table(&kernel_data.mods.modules)).style(container::rounded_box);
111
112            let layout = column![
113                text(fl!("kernel-summary-hdr")).style(text::warning),
114                kern_summary_data,
115                text(fl!("kernel-mods-hdr")).style(text::warning),
116                kern_modules.padding(Padding::new(0.).right(10.)),
117            ]
118            .spacing(5);
119
120            container(scrollable(layout))
121        }
122        DataLoadingState::Error(why) => super::error_page(why),
123        DataLoadingState::Loading => super::loading_page(),
124    }
125}