From 42fa310a5fc0c119c7cfd661d05b95cde7a73333 Mon Sep 17 00:00:00 2001 From: Ward from fusion-voyager-3 Date: Sat, 10 Feb 2024 21:03:19 +0300 Subject: [PATCH] RR: Seperate Partitioning pages --- .idea/.gitignore | 8 + .idea/modules.xml | 8 + .idea/pkg-pika-installer-gtk4.iml | 11 + .idea/vcs.xml | 6 + src/automatic_paritioning.rs | 281 +++++++++++ src/main.rs | 5 + src/manual_partitioning.rs | 523 ++++++++++++++++++++ src/partitioning_page.rs | 759 +----------------------------- 8 files changed, 852 insertions(+), 749 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/pkg-pika-installer-gtk4.iml create mode 100644 .idea/vcs.xml create mode 100644 src/automatic_paritioning.rs create mode 100644 src/manual_partitioning.rs diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e957f63 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/pkg-pika-installer-gtk4.iml b/.idea/pkg-pika-installer-gtk4.iml new file mode 100644 index 0000000..cf84ae4 --- /dev/null +++ b/.idea/pkg-pika-installer-gtk4.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/automatic_paritioning.rs b/src/automatic_paritioning.rs new file mode 100644 index 0000000..4f53cb7 --- /dev/null +++ b/src/automatic_paritioning.rs @@ -0,0 +1,281 @@ +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use std::env; +use pretty_bytes::converter::convert; + +use std::thread; +use std::time::*; + +use std::fs; +use std::path::Path; + +use crate::install_page; +pub fn automatic_partitioning(partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer) { + let partition_method_automatic_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_bottom(15) + .margin_top(15) + .margin_end(15) + .margin_start(15) + .build(); + + let partition_method_automatic_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the partitioning page + let partition_method_automatic_header_text = gtk::Label::builder() + .label("Automatic Partitioning Installer") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + partition_method_automatic_header_text.add_css_class("header_sized_text"); + + // the header icon for the partitioning icon + let partition_method_automatic_header_icon = gtk::Image::builder() + .icon_name("media-playlist-shuffle") + .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_automatic_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let partition_method_automatic_selection_text = gtk::Label::builder() + .label("Choose the Drive you want to install PikaOS on\nNote: This will erase the entire drive backup your data!") + .justify(Justification::Center) + .halign(gtk::Align::Center) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + partition_method_automatic_selection_text.add_css_class("medium_sized_text"); + + let devices_selection_expander_row = adw::ExpanderRow::builder() + .title("No disk selected for selection") + .build(); + + let null_checkbutton = gtk::CheckButton::builder() + .build(); + + let devices_selection_expander_row_viewport = gtk::ScrolledWindow::builder() + .height_request(200) + .build(); + + let devices_selection_expander_row_viewport_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + devices_selection_expander_row_viewport.set_child(Some(&devices_selection_expander_row_viewport_box)); + + let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder() + .selection_mode(SelectionMode::None) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + devices_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); + devices_selection_expander_row_viewport_listbox.append(&devices_selection_expander_row); + + devices_selection_expander_row.add_row(&devices_selection_expander_row_viewport); + + let partition_method_automatic_get_devices_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("get_block_devices") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + let partition_method_automatic_get_devices_reader = BufReader::new(partition_method_automatic_get_devices_cli.stdout.expect("could not get stdout")); + + let partition_method_automatic_disk_error_label = gtk::Label::builder() + .label("No Disk specified.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .build(); + partition_method_automatic_disk_error_label.add_css_class("small_error_text"); + + let partition_method_automatic_luks_error_label = gtk::Label::builder() + .label("LUKS Encryption Enabled but no password provided.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .visible(false) + .build(); + partition_method_automatic_luks_error_label.add_css_class("small_error_text"); + + let partition_method_automatic_luks_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + let partition_method_automatic_luks_checkbutton = gtk::CheckButton::builder() + .label("Enable LUKS2 Disk Encryption") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let partition_method_automatic_luks_listbox = gtk::ListBox::builder() + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + partition_method_automatic_luks_listbox.add_css_class("boxed-list"); + + let partition_method_automatic_luks_password_entry = adw::PasswordEntryRow::builder() + .title("LUKS Password") + .hexpand(true) + .sensitive(false) + .build(); + + let partition_method_automatic_target_buffer = gtk::TextBuffer::builder() + .build(); + + let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder() + .build(); + + for device in partition_method_automatic_get_devices_reader.lines() { + let device = device.unwrap(); + let device_size_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("get_block_size") + .arg(device.clone()) + .output() + .expect("failed to execute process"); + let device_size = String::from_utf8(device_size_cli.stdout).expect("Failed to create float").trim().parse::().unwrap(); + let device_button = gtk::CheckButton::builder() + .valign(Align::Center) + .can_focus(false) + .build(); + device_button.set_group(Some(&null_checkbutton)); + let device_row = adw::ActionRow::builder() + .activatable_widget(&device_button) + .title(device.clone()) + .subtitle(pretty_bytes::converter::convert(device_size)) + .build(); + device_row.add_prefix(&device_button); + devices_selection_expander_row_viewport_box.append(&device_row); + device_button.connect_toggled(clone!(@weak device_button,@weak partition_method_automatic_luks_password_entry, @weak devices_selection_expander_row, @weak bottom_next_button, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { + if device_button.is_active() == true { + devices_selection_expander_row.set_title(&device); + if device_size > 39000000000.0 { + partition_method_automatic_disk_error_label.set_visible(false); + if partition_method_automatic_luks_checkbutton.is_active() == true { + if partition_method_automatic_luks_error_label.get_visible() { + // + } else { + bottom_next_button.set_sensitive(true); + } + } else { + partition_method_automatic_target_buffer.set_text(&device); + partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); + bottom_next_button.set_sensitive(true); + } + } else { + partition_method_automatic_disk_error_label.set_visible(true); + partition_method_automatic_disk_error_label.set_label("Disk Size too small, PikaOS needs 40GB Disk"); + bottom_next_button.set_sensitive(false); + } + } + })); + } + + partition_method_automatic_luks_checkbutton.connect_toggled(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { + if partition_method_automatic_luks_checkbutton.is_active() == true { + partition_method_automatic_luks_password_entry.set_sensitive(true); + if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { + partition_method_automatic_luks_error_label.set_visible(true); + bottom_next_button.set_sensitive(false); + } else { + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + bottom_next_button.set_sensitive(true); + } + } + } else { + partition_method_automatic_luks_password_entry.set_sensitive(false); + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + bottom_next_button.set_sensitive(true); + } + } + })); + + partition_method_automatic_luks_password_entry.connect_changed(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_luks_buffer => move |_| { + if partition_method_automatic_luks_checkbutton.is_active() == true { + partition_method_automatic_luks_password_entry.set_sensitive(true); + if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { + partition_method_automatic_luks_error_label.set_visible(true); + bottom_next_button.set_sensitive(false); + } else { + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); + bottom_next_button.set_sensitive(true); + } + } + } else { + partition_method_automatic_luks_password_entry.set_sensitive(false); + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); + bottom_next_button.set_sensitive(true); + } + } + })); + + partition_method_automatic_luks_listbox.append(&partition_method_automatic_luks_password_entry); + partition_method_automatic_luks_box.append(&partition_method_automatic_luks_checkbutton); + partition_method_automatic_luks_box.append(&partition_method_automatic_luks_listbox); + partition_method_automatic_header_box.append(&partition_method_automatic_header_text); + partition_method_automatic_header_box.append(&partition_method_automatic_header_icon); + partition_method_automatic_selection_box.append(&partition_method_automatic_selection_text); + partition_method_automatic_main_box.append(&partition_method_automatic_header_box); + partition_method_automatic_main_box.append(&partition_method_automatic_selection_box); + partition_method_automatic_main_box.append(&devices_selection_expander_row_viewport_listbox); + partition_method_automatic_main_box.append(&partition_method_automatic_luks_box); + partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_label); + partition_method_automatic_main_box.append(&partition_method_automatic_disk_error_label); + + partitioning_stack.add_titled(&partition_method_automatic_main_box, Some("partition_method_automatic_page"), "partition_method_automatic_page"); + + return(partition_method_automatic_target_buffer, partition_method_automatic_luks_buffer) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 782a880..5008e17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,9 @@ mod keyboard_page; mod partitioning_page; mod install_page; mod done_page; +mod automatic_paritioning; +mod manual_partitioning; + use crate::save_window_size::save_window_size; use crate::welcome_page::welcome_page; use crate::efi_error_page::efi_error_page; @@ -29,6 +32,8 @@ use crate::eula_page::eula_page; use crate::timezone_page::timezone_page; use crate::keyboard_page::keyboard_page; use crate::partitioning_page::partitioning_page; +use crate::automatic_paritioning::automatic_partitioning; +use crate::manual_partitioning::manual_partitioning; use crate::install_page::install_page; use crate::done_page::done_page; diff --git a/src/manual_partitioning.rs b/src/manual_partitioning.rs new file mode 100644 index 0000000..ce3e73c --- /dev/null +++ b/src/manual_partitioning.rs @@ -0,0 +1,523 @@ +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use std::env; +use pretty_bytes::converter::convert; + +use std::thread; +use std::time::*; + +use std::fs; +use std::path::Path; + +use crate::install_page; + + +pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) { + 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_selection_text = gtk::Label::builder() + .label(" - Mount your custom root drive somewhere.\n - Mount all your additional mountpoints relative to it.\n - Make sure to have the the following mountpoints:\n (CUSTOM_ROOT)/boot ~ 1000mb ext4\n (CUSTOM_ROOT)/boot/efi ~ 512mb vfat/fat32\n- If (CUSTOM_ROOT)/home has LUKS encryption, make sure to enable it here.\n - Note: This doesn't erase any data automatically, format your drives manually.") + .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"); + + let partition_method_manual_chroot_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let partition_method_manual_chroot_listbox = gtk::ListBox::builder() + .build(); + partition_method_manual_chroot_listbox.add_css_class("boxed-list"); + + let partition_method_manual_chroot_dir_file_dialog = gtk::FileChooserNative::new( + Some("Open File"), + gtk::Window::NONE, + gtk::FileChooserAction::SelectFolder, + Some("Open"), + Some("Cancel"), + ); + + partition_method_manual_chroot_dir_file_dialog.set_transient_for(Some(window)); + + let partition_method_manual_chroot_dir_entry = adw::EntryRow::builder() + .title("Custom Root Mountpoint") + .hexpand(true) + .build(); + + let partition_method_manual_chroot_dir_button_content = adw::ButtonContent::builder() + .label("Open") + .icon_name("folder-open") + .build(); + + let partition_method_manual_chroot_dir_button = gtk::Button::builder() + .child(&partition_method_manual_chroot_dir_button_content) + .margin_start(10) + .build(); + + let partition_method_manual_luks_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + let partition_method_manual_luks_listbox = gtk::ListBox::builder() + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + partition_method_manual_luks_listbox.add_css_class("boxed-list"); + + let partition_method_manual_luks_password_entry = adw::PasswordEntryRow::builder() + .title("LUKS Password") + .hexpand(true) + .sensitive(false) + .build(); + + let partition_method_manual_chroot_error_label = gtk::Label::builder() + .label("No mountpoint specified.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .build(); + partition_method_manual_chroot_error_label.add_css_class("small_error_text"); + + let partition_method_manual_boot_error_label = gtk::Label::builder() + .label("No boot partition found in chroot, mount (CUSTOM_ROOT)/boot.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .visible(false) + .build(); + partition_method_manual_boot_error_label.add_css_class("small_error_text"); + + let partition_method_manual_efi_error_label = gtk::Label::builder() + .label("No EFI partition found in chroot, mount (CUSTOM_ROOT)/boot/efi.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .visible(false) + .build(); + partition_method_manual_efi_error_label.add_css_class("small_error_text"); + + let partition_method_manual_luks_error_label = gtk::Label::builder() + .label("Home partition encrypted, but no LUKS password provided.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .visible(false) + .build(); + partition_method_manual_luks_error_label.add_css_class("small_error_text"); + + 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::End) + .build(); + + partition_method_manual_luks_listbox.append(&partition_method_manual_luks_password_entry); + partition_method_manual_luks_box.append(&partition_method_manual_luks_listbox); + partition_method_manual_header_box.append(&partition_method_manual_header_text); + partition_method_manual_header_box.append(&partition_method_manual_header_icon); + partition_method_manual_selection_box.append(&partition_method_manual_selection_text); + partition_method_manual_main_box.append(&partition_method_manual_header_box); + partition_method_manual_main_box.append(&partition_method_manual_selection_box); + partition_method_manual_chroot_listbox.append(&partition_method_manual_chroot_dir_entry); + partition_method_manual_chroot_box.append(&partition_method_manual_chroot_listbox); + partition_method_manual_chroot_box.append(&partition_method_manual_chroot_dir_button); + 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); + partition_method_manual_main_box.append(&partition_method_manual_chroot_box); + partition_method_manual_main_box.append(&partition_method_manual_luks_box); + partition_method_manual_main_box.append(&partition_method_manual_luks_error_label); + partition_method_manual_main_box.append(&partition_method_manual_chroot_error_label); + partition_method_manual_main_box.append(&partition_method_manual_boot_error_label); + partition_method_manual_main_box.append(&partition_method_manual_efi_error_label); + partition_method_manual_main_box.append(&partition_method_manual_gparted_button); + + // clone partition_method_manual_chroot_dir_file_dialog as rust becuase glib breaks it show function for some reason + let partition_method_manual_chroot_dir_file_dialog_clone = partition_method_manual_chroot_dir_file_dialog.clone(); + partition_method_manual_chroot_dir_button.connect_clicked(move |_| { + partition_method_manual_chroot_dir_file_dialog_clone.set_visible(true); + }); + + partition_method_manual_chroot_dir_file_dialog.connect_response(clone!(@weak partition_method_manual_chroot_dir_file_dialog, @weak partition_method_manual_chroot_dir_entry => move |_, response| { + if response == gtk::ResponseType::Accept { + if partition_method_manual_chroot_dir_file_dialog.file().is_some() { + partition_method_manual_chroot_dir_entry.set_text(&partition_method_manual_chroot_dir_file_dialog.file().expect("FILE PATHING FAIL").path().expect("PATH STRINGING FAIL").into_os_string().into_string().unwrap()); + } + } + })); + + let partition_method_manual_target_buffer = gtk::TextBuffer::builder() + .build(); + + let partition_method_manual_luks_buffer = gtk::TextBuffer::builder() + .build(); + + partition_method_manual_chroot_dir_entry.connect_changed(clone!(@weak bottom_next_button, @weak partition_method_manual_luks_password_entry, @weak partition_method_manual_luks_error_label, @weak partition_method_manual_chroot_dir_entry, @weak partition_method_manual_chroot_error_label, @weak partition_method_manual_boot_error_label, @weak partition_method_manual_efi_error_label, @weak partition_method_manual_target_buffer, @weak partition_method_manual_luks_buffer => move |_| { + bottom_next_button.set_sensitive(false); + let custom_root_mountpoint = partition_method_manual_chroot_dir_entry.text().to_string(); + // Mountpoint Check + if custom_root_mountpoint.is_empty() { + partition_method_manual_chroot_error_label.set_label("No mountpoint specified."); + partition_method_manual_chroot_error_label.set_visible(true); + } else if custom_root_mountpoint.contains("/dev") { + partition_method_manual_chroot_error_label.set_label("This Installer Takes mountpoints not devices."); + partition_method_manual_chroot_error_label.set_visible(true); + } else { + partition_method_manual_chroot_error_label.set_visible(false); + } + // Home partition Check + let home_not_root_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("home_not_root") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + if home_not_root_cli.status.success() { + // Home encryption Checking + let (luks_manual_is_encrypt_sender, luks_manual_is_encrypt_receiver) = async_channel::unbounded(); + let luks_manual_is_encrypt_sender = luks_manual_is_encrypt_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(clone!(@strong custom_root_mountpoint => move || { + let check_home_encryption_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("check_home_encryption") + .arg(custom_root_mountpoint) + .output() + .expect("failed to execute process"); + if check_home_encryption_cli.status.success() { + luks_manual_is_encrypt_sender + .send_blocking(true) + .expect("The channel needs to be open."); + } else { + luks_manual_is_encrypt_sender + .send_blocking(false) + .expect("The channel needs to be open."); + } + })); + let luks_manual_is_encrypt_main_context = MainContext::default(); + // The main loop executes the asynchronous block + luks_manual_is_encrypt_main_context.spawn_local(clone!(@weak partition_method_manual_luks_password_entry => async move { + while let Ok(state) = luks_manual_is_encrypt_receiver.recv().await { + partition_method_manual_luks_password_entry.set_sensitive(state); + } + })); + // Luks Password Checking + let luks_passwd = partition_method_manual_luks_password_entry.text().to_string(); + let (luks_manual_password_sender, luks_manual_password_receiver) = async_channel::unbounded(); + let luks_manual_password_sender = luks_manual_password_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(clone!(@strong custom_root_mountpoint, @strong luks_passwd, @strong custom_root_mountpoint => move || { + let luks_check_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("check_home_luks_passwd") + .arg(custom_root_mountpoint) + .arg(luks_passwd) + .output() + .expect("failed to execute process"); + if luks_check_cli.status.success() { + luks_manual_password_sender + .send_blocking(false) + .expect("The channel needs to be open."); + } else { + luks_manual_password_sender + .send_blocking(true) + .expect("The channel needs to be open."); + } + })); + let luks_manual_password_main_context = MainContext::default(); + // The main loop executes the asynchronous block + luks_manual_password_main_context.spawn_local(clone!(@weak partition_method_manual_luks_error_label, @weak bottom_next_button => async move { + while let Ok(state) = luks_manual_password_receiver.recv().await { + partition_method_manual_luks_error_label.set_visible(state); + bottom_next_button.set_sensitive(!state); + } + })); + } + // Boot partition Checks + let home_not_boot_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("home_not_boot") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + let root_not_boot_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("root_not_boot") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + let boot_not_efi_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("boot_not_efi") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + + if home_not_boot_cli.status.success() && root_not_boot_cli.status.success() && boot_not_efi_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false) + } else { + if home_not_boot_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false); + } else { + partition_method_manual_boot_error_label.set_label("the /home and /boot partitions are the same."); + partition_method_manual_boot_error_label.set_visible(true); + } + if boot_not_efi_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false); + } else { + partition_method_manual_boot_error_label.set_label("the /boot/efi and /boot partitions are the same."); + partition_method_manual_boot_error_label.set_visible(true); + } + if root_not_boot_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false); + } else { + partition_method_manual_boot_error_label.set_label("No boot partition found in chroot, mount (CUSTOM_ROOT)/boot."); + partition_method_manual_boot_error_label.set_visible(true); + } + } + // EFI partition Checks + let root_not_efi_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("root_not_efi") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + if root_not_efi_cli.status.success() { + partition_method_manual_efi_error_label.set_visible(false); + } else { + partition_method_manual_efi_error_label.set_label("No EFI partition found in chroot, mount (CUSTOM_ROOT)/boot/efi."); + partition_method_manual_efi_error_label.set_visible(true); + } + if partition_method_manual_chroot_error_label.get_visible() == false && partition_method_manual_luks_error_label.get_visible() == false && partition_method_manual_boot_error_label.get_visible() == false && partition_method_manual_efi_error_label.get_visible() == false { + partition_method_manual_target_buffer.set_text(&custom_root_mountpoint); + bottom_next_button.set_sensitive(true); + } + })); + + partition_method_manual_luks_password_entry.connect_changed(clone!(@weak bottom_next_button, @weak partition_method_manual_chroot_dir_entry, @weak partition_method_manual_luks_password_entry, @weak partition_method_manual_luks_error_label, @weak partition_method_manual_chroot_error_label, @weak partition_method_manual_boot_error_label, @weak partition_method_manual_efi_error_label, @weak partition_method_manual_target_buffer, @weak partition_method_manual_luks_buffer => move |_| { + bottom_next_button.set_sensitive(false); + let custom_root_mountpoint = partition_method_manual_chroot_dir_entry.text().to_string(); + // Mountpoint Check + if custom_root_mountpoint.is_empty() { + partition_method_manual_chroot_error_label.set_label("No mountpoint specified."); + partition_method_manual_chroot_error_label.set_visible(true); + } else if custom_root_mountpoint.contains("/dev") { + partition_method_manual_chroot_error_label.set_label("This Installer Takes mountpoints not devices."); + partition_method_manual_chroot_error_label.set_visible(true); + } else { + partition_method_manual_chroot_error_label.set_visible(false); + } + // Home partition Check + let home_not_root_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("home_not_root") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + if home_not_root_cli.status.success() { + // Home encryption Checking + let (luks_manual_is_encrypt_sender, luks_manual_is_encrypt_receiver) = async_channel::unbounded(); + let luks_manual_is_encrypt_sender = luks_manual_is_encrypt_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(clone!(@strong custom_root_mountpoint => move || { + let check_home_encryption_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("check_home_encryption") + .arg(custom_root_mountpoint) + .output() + .expect("failed to execute process"); + if check_home_encryption_cli.status.success() { + luks_manual_is_encrypt_sender + .send_blocking(true) + .expect("The channel needs to be open."); + } else { + luks_manual_is_encrypt_sender + .send_blocking(false) + .expect("The channel needs to be open."); + } + })); + let luks_manual_is_encrypt_main_context = MainContext::default(); + // The main loop executes the asynchronous block + luks_manual_is_encrypt_main_context.spawn_local(clone!(@weak partition_method_manual_luks_password_entry => async move { + while let Ok(state) = luks_manual_is_encrypt_receiver.recv().await { + partition_method_manual_luks_password_entry.set_sensitive(state); + } + })); + // Luks Password Checking + let luks_passwd = partition_method_manual_luks_password_entry.text().to_string(); + let (luks_manual_password_sender, luks_manual_password_receiver) = async_channel::unbounded(); + let luks_manual_password_sender = luks_manual_password_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(clone!(@strong custom_root_mountpoint, @strong luks_passwd => move || { + let luks_check_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("check_home_luks_passwd") + .arg(custom_root_mountpoint) + .arg(luks_passwd) + .output() + .expect("failed to execute process"); + if luks_check_cli.status.success() { + luks_manual_password_sender + .send_blocking(false) + .expect("The channel needs to be open."); + } else { + luks_manual_password_sender + .send_blocking(true) + .expect("The channel needs to be open."); + } + })); + let luks_manual_password_main_context = MainContext::default(); + // The main loop executes the asynchronous block + luks_manual_password_main_context.spawn_local(clone!(@weak partition_method_manual_luks_error_label, @weak bottom_next_button => async move { + while let Ok(state) = luks_manual_password_receiver.recv().await { + partition_method_manual_luks_error_label.set_visible(state); + bottom_next_button.set_sensitive(!state); + } + })); + } + // Boot partition Checks + let home_not_boot_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("home_not_boot") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + let root_not_boot_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("root_not_boot") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + let boot_not_efi_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("boot_not_efi") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + + if home_not_boot_cli.status.success() && root_not_boot_cli.status.success() && boot_not_efi_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false) + } else { + if home_not_boot_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false); + } else { + partition_method_manual_boot_error_label.set_label("the /home and /boot partitions are the same."); + partition_method_manual_boot_error_label.set_visible(true); + } + if boot_not_efi_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false); + } else { + partition_method_manual_boot_error_label.set_label("the /boot/efi and /boot partitions are the same."); + partition_method_manual_boot_error_label.set_visible(true); + } + if root_not_boot_cli.status.success() { + partition_method_manual_boot_error_label.set_visible(false); + } else { + partition_method_manual_boot_error_label.set_label("No boot partition found in chroot, mount (CUSTOM_ROOT)/boot."); + partition_method_manual_boot_error_label.set_visible(true); + } + } + // EFI partition Checks + let root_not_efi_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("root_not_efi") + .arg(custom_root_mountpoint.clone()) + .output() + .expect("failed to execute process"); + if root_not_efi_cli.status.success() { + partition_method_manual_efi_error_label.set_visible(false); + } else { + partition_method_manual_efi_error_label.set_label("No EFI partition found in chroot, mount (CUSTOM_ROOT)/boot/efi."); + partition_method_manual_efi_error_label.set_visible(true); + } + if partition_method_manual_chroot_error_label.get_visible() == false && partition_method_manual_luks_error_label.get_visible() == false && partition_method_manual_boot_error_label.get_visible() == false && partition_method_manual_efi_error_label.get_visible() == false { + partition_method_manual_target_buffer.set_text(&custom_root_mountpoint); + bottom_next_button.set_sensitive(true); + } + })); + + partition_method_manual_gparted_button.connect_clicked(move |_| { + Command::new("gparted") + .spawn() + .expect("gparted failed to start"); + }); + + partitioning_stack.add_titled(&partition_method_manual_main_box, Some("partition_method_manual_page"), "partition_method_manual_page"); + + return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry) +} \ No newline at end of file diff --git a/src/partitioning_page.rs b/src/partitioning_page.rs index c52fb56..e1ebe59 100644 --- a/src/partitioning_page.rs +++ b/src/partitioning_page.rs @@ -9,6 +9,9 @@ use glib::*; use gdk::Display; use gtk::subclass::layout_child; +use crate::automatic_paritioning::automatic_partitioning; +use crate::manual_partitioning::manual_partitioning; + use std::io::BufRead; use std::io::BufReader; use std::process::Command; @@ -203,753 +206,11 @@ pub fn partitioning_page(done_main_box: >k::Box, install_main_box: >k::Box , partitioning_method_main_box.append(&partitioning_selection_box); manual_method_button_content_box.append(&manual_method_button_content_image); - - // Automatic Partitioning Yard - let partition_method_automatic_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_bottom(15) - .margin_top(15) - .margin_end(15) - .margin_start(15) - .build(); - - let partition_method_automatic_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the partitioning page - let partition_method_automatic_header_text = gtk::Label::builder() - .label("Automatic Partitioning Installer") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - partition_method_automatic_header_text.add_css_class("header_sized_text"); - - // the header icon for the partitioning icon - let partition_method_automatic_header_icon = gtk::Image::builder() - .icon_name("media-playlist-shuffle") - .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_automatic_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let partition_method_automatic_selection_text = gtk::Label::builder() - .label("Choose the Drive you want to install PikaOS on\nNote: This will erase the entire drive backup your data!") - .justify(Justification::Center) - .halign(gtk::Align::Center) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - partition_method_automatic_selection_text.add_css_class("medium_sized_text"); - - let devices_selection_expander_row = adw::ExpanderRow::builder() - .title("No disk selected for selection") - .build(); - - let null_checkbutton = gtk::CheckButton::builder() - .build(); - - let devices_selection_expander_row_viewport = gtk::ScrolledWindow::builder() - .height_request(200) - .build(); - - let devices_selection_expander_row_viewport_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - devices_selection_expander_row_viewport.set_child(Some(&devices_selection_expander_row_viewport_box)); - - let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder() - .selection_mode(SelectionMode::None) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - devices_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); - devices_selection_expander_row_viewport_listbox.append(&devices_selection_expander_row); - - devices_selection_expander_row.add_row(&devices_selection_expander_row_viewport); - - let partition_method_automatic_get_devices_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("get_block_devices") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("failed {}", e)); - let partition_method_automatic_get_devices_reader = BufReader::new(partition_method_automatic_get_devices_cli.stdout.expect("could not get stdout")); - - let partition_method_automatic_disk_error_label = gtk::Label::builder() - .label("No Disk specified.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .build(); - partition_method_automatic_disk_error_label.add_css_class("small_error_text"); - - let partition_method_automatic_luks_error_label = gtk::Label::builder() - .label("LUKS Encryption Enabled but no password provided.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .visible(false) - .build(); - partition_method_automatic_luks_error_label.add_css_class("small_error_text"); - - let partition_method_automatic_luks_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - let partition_method_automatic_luks_checkbutton = gtk::CheckButton::builder() - .label("Enable LUKS2 Disk Encryption") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let partition_method_automatic_luks_listbox = gtk::ListBox::builder() - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - partition_method_automatic_luks_listbox.add_css_class("boxed-list"); - - let partition_method_automatic_luks_password_entry = adw::PasswordEntryRow::builder() - .title("LUKS Password") - .hexpand(true) - .sensitive(false) - .build(); - - let partition_method_automatic_target_buffer = gtk::TextBuffer::builder() - .build(); - - let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder() - .build(); - - for device in partition_method_automatic_get_devices_reader.lines() { - let device = device.unwrap(); - let device_size_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("get_block_size") - .arg(device.clone()) - .output() - .expect("failed to execute process"); - let device_size = String::from_utf8(device_size_cli.stdout).expect("Failed to create float").trim().parse::().unwrap(); - let device_button = gtk::CheckButton::builder() - .valign(Align::Center) - .can_focus(false) - .build(); - device_button.set_group(Some(&null_checkbutton)); - let device_row = adw::ActionRow::builder() - .activatable_widget(&device_button) - .title(device.clone()) - .subtitle(pretty_bytes::converter::convert(device_size)) - .build(); - device_row.add_prefix(&device_button); - devices_selection_expander_row_viewport_box.append(&device_row); - device_button.connect_toggled(clone!(@weak device_button,@weak partition_method_automatic_luks_password_entry, @weak devices_selection_expander_row, @weak bottom_next_button, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { - if device_button.is_active() == true { - devices_selection_expander_row.set_title(&device); - if device_size > 39000000000.0 { - partition_method_automatic_disk_error_label.set_visible(false); - if partition_method_automatic_luks_checkbutton.is_active() == true { - if partition_method_automatic_luks_error_label.get_visible() { - // - } else { - bottom_next_button.set_sensitive(true); - } - } else { - partition_method_automatic_target_buffer.set_text(&device); - partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); - bottom_next_button.set_sensitive(true); - } - } else { - partition_method_automatic_disk_error_label.set_visible(true); - partition_method_automatic_disk_error_label.set_label("Disk Size too small, PikaOS needs 40GB Disk"); - bottom_next_button.set_sensitive(false); - } - } - })); - } - - partition_method_automatic_luks_checkbutton.connect_toggled(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { - if partition_method_automatic_luks_checkbutton.is_active() == true { - partition_method_automatic_luks_password_entry.set_sensitive(true); - if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { - partition_method_automatic_luks_error_label.set_visible(true); - bottom_next_button.set_sensitive(false); - } else { - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - bottom_next_button.set_sensitive(true); - } - } - } else { - partition_method_automatic_luks_password_entry.set_sensitive(false); - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - bottom_next_button.set_sensitive(true); - } - } - })); - - partition_method_automatic_luks_password_entry.connect_changed(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_luks_buffer => move |_| { - if partition_method_automatic_luks_checkbutton.is_active() == true { - partition_method_automatic_luks_password_entry.set_sensitive(true); - if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { - partition_method_automatic_luks_error_label.set_visible(true); - bottom_next_button.set_sensitive(false); - } else { - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); - bottom_next_button.set_sensitive(true); - } - } - } else { - partition_method_automatic_luks_password_entry.set_sensitive(false); - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); - bottom_next_button.set_sensitive(true); - } - } - })); - - partition_method_automatic_luks_listbox.append(&partition_method_automatic_luks_password_entry); - partition_method_automatic_luks_box.append(&partition_method_automatic_luks_checkbutton); - partition_method_automatic_luks_box.append(&partition_method_automatic_luks_listbox); - partition_method_automatic_header_box.append(&partition_method_automatic_header_text); - partition_method_automatic_header_box.append(&partition_method_automatic_header_icon); - partition_method_automatic_selection_box.append(&partition_method_automatic_selection_text); - partition_method_automatic_main_box.append(&partition_method_automatic_header_box); - partition_method_automatic_main_box.append(&partition_method_automatic_selection_box); - partition_method_automatic_main_box.append(&devices_selection_expander_row_viewport_listbox); - partition_method_automatic_main_box.append(&partition_method_automatic_luks_box); - partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_label); - partition_method_automatic_main_box.append(&partition_method_automatic_disk_error_label); - - // Manual Partitioning Yard - 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_selection_text = gtk::Label::builder() - .label(" - Mount your custom root drive somewhere.\n - Mount all your additional mountpoints relative to it.\n - Make sure to have the the following mountpoints:\n (CUSTOM_ROOT)/boot ~ 1000mb ext4\n (CUSTOM_ROOT)/boot/efi ~ 512mb vfat/fat32\n- If (CUSTOM_ROOT)/home has LUKS encryption, make sure to enable it here.\n - Note: This doesn't erase any data automatically, format your drives manually.") - .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"); - - let partition_method_manual_chroot_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let partition_method_manual_chroot_listbox = gtk::ListBox::builder() - .build(); - partition_method_manual_chroot_listbox.add_css_class("boxed-list"); - - let partition_method_manual_chroot_dir_file_dialog = gtk::FileChooserNative::new( - Some("Open File"), - gtk::Window::NONE, - gtk::FileChooserAction::SelectFolder, - Some("Open"), - Some("Cancel"), - ); - - partition_method_manual_chroot_dir_file_dialog.set_transient_for(Some(window)); - - let partition_method_manual_chroot_dir_entry = adw::EntryRow::builder() - .title("Custom Root Mountpoint") - .hexpand(true) - .build(); - - let partition_method_manual_chroot_dir_button_content = adw::ButtonContent::builder() - .label("Open") - .icon_name("folder-open") - .build(); - - let partition_method_manual_chroot_dir_button = gtk::Button::builder() - .child(&partition_method_manual_chroot_dir_button_content) - .margin_start(10) - .build(); - - let partition_method_manual_luks_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - let partition_method_manual_luks_listbox = gtk::ListBox::builder() - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - partition_method_manual_luks_listbox.add_css_class("boxed-list"); - - let partition_method_manual_luks_password_entry = adw::PasswordEntryRow::builder() - .title("LUKS Password") - .hexpand(true) - .sensitive(false) - .build(); - - let partition_method_manual_chroot_error_label = gtk::Label::builder() - .label("No mountpoint specified.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .build(); - partition_method_manual_chroot_error_label.add_css_class("small_error_text"); - - let partition_method_manual_boot_error_label = gtk::Label::builder() - .label("No boot partition found in chroot, mount (CUSTOM_ROOT)/boot.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .visible(false) - .build(); - partition_method_manual_boot_error_label.add_css_class("small_error_text"); - - let partition_method_manual_efi_error_label = gtk::Label::builder() - .label("No EFI partition found in chroot, mount (CUSTOM_ROOT)/boot/efi.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .visible(false) - .build(); - partition_method_manual_efi_error_label.add_css_class("small_error_text"); - - let partition_method_manual_luks_error_label = gtk::Label::builder() - .label("Home partition encrypted, but no LUKS password provided.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .visible(false) - .build(); - partition_method_manual_luks_error_label.add_css_class("small_error_text"); - - 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::End) - .build(); - - partition_method_manual_luks_listbox.append(&partition_method_manual_luks_password_entry); - partition_method_manual_luks_box.append(&partition_method_manual_luks_listbox); - partition_method_manual_header_box.append(&partition_method_manual_header_text); - partition_method_manual_header_box.append(&partition_method_manual_header_icon); - partition_method_manual_selection_box.append(&partition_method_manual_selection_text); - partition_method_manual_main_box.append(&partition_method_manual_header_box); - partition_method_manual_main_box.append(&partition_method_manual_selection_box); - partition_method_manual_chroot_listbox.append(&partition_method_manual_chroot_dir_entry); - partition_method_manual_chroot_box.append(&partition_method_manual_chroot_listbox); - partition_method_manual_chroot_box.append(&partition_method_manual_chroot_dir_button); - 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); - partition_method_manual_main_box.append(&partition_method_manual_chroot_box); - partition_method_manual_main_box.append(&partition_method_manual_luks_box); - partition_method_manual_main_box.append(&partition_method_manual_luks_error_label); - partition_method_manual_main_box.append(&partition_method_manual_chroot_error_label); - partition_method_manual_main_box.append(&partition_method_manual_boot_error_label); - partition_method_manual_main_box.append(&partition_method_manual_efi_error_label); - partition_method_manual_main_box.append(&partition_method_manual_gparted_button); - - // clone partition_method_manual_chroot_dir_file_dialog as rust becuase glib breaks it show function for some reason - let partition_method_manual_chroot_dir_file_dialog_clone = partition_method_manual_chroot_dir_file_dialog.clone(); - partition_method_manual_chroot_dir_button.connect_clicked(move |_| { - partition_method_manual_chroot_dir_file_dialog_clone.set_visible(true); - }); - - partition_method_manual_chroot_dir_file_dialog.connect_response(clone!(@weak partition_method_manual_chroot_dir_file_dialog, @weak partition_method_manual_chroot_dir_entry => move |_, response| { - if response == gtk::ResponseType::Accept { - if partition_method_manual_chroot_dir_file_dialog.file().is_some() { - partition_method_manual_chroot_dir_entry.set_text(&partition_method_manual_chroot_dir_file_dialog.file().expect("FILE PATHING FAIL").path().expect("PATH STRINGING FAIL").into_os_string().into_string().unwrap()); - } - } - })); - - let partition_method_manual_target_buffer = gtk::TextBuffer::builder() - .build(); - - let partition_method_manual_luks_buffer = gtk::TextBuffer::builder() - .build(); - - partition_method_manual_chroot_dir_entry.connect_changed(clone!(@weak bottom_next_button, @weak partition_method_manual_chroot_dir_entry, @weak partition_method_manual_luks_password_entry, @weak partition_method_manual_luks_error_label, @weak partition_method_manual_chroot_error_label, @weak partition_method_manual_boot_error_label, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer, @weak partition_method_manual_efi_error_label, @weak partition_method_manual_target_buffer, @weak partition_method_manual_luks_buffer => move |_| { - bottom_next_button.set_sensitive(false); - let custom_root_mountpoint = partition_method_manual_chroot_dir_entry.text().to_string(); - // Mountpoint Check - if custom_root_mountpoint.is_empty() { - partition_method_manual_chroot_error_label.set_label("No mountpoint specified."); - partition_method_manual_chroot_error_label.set_visible(true); - } else if custom_root_mountpoint.contains("/dev") { - partition_method_manual_chroot_error_label.set_label("This Installer Takes mountpoints not devices."); - partition_method_manual_chroot_error_label.set_visible(true); - } else { - partition_method_manual_chroot_error_label.set_visible(false); - } - // Home partition Check - let home_not_root_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("home_not_root") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - if home_not_root_cli.status.success() { - // Home encryption Checking - let (luks_manual_is_encrypt_sender, luks_manual_is_encrypt_receiver) = async_channel::unbounded(); - let luks_manual_is_encrypt_sender = luks_manual_is_encrypt_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(clone!(@strong custom_root_mountpoint => move || { - let check_home_encryption_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("check_home_encryption") - .arg(custom_root_mountpoint) - .output() - .expect("failed to execute process"); - if check_home_encryption_cli.status.success() { - luks_manual_is_encrypt_sender - .send_blocking(true) - .expect("The channel needs to be open."); - } else { - luks_manual_is_encrypt_sender - .send_blocking(false) - .expect("The channel needs to be open."); - } - })); - let luks_manual_is_encrypt_main_context = MainContext::default(); - // The main loop executes the asynchronous block - luks_manual_is_encrypt_main_context.spawn_local(clone!(@weak partition_method_manual_luks_password_entry => async move { - while let Ok(state) = luks_manual_is_encrypt_receiver.recv().await { - partition_method_manual_luks_password_entry.set_sensitive(state); - } - })); - // Luks Password Checking - let luks_passwd = partition_method_manual_luks_password_entry.text().to_string(); - let (luks_manual_password_sender, luks_manual_password_receiver) = async_channel::unbounded(); - let luks_manual_password_sender = luks_manual_password_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(clone!(@strong custom_root_mountpoint, @strong luks_passwd => move || { - let luks_check_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("check_home_luks_passwd") - .arg(custom_root_mountpoint) - .arg(luks_passwd) - .output() - .expect("failed to execute process"); - if luks_check_cli.status.success() { - luks_manual_password_sender - .send_blocking(false) - .expect("The channel needs to be open."); - } else { - luks_manual_password_sender - .send_blocking(true) - .expect("The channel needs to be open."); - } - })); - let luks_manual_password_main_context = MainContext::default(); - // The main loop executes the asynchronous block - luks_manual_password_main_context.spawn_local(clone!(@weak partition_method_manual_luks_error_label, @weak bottom_next_button => async move { - while let Ok(state) = luks_manual_password_receiver.recv().await { - partition_method_manual_luks_error_label.set_visible(state); - bottom_next_button.set_sensitive(!state); - } - })); - } - // Boot partition Checks - let home_not_boot_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("home_not_boot") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - let root_not_boot_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("root_not_boot") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - let boot_not_efi_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("boot_not_efi") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - - if home_not_boot_cli.status.success() && root_not_boot_cli.status.success() && boot_not_efi_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false) - } else { - if home_not_boot_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false); - } else { - partition_method_manual_boot_error_label.set_label("the /home and /boot partitions are the same."); - partition_method_manual_boot_error_label.set_visible(true); - } - if boot_not_efi_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false); - } else { - partition_method_manual_boot_error_label.set_label("the /boot/efi and /boot partitions are the same."); - partition_method_manual_boot_error_label.set_visible(true); - } - if root_not_boot_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false); - } else { - partition_method_manual_boot_error_label.set_label("No boot partition found in chroot, mount (CUSTOM_ROOT)/boot."); - partition_method_manual_boot_error_label.set_visible(true); - } - } - // EFI partition Checks - let root_not_efi_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("root_not_efi") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - if root_not_efi_cli.status.success() { - partition_method_manual_efi_error_label.set_visible(false); - } else { - partition_method_manual_efi_error_label.set_label("No EFI partition found in chroot, mount (CUSTOM_ROOT)/boot/efi."); - partition_method_manual_efi_error_label.set_visible(true); - } - if partition_method_manual_chroot_error_label.get_visible() == false && partition_method_manual_luks_error_label.get_visible() == false && partition_method_manual_boot_error_label.get_visible() == false && partition_method_manual_efi_error_label.get_visible() == false { - partition_method_manual_target_buffer.set_text(&custom_root_mountpoint); - bottom_next_button.set_sensitive(true); - } - })); - - partition_method_manual_luks_password_entry.connect_changed(clone!(@weak bottom_next_button, @weak partition_method_manual_chroot_dir_entry, @weak partition_method_manual_luks_password_entry, @weak partition_method_manual_luks_error_label, @weak partition_method_manual_chroot_error_label, @weak partition_method_manual_boot_error_label, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer, @weak partition_method_manual_efi_error_label, @weak partition_method_manual_target_buffer, @weak partition_method_manual_luks_buffer => move |_| { - bottom_next_button.set_sensitive(false); - let custom_root_mountpoint = partition_method_manual_chroot_dir_entry.text().to_string(); - // Mountpoint Check - if custom_root_mountpoint.is_empty() { - partition_method_manual_chroot_error_label.set_label("No mountpoint specified."); - partition_method_manual_chroot_error_label.set_visible(true); - } else if custom_root_mountpoint.contains("/dev") { - partition_method_manual_chroot_error_label.set_label("This Installer Takes mountpoints not devices."); - partition_method_manual_chroot_error_label.set_visible(true); - } else { - partition_method_manual_chroot_error_label.set_visible(false); - } - // Home partition Check - let home_not_root_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("home_not_root") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - if home_not_root_cli.status.success() { - // Home encryption Checking - let (luks_manual_is_encrypt_sender, luks_manual_is_encrypt_receiver) = async_channel::unbounded(); - let luks_manual_is_encrypt_sender = luks_manual_is_encrypt_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(clone!(@strong custom_root_mountpoint => move || { - let check_home_encryption_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("check_home_encryption") - .arg(custom_root_mountpoint) - .output() - .expect("failed to execute process"); - if check_home_encryption_cli.status.success() { - luks_manual_is_encrypt_sender - .send_blocking(true) - .expect("The channel needs to be open."); - } else { - luks_manual_is_encrypt_sender - .send_blocking(false) - .expect("The channel needs to be open."); - } - })); - let luks_manual_is_encrypt_main_context = MainContext::default(); - // The main loop executes the asynchronous block - luks_manual_is_encrypt_main_context.spawn_local(clone!(@weak partition_method_manual_luks_password_entry => async move { - while let Ok(state) = luks_manual_is_encrypt_receiver.recv().await { - partition_method_manual_luks_password_entry.set_sensitive(state); - } - })); - // Luks Password Checking - let luks_passwd = partition_method_manual_luks_password_entry.text().to_string(); - let (luks_manual_password_sender, luks_manual_password_receiver) = async_channel::unbounded(); - let luks_manual_password_sender = luks_manual_password_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(clone!(@strong custom_root_mountpoint, @strong luks_passwd => move || { - let luks_check_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("check_home_luks_passwd") - .arg(custom_root_mountpoint) - .arg(luks_passwd) - .output() - .expect("failed to execute process"); - if luks_check_cli.status.success() { - luks_manual_password_sender - .send_blocking(false) - .expect("The channel needs to be open."); - } else { - luks_manual_password_sender - .send_blocking(true) - .expect("The channel needs to be open."); - } - })); - let luks_manual_password_main_context = MainContext::default(); - // The main loop executes the asynchronous block - luks_manual_password_main_context.spawn_local(clone!(@weak partition_method_manual_luks_error_label, @weak bottom_next_button => async move { - while let Ok(state) = luks_manual_password_receiver.recv().await { - partition_method_manual_luks_error_label.set_visible(state); - bottom_next_button.set_sensitive(!state); - } - })); - } - // Boot partition Checks - let home_not_boot_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("home_not_boot") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - let root_not_boot_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("root_not_boot") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - let boot_not_efi_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("boot_not_efi") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - - if home_not_boot_cli.status.success() && root_not_boot_cli.status.success() && boot_not_efi_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false) - } else { - if home_not_boot_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false); - } else { - partition_method_manual_boot_error_label.set_label("the /home and /boot partitions are the same."); - partition_method_manual_boot_error_label.set_visible(true); - } - if boot_not_efi_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false); - } else { - partition_method_manual_boot_error_label.set_label("the /boot/efi and /boot partitions are the same."); - partition_method_manual_boot_error_label.set_visible(true); - } - if root_not_boot_cli.status.success() { - partition_method_manual_boot_error_label.set_visible(false); - } else { - partition_method_manual_boot_error_label.set_label("No boot partition found in chroot, mount (CUSTOM_ROOT)/boot."); - partition_method_manual_boot_error_label.set_visible(true); - } - } - // EFI partition Checks - let root_not_efi_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("root_not_efi") - .arg(custom_root_mountpoint.clone()) - .output() - .expect("failed to execute process"); - if root_not_efi_cli.status.success() { - partition_method_manual_efi_error_label.set_visible(false); - } else { - partition_method_manual_efi_error_label.set_label("No EFI partition found in chroot, mount (CUSTOM_ROOT)/boot/efi."); - partition_method_manual_efi_error_label.set_visible(true); - } - if partition_method_manual_chroot_error_label.get_visible() == false && partition_method_manual_luks_error_label.get_visible() == false && partition_method_manual_boot_error_label.get_visible() == false && partition_method_manual_efi_error_label.get_visible() == false { - partition_method_manual_target_buffer.set_text(&custom_root_mountpoint); - bottom_next_button.set_sensitive(true); - } - })); - - partition_method_manual_gparted_button.connect_clicked(move |_| { - Command::new("gparted") - .spawn() - .expect("gparted failed to start"); - }); /// add all pages to partitioning stack partitioning_stack.add_titled(&partitioning_method_main_box, Some("partition_method_select_page"), "partition_method_select_page"); - partitioning_stack.add_titled(&partition_method_automatic_main_box, Some("partition_method_automatic_page"), "partition_method_automatic_page"); - partitioning_stack.add_titled(&partition_method_manual_main_box, Some("partition_method_manual_page"), "partition_method_manual_page"); + let partitioning_page_automatic_partitioning = automatic_partitioning(&partitioning_stack, &bottom_next_button); + let partitioning_page_manual_partitioning= manual_partitioning(window, &partitioning_stack, &bottom_next_button); // add everything to the main box partitioning_main_box.append(&partitioning_stack); @@ -962,13 +223,13 @@ pub fn partitioning_page(done_main_box: >k::Box, install_main_box: >k::Box , automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page"))); manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page"))); - let partition_method_automatic_target_buffer_clone = partition_method_automatic_target_buffer.clone(); + let partition_method_automatic_target_buffer_clone = partitioning_page_automatic_partitioning.0.clone(); - let partition_method_automatic_luks_buffer_clone = partition_method_automatic_luks_buffer.clone(); + let partition_method_automatic_luks_buffer_clone = partitioning_page_automatic_partitioning.1.clone(); - let partition_method_manual_target_buffer_clone = partition_method_manual_target_buffer.clone(); + let partition_method_manual_target_buffer_clone = partitioning_page_manual_partitioning.0.clone(); - let partition_method_manual_luks_buffer_clone = partition_method_manual_luks_buffer.clone(); + let partition_method_manual_luks_buffer_clone = partitioning_page_manual_partitioning.1.clone(); bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { content_stack.set_visible_child_name("install_page") @@ -1004,7 +265,7 @@ pub fn partitioning_page(done_main_box: >k::Box, install_main_box: >k::Box , content_stack.set_visible_child_name("install_page"); } else { fs::write("/tmp/pika-installer-gtk4-target-manual.txt", partition_method_manual_target_buffer_clone.text(&partition_method_manual_target_buffer_clone.bounds().0, &partition_method_manual_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); - partition_method_manual_luks_buffer_clone.set_text(&partition_method_manual_luks_password_entry.text().to_string()); + partition_method_manual_luks_buffer_clone.set_text(&partitioning_page_manual_partitioning.2.text().to_string()); let manual_luks_result = partition_method_manual_luks_buffer_clone.text(&partition_method_manual_luks_buffer_clone.bounds().0, &partition_method_manual_luks_buffer_clone.bounds().1, true).to_string(); if manual_luks_result.is_empty() { //