2024-02-14 16:32:01 +01:00
// Use libraries
use adw ::prelude ::* ;
use adw ::* ;
2024-02-16 22:21:09 +01:00
use glib ::* ;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk ::* ;
use std ::thread ;
2024-02-14 16:32:01 +01:00
2024-02-18 18:28:14 +01:00
use gettextrs ::{ gettext , LocaleCategory } ;
2024-02-17 20:05:42 +01:00
use std ::cell ::{ RefCell } ;
2024-02-14 16:32:01 +01:00
use std ::rc ::Rc ;
2024-02-16 08:51:28 +01:00
2024-02-16 22:21:09 +01:00
use duct ::cmd ;
2024-02-14 16:32:01 +01:00
use std ::{
2024-02-16 22:21:09 +01:00
collections ::HashSet ,
hash ::Hash ,
io ::{ BufRead , BufReader } ,
2024-02-17 14:52:07 +01:00
process ::{ Command } ,
time ::{ Duration } ,
2024-02-14 16:32:01 +01:00
} ;
use crate ::drive_mount_row ::DriveMountRow ;
2024-02-16 16:16:45 +01:00
use serde ::* ;
2024-02-14 16:32:01 +01:00
2024-02-16 22:21:09 +01:00
#[ derive(PartialEq, Debug, Eq, Hash, Clone, Serialize, Deserialize) ]
2024-02-16 08:51:28 +01:00
pub struct DriveMount {
2024-02-16 16:16:45 +01:00
pub partition : String ,
pub mountpoint : String ,
pub mountopt : String ,
2024-02-16 08:51:28 +01:00
}
2024-02-16 22:21:09 +01:00
fn create_mount_row (
listbox : & gtk ::ListBox ,
2024-02-18 17:44:00 +01:00
partition_method_manual_error_label : & gtk ::Label ,
partition_method_manual_valid_label : & gtk ::Label ,
2024-02-16 22:21:09 +01:00
manual_drive_mount_array : & Rc < RefCell < Vec < DriveMount > > > ,
part_table_array : & Rc < RefCell < Vec < String > > > ,
2024-02-17 14:52:07 +01:00
_check_part_unique : & Rc < RefCell < bool > > ,
2024-02-16 22:21:09 +01:00
) -> DriveMountRow {
let partition_scroll_child = gtk ::ListBox ::builder ( ) . build ( ) ;
2024-02-16 08:51:28 +01:00
let partitions_scroll = gtk ::ScrolledWindow ::builder ( )
. hexpand ( true )
. vexpand ( true )
. child ( & partition_scroll_child )
. build ( ) ;
2024-02-14 16:32:01 +01:00
// Create row
2024-02-16 08:51:28 +01:00
let row = DriveMountRow ::new_with_scroll ( & partitions_scroll ) ;
2024-02-14 16:32:01 +01:00
2024-02-16 22:21:09 +01:00
let null_checkbutton = gtk ::CheckButton ::builder ( ) . build ( ) ;
2024-02-14 16:32:01 +01:00
2024-02-17 14:52:07 +01:00
let part_table_array_ref = part_table_array . borrow_mut ( ) ;
2024-02-16 14:25:56 +01:00
for partition in part_table_array_ref . iter ( ) {
2024-02-16 08:51:28 +01:00
let partition_size_cli = Command ::new ( " sudo " )
. arg ( " /usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh " )
. arg ( " get_part_size " )
. arg ( partition . clone ( ) )
. output ( )
. expect ( " failed to execute process " ) ;
let partition_fs_cli = Command ::new ( " sudo " )
. arg ( " /usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh " )
. arg ( " get_part_fs " )
. arg ( partition . clone ( ) . replace ( " mapper/ " , " " ) )
. output ( )
. expect ( " failed to execute process " ) ;
2024-02-16 22:21:09 +01:00
let partition_size = String ::from_utf8 ( partition_size_cli . stdout )
. expect ( " Failed to create float " )
. trim ( )
. parse ::< f64 > ( )
. unwrap ( ) ;
let partition_fs = String ::from_utf8 ( partition_fs_cli . stdout ) . expect ( " Failed read stdout " ) ;
2024-02-16 08:51:28 +01:00
let partition_button = gtk ::CheckButton ::builder ( )
. valign ( Align ::Center )
. can_focus ( false )
. build ( ) ;
partition_button . set_group ( Some ( & null_checkbutton ) ) ;
2024-02-16 22:21:09 +01:00
let partition_row : adw ::ActionRow =
if partition_fs . contains ( " crypto_LUKS " ) | | partition_fs . contains ( " lvm " ) {
let prow = adw ::ActionRow ::builder ( )
. activatable_widget ( & partition_button )
. title ( partition . clone ( ) )
. name ( partition . clone ( ) )
. subtitle ( " This partition needs a mapper! " )
. build ( ) ;
prow
} else {
let prow = adw ::ActionRow ::builder ( )
. activatable_widget ( & partition_button )
. title ( partition . clone ( ) )
. name ( partition . clone ( ) )
. subtitle ( partition_fs + & pretty_bytes ::converter ::convert ( partition_size ) )
. build ( ) ;
prow
} ;
2024-02-16 08:51:28 +01:00
partition_row . add_prefix ( & partition_button ) ;
partition_button . connect_toggled ( clone! ( @ weak row , @ weak listbox , @ weak partition_button , @ strong manual_drive_mount_array , @ strong partition = > move | _ | {
let mut manual_drive_mount_array_ref = RefCell ::borrow_mut ( & manual_drive_mount_array ) ;
if partition_button . is_active ( ) = = true {
row . set_partition ( partition . clone ( ) ) ;
} else {
2024-02-16 14:25:56 +01:00
let manual_drive_mount_array_ref_index = manual_drive_mount_array_ref . iter ( ) . position ( | x | x . partition = = partition . clone ( ) ) . unwrap ( ) ;
2024-02-16 08:51:28 +01:00
manual_drive_mount_array_ref . remove ( manual_drive_mount_array_ref_index ) ;
}
} ) ) ;
partition_scroll_child . append ( & partition_row ) ;
}
let listbox_clone = listbox . clone ( ) ;
2024-02-14 16:32:01 +01:00
row . connect_closure (
" row-deleted " ,
false ,
2024-02-18 17:44:00 +01:00
closure_local! ( @ strong partition_method_manual_error_label , @ strong partition_method_manual_valid_label , @ strong row as _row = > move | _row : DriveMountRow | {
listbox_clone . remove ( & _row ) ;
partition_method_manual_error_label . set_label ( " " ) ;
partition_method_manual_error_label . set_visible ( false ) ;
partition_method_manual_valid_label . set_label ( " " ) ;
partition_method_manual_valid_label . set_visible ( false ) ;
2024-02-16 22:21:09 +01:00
} ) ,
2024-02-14 16:32:01 +01:00
) ;
// Return row
row
}
//pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) {
2024-02-16 22:21:09 +01:00
pub fn manual_partitioning (
partitioning_stack : & gtk ::Stack ,
bottom_next_button : & gtk ::Button ,
manual_drive_mount_array : & Rc < RefCell < Vec < DriveMount > > > ,
) {
2024-02-16 14:25:56 +01:00
let part_table_array : Rc < RefCell < Vec < String > > > = Default ::default ( ) ;
2024-02-16 08:51:28 +01:00
let check_part_unique = Rc ::new ( RefCell ::new ( true ) ) ;
2024-02-14 16:32:01 +01:00
let partition_method_manual_main_box = gtk ::Box ::builder ( )
. orientation ( Orientation ::Vertical )
. margin_bottom ( 15 )
. margin_top ( 15 )
. margin_end ( 15 )
. margin_start ( 15 )
. build ( ) ;
let partition_method_manual_header_box = gtk ::Box ::builder ( )
. orientation ( Orientation ::Horizontal )
. build ( ) ;
// the header text for the partitioning page
let partition_method_manual_header_text = gtk ::Label ::builder ( )
. label ( " Manual Partitioning Installer " )
. halign ( gtk ::Align ::End )
. hexpand ( true )
. margin_top ( 15 )
. margin_bottom ( 15 )
. margin_start ( 15 )
. margin_end ( 5 )
. build ( ) ;
partition_method_manual_header_text . add_css_class ( " header_sized_text " ) ;
// the header icon for the partitioning icon
let partition_method_manual_header_icon = gtk ::Image ::builder ( )
. icon_name ( " input-tablet " )
. halign ( gtk ::Align ::Start )
. hexpand ( true )
. pixel_size ( 78 )
. margin_top ( 15 )
. margin_bottom ( 15 )
. margin_start ( 0 )
. margin_end ( 15 )
. build ( ) ;
let partition_method_manual_selection_box = gtk ::Box ::builder ( )
. orientation ( Orientation ::Vertical )
. build ( ) ;
let partition_method_manual_gparted_button_content_box = gtk ::Box ::builder ( )
. orientation ( Orientation ::Vertical )
. build ( ) ;
let partition_method_manual_gparted_button_content_text = gtk ::Label ::builder ( )
. label ( " Use this utility to partition/mount/format your drives. " )
. build ( ) ;
let partition_method_manual_gparted_button_content = adw ::ButtonContent ::builder ( )
. label ( " Open GPARTED " )
. icon_name ( " gparted " )
. build ( ) ;
let partition_method_manual_gparted_button = gtk ::Button ::builder ( )
. child ( & partition_method_manual_gparted_button_content_box )
. halign ( Align ::Center )
. valign ( Align ::Start )
. build ( ) ;
2024-02-16 22:21:09 +01:00
let drive_mounts_adw_listbox = gtk ::ListBox ::builder ( ) . hexpand ( true ) . vexpand ( true ) . build ( ) ;
2024-02-14 16:32:01 +01:00
drive_mounts_adw_listbox . add_css_class ( " boxed-list " ) ;
let drive_mounts_viewport = gtk ::ScrolledWindow ::builder ( )
. halign ( Align ::Center )
. valign ( Align ::Center )
. margin_top ( 30 )
. margin_bottom ( 30 )
. margin_start ( 30 )
. margin_end ( 30 )
. propagate_natural_height ( true )
. propagate_natural_width ( true )
2024-02-16 08:51:28 +01:00
. min_content_height ( 200 )
. min_content_width ( 200 )
2024-02-14 16:32:01 +01:00
. hexpand ( true )
. vexpand ( true )
. child ( & drive_mounts_adw_listbox )
. build ( ) ;
2024-02-16 11:41:51 +01:00
let partition_method_manual_selection_text = gtk ::Label ::builder ( )
2024-02-16 14:25:56 +01:00
. label ( " \n - Press the plus button below to begin adding filesystem entries. \n Notes: \n - This installer doesn't erase any data automatically, format your drives manually via gparted. \n - To Add a linux-swap partition set mountpoint to [SWAP] \n - We recommend the following partitions as a base layout: \n /boot ~ 1000mb ext4. \n /boot/efi ~ 512mb vfat/fat32. \n / >= 25GB btrfs. \n " )
2024-02-16 11:41:51 +01:00
. halign ( gtk ::Align ::Center )
. hexpand ( true )
. margin_top ( 15 )
. margin_bottom ( 15 )
. margin_start ( 15 )
. margin_end ( 15 )
. build ( ) ;
partition_method_manual_selection_text . add_css_class ( " medium_sized_text " ) ;
2024-02-16 14:25:56 +01:00
let partition_refresh_button = gtk ::Button ::builder ( )
. label ( " Refresh Partition Table " )
. halign ( gtk ::Align ::End )
. build ( ) ;
partition_refresh_button . add_css_class ( " destructive-action " ) ;
2024-02-17 20:05:42 +01:00
let fstab_valid_check = gtk ::Button ::builder ( )
. label ( " Validate Filesystem Table " )
. halign ( gtk ::Align ::Start )
. build ( ) ;
fstab_valid_check . add_css_class ( " valid-action " ) ;
2024-02-14 16:32:01 +01:00
let drive_mount_add_button = gtk ::Button ::builder ( )
. icon_name ( " list-add " )
2024-02-16 08:51:28 +01:00
. vexpand ( true )
. hexpand ( true )
2024-02-14 16:32:01 +01:00
. build ( ) ;
2024-02-16 08:51:28 +01:00
let partition_method_manual_error_label = gtk ::Label ::builder ( )
. halign ( Align ::Start )
. valign ( Align ::End )
. vexpand ( true )
. visible ( false )
. build ( ) ;
partition_method_manual_error_label . add_css_class ( " small_error_text " ) ;
2024-02-17 20:05:42 +01:00
let partition_method_manual_valid_label = gtk ::Label ::builder ( )
. halign ( Align ::Start )
. valign ( Align ::End )
. vexpand ( true )
. visible ( false )
. label ( " Filesystem Table is valid! " )
. build ( ) ;
partition_method_manual_valid_label . add_css_class ( " small_valid_text " ) ;
2024-02-16 08:51:28 +01:00
let partition_method_manual_warn_label = gtk ::Label ::builder ( )
. halign ( Align ::Start )
. valign ( Align ::End )
. vexpand ( true )
. visible ( false )
. build ( ) ;
partition_method_manual_warn_label . add_css_class ( " small_warn_text " ) ;
2024-02-14 16:32:01 +01:00
partition_method_manual_header_box . append ( & partition_method_manual_header_text ) ;
partition_method_manual_header_box . append ( & partition_method_manual_header_icon ) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_selection_box . append ( & partition_method_manual_selection_text ) ;
2024-02-16 14:25:56 +01:00
partition_method_manual_selection_box . append ( & partition_refresh_button ) ;
2024-02-14 16:32:01 +01:00
partition_method_manual_main_box . append ( & partition_method_manual_header_box ) ;
partition_method_manual_main_box . append ( & partition_method_manual_selection_box ) ;
2024-02-16 22:21:09 +01:00
partition_method_manual_gparted_button_content_box
. append ( & partition_method_manual_gparted_button_content ) ;
partition_method_manual_gparted_button_content_box
. append ( & partition_method_manual_gparted_button_content_text ) ;
2024-02-14 16:32:01 +01:00
partition_method_manual_main_box . append ( & partition_method_manual_gparted_button ) ;
drive_mounts_adw_listbox . append ( & drive_mount_add_button ) ;
partition_method_manual_main_box . append ( & drive_mounts_viewport ) ;
2024-02-17 20:05:42 +01:00
partition_method_manual_main_box . append ( & fstab_valid_check ) ;
2024-02-16 08:51:28 +01:00
partition_method_manual_main_box . append ( & partition_method_manual_error_label ) ;
2024-02-17 20:05:42 +01:00
partition_method_manual_main_box . append ( & partition_method_manual_valid_label ) ;
2024-02-16 08:51:28 +01:00
partition_method_manual_main_box . append ( & partition_method_manual_warn_label ) ;
2024-02-14 16:32:01 +01:00
2024-02-17 20:05:42 +01:00
fstab_valid_check . connect_clicked ( clone! ( @ weak partition_method_manual_error_label , @ weak partition_method_manual_valid_label , @ strong manual_drive_mount_array , @ strong check_part_unique = > move | _ | {
partition_err_check ( & partition_method_manual_error_label , & partition_method_manual_valid_label , & manual_drive_mount_array ) ;
} ) ) ;
2024-02-17 16:54:33 +01:00
partition_refresh_button . connect_clicked ( clone! ( @ weak drive_mounts_adw_listbox , @ strong part_table_array , @ strong manual_drive_mount_array = > move | _ | {
while let Some ( row ) = drive_mounts_adw_listbox . last_child ( ) {
2024-02-16 14:25:56 +01:00
if row . widget_name ( ) = = " DriveMountRow " {
2024-02-17 16:54:33 +01:00
drive_mounts_adw_listbox . remove ( & row ) ;
} else {
break
2024-02-16 14:25:56 +01:00
}
2024-02-17 16:54:33 +01:00
}
2024-02-17 14:52:07 +01:00
let partition_method_manual_get_partitions_lines = BufReader ::new ( cmd! ( " bash " , " -c " , " sudo /usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh get_partitions " ) . reader ( ) . unwrap ( ) ) . lines ( ) ;
2024-02-16 14:25:56 +01:00
let mut part_table_array_ref = part_table_array . borrow_mut ( ) ;
part_table_array_ref . clear ( ) ;
2024-02-17 16:54:33 +01:00
let mut manual_drive_mount_array_ref = manual_drive_mount_array . borrow_mut ( ) ;
manual_drive_mount_array_ref . clear ( ) ;
2024-02-16 14:25:56 +01:00
for partition in partition_method_manual_get_partitions_lines {
part_table_array_ref . push ( partition . unwrap ( ) ) ;
}
} ) ) ;
partition_refresh_button . emit_clicked ( ) ;
2024-02-14 16:32:01 +01:00
partition_method_manual_gparted_button . connect_clicked ( move | _ | {
Command ::new ( " gparted " )
. spawn ( )
. expect ( " gparted failed to start " ) ;
} ) ;
2024-02-18 17:44:00 +01:00
drive_mount_add_button . connect_clicked ( clone! ( @ weak partition_method_manual_error_label , @ weak partition_method_manual_valid_label , @ weak drive_mounts_adw_listbox , @ strong manual_drive_mount_array , @ strong part_table_array , @ strong check_part_unique = > move | _ | {
drive_mounts_adw_listbox . append ( & create_mount_row ( & drive_mounts_adw_listbox , & partition_method_manual_error_label , & partition_method_manual_valid_label , & manual_drive_mount_array , & part_table_array , & check_part_unique ) )
2024-02-14 16:32:01 +01:00
} ) ) ;
2024-02-16 08:51:28 +01:00
let ( anti_dup_partition_sender , anti_dup_partition_receiver ) = async_channel ::unbounded ( ) ;
let anti_dup_partition_sender = anti_dup_partition_sender . clone ( ) ;
// The long running operation runs now in a separate thread
2024-02-16 22:21:09 +01:00
gio ::spawn_blocking ( move | | loop {
thread ::sleep ( Duration ::from_millis ( 400 ) ) ;
anti_dup_partition_sender
. send_blocking ( true )
. expect ( " The channel needs to be open. " ) ;
2024-02-16 08:51:28 +01:00
} ) ;
2024-02-14 16:32:01 +01:00
2024-02-16 08:51:28 +01:00
let anti_dup_partition_loop_context = MainContext ::default ( ) ;
2024-02-18 17:44:00 +01:00
anti_dup_partition_loop_context . spawn_local ( clone! ( @ weak partition_method_manual_error_label , @ weak partition_method_manual_valid_label , @ weak drive_mounts_adw_listbox , @ weak partitioning_stack , @ strong manual_drive_mount_array , @ weak bottom_next_button , @ strong check_part_unique = > async move {
2024-02-16 08:51:28 +01:00
while let Ok ( _state ) = anti_dup_partition_receiver . recv ( ) . await {
let mut counter = drive_mounts_adw_listbox . first_child ( ) ;
let mut manual_drive_mount_array_ref = manual_drive_mount_array . borrow_mut ( ) ;
// usage of while loop
manual_drive_mount_array_ref . clear ( ) ;
while let Some ( row ) = counter {
if row . widget_name ( ) = = " DriveMountRow " {
let row_mount = DriveMount {
partition : row . clone ( ) . property ( " partition " ) ,
mountpoint : row . clone ( ) . property ( " mountpoint " ) ,
mountopt : row . clone ( ) . property ( " mountopt " ) ,
} ;
manual_drive_mount_array_ref . push ( row_mount ) ;
}
counter = row . next_sibling ( ) ;
2024-02-14 16:32:01 +01:00
}
2024-02-16 08:51:28 +01:00
let mut counter = drive_mounts_adw_listbox . first_child ( ) ;
while let Some ( ref row ) = counter {
if row . widget_name ( ) = = " DriveMountRow " {
let mut counter_scrw = row . property ::< gtk ::ScrolledWindow > ( " partitionscroll " ) . child ( ) . unwrap ( ) . first_child ( ) . unwrap ( ) . first_child ( ) ;
while let Some ( ref row_scrw ) = counter_scrw {
if manual_drive_mount_array_ref . iter ( ) . any ( | e | {
if ! e . partition . is_empty ( ) {
row_scrw . widget_name ( ) . contains ( & e . partition )
} else {
return false
}
} ) {
if * check_part_unique . borrow_mut ( ) = = true {
row_scrw . set_sensitive ( false )
2024-02-16 22:21:09 +01:00
} else if row_scrw . property ::< String > ( " subtitle " ) . contains ( " This partition needs a mapper! " ) {
row_scrw . set_sensitive ( false )
2024-02-16 08:51:28 +01:00
} else {
row_scrw . set_sensitive ( true )
}
2024-02-16 22:21:09 +01:00
}
else if row_scrw . property ::< String > ( " subtitle " ) . contains ( " This partition needs a mapper! " ) {
row_scrw . set_sensitive ( false )
2024-02-16 08:51:28 +01:00
} else {
row_scrw . set_sensitive ( true )
}
counter_scrw = row_scrw . next_sibling ( ) ;
}
}
counter = row . next_sibling ( ) ;
}
2024-02-16 12:34:45 +01:00
let manual_drive_mount_array_ref_clone = manual_drive_mount_array_ref . clone ( ) ;
2024-02-17 20:05:42 +01:00
* check_part_unique . borrow_mut ( ) = true ;
for mountopts in manual_drive_mount_array_ref
. iter ( )
. map ( | x | x . mountopt . as_str ( ) )
. collect ::< HashSet < & str > > ( )
{
if mountopts . contains ( " subvol " ) {
* check_part_unique . borrow_mut ( ) = false
}
}
if * check_part_unique . borrow_mut ( ) = = false {
partition_method_manual_warn_label
. set_label ( " Partition reuse check will be skipped due to subvol usage. " ) ;
partition_method_manual_warn_label . set_visible ( true ) ;
} else {
partition_method_manual_warn_label . set_visible ( false ) ;
}
2024-02-16 16:16:45 +01:00
if partitioning_stack . visible_child_name ( ) = = Some ( GString ::from_string_unchecked ( " partition_method_manual_page " . into ( ) ) ) {
2024-02-17 20:05:42 +01:00
if manual_drive_mount_array_ref_clone . iter ( ) . any ( | x | { if x . mountpoint = = " / " { return true } else { return false } } ) & & manual_drive_mount_array_ref_clone . iter ( ) . any ( | x | { if x . mountpoint = = " /boot " { return true } else { return false } } ) & & manual_drive_mount_array_ref_clone . iter ( ) . any ( | x | { if x . mountpoint = = " /boot/efi " { return true } else { return false } } ) & & ! partition_method_manual_error_label . is_visible ( ) & & partition_method_manual_valid_label . is_visible ( ) {
2024-02-16 16:16:45 +01:00
if ! bottom_next_button . is_sensitive ( ) {
bottom_next_button . set_sensitive ( true ) ;
}
} else {
if bottom_next_button . is_sensitive ( ) {
bottom_next_button . set_sensitive ( false ) ;
}
2024-02-16 12:34:45 +01:00
}
}
2024-02-14 16:32:01 +01:00
}
} ) ) ;
2024-02-16 22:21:09 +01:00
partitioning_stack . add_titled (
& partition_method_manual_main_box ,
Some ( " partition_method_manual_page " ) ,
" partition_method_manual_page " ,
) ;
2024-02-14 16:32:01 +01:00
//return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry)
}
2024-02-16 08:51:28 +01:00
2024-02-16 22:21:09 +01:00
fn partition_err_check (
partition_method_manual_error_label : & gtk ::Label ,
2024-02-17 20:05:42 +01:00
partition_method_manual_valid_label : & gtk ::Label ,
manual_drive_mount_array : & Rc < RefCell < Vec < DriveMount > > > ,
2024-02-16 22:21:09 +01:00
) {
2024-02-16 11:41:51 +01:00
let mut empty_mountpoint = false ;
2024-02-17 20:05:42 +01:00
let manual_drive_mount_array_ref = manual_drive_mount_array . borrow_mut ( ) ;
2024-02-16 22:21:09 +01:00
for mountpoint in manual_drive_mount_array_ref
. iter ( )
. map ( | x | x . mountpoint . as_str ( ) )
. collect ::< HashSet < & str > > ( )
{
2024-02-16 11:41:51 +01:00
if empty_mountpoint = = false {
if mountpoint . is_empty ( ) {
empty_mountpoint = true
}
}
}
let mut empty_partition = false ;
2024-02-16 22:21:09 +01:00
for partition in manual_drive_mount_array_ref
. iter ( )
. map ( | x | x . partition . as_str ( ) )
. collect ::< HashSet < & str > > ( )
{
2024-02-16 11:41:51 +01:00
if empty_partition = = false {
if partition . is_empty ( ) {
empty_partition = true
}
}
}
if empty_mountpoint = = false {
2024-02-16 22:21:09 +01:00
if & partition_method_manual_error_label . label ( )
= = " Some drives don't have a mountpoint configured. "
{
partition_method_manual_error_label . set_visible ( false ) ;
}
if manual_drive_mount_array_ref . len ( )
- manual_drive_mount_array_ref
. iter ( )
. map ( | x | x . mountpoint . as_str ( ) )
. collect ::< HashSet < & str > > ( )
. len ( )
> 0
{
2024-02-16 11:41:51 +01:00
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label
. set_label ( " Multiple drives were mounted to the same mountpoint. " ) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
2024-02-16 22:21:09 +01:00
} else {
if partition_method_manual_error_label . label ( )
= = " Multiple drives were mounted to the same mountpoint. "
{
partition_method_manual_error_label . set_visible ( false ) ;
}
}
} else {
if ! partition_method_manual_error_label . is_visible ( ) {
partition_method_manual_error_label
. set_label ( " Some drives don't have a mountpoint configured. " ) ;
partition_method_manual_error_label . set_visible ( true ) ;
}
}
2024-02-16 11:41:51 +01:00
if empty_partition = = true {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label
. set_label ( " There's a drive row without a partition. " ) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
2024-02-16 08:51:28 +01:00
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label . label ( ) = = " There's a drive row without a partition. "
{
2024-02-16 08:51:28 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
2024-02-16 22:21:09 +01:00
for drivemounts in manual_drive_mount_array_ref
. iter ( )
. map ( | x | x )
. collect ::< HashSet < & DriveMount > > ( )
{
2024-02-16 11:41:51 +01:00
if ! drivemounts . partition . is_empty ( ) {
let partition_size_cli = Command ::new ( " sudo " )
. arg ( " /usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh " )
. arg ( " get_part_size " )
. arg ( drivemounts . partition . clone ( ) )
. output ( )
. expect ( " failed to execute process " ) ;
let partition_fs_cli = Command ::new ( " sudo " )
. arg ( " /usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh " )
. arg ( " get_part_fs " )
. arg ( drivemounts . partition . replace ( " mapper/ " , " " ) )
. output ( )
. expect ( " failed to execute process " ) ;
2024-02-16 22:21:09 +01:00
let partition_size = String ::from_utf8 ( partition_size_cli . stdout )
. expect ( " Failed to create float " )
. trim ( )
. parse ::< f64 > ( )
. unwrap ( ) ;
let partition_fs = String ::from_utf8 ( partition_fs_cli . stdout )
. expect ( " Failed to create string " )
. trim ( )
. parse ::< String > ( )
. unwrap ( ) ;
2024-02-16 11:41:51 +01:00
if drivemounts . mountpoint = = " /boot/efi " {
if partition_size < 500000000.0 {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Small size: The partition mounted to /boot/efi (/dev/ " . to_owned ( )
+ & drivemounts . partition
+ " ) Must at least be 512MBs " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Small size: The partition mounted to /boot/efi (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
if partition_fs ! = " vfat " {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Bad Filesystem: The partition mounted to /boot/efi (/dev/ "
. to_owned ( )
+ & drivemounts . partition
+ " ) Must at be FAT32/vFAT " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Bad Filesystem: The partition mounted to /boot/efi (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
}
if drivemounts . mountpoint = = " /boot " {
if partition_size < 1000000000.0 {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Small size: The partition mounted to /boot (/dev/ " . to_owned ( )
+ & drivemounts . partition
+ " ) Must at least be 1000MBs " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Small size: The partition mounted to /boot (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
if partition_fs = = " vfat " {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Bad Filesystem: The partition mounted to /boot (/dev/ " . to_owned ( )
+ & drivemounts . partition
+ " ) Cannot be FAT32/vFAT " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Bad Filesystem: The partition mounted to /boot (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
}
if drivemounts . mountpoint = = " / " {
if partition_size < 25000000000.0 {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Small size: The partition mounted to / (/dev/ " . to_owned ( )
+ & drivemounts . partition
+ " ) Must at least be 25GBs " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Small size: The partition mounted to / (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
2024-02-18 17:44:00 +01:00
if partition_fs = = " vfat " | | partition_fs = = " vfat " | | partition_fs = = " ntfs " | | partition_fs = = " swap " | | partition_fs = = " exfat " {
2024-02-16 11:41:51 +01:00
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Bad Filesystem: The partition mounted to / (/dev/ " . to_owned ( )
+ & drivemounts . partition
2024-02-18 17:44:00 +01:00
+ " ) Has an Invalid Filesystem " ) ,
2024-02-16 22:21:09 +01:00
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Bad Filesystem: The partition mounted to / (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
}
if drivemounts . mountpoint = = " /home " {
if partition_size < 10000000000.0 {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Small size: The partition mounted to /home (/dev/ " . to_owned ( )
+ & drivemounts . partition
+ " ) Must at least be 10GBs " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Small size: The partition mounted to /home (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
if partition_fs = = " vfat " {
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Bad Filesystem: The partition mounted to /home (/dev/ " . to_owned ( )
+ & drivemounts . partition
+ " ) Cannot be FAT32/vFAT " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Bad Filesystem: The partition mounted to /home (/dev/ " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
2024-02-16 12:34:45 +01:00
}
if drivemounts . mountpoint = = " [SWAP] " {
2024-02-17 20:29:23 +01:00
if partition_fs ! = " swap " {
2024-02-16 12:34:45 +01:00
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Bad Filesystem: " . to_owned ( )
+ & drivemounts . partition
+ " Is not a swap partition " ) ,
) ;
2024-02-16 12:34:45 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Is not a swap partition " )
{
2024-02-16 12:34:45 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
2024-02-16 11:41:51 +01:00
}
2024-02-16 22:21:09 +01:00
if empty_mountpoint = = false
& & ! drivemounts . mountpoint . starts_with ( " / " )
& & drivemounts . mountpoint ! = " [SWAP] "
{
2024-02-16 11:41:51 +01:00
if ! partition_method_manual_error_label . is_visible ( ) {
2024-02-16 22:21:09 +01:00
partition_method_manual_error_label . set_label (
& ( " Bad Mountpoint: " . to_owned ( )
+ & drivemounts . mountpoint
+ " Is not a valid mountpoint " ) ,
) ;
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( true ) ;
}
} else {
2024-02-16 22:21:09 +01:00
if partition_method_manual_error_label
. label ( )
. contains ( " Is not a valid mountpoint " )
{
2024-02-16 11:41:51 +01:00
partition_method_manual_error_label . set_visible ( false ) ;
}
}
2024-02-17 20:05:42 +01:00
if ! partition_method_manual_error_label . is_visible ( ) {
partition_method_manual_valid_label . set_visible ( true )
} else {
partition_method_manual_valid_label . set_visible ( false )
}
2024-02-16 11:41:51 +01:00
}
}
2024-02-16 22:21:09 +01:00
}