2024-08-23 01:02:58 +03:00
|
|
|
use crate::{
|
|
|
|
automatic_partitioning_page,
|
|
|
|
build_ui::{BlockDevice, CrypttabEntry, FstabEntry, Partition, SubvolDeclaration},
|
|
|
|
installer_stack_page, manual_partitioning_page,
|
|
|
|
};
|
2024-08-19 02:12:35 +03:00
|
|
|
use glib::{clone, closure_local, Properties};
|
|
|
|
use gtk::{gio, glib, prelude::*};
|
2024-08-14 01:17:57 +03:00
|
|
|
use std::io::BufRead;
|
2024-08-19 02:12:35 +03:00
|
|
|
use std::{cell::RefCell, rc::Rc};
|
2024-08-08 18:56:02 +03:00
|
|
|
|
2024-08-07 02:27:24 +03:00
|
|
|
pub fn partitioning_page(
|
|
|
|
main_carousel: &adw::Carousel,
|
2024-08-19 23:42:36 +03:00
|
|
|
window: adw::ApplicationWindow,
|
2024-08-15 21:07:01 +03:00
|
|
|
partition_method_type_refcell: &Rc<RefCell<String>>,
|
2024-08-22 18:18:26 +03:00
|
|
|
partition_method_automatic_target_refcell: &Rc<RefCell<BlockDevice>>,
|
2024-08-19 02:12:35 +03:00
|
|
|
partition_method_automatic_target_fs_refcell: &Rc<RefCell<String>>,
|
|
|
|
partition_method_automatic_luks_enabled_refcell: &Rc<RefCell<bool>>,
|
2024-08-15 21:07:01 +03:00
|
|
|
partition_method_automatic_luks_refcell: &Rc<RefCell<String>>,
|
2024-08-16 07:18:37 +03:00
|
|
|
partition_method_automatic_ratio_refcell: &Rc<RefCell<f64>>,
|
2024-08-15 21:07:01 +03:00
|
|
|
partition_method_automatic_seperation_refcell: &Rc<RefCell<String>>,
|
2024-08-18 01:17:57 +03:00
|
|
|
partition_method_manual_fstab_entry_array_refcell: &Rc<RefCell<Vec<FstabEntry>>>,
|
2024-08-17 01:15:03 +03:00
|
|
|
partition_method_manual_luks_enabled_refcell: &Rc<RefCell<bool>>,
|
2024-08-18 01:17:57 +03:00
|
|
|
partition_method_manual_crypttab_entry_array_refcell: &Rc<RefCell<Vec<CrypttabEntry>>>,
|
2024-08-19 02:12:35 +03:00
|
|
|
language_changed_action: &gio::SimpleAction,
|
2024-08-22 10:06:22 +03:00
|
|
|
page_done_action: &gio::SimpleAction,
|
2024-08-07 02:27:24 +03:00
|
|
|
) {
|
|
|
|
let partitioning_page = installer_stack_page::InstallerStackPage::new();
|
|
|
|
partitioning_page.set_page_icon("media-floppy-symbolic");
|
|
|
|
partitioning_page.set_back_sensitive(true);
|
2024-08-22 02:39:16 +03:00
|
|
|
partitioning_page.set_next_sensitive(false);
|
2024-08-07 02:27:24 +03:00
|
|
|
partitioning_page.set_back_visible(true);
|
2024-08-22 02:39:16 +03:00
|
|
|
partitioning_page.set_next_visible(true);
|
2024-08-07 02:27:24 +03:00
|
|
|
|
|
|
|
let partitioning_carousel = adw::Carousel::builder()
|
|
|
|
.allow_long_swipes(false)
|
|
|
|
.allow_mouse_drag(false)
|
|
|
|
.allow_scroll_wheel(false)
|
|
|
|
.interactive(false)
|
|
|
|
.vexpand(true)
|
|
|
|
.hexpand(true)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let content_box = gtk::Box::builder()
|
|
|
|
.orientation(gtk::Orientation::Vertical)
|
|
|
|
.vexpand(true)
|
|
|
|
.hexpand(true)
|
|
|
|
.valign(gtk::Align::Center)
|
|
|
|
.halign(gtk::Align::Center)
|
|
|
|
.homogeneous(true)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
content_box.add_css_class("linked");
|
|
|
|
|
2024-08-19 09:38:35 +03:00
|
|
|
let manual_method_button_icon = gtk::Image::builder()
|
|
|
|
.icon_name("emblem-system-symbolic")
|
|
|
|
.margin_end(2)
|
|
|
|
.halign(gtk::Align::Start)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let manual_method_button_label = gtk::Label::builder()
|
|
|
|
.label(t!("manual_method_button_label"))
|
|
|
|
.halign(gtk::Align::Center)
|
|
|
|
.hexpand(true)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let manual_method_button_child_box = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
|
|
|
|
|
|
|
manual_method_button_child_box.append(&manual_method_button_icon);
|
|
|
|
manual_method_button_child_box.append(&manual_method_button_label);
|
|
|
|
|
|
|
|
let automatic_method_button_icon = gtk::Image::builder()
|
|
|
|
.icon_name("builder")
|
|
|
|
.margin_end(2)
|
|
|
|
.halign(gtk::Align::Start)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let automatic_method_button_label = gtk::Label::builder()
|
|
|
|
.label(t!("automatic_method_button_label"))
|
|
|
|
.halign(gtk::Align::Center)
|
|
|
|
.hexpand(true)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let automatic_method_button_child_box = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
|
|
|
|
|
|
|
automatic_method_button_child_box.append(&automatic_method_button_icon);
|
|
|
|
automatic_method_button_child_box.append(&automatic_method_button_label);
|
|
|
|
|
|
|
|
let method_labels_size_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Both);
|
|
|
|
let method_icons_size_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Both);
|
|
|
|
|
|
|
|
method_labels_size_group.add_widget(&manual_method_button_label);
|
|
|
|
method_labels_size_group.add_widget(&automatic_method_button_label);
|
|
|
|
|
|
|
|
method_icons_size_group.add_widget(&manual_method_button_icon);
|
|
|
|
method_icons_size_group.add_widget(&automatic_method_button_icon);
|
2024-08-07 02:27:24 +03:00
|
|
|
|
|
|
|
let manual_method_button = gtk::Button::builder()
|
2024-08-19 09:38:35 +03:00
|
|
|
.child(&manual_method_button_child_box)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let automatic_method_button = gtk::Button::builder()
|
|
|
|
.child(&automatic_method_button_child_box)
|
2024-08-07 02:27:24 +03:00
|
|
|
.build();
|
|
|
|
|
2024-08-19 02:12:35 +03:00
|
|
|
automatic_method_button.connect_clicked(clone!(
|
|
|
|
#[weak]
|
|
|
|
partitioning_carousel,
|
|
|
|
move |_| partitioning_carousel.scroll_to(&partitioning_carousel.nth_page(1), true)
|
|
|
|
));
|
2024-08-07 02:27:24 +03:00
|
|
|
|
2024-08-19 02:12:35 +03:00
|
|
|
manual_method_button.connect_clicked(clone!(
|
|
|
|
#[weak]
|
|
|
|
partitioning_carousel,
|
|
|
|
move |_| partitioning_carousel.scroll_to(&partitioning_carousel.nth_page(2), true)
|
|
|
|
));
|
2024-08-07 02:27:24 +03:00
|
|
|
|
|
|
|
content_box.append(&automatic_method_button);
|
|
|
|
content_box.append(&manual_method_button);
|
|
|
|
|
|
|
|
partitioning_page.set_child_widget(&content_box);
|
|
|
|
|
|
|
|
//
|
2024-08-19 02:12:35 +03:00
|
|
|
language_changed_action.connect_activate(clone!(
|
|
|
|
#[weak]
|
|
|
|
partitioning_page,
|
|
|
|
move |_, _| {
|
2024-08-19 02:50:56 +03:00
|
|
|
partitioning_page.set_page_title(t!("partitioning_page_title"));
|
|
|
|
partitioning_page.set_page_subtitle(t!("partitioning_page_subtitle"));
|
2024-08-19 02:12:35 +03:00
|
|
|
partitioning_page.set_back_tooltip_label(t!("back"));
|
|
|
|
partitioning_page.set_next_tooltip_label(t!("next"));
|
|
|
|
//
|
2024-08-19 09:38:35 +03:00
|
|
|
automatic_method_button_label.set_label(&t!("automatic_method_button_label"));
|
2024-08-19 02:12:35 +03:00
|
|
|
//
|
2024-08-19 09:38:35 +03:00
|
|
|
manual_method_button_label.set_label(&t!("manual_method_button_label"));
|
2024-08-19 02:12:35 +03:00
|
|
|
}
|
|
|
|
));
|
2024-08-07 02:27:24 +03:00
|
|
|
//
|
|
|
|
|
|
|
|
partitioning_carousel.append(&partitioning_page);
|
2024-08-15 02:03:18 +03:00
|
|
|
automatic_partitioning_page::automatic_partitioning_page(
|
2024-08-22 02:39:16 +03:00
|
|
|
&main_carousel,
|
2024-08-19 02:12:35 +03:00
|
|
|
&partitioning_carousel,
|
2024-08-15 21:07:01 +03:00
|
|
|
&partition_method_type_refcell,
|
|
|
|
&partition_method_automatic_target_refcell,
|
2024-08-15 21:12:24 +03:00
|
|
|
&partition_method_automatic_target_fs_refcell,
|
2024-08-15 21:07:01 +03:00
|
|
|
&partition_method_automatic_luks_enabled_refcell,
|
|
|
|
&partition_method_automatic_luks_refcell,
|
|
|
|
&partition_method_automatic_ratio_refcell,
|
|
|
|
&partition_method_automatic_seperation_refcell,
|
2024-08-19 02:12:35 +03:00
|
|
|
&language_changed_action,
|
2024-08-22 10:06:22 +03:00
|
|
|
&page_done_action,
|
2024-08-19 02:12:35 +03:00
|
|
|
);
|
2024-08-17 01:15:03 +03:00
|
|
|
manual_partitioning_page::manual_partitioning_page(
|
2024-08-22 02:39:16 +03:00
|
|
|
&main_carousel,
|
2024-08-19 02:12:35 +03:00
|
|
|
&partitioning_carousel,
|
2024-08-19 23:42:36 +03:00
|
|
|
window,
|
2024-08-19 02:12:35 +03:00
|
|
|
&partition_method_type_refcell,
|
|
|
|
&partition_method_manual_fstab_entry_array_refcell,
|
|
|
|
&partition_method_manual_luks_enabled_refcell,
|
|
|
|
&partition_method_manual_crypttab_entry_array_refcell,
|
|
|
|
&language_changed_action,
|
2024-08-22 10:06:22 +03:00
|
|
|
page_done_action,
|
2024-08-19 02:12:35 +03:00
|
|
|
);
|
2024-08-07 02:27:24 +03:00
|
|
|
|
|
|
|
partitioning_page.connect_closure(
|
|
|
|
"back-button-pressed",
|
|
|
|
false,
|
|
|
|
closure_local!(
|
|
|
|
#[weak]
|
|
|
|
main_carousel,
|
2024-08-19 02:12:35 +03:00
|
|
|
move |_partitioning_page: installer_stack_page::InstallerStackPage| {
|
|
|
|
main_carousel.scroll_to(&main_carousel.nth_page(4), true)
|
2024-08-07 02:27:24 +03:00
|
|
|
}
|
2024-08-19 02:12:35 +03:00
|
|
|
),
|
2024-08-07 02:27:24 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
main_carousel.append(&partitioning_carousel)
|
2024-08-14 01:17:57 +03:00
|
|
|
}
|
|
|
|
|
2024-08-14 18:33:26 +03:00
|
|
|
pub fn get_block_devices() -> Vec<BlockDevice> {
|
|
|
|
let mut block_devices = Vec::new();
|
|
|
|
|
|
|
|
let command = match std::process::Command::new("sudo")
|
2024-08-14 01:17:57 +03:00
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_block_devices")
|
|
|
|
.stdin(std::process::Stdio::piped())
|
|
|
|
.stdout(std::process::Stdio::piped())
|
2024-08-19 02:12:35 +03:00
|
|
|
.spawn()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return block_devices,
|
|
|
|
};
|
2024-08-14 01:17:57 +03:00
|
|
|
|
|
|
|
match command.stdout {
|
|
|
|
Some(t) => {
|
|
|
|
for blockdev in std::io::BufReader::new(t).lines() {
|
|
|
|
match blockdev {
|
2024-08-14 18:33:26 +03:00
|
|
|
Ok(r) => {
|
|
|
|
let block_size = get_block_size(&r);
|
2024-08-19 02:12:35 +03:00
|
|
|
block_devices.push(BlockDevice {
|
|
|
|
block_name: r,
|
|
|
|
block_size: block_size,
|
|
|
|
block_size_pretty: pretty_bytes::converter::convert(block_size),
|
|
|
|
})
|
2024-08-14 18:33:26 +03:00
|
|
|
}
|
2024-08-19 02:12:35 +03:00
|
|
|
Err(_) => return block_devices,
|
2024-08-14 01:17:57 +03:00
|
|
|
}
|
|
|
|
}
|
2024-08-19 02:12:35 +03:00
|
|
|
}
|
|
|
|
None => return block_devices,
|
2024-08-14 18:33:26 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
block_devices
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_block_size(block_dev: &str) -> f64 {
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_block_size")
|
|
|
|
.arg(block_dev)
|
2024-08-19 02:12:35 +03:00
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return 0.0,
|
|
|
|
};
|
2024-08-14 18:33:26 +03:00
|
|
|
let size = match String::from_utf8(command.stdout) {
|
2024-08-19 02:12:35 +03:00
|
|
|
Ok(t) => t.trim().parse::<f64>().unwrap_or(0.0),
|
|
|
|
Err(_) => 0.0,
|
2024-08-14 01:17:57 +03:00
|
|
|
};
|
|
|
|
|
2024-08-14 18:33:26 +03:00
|
|
|
size
|
2024-08-16 16:51:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_partitions() -> Vec<Partition> {
|
|
|
|
let mut partitions = Vec::new();
|
|
|
|
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_partitions")
|
|
|
|
.stdin(std::process::Stdio::piped())
|
|
|
|
.stdout(std::process::Stdio::piped())
|
2024-08-19 02:12:35 +03:00
|
|
|
.spawn()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return partitions,
|
|
|
|
};
|
2024-08-16 16:51:55 +03:00
|
|
|
|
|
|
|
match command.stdout {
|
|
|
|
Some(t) => {
|
|
|
|
for partition in std::io::BufReader::new(t).lines() {
|
|
|
|
match partition {
|
2024-08-19 23:42:36 +03:00
|
|
|
Ok(r) => partitions.push(create_parition_struct(&r)),
|
2024-08-19 02:12:35 +03:00
|
|
|
Err(_) => return partitions,
|
2024-08-16 16:51:55 +03:00
|
|
|
}
|
|
|
|
}
|
2024-08-19 02:12:35 +03:00
|
|
|
}
|
|
|
|
None => return partitions,
|
2024-08-16 16:51:55 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
partitions
|
|
|
|
}
|
|
|
|
|
2024-08-19 23:42:36 +03:00
|
|
|
pub fn create_parition_struct(part_dev: &str) -> Partition {
|
|
|
|
let part_size = get_part_size(&part_dev);
|
|
|
|
let part_fs = get_part_fs(&part_dev);
|
|
|
|
Partition {
|
|
|
|
has_encryption: is_encrypted(&part_dev),
|
|
|
|
need_mapper: is_needs_mapper(&part_fs),
|
|
|
|
part_uuid: get_part_uuid(&part_dev),
|
|
|
|
part_name: part_dev.to_string(),
|
|
|
|
part_fs: part_fs,
|
|
|
|
part_size: part_size,
|
|
|
|
part_size_pretty: pretty_bytes::converter::convert(part_size),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 16:51:55 +03:00
|
|
|
fn get_part_size(part_dev: &str) -> f64 {
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_part_size")
|
|
|
|
.arg(part_dev)
|
2024-08-19 02:12:35 +03:00
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return 0.0,
|
|
|
|
};
|
2024-08-16 16:51:55 +03:00
|
|
|
let size = match String::from_utf8(command.stdout) {
|
2024-08-19 02:12:35 +03:00
|
|
|
Ok(t) => t.trim().parse::<f64>().unwrap_or(0.0),
|
|
|
|
Err(_) => 0.0,
|
2024-08-16 16:51:55 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
size
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_part_fs(part_dev: &str) -> String {
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_part_fs")
|
|
|
|
.arg(part_dev.replace("mapper/", ""))
|
2024-08-19 02:12:35 +03:00
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return String::from(t!("fs_unknown")),
|
|
|
|
};
|
2024-08-16 16:51:55 +03:00
|
|
|
let fs = match String::from_utf8(command.stdout) {
|
2024-08-19 02:12:35 +03:00
|
|
|
Ok(t) => t.trim().to_owned(),
|
|
|
|
Err(_) => String::from(t!("fs_unknown")),
|
2024-08-16 16:51:55 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
fs
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_needs_mapper(part_fs: &str) -> bool {
|
2024-08-19 02:12:35 +03:00
|
|
|
if part_fs.contains("crypto_LUKS") || part_fs.contains("lvm") || part_fs.contains("BitLocker") {
|
2024-08-16 16:51:55 +03:00
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_encrypted(part_dev: &str) -> bool {
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("has_encryption")
|
|
|
|
.arg(part_dev)
|
2024-08-19 02:12:35 +03:00
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return false,
|
|
|
|
};
|
|
|
|
|
2024-08-16 16:51:55 +03:00
|
|
|
if command.status.success() {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2024-08-19 02:12:35 +03:00
|
|
|
}
|
2024-08-19 23:42:36 +03:00
|
|
|
|
|
|
|
pub fn test_luks_passwd(part_dev: &str, passwd: &str) -> bool {
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("test_luks_passwd")
|
|
|
|
.arg(part_dev)
|
|
|
|
.arg(passwd)
|
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return false,
|
|
|
|
};
|
|
|
|
|
|
|
|
if command.status.success() {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_part_uuid(part_dev: &str) -> String {
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_part_uuid")
|
|
|
|
.arg(part_dev)
|
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return String::from(""),
|
|
|
|
};
|
|
|
|
let fs = match String::from_utf8(command.stdout) {
|
|
|
|
Ok(t) => t.trim().to_owned(),
|
|
|
|
Err(_) => String::from(""),
|
|
|
|
};
|
|
|
|
|
|
|
|
fs
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_luks_uuid(part_dev: &str) -> String {
|
|
|
|
let command = match std::process::Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_luks_uuid")
|
|
|
|
.arg(part_dev)
|
|
|
|
.output()
|
|
|
|
{
|
|
|
|
Ok(t) => t,
|
|
|
|
Err(_) => return String::from(""),
|
|
|
|
};
|
|
|
|
let fs = match String::from_utf8(command.stdout) {
|
|
|
|
Ok(t) => t.trim().to_owned(),
|
|
|
|
Err(_) => String::from(""),
|
|
|
|
};
|
|
|
|
|
|
|
|
fs
|
2024-08-19 22:41:36 +00:00
|
|
|
}
|