Add luks support
This commit is contained in:
parent
907a7f1498
commit
d84f14ea6d
@ -36,6 +36,16 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$1" = "get_part_uuid" ]]
|
||||
then
|
||||
echo "$(blkid /dev/$2 -s UUID -o value)"
|
||||
fi
|
||||
|
||||
if [[ "$1" = "get_luks_uuid" ]]
|
||||
then
|
||||
echo "$(blkid "$(lsblk -sJp | jq -r --arg dsk /dev/"$2" '.blockdevices | .[] | select(.name == $dsk) | .children | .[0] | .name')" -s UUID -o value)"
|
||||
fi
|
||||
|
||||
if [[ "$1" = "get_partitions" ]]
|
||||
then
|
||||
lsblk -ln -o NAME,TYPE | grep -E "part|crypt|lvm" | awk '{print $1}' | while read i ; do
|
||||
|
@ -100,6 +100,7 @@ pub fn build_ui(app: &adw::Application) {
|
||||
|
||||
partitioning_page::partitioning_page(
|
||||
&carousel,
|
||||
window.clone(),
|
||||
&partition_method_type_refcell,
|
||||
&partition_method_automatic_target_refcell,
|
||||
&partition_method_automatic_target_fs_refcell,
|
||||
|
@ -3,6 +3,7 @@ mod imp;
|
||||
use glib::Object;
|
||||
use gtk::glib;
|
||||
|
||||
use crate::partitioning_page::create_parition_struct;
|
||||
use crate::partitioning_page::FstabEntry;
|
||||
|
||||
glib::wrapper! {
|
||||
@ -22,7 +23,7 @@ impl DriveMountRow {
|
||||
}
|
||||
pub fn get_fstab_entry(&self) -> FstabEntry {
|
||||
FstabEntry {
|
||||
partition: self.partition(),
|
||||
partition: create_parition_struct(&self.partition()),
|
||||
mountpoint: self.mountpoint(),
|
||||
mountopts: self.mountopts(),
|
||||
}
|
||||
|
@ -853,4 +853,4 @@ fn post_check_drive_mount(
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,19 @@
|
||||
use crate::drive_mount_row::DriveMountRow;
|
||||
use crate::installer_stack_page;
|
||||
use crate::partitioning_page;
|
||||
use crate::partitioning_page::{get_partitions, CrypttabEntry, FstabEntry, Partition};
|
||||
use adw::gio;
|
||||
use adw::prelude::*;
|
||||
use glib::{clone, closure_local, ffi::gboolean};
|
||||
use gtk::{glib, prelude::*, Orientation};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use std::{cell::RefCell, collections::HashSet, rc::Rc};
|
||||
use crate::partitioning_page::get_luks_uuid;
|
||||
|
||||
mod func;
|
||||
|
||||
pub fn manual_partitioning_page(
|
||||
partition_carousel: &adw::Carousel,
|
||||
window: adw::ApplicationWindow,
|
||||
partition_method_type_refcell: &Rc<RefCell<String>>,
|
||||
partition_method_manual_fstab_entry_array_refcell: &Rc<RefCell<Vec<FstabEntry>>>,
|
||||
partition_method_manual_luks_enabled_refcell: &Rc<RefCell<bool>>,
|
||||
@ -104,15 +107,13 @@ pub fn manual_partitioning_page(
|
||||
open_disk_utility_button.connect_clicked(clone!(
|
||||
#[weak]
|
||||
filesystem_table_refresh_button,
|
||||
move |_|
|
||||
{
|
||||
let command = std::process::Command::new("blivet-gui").status();
|
||||
if command.unwrap().success() {
|
||||
filesystem_table_refresh_button.emit_by_name("clicked", &[])
|
||||
}
|
||||
move |_| {
|
||||
let command = std::process::Command::new("blivet-gui").status();
|
||||
if command.unwrap().success() {
|
||||
filesystem_table_refresh_button.emit_by_name("clicked", &[])
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
));
|
||||
|
||||
filesystem_table_refresh_button.connect_clicked(clone!(
|
||||
#[weak]
|
||||
@ -135,30 +136,176 @@ pub fn manual_partitioning_page(
|
||||
partition_method_manual_luks_enabled_refcell,
|
||||
#[strong]
|
||||
partition_method_manual_crypttab_entry_array_refcell,
|
||||
move |_|
|
||||
{
|
||||
while let Some(row) = drive_mounts_adw_listbox.last_child() {
|
||||
drive_mounts_adw_listbox.remove(&row);
|
||||
}
|
||||
|
||||
(*partition_method_manual_fstab_entry_array_refcell.borrow_mut()) = Vec::new();
|
||||
(*partition_method_manual_luks_enabled_refcell.borrow_mut()) = false;
|
||||
(*partition_method_manual_crypttab_entry_array_refcell.borrow_mut()) = Vec::new();
|
||||
(*used_partition_array_refcell.borrow_mut()) = Vec::new();
|
||||
(*subvol_partition_array_refcell.borrow_mut()) = Vec::new();
|
||||
create_hardcoded_rows(
|
||||
&drive_mounts_adw_listbox,
|
||||
&drive_rows_size_group,
|
||||
&partition_array_refcell,
|
||||
&partition_changed_action,
|
||||
&language_changed_action,
|
||||
&used_partition_array_refcell,
|
||||
&subvol_partition_array_refcell,
|
||||
);
|
||||
move |_| {
|
||||
while let Some(row) = drive_mounts_adw_listbox.last_child() {
|
||||
drive_mounts_adw_listbox.remove(&row);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
(*partition_method_manual_fstab_entry_array_refcell.borrow_mut()) = Vec::new();
|
||||
(*partition_method_manual_luks_enabled_refcell.borrow_mut()) = false;
|
||||
(*partition_method_manual_crypttab_entry_array_refcell.borrow_mut()) = Vec::new();
|
||||
(*used_partition_array_refcell.borrow_mut()) = Vec::new();
|
||||
(*subvol_partition_array_refcell.borrow_mut()) = Vec::new();
|
||||
create_hardcoded_rows(
|
||||
&drive_mounts_adw_listbox,
|
||||
&drive_rows_size_group,
|
||||
&partition_array_refcell,
|
||||
&partition_changed_action,
|
||||
&language_changed_action,
|
||||
&used_partition_array_refcell,
|
||||
&subvol_partition_array_refcell,
|
||||
);
|
||||
}
|
||||
));
|
||||
|
||||
filesystem_table_validate_button.connect_clicked(clone!(
|
||||
#[weak]
|
||||
drive_mounts_adw_listbox,
|
||||
#[strong]
|
||||
window,
|
||||
#[strong]
|
||||
partition_method_manual_fstab_entry_array_refcell,
|
||||
#[strong]
|
||||
partition_method_manual_luks_enabled_refcell,
|
||||
#[strong]
|
||||
partition_method_manual_crypttab_entry_array_refcell,
|
||||
move |_| {
|
||||
let mut errored = false;
|
||||
|
||||
(*partition_method_manual_fstab_entry_array_refcell.borrow_mut()) = Vec::new();
|
||||
(*partition_method_manual_luks_enabled_refcell.borrow_mut()) = false;
|
||||
(*partition_method_manual_crypttab_entry_array_refcell.borrow_mut()) = Vec::new();
|
||||
let mut seen_mountpoints = HashSet::new();
|
||||
|
||||
for fs_entry in generate_filesystem_table_array(&drive_mounts_adw_listbox) {
|
||||
let fs_entry_clone0 = fs_entry.clone();
|
||||
if fs_entry.mountpoint.is_empty() {
|
||||
errored = true;
|
||||
println!("mountpoint empty");
|
||||
break;
|
||||
}
|
||||
if fs_entry.mountpoint != "[SWAP]"
|
||||
|| !fs_entry.mountpoint.starts_with("/")
|
||||
|| fs_entry.mountpoint.starts_with("/dev")
|
||||
{
|
||||
errored = true;
|
||||
println!("mountpoint invalid");
|
||||
//break;
|
||||
}
|
||||
if fs_entry.partition.part_name.is_empty() {
|
||||
errored = true;
|
||||
println!("partition empty");
|
||||
//break;
|
||||
}
|
||||
if !seen_mountpoints.insert(fs_entry.clone().mountpoint) {
|
||||
errored = true;
|
||||
println!("duplicate found");
|
||||
//break;
|
||||
}
|
||||
//
|
||||
(*partition_method_manual_fstab_entry_array_refcell.borrow_mut()).push(fs_entry);
|
||||
//
|
||||
|
||||
if fs_entry_clone0.partition.has_encryption
|
||||
&& !partition_method_manual_crypttab_entry_array_refcell
|
||||
.borrow()
|
||||
.iter()
|
||||
.any(|x| x.partition == fs_entry_clone0.partition.part_name)
|
||||
{
|
||||
let fs_entry = fs_entry_clone0.clone();
|
||||
let (luks_manual_password_sender, luks_manual_password_receiver) =
|
||||
async_channel::unbounded::<bool>();
|
||||
let crypttab_password_listbox = gtk::ListBox::builder()
|
||||
.margin_top(10)
|
||||
.margin_bottom(10)
|
||||
.margin_start(10)
|
||||
.margin_end(10)
|
||||
.build();
|
||||
crypttab_password_listbox.add_css_class("boxed-list");
|
||||
let crypttab_password = adw::PasswordEntryRow::builder()
|
||||
.title(t!("luks_password_for").to_string() + &fs_entry.partition.part_name)
|
||||
.build();
|
||||
crypttab_password.set_show_apply_button(true);
|
||||
crypttab_password_listbox.append(&crypttab_password);
|
||||
let crypttab_dialog = adw::MessageDialog::builder()
|
||||
.transient_for(&window)
|
||||
.hide_on_close(true)
|
||||
.extra_child(&crypttab_password_listbox)
|
||||
.width_request(400)
|
||||
.height_request(200)
|
||||
.heading(
|
||||
t!("luks_how_should").to_string()
|
||||
+ &fs_entry.partition.part_name
|
||||
+ &t!("be_added_crypttab"),
|
||||
)
|
||||
.build();
|
||||
crypttab_dialog
|
||||
.add_response("crypttab_dialog_boot", &t!("unlock_boot_manually"));
|
||||
crypttab_dialog.add_response("crypttab_dialog_auto", &t!("unlock_boot_manual"));
|
||||
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", false);
|
||||
crypttab_password.connect_apply(clone!(
|
||||
#[weak]
|
||||
crypttab_password,
|
||||
#[strong]
|
||||
fs_entry,
|
||||
#[weak]
|
||||
crypttab_dialog,
|
||||
move |_| {
|
||||
let luks_manual_password_sender = luks_manual_password_sender.clone();
|
||||
let luks_password = crypttab_password.text().to_string();
|
||||
|
||||
let fs_entry_clone1 = fs_entry.clone();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
luks_manual_password_sender
|
||||
.send_blocking(partitioning_page::test_luks_passwd(
|
||||
&fs_entry_clone1.partition.part_name,
|
||||
&luks_password,
|
||||
))
|
||||
.expect("The channel needs to be open.");
|
||||
});
|
||||
}
|
||||
));
|
||||
let luks_manual_password_main_context = glib::MainContext::default();
|
||||
// The main loop executes the asynchronous block
|
||||
luks_manual_password_main_context.spawn_local(clone!(
|
||||
#[weak]
|
||||
crypttab_dialog,
|
||||
async move {
|
||||
while let Ok(state) = luks_manual_password_receiver.recv().await {
|
||||
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", state);
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
let partition_method_manual_crypttab_entry_array_refcell_clone0 = partition_method_manual_crypttab_entry_array_refcell.clone();
|
||||
|
||||
crypttab_dialog.choose(None::<&gio::Cancellable>,
|
||||
move |choice|
|
||||
{
|
||||
let part_name = fs_entry.partition.part_name;
|
||||
if choice == "crypttab_dialog_auto" {
|
||||
(*partition_method_manual_crypttab_entry_array_refcell_clone0.borrow_mut()).push(CrypttabEntry{
|
||||
partition: part_name.clone(),
|
||||
map: part_name.replace("mapper/", ""),
|
||||
uuid: get_luks_uuid(&part_name),
|
||||
password: None,
|
||||
});
|
||||
} else {
|
||||
(*partition_method_manual_crypttab_entry_array_refcell_clone0.borrow_mut()).push(CrypttabEntry{
|
||||
partition: part_name.clone(),
|
||||
map: part_name.replace("mapper/", ""),
|
||||
uuid: get_luks_uuid(&part_name),
|
||||
password: Some(crypttab_password.text().to_string()),
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
content_box.append(&drive_mounts_viewport);
|
||||
content_box.append(&utility_buttons_box);
|
||||
|
||||
@ -310,3 +457,18 @@ fn create_hardcoded_rows(
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
fn generate_filesystem_table_array(drive_mounts_adw_listbox: >k::ListBox) -> Vec<FstabEntry> {
|
||||
let mut fstab_array: Vec<FstabEntry> = Vec::new();
|
||||
let mut widget_counter = drive_mounts_adw_listbox.first_child();
|
||||
while let Some(ref child) = widget_counter {
|
||||
match child.clone().downcast::<DriveMountRow>() {
|
||||
Ok(t) => {
|
||||
fstab_array.push(DriveMountRow::get_fstab_entry(&t));
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
widget_counter = child.next_sibling();
|
||||
}
|
||||
fstab_array
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub fn partitioning_page(
|
||||
main_carousel: &adw::Carousel,
|
||||
window: adw::ApplicationWindow,
|
||||
partition_method_type_refcell: &Rc<RefCell<String>>,
|
||||
partition_method_automatic_target_refcell: &Rc<RefCell<String>>,
|
||||
partition_method_automatic_target_fs_refcell: &Rc<RefCell<String>>,
|
||||
@ -145,6 +146,7 @@ pub fn partitioning_page(
|
||||
);
|
||||
manual_partitioning_page::manual_partitioning_page(
|
||||
&partitioning_carousel,
|
||||
window,
|
||||
&partition_method_type_refcell,
|
||||
&partition_method_manual_fstab_entry_array_refcell,
|
||||
&partition_method_manual_luks_enabled_refcell,
|
||||
@ -173,24 +175,26 @@ pub struct BlockDevice {
|
||||
pub block_size_pretty: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Partition {
|
||||
pub part_name: String,
|
||||
pub part_fs: String,
|
||||
pub part_uuid: String,
|
||||
pub has_encryption: bool,
|
||||
pub need_mapper: bool,
|
||||
pub part_size: f64,
|
||||
pub part_size_pretty: String,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Clone)]
|
||||
pub struct FstabEntry {
|
||||
pub partition: String,
|
||||
pub partition: Partition,
|
||||
pub mountpoint: String,
|
||||
pub mountopts: String,
|
||||
}
|
||||
|
||||
pub struct CrypttabEntry {
|
||||
pub partition: String,
|
||||
pub map: String,
|
||||
pub uuid: String,
|
||||
pub password: Option<String>,
|
||||
@ -268,18 +272,7 @@ pub fn get_partitions() -> Vec<Partition> {
|
||||
Some(t) => {
|
||||
for partition in std::io::BufReader::new(t).lines() {
|
||||
match partition {
|
||||
Ok(r) => {
|
||||
let part_size = get_part_size(&r);
|
||||
let part_fs = get_part_fs(&r);
|
||||
partitions.push(Partition {
|
||||
has_encryption: is_encrypted(&r),
|
||||
need_mapper: is_needs_mapper(&part_fs),
|
||||
part_name: r,
|
||||
part_fs: part_fs,
|
||||
part_size: part_size,
|
||||
part_size_pretty: pretty_bytes::converter::convert(part_size),
|
||||
})
|
||||
}
|
||||
Ok(r) => partitions.push(create_parition_struct(&r)),
|
||||
Err(_) => return partitions,
|
||||
}
|
||||
}
|
||||
@ -290,6 +283,20 @@ pub fn get_partitions() -> Vec<Partition> {
|
||||
partitions
|
||||
}
|
||||
|
||||
pub fn create_parition_struct(part_dev: &str) -> Partition {
|
||||
let part_size = get_part_size(&part_dev);
|
||||
let part_fs = get_part_fs(&part_dev);
|
||||
Partition {
|
||||
has_encryption: is_encrypted(&part_dev),
|
||||
need_mapper: is_needs_mapper(&part_fs),
|
||||
part_uuid: get_part_uuid(&part_dev),
|
||||
part_name: part_dev.to_string(),
|
||||
part_fs: part_fs,
|
||||
part_size: part_size,
|
||||
part_size_pretty: pretty_bytes::converter::convert(part_size),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_part_size(part_dev: &str) -> f64 {
|
||||
let command = match std::process::Command::new("sudo")
|
||||
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
||||
@ -351,3 +358,58 @@ fn is_encrypted(part_dev: &str) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_luks_passwd(part_dev: &str, passwd: &str) -> bool {
|
||||
let command = match std::process::Command::new("sudo")
|
||||
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
||||
.arg("test_luks_passwd")
|
||||
.arg(part_dev)
|
||||
.arg(passwd)
|
||||
.output()
|
||||
{
|
||||
Ok(t) => t,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
if command.status.success() {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn get_part_uuid(part_dev: &str) -> String {
|
||||
let command = match std::process::Command::new("sudo")
|
||||
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
||||
.arg("get_part_uuid")
|
||||
.arg(part_dev)
|
||||
.output()
|
||||
{
|
||||
Ok(t) => t,
|
||||
Err(_) => return String::from(""),
|
||||
};
|
||||
let fs = match String::from_utf8(command.stdout) {
|
||||
Ok(t) => t.trim().to_owned(),
|
||||
Err(_) => String::from(""),
|
||||
};
|
||||
|
||||
fs
|
||||
}
|
||||
|
||||
pub fn get_luks_uuid(part_dev: &str) -> String {
|
||||
let command = match std::process::Command::new("sudo")
|
||||
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
||||
.arg("get_luks_uuid")
|
||||
.arg(part_dev)
|
||||
.output()
|
||||
{
|
||||
Ok(t) => t,
|
||||
Err(_) => return String::from(""),
|
||||
};
|
||||
let fs = match String::from_utf8(command.stdout) {
|
||||
Ok(t) => t.trim().to_owned(),
|
||||
Err(_) => String::from(""),
|
||||
};
|
||||
|
||||
fs
|
||||
}
|
Loading…
Reference in New Issue
Block a user