Minor changes and fixes.

This commit is contained in:
2026-05-25 13:30:16 +02:00
parent b1f3644092
commit 66f7851574
4 changed files with 119 additions and 201 deletions
+41 -135
View File
@@ -1,122 +1,34 @@
// <Kira Installer - universal Linux installer.>
// Copyright (C) <2026> <Kira Foundation>
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/*
Functions for working with disk layout
*/
use std::collections::HashMap; use std::collections::HashMap;
use std::ops::{Add, Sub}; use crate::kira_size::{KiraSize};
pub fn format_bytes_size(size: u64) -> String {
let suffixs: [&str; 5] = ["KB", "MB", "GB", "TB", "PB"];
if size < 1000 {
format!("{}B", size)
} else {
let mut s = size as f64;
let mut idx = 0;
for i in 0..5 {
s = s / 1024.0;
idx = i;
if s < 1000.0 {
break;
}
}
format!("{:.2}{}", s, suffixs[idx])
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BlkSize {
size_bytes: u64,
}
impl std::fmt::Display for BlkSize {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.size_bytes < 1000 {
write!(f, "{}B", self.size_bytes)
} else {
let mut s = self.size_bytes as f64;
let mut idx = 0;
for i in 0..5 {
s = s / 1024.0;
idx = i;
if s < 1000.0 {
break;
}
}
write!(f, "{:.2}{}", s, Self::SUFFIXS[idx])
}
}
}
impl BlkSize {
pub const SUFFIXS: [&str; 5] = ["KB", "MB", "GB", "TB", "PB"];
pub fn new(size:u64) -> Self {
Self { size_bytes: size }
}
pub fn new_kb(size:u64) -> Self {
Self { size_bytes: size * 1024 }
}
pub fn new_mb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(2) }
}
pub fn new_gb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(3) }
}
pub fn new_tb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(4) }
}
pub fn new_pb(size:u64) -> Self {
Self { size_bytes: size * 1024u64.pow(5) }
}
pub fn b(&self) -> u64 {
self.size_bytes
}
pub fn kb(&self) -> u64 {
self.size_bytes / 1024u64.pow(2)
}
pub fn mb(&self) -> u64 {
self.size_bytes / 1024u64.pow(3)
}
pub fn gb(&self) -> u64 {
self.size_bytes / 1024u64.pow(4)
}
pub fn tb(&self) -> u64 {
self.size_bytes / 1024u64.pow(5)
}
pub fn pb(&self) -> u64 {
self.size_bytes / 1024u64.pow(6)
}
pub fn from_str_bytes(s: &str) -> Option<Self> {
Some(Self::new(u64::from_str_radix(s, 10).ok()?))
}
}
impl Add for BlkSize {
type Output = BlkSize;
fn add(self, other: BlkSize) -> BlkSize {
BlkSize {
size_bytes: self.size_bytes + other.size_bytes,
}
}
}
impl Sub for BlkSize {
type Output = BlkSize;
fn sub(self, other: BlkSize) -> BlkSize {
BlkSize {
size_bytes: self.size_bytes.strict_sub(other.size_bytes),
}
}
}
/// ///
/// size - device size in bytes /// size - device size in bytes
/// sector size - default 4096 /// sector size - default 4096
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct BlkDev { pub struct BlkDev {
pub name: String, pub name: String,
pub size: BlkSize, pub size: KiraSize,
pub sector_size: BlkSize, pub sector_size: KiraSize,
} }
impl std::fmt::Display for BlkDev { impl std::fmt::Display for BlkDev {
@@ -126,18 +38,18 @@ impl std::fmt::Display for BlkDev {
} }
impl BlkDev { impl BlkDev {
pub fn new(name: String, size: BlkSize) -> Self { pub fn new(name: String, size: KiraSize) -> Self {
Self { Self {
name: name, name: name,
size: size, size: size,
sector_size: BlkSize::new(4096), sector_size: KiraSize::new(4096),
} }
} }
pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> { pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> {
Some(Self { Some(Self {
name: data.get("NAME")?.clone(), name: data.get("NAME")?.clone(),
size: BlkSize::from_str_bytes(data.get("SIZE")?)?, size: KiraSize::from_str_bytes(data.get("SIZE")?)?,
sector_size: BlkSize::new(4096), sector_size: KiraSize::new(4096),
}) })
} }
/// this is blocking function /// this is blocking function
@@ -254,8 +166,8 @@ pub enum PartRole {
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct PartInfo { pub struct PartInfo {
pub name: String, pub name: String,
pub size: BlkSize, pub size: KiraSize,
pub start: BlkSize, pub start: KiraSize,
pub fs_type: FSType, pub fs_type: FSType,
pub gpt_label: Option<String>, pub gpt_label: Option<String>,
pub fs_label: Option<String>, pub fs_label: Option<String>,
@@ -279,8 +191,8 @@ impl PartInfo {
pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> { pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> {
Some(Self { Some(Self {
name: data.get("NAME")?.clone(), name: data.get("NAME")?.clone(),
size: BlkSize::from_str_bytes(data.get("SIZE")?)?, size: KiraSize::from_str_bytes(data.get("SIZE")?)?,
start: BlkSize::new(0), start: KiraSize::new(0),
fs_type: FSType::from_str(data.get("FSTYPE")?), fs_type: FSType::from_str(data.get("FSTYPE")?),
gpt_label: data gpt_label: data
.get("PARTLABEL") .get("PARTLABEL")
@@ -389,7 +301,7 @@ pub fn align_part(size: u64, start: u64, align: u64) -> Option<(u64, u64, u64)>
pub struct PartLayout { pub struct PartLayout {
pub dev: BlkDev, pub dev: BlkDev,
pub empty_space: BlkSize, pub empty_space: KiraSize,
pub part_list: Vec<PartInfo>, pub part_list: Vec<PartInfo>,
} }
@@ -404,7 +316,7 @@ impl PartLayout {
pub fn read_from_disk(dev: &BlkDev) -> Result<Self, String> { pub fn read_from_disk(dev: &BlkDev) -> Result<Self, String> {
let part_list = get_dev_part_blocking(&dev.name)?; let part_list = get_dev_part_blocking(&dev.name)?;
let parts_size = part_list.iter().fold(BlkSize::new(0), |acc, part| acc + part.size); let parts_size = part_list.iter().fold(KiraSize::new(0), |acc, part| acc + part.size);
Ok(Self { Ok(Self {
dev: dev.clone(), dev: dev.clone(),
empty_space: dev.size - parts_size, empty_space: dev.size - parts_size,
@@ -420,7 +332,7 @@ impl PartLayout {
pub fn add_part( pub fn add_part(
mut self, mut self,
part_size: BlkSize, part_size: KiraSize,
fs_type: FSType, fs_type: FSType,
gpt_label: Option<String>, gpt_label: Option<String>,
fs_label: Option<String>, fs_label: Option<String>,
@@ -428,7 +340,7 @@ impl PartLayout {
role: Option<PartRole>, role: Option<PartRole>,
) -> Self { ) -> Self {
let part_start = if self.part_list.is_empty() { let part_start = if self.part_list.is_empty() {
BlkSize::new_mb(2) KiraSize::new_mb(2)
} else { } else {
self.dev.size - self.empty_space self.dev.size - self.empty_space
}; };
@@ -439,8 +351,8 @@ impl PartLayout {
let part_name = format!("{}p{}", self.dev.name, self.part_list.len() + 1); let part_name = format!("{}p{}", self.dev.name, self.part_list.len() + 1);
self.part_list.push(PartInfo { self.part_list.push(PartInfo {
name: part_name, name: part_name,
size: BlkSize::new(size), size: KiraSize::new(size),
start: BlkSize::new(start), start: KiraSize::new(start),
fs_type: fs_type, fs_type: fs_type,
gpt_label: gpt_label, gpt_label: gpt_label,
fs_label: fs_label, fs_label: fs_label,
@@ -448,13 +360,13 @@ impl PartLayout {
role: role, role: role,
}); });
self.empty_space = self.empty_space - BlkSize::new(size); self.empty_space = self.empty_space - KiraSize::new(size);
self self
} }
pub fn add_part_reserve( pub fn add_part_reserve(
self, self,
reserve_space: BlkSize, reserve_space: KiraSize,
fs_type: FSType, fs_type: FSType,
gpt_label: Option<String>, gpt_label: Option<String>,
fs_label: Option<String>, fs_label: Option<String>,
@@ -465,7 +377,7 @@ impl PartLayout {
self.add_part(p_size, fs_type, gpt_label, fs_label, mount_point, role) self.add_part(p_size, fs_type, gpt_label, fs_label, mount_point, role)
} }
pub fn gen_classic_layout(dev: BlkDev, efi_size: BlkSize, swap_size: BlkSize) -> Self { pub fn gen_classic_layout(dev: BlkDev, efi_size: KiraSize, swap_size: KiraSize) -> Self {
let mut res: PartLayout = PartLayout::new(dev); let mut res: PartLayout = PartLayout::new(dev);
// UEFI partition // UEFI partition
@@ -555,9 +467,3 @@ mod tests {
} }
} }
// fn add_part(part_list: Vec<PartInfo>, rem_size: u64, part_t: PartType, )
// fn gen_layout(dev: &BlkDev, swap_size: u64) -> Vec<PartInfo> {
// Vec::new()
// }
+20
View File
@@ -1,3 +1,23 @@
// <Kira Installer - universal Linux installer.>
// Copyright (C) <2026> <Kira Foundation>
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/*
Scroll List iced widget implementation
*/
use std::fmt::Display; use std::fmt::Display;
use iced::widget::{Column, button, container, scrollable, text}; use iced::widget::{Column, button, container, scrollable, text};
+2
View File
@@ -36,6 +36,8 @@ mod kira_theming;
mod kira_scroll_list; mod kira_scroll_list;
mod kira_color_bar; mod kira_color_bar;
mod kira_disk_layout; mod kira_disk_layout;
mod kira_size;
mod kira_sysinfo;
mod stage; mod stage;
mod stages; mod stages;
+56 -66
View File
@@ -21,7 +21,9 @@
use crate::stage::{StageAction, StageResult}; use crate::stage::{StageAction, StageResult};
use crate::kira_color_bar; use crate::kira_color_bar;
use crate::kira_disk_layout::{BlkDev, BlkSize, FSType, PartInfo, PartLayout}; use crate::kira_disk_layout::{BlkDev, FSType, PartInfo, PartLayout};
use crate::kira_size::KiraSize;
use crate::kira_sysinfo;
use iced::{Alignment, Color, widget}; use iced::{Alignment, Color, widget};
use rust_i18n::t; use rust_i18n::t;
use toml::Table; use toml::Table;
@@ -61,7 +63,7 @@ fn part_type_to_color(t: &FSType) -> Color {
} }
} }
fn part_to_ct_params(part: &PartInfo, dev_size: BlkSize) -> (String, u16, Color) { fn part_to_ct_params(part: &PartInfo, dev_size: KiraSize) -> (String, u16, Color) {
let fill_ratio: u16 = ((part.size.b() as f32 / dev_size.b() as f32) * 11.0) as u16; let fill_ratio: u16 = ((part.size.b() as f32 / dev_size.b() as f32) * 11.0) as u16;
let fill_ratio = fill_ratio.max(1); let fill_ratio = fill_ratio.max(1);
let part_color = part_type_to_color(&part.fs_type); let part_color = part_type_to_color(&part.fs_type);
@@ -77,6 +79,8 @@ pub struct PartitionStage {
secure_boot: bool, secure_boot: bool,
selected_disk_parts: Option<Vec<(String, u16, Color)>>, selected_disk_parts: Option<Vec<(String, u16, Color)>>,
generated_disk_parts: Option<Vec<(String, u16, Color)>>, generated_disk_parts: Option<Vec<(String, u16, Color)>>,
system_ram_size: KiraSize,
vram_of_all_gpus_size: KiraSize,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -90,55 +94,6 @@ pub enum Message {
} }
impl PartitionStage { impl PartitionStage {
// pub fn gen_disk_layout_estimate(&self) -> PartLayout {
// let dev = self.device.clone().unwrap();
// let swap_size: u64 = match self.swap_mode {
// Some(SwapMode::NoSwap) => 0,
// Some(SwapMode::SwapHibernate) => 666 * 1024 * 1024,
// Some(SwapMode::SwapNoHibernate) => 1024 * 1024 * 1024,
// _ => 1024 * 1024 * 1024,
// };
// let mut res: PartLayout = PartLayout::new(dev);
// // UEFI partition
// res = res
// .add_part(
// 256 * 1024 * 1024,
// FSType::VFAT,
// Some("kira-efi".into()),
// Some("EFI".into()),
// Some("/efi".into()),
// )
// .add_part(
// 512 * 1024 * 1024,
// FSType::XFS,
// Some("kira-boot-a".into()),
// None,
// Some("/".into()),
// )
// .add_part_reserve(
// swap_size,
// FSType::XFS,
// Some("kira-home".into()),
// None,
// Some("/home".into()),
// );
// // swap
// if swap_size > 0 {
// res = res.add_part(
// swap_size,
// FSType::SWAP,
// Some("kira-swap".into()),
// None,
// Some("SWAP".into()),
// );
// }
// res
// }
pub fn new(toml_config: &Table) -> Result<Self, String> { pub fn new(toml_config: &Table) -> Result<Self, String> {
let maybe_dev_list = BlkDev::list_sys_blk_dev(); let maybe_dev_list = BlkDev::list_sys_blk_dev();
@@ -149,7 +104,7 @@ impl PartitionStage {
.and_then(|v| v.as_integer()) .and_then(|v| v.as_integer())
.unwrap_or(8192); .unwrap_or(8192);
let min_disk_size: BlkSize = BlkSize::new_mb(min_disk_size_mb.try_into().unwrap_or(8192)); let min_disk_size: KiraSize = KiraSize::new_mb(min_disk_size_mb.try_into().unwrap_or(8192));
match maybe_dev_list { match maybe_dev_list {
Ok(dev_list) => { Ok(dev_list) => {
@@ -159,6 +114,18 @@ impl PartitionStage {
.cloned() .cloned()
.collect(); .collect();
// getting system memory info
let system_ram_size = KiraSize::new_kb(kira_sysinfo::get_meminfo()["MemTotal"]); // from kB to bytes
let vram_of_all_gpus_size = KiraSize::new(
kira_sysinfo::get_gpus_list()
.iter()
.fold(0u64, |acc, gpi| acc + gpi.vis_vram_total),
);
println!(
"stage init ram {} vram {}",
system_ram_size, vram_of_all_gpus_size
);
Ok(Self { Ok(Self {
device: None, device: None,
devices: acepted_dev, devices: acepted_dev,
@@ -167,12 +134,42 @@ impl PartitionStage {
secure_boot: false, secure_boot: false,
selected_disk_parts: None, selected_disk_parts: None,
generated_disk_parts: None, generated_disk_parts: None,
system_ram_size: system_ram_size,
vram_of_all_gpus_size: vram_of_all_gpus_size,
}) })
} }
Err(ex) => Err(ex), Err(ex) => Err(ex),
} }
} }
fn get_swap_size(&self) -> KiraSize {
let total_ram = self.system_ram_size + self.vram_of_all_gpus_size;
println!("total_ram {}", total_ram);
let sys_ram_gb = self.system_ram_size.gb();
println!("sys_ram_gb {}", sys_ram_gb);
let disk_swap_gb = if sys_ram_gb >= 32 {
1u64
} else if sys_ram_gb >= 24 {
2u64
} else if sys_ram_gb >= 16 {
sys_ram_gb / 2
} else if sys_ram_gb >= 8 {
sys_ram_gb
} else {
sys_ram_gb * 2
};
println!("disk_swap_gb {}", disk_swap_gb);
let disk_swap = KiraSize::new_gb(disk_swap_gb);
println!("disk_swap {}", disk_swap);
match self.swap_mode {
Some(SwapMode::NoSwap) => KiraSize::new(0),
Some(SwapMode::SwapHibernate) => disk_swap + total_ram,
Some(SwapMode::SwapNoHibernate) => disk_swap,
_ => KiraSize::new_gb(2),
}
}
fn gen_result(&self) -> StageResult { fn gen_result(&self) -> StageResult {
StageResult::new("partition") StageResult::new("partition")
.add_val_string( .add_val_string(
@@ -210,14 +207,10 @@ impl PartitionStage {
} }
}; };
let swap_size: BlkSize = match self.swap_mode { let swap_size: KiraSize = self.get_swap_size();
Some(SwapMode::NoSwap) => BlkSize::new(0),
Some(SwapMode::SwapHibernate) => BlkSize::new_gb(4),
Some(SwapMode::SwapNoHibernate) => BlkSize::new_gb(2),
_ => BlkSize::new_gb(2),
};
self.generated_disk_parts = Some( self.generated_disk_parts = Some(
PartLayout::gen_classic_layout(dev.clone(), BlkSize::new_mb(512), swap_size) PartLayout::gen_classic_layout(dev.clone(), KiraSize::new_mb(512), swap_size)
.part_list .part_list
.iter() .iter()
.map(|part_info| part_to_ct_params(part_info, dev.size)) .map(|part_info| part_to_ct_params(part_info, dev.size))
@@ -227,18 +220,16 @@ impl PartitionStage {
self.device = Some(dev); self.device = Some(dev);
StageAction::None StageAction::None
} }
Message::SelectSwapMode(sm) => { Message::SelectSwapMode(sm) => {
self.swap_mode = Some(sm);
if let Some(dev) = self.device.clone() { if let Some(dev) = self.device.clone() {
let swap_size: BlkSize = match sm { let swap_size: KiraSize = self.get_swap_size();
SwapMode::NoSwap => BlkSize::new(0),
SwapMode::SwapHibernate => BlkSize::new_gb(4),
SwapMode::SwapNoHibernate => BlkSize::new_gb(2),
};
self.generated_disk_parts = Some( self.generated_disk_parts = Some(
PartLayout::gen_classic_layout( PartLayout::gen_classic_layout(
dev.clone(), dev.clone(),
BlkSize::new_mb(512), KiraSize::new_mb(512),
swap_size, swap_size,
) )
.part_list .part_list
@@ -248,7 +239,6 @@ impl PartitionStage {
); );
} }
self.swap_mode = Some(sm);
StageAction::None StageAction::None
} }
Message::ToggleSecureBoot(t) => { Message::ToggleSecureBoot(t) => {