refactor
This commit is contained in:
parent
eabd898ccf
commit
f2b1a43f62
13 changed files with 453 additions and 390 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -150,6 +150,7 @@ dependencies = [
|
|||
"nix",
|
||||
"serde",
|
||||
"toml",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -355,3 +356,9 @@ checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
|
|||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||
|
|
|
@ -8,3 +8,4 @@ clap = { version = "4.5.23", features = ["cargo"] }
|
|||
nix = { version = "0.29.0", features = ["user"] }
|
||||
serde = { version = "1.0.216", features = ["derive"] }
|
||||
toml = "0.8.19"
|
||||
yansi = "1.0.1"
|
||||
|
|
382
src/install.rs
382
src/install.rs
|
@ -1,382 +0,0 @@
|
|||
// TODO : Setup ssh (config + authorized_keys)
|
||||
// TODO : Setup virtualization
|
||||
// TODO : Setup docker
|
||||
// TODO : Autojoin docker swarm
|
||||
// TODO : Autojoin teleport
|
||||
|
||||
// DRIVE SELECTION
|
||||
|
||||
use crate::{
|
||||
config::{DriveConfig, GeneralConfig, InstallConfig, PackageConfig, UserConfig},
|
||||
pkg::{self, install_pkgs},
|
||||
run_command,
|
||||
};
|
||||
|
||||
pub fn str_vec(v: Vec<&str>) -> Vec<String> {
|
||||
v.into_iter().map(|x| x.to_string()).collect()
|
||||
}
|
||||
|
||||
pub fn format_drives(conf: &DriveConfig, encrypted: bool) {
|
||||
// EFI (BOOT)
|
||||
run_command(
|
||||
&str_vec(vec!["mkfs.vfat", "-F", "32", conf.boot.as_str()]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
// ROOT
|
||||
if encrypted {
|
||||
run_command(
|
||||
&str_vec(vec!["cryptsetup", "luksFormat", conf.root.as_str()]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
run_command(&str_vec(vec!["mkfs.ext4", conf.root.as_str()]), None, false);
|
||||
}
|
||||
}
|
||||
|
||||
// MOUNT
|
||||
|
||||
pub fn mount_drives(conf: &DriveConfig, encrypted: bool) {
|
||||
if encrypted {
|
||||
run_command(
|
||||
&str_vec(vec!["cryptsetup", "open", conf.root.as_str(), "root"]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["mount", "/dev/mapper/root", "/mnt"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
} else {
|
||||
run_command(
|
||||
&str_vec(vec!["mount", conf.root.as_str(), "/mnt"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
// TODO : Secure mount options
|
||||
run_command(
|
||||
&str_vec(vec!["mount", "--mkdir", conf.boot.as_str(), "/mnt/boot"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
// PACSTRAP
|
||||
|
||||
pub fn pacstrap(conf: &PackageConfig) {
|
||||
let mut cmd: Vec<String> = vec![
|
||||
"pacstrap".into(),
|
||||
"-K".into(),
|
||||
"/mnt".into(),
|
||||
"base".into(),
|
||||
"linux".into(),
|
||||
"linux-firmware".into(),
|
||||
"linux-headers".into(),
|
||||
"git".into(),
|
||||
"networkmanager".into(),
|
||||
"nano".into(),
|
||||
"doas".into(),
|
||||
];
|
||||
|
||||
cmd.extend(conf.pkg.clone());
|
||||
|
||||
run_command(&cmd, None, true);
|
||||
}
|
||||
|
||||
// GENFSTAB
|
||||
|
||||
pub fn genfstab() {
|
||||
let (stdout, _) = run_command(&str_vec(vec!["genfstab", "-U", "/mnt"]), None, false);
|
||||
std::fs::write("/mnt/etc/fstab", stdout).unwrap();
|
||||
}
|
||||
|
||||
pub fn first_boot_values(conf: &GeneralConfig) {
|
||||
// CHROOT
|
||||
run_command(
|
||||
&vec![
|
||||
"arch-chroot".into(),
|
||||
"/mnt".into(),
|
||||
"systemd-firstboot".into(),
|
||||
format!("--locale={}", conf.locale),
|
||||
format!("--keymap={}", conf.keymap),
|
||||
format!("--timezone={}", conf.timezone),
|
||||
format!("--hostname={}", conf.hostname),
|
||||
],
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
// LOCALE
|
||||
uncomment_first_value_of(&conf.locale, "/mnt/etc/locale.gen");
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "locale-gen"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "hwclock", "--systohc"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemctl",
|
||||
"enable",
|
||||
"NetworkManager.service",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn uncomment_first_value_of(value: &str, file: &str) {
|
||||
// read in the file
|
||||
let content = std::fs::read_to_string(file).unwrap();
|
||||
let mut new = String::new();
|
||||
let mut found = false;
|
||||
|
||||
// search for the first instance of `value` in the file
|
||||
// uncomment the '#' symbol if there is one
|
||||
for line in content.lines() {
|
||||
if line.contains(value) && !found {
|
||||
new.push_str(&format!("{}\n", line.replace("#", "")));
|
||||
found = true;
|
||||
} else {
|
||||
new.push_str(&format!("{line}\n"));
|
||||
}
|
||||
}
|
||||
// write back
|
||||
std::fs::write(file, new).unwrap();
|
||||
}
|
||||
|
||||
pub fn setup_zram() {
|
||||
install_pkgs(&["zram-generator"]);
|
||||
std::fs::write(
|
||||
"/mnt/etc/systemd/zram-generator.conf",
|
||||
include_str!("root/zram-generator.conf"),
|
||||
)
|
||||
.unwrap();
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemctl",
|
||||
"enable",
|
||||
"systemd-zram-setup@zram0.service",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
// MKINITCPIO + UKI
|
||||
|
||||
pub fn setup_mkinitcpio() {
|
||||
std::fs::write(
|
||||
"/mnt/etc/mkinitcpio.d/linux.preset",
|
||||
include_str!("root/mkinitcpio/linux.preset"),
|
||||
)
|
||||
.unwrap();
|
||||
// TODO : more configs
|
||||
std::fs::write(
|
||||
"/mnt/etc/mkinitcpio.conf",
|
||||
include_str!("root/mkinitcpio.conf"),
|
||||
)
|
||||
.unwrap();
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "mkinitcpio", "--allpresets"]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
// SECURE BOOT
|
||||
|
||||
pub fn setup_secure_boot() {
|
||||
// TODO : Assert sb setup mode
|
||||
let (stdout, _) = run_command(&str_vec(vec!["sbctl", "status"]), None, false);
|
||||
let binding = stdout.lines().collect::<Vec<&str>>();
|
||||
let status = binding.get(2).unwrap();
|
||||
|
||||
if !status.contains("Setup Mode") {
|
||||
println!("[!] Secure Boot is not in Setup Mode");
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
if !status.contains("Enabled") {
|
||||
println!("[!] Secure Boot is not in Setup Mode");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
run_command(&vec!["sbctl".into(), "create-keys".into()], None, false);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["sbctl", "enroll-keys", "--microsoft"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"sbctl",
|
||||
"sign",
|
||||
"-s",
|
||||
"/boot/EFI/Linux/arch-linux.efi",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"sbctl",
|
||||
"sign",
|
||||
"-s",
|
||||
"/boot/EFI/Linux/arch-linux-fallback.efi",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"sbctl",
|
||||
"sign",
|
||||
"-s",
|
||||
"/boot/EFI/systemd/systemd-bootx64.efi",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["sbctl", "sign", "-s", "/boot/EFI/Boot/bootx64.efi"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(&str_vec(vec!["sbctl", "verify"]), None, false);
|
||||
}
|
||||
|
||||
// MODS
|
||||
|
||||
/// Post Installer
|
||||
|
||||
// TPM Unlock
|
||||
|
||||
pub fn setup_tpm_unlock(conf: &DriveConfig) {
|
||||
install_pkgs(&["tpm2-tools"]);
|
||||
|
||||
// systemd-cryptenroll --tpm2-device=list
|
||||
|
||||
// Recovery Key
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemd-cryptenroll",
|
||||
"--recovery-key",
|
||||
&conf.root,
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemd-cryptenroll",
|
||||
"--tpm2-device=auto",
|
||||
&conf.root,
|
||||
"--tpm2-pcrs=7",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn setup_bootloader() {
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "bootctl", "install"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn setup_users(conf: &[UserConfig]) {
|
||||
let mut doas_conf = String::new();
|
||||
|
||||
for user in conf {
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "useradd", "-m", &user.name]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "passwd", &user.name]),
|
||||
Some(&format!("{}\n{}\n", user.password, user.password)),
|
||||
false,
|
||||
);
|
||||
|
||||
if user.doas_root {
|
||||
doas_conf.push_str(&format!("permit {} as root\n", user.name));
|
||||
}
|
||||
}
|
||||
|
||||
std::fs::write("/mnt/etc/doas.conf", doas_conf).unwrap();
|
||||
}
|
||||
|
||||
pub fn install(conf: InstallConfig) {
|
||||
// Drive Setup
|
||||
format_drives(&conf.drive, conf.general.encryption);
|
||||
mount_drives(&conf.drive, conf.general.encryption);
|
||||
|
||||
// Base Install
|
||||
pacstrap(&conf.pkg);
|
||||
genfstab();
|
||||
|
||||
// System Setup
|
||||
first_boot_values(&conf.general);
|
||||
setup_users(&conf.user);
|
||||
|
||||
setup_bootloader();
|
||||
|
||||
match conf.general.mode {
|
||||
crate::config::InstallMode::Base => {}
|
||||
crate::config::InstallMode::Desktop => {
|
||||
install_pkgs(&pkg::DESKTOP_PKG);
|
||||
}
|
||||
crate::config::InstallMode::Server => {
|
||||
install_pkgs(&pkg::SERVER_PKG);
|
||||
}
|
||||
crate::config::InstallMode::Kiosk => {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
if conf.pkg.virtualization {
|
||||
// TODO : Enable virtualization
|
||||
}
|
||||
|
||||
if conf.pkg.docker {
|
||||
// TODO : Enable docker
|
||||
}
|
||||
|
||||
setup_zram();
|
||||
setup_secure_boot();
|
||||
setup_mkinitcpio();
|
||||
setup_tpm_unlock(&conf.drive);
|
||||
|
||||
println!("System install complete");
|
||||
}
|
11
src/install/boot.rs
Normal file
11
src/install/boot.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use crate::run_command;
|
||||
|
||||
use super::str_vec;
|
||||
|
||||
pub fn setup_bootloader() {
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "bootctl", "install"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
60
src/install/drives.rs
Normal file
60
src/install/drives.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use crate::{config::DriveConfig, run_command};
|
||||
|
||||
use super::str_vec;
|
||||
|
||||
pub fn format_drives(conf: &DriveConfig, encrypted: bool) {
|
||||
// EFI (BOOT)
|
||||
run_command(
|
||||
&str_vec(vec!["mkfs.vfat", "-F", "32", conf.boot.as_str()]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
// ROOT
|
||||
if encrypted {
|
||||
run_command(
|
||||
&str_vec(vec!["cryptsetup", "luksFormat", conf.root.as_str()]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
run_command(&str_vec(vec!["mkfs.ext4", conf.root.as_str()]), None, false);
|
||||
}
|
||||
}
|
||||
|
||||
// MOUNT
|
||||
|
||||
pub fn mount_drives(conf: &DriveConfig, encrypted: bool) {
|
||||
if encrypted {
|
||||
run_command(
|
||||
&str_vec(vec!["cryptsetup", "open", conf.root.as_str(), "root"]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["mount", "/dev/mapper/root", "/mnt"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
} else {
|
||||
run_command(
|
||||
&str_vec(vec!["mount", conf.root.as_str(), "/mnt"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"mount",
|
||||
"--mkdir",
|
||||
conf.boot.as_str(),
|
||||
"/mnt/boot",
|
||||
"-o",
|
||||
"rw,nosuid,nodev,noatime,fmask=0137,dmask=0027",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
53
src/install/first_boot.rs
Normal file
53
src/install/first_boot.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
// GENFSTAB
|
||||
|
||||
use crate::{config::GeneralConfig, run_command};
|
||||
|
||||
use super::{str_vec, uncomment_first_value_of};
|
||||
|
||||
pub fn genfstab() {
|
||||
let (stdout, _) = run_command(&str_vec(vec!["genfstab", "-U", "/mnt"]), None, false);
|
||||
std::fs::write("/mnt/etc/fstab", stdout).unwrap();
|
||||
}
|
||||
|
||||
pub fn first_boot_values(conf: &GeneralConfig) {
|
||||
// CHROOT
|
||||
run_command(
|
||||
&vec![
|
||||
"arch-chroot".into(),
|
||||
"/mnt".into(),
|
||||
"systemd-firstboot".into(),
|
||||
format!("--locale={}", conf.locale),
|
||||
format!("--keymap={}", conf.keymap),
|
||||
format!("--timezone={}", conf.timezone),
|
||||
format!("--hostname={}", conf.hostname),
|
||||
],
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
// LOCALE
|
||||
uncomment_first_value_of(&conf.locale, "/mnt/etc/locale.gen");
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "locale-gen"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "hwclock", "--systohc"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemctl",
|
||||
"enable",
|
||||
"NetworkManager.service",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
24
src/install/kernel.rs
Normal file
24
src/install/kernel.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
// MKINITCPIO + UKI
|
||||
|
||||
use crate::run_command;
|
||||
|
||||
use super::str_vec;
|
||||
|
||||
pub fn setup_mkinitcpio() {
|
||||
std::fs::write(
|
||||
"/mnt/etc/mkinitcpio.d/linux.preset",
|
||||
include_str!("../root/mkinitcpio/linux.preset"),
|
||||
)
|
||||
.unwrap();
|
||||
// TODO : more configs
|
||||
std::fs::write(
|
||||
"/mnt/etc/mkinitcpio.conf",
|
||||
include_str!("../root/mkinitcpio.conf"),
|
||||
)
|
||||
.unwrap();
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "mkinitcpio", "--allpresets"]),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
}
|
97
src/install/mod.rs
Normal file
97
src/install/mod.rs
Normal file
|
@ -0,0 +1,97 @@
|
|||
// TODO : Setup ssh (config + authorized_keys)
|
||||
// TODO : Setup virtualization
|
||||
// TODO : Setup docker
|
||||
// TODO : Autojoin docker swarm
|
||||
// TODO : Autojoin teleport
|
||||
|
||||
// DRIVE SELECTION
|
||||
|
||||
use boot::setup_bootloader;
|
||||
use drives::{format_drives, mount_drives};
|
||||
use first_boot::{first_boot_values, genfstab};
|
||||
use kernel::setup_mkinitcpio;
|
||||
use security::{setup_secure_boot, setup_tpm_unlock};
|
||||
use user::setup_users;
|
||||
use yansi::{Color, Paint};
|
||||
use zram::setup_zram;
|
||||
|
||||
pub mod boot;
|
||||
pub mod drives;
|
||||
pub mod first_boot;
|
||||
pub mod kernel;
|
||||
pub mod security;
|
||||
pub mod user;
|
||||
pub mod zram;
|
||||
|
||||
use crate::{
|
||||
config::InstallConfig,
|
||||
pkg::{self, install_pkgs, pacstrap},
|
||||
};
|
||||
|
||||
pub fn str_vec(v: Vec<&str>) -> Vec<String> {
|
||||
v.into_iter().map(|x| x.to_string()).collect()
|
||||
}
|
||||
|
||||
pub fn uncomment_first_value_of(value: &str, file: &str) {
|
||||
// read in the file
|
||||
let content = std::fs::read_to_string(file).unwrap();
|
||||
let mut new = String::new();
|
||||
let mut found = false;
|
||||
|
||||
// search for the first instance of `value` in the file
|
||||
// uncomment the '#' symbol if there is one
|
||||
for line in content.lines() {
|
||||
if line.contains(value) && !found {
|
||||
new.push_str(&format!("{}\n", line.replace("#", "")));
|
||||
found = true;
|
||||
} else {
|
||||
new.push_str(&format!("{line}\n"));
|
||||
}
|
||||
}
|
||||
// write back
|
||||
std::fs::write(file, new).unwrap();
|
||||
}
|
||||
|
||||
pub fn install(conf: InstallConfig) {
|
||||
// Drive Setup
|
||||
format_drives(&conf.drive, conf.general.encryption);
|
||||
mount_drives(&conf.drive, conf.general.encryption);
|
||||
|
||||
// Base Install
|
||||
pacstrap(&conf.pkg);
|
||||
genfstab();
|
||||
|
||||
// System Setup
|
||||
first_boot_values(&conf.general);
|
||||
setup_users(&conf.user);
|
||||
|
||||
setup_bootloader();
|
||||
|
||||
match conf.general.mode {
|
||||
crate::config::InstallMode::Base => {}
|
||||
crate::config::InstallMode::Desktop => {
|
||||
install_pkgs(&pkg::DESKTOP_PKG);
|
||||
}
|
||||
crate::config::InstallMode::Server => {
|
||||
install_pkgs(&pkg::SERVER_PKG);
|
||||
}
|
||||
crate::config::InstallMode::Kiosk => {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
if conf.pkg.virtualization {
|
||||
// TODO : Enable virtualization
|
||||
}
|
||||
|
||||
if conf.pkg.docker {
|
||||
// TODO : Enable docker
|
||||
}
|
||||
|
||||
setup_zram();
|
||||
setup_secure_boot();
|
||||
setup_mkinitcpio();
|
||||
setup_tpm_unlock(&conf.drive);
|
||||
|
||||
println!("{}", "System install complete".paint(Color::Green));
|
||||
}
|
103
src/install/security.rs
Normal file
103
src/install/security.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
// TPM Unlock
|
||||
|
||||
use crate::{config::DriveConfig, pkg::install_pkgs, run_command};
|
||||
|
||||
use super::str_vec;
|
||||
|
||||
pub fn setup_tpm_unlock(conf: &DriveConfig) {
|
||||
install_pkgs(&["tpm2-tools"]);
|
||||
|
||||
// systemd-cryptenroll --tpm2-device=list
|
||||
|
||||
// Recovery Key
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemd-cryptenroll",
|
||||
"--recovery-key",
|
||||
&conf.root,
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemd-cryptenroll",
|
||||
"--tpm2-device=auto",
|
||||
&conf.root,
|
||||
"--tpm2-pcrs=7",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
// SECURE BOOT
|
||||
|
||||
pub fn setup_secure_boot() {
|
||||
let (stdout, _) = run_command(&str_vec(vec!["sbctl", "status"]), None, false);
|
||||
let binding = stdout.lines().collect::<Vec<&str>>();
|
||||
let status = binding.get(1).unwrap();
|
||||
|
||||
if !status.contains("Setup Mode") {
|
||||
println!("[!] Secure Boot is not in Setup Mode");
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
if !status.contains("Enabled") {
|
||||
println!("[!] Secure Boot is not in Setup Mode");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
run_command(&vec!["sbctl".into(), "create-keys".into()], None, false);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["sbctl", "enroll-keys", "--microsoft"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"sbctl",
|
||||
"sign",
|
||||
"-s",
|
||||
"/boot/EFI/Linux/arch-linux.efi",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"sbctl",
|
||||
"sign",
|
||||
"-s",
|
||||
"/boot/EFI/Linux/arch-linux-fallback.efi",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"sbctl",
|
||||
"sign",
|
||||
"-s",
|
||||
"/boot/EFI/systemd/systemd-bootx64.efi",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["sbctl", "sign", "-s", "/boot/EFI/Boot/bootx64.efi"]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(&str_vec(vec!["sbctl", "verify"]), None, false);
|
||||
}
|
27
src/install/user.rs
Normal file
27
src/install/user.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
use crate::{config::UserConfig, run_command};
|
||||
|
||||
use super::str_vec;
|
||||
|
||||
pub fn setup_users(conf: &[UserConfig]) {
|
||||
let mut doas_conf = String::new();
|
||||
|
||||
for user in conf {
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "useradd", "-m", &user.name]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
run_command(
|
||||
&str_vec(vec!["arch-chroot", "/mnt", "passwd", &user.name]),
|
||||
Some(&format!("{}\n{}\n", user.password, user.password)),
|
||||
false,
|
||||
);
|
||||
|
||||
if user.doas_root {
|
||||
doas_conf.push_str(&format!("permit {} as root\n", user.name));
|
||||
}
|
||||
}
|
||||
|
||||
std::fs::write("/mnt/etc/doas.conf", doas_conf).unwrap();
|
||||
}
|
23
src/install/zram.rs
Normal file
23
src/install/zram.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use crate::{pkg::install_pkgs, run_command};
|
||||
|
||||
use super::str_vec;
|
||||
|
||||
pub fn setup_zram() {
|
||||
install_pkgs(&["zram-generator"]);
|
||||
std::fs::write(
|
||||
"/mnt/etc/systemd/zram-generator.conf",
|
||||
include_str!("../root/zram-generator.conf"),
|
||||
)
|
||||
.unwrap();
|
||||
run_command(
|
||||
&str_vec(vec![
|
||||
"arch-chroot",
|
||||
"/mnt",
|
||||
"systemctl",
|
||||
"enable",
|
||||
"systemd-zram-setup@zram0.service",
|
||||
]),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
31
src/main.rs
31
src/main.rs
|
@ -10,13 +10,18 @@ mod install;
|
|||
mod pkg;
|
||||
use create_iso::create_iso;
|
||||
use install::install;
|
||||
use yansi::{Color, Paint};
|
||||
|
||||
fn is_root() -> bool {
|
||||
getuid() == Uid::from_raw(0)
|
||||
}
|
||||
|
||||
fn run_command(cmd: &[String], input: Option<&str>, inherit: bool) -> (String, String) {
|
||||
println!("--> {}", cmd.join(" "));
|
||||
println!(
|
||||
"{} {}",
|
||||
"-->".paint(Color::Red),
|
||||
cmd.join(" ").paint(Color::Blue.bold())
|
||||
);
|
||||
|
||||
let mut cmd_setup = std::process::Command::new(cmd[0].clone());
|
||||
let mut cmd_setup = cmd_setup.args(cmd.into_iter().skip(1).collect::<Vec<_>>());
|
||||
|
@ -62,7 +67,11 @@ fn run_command(cmd: &[String], input: Option<&str>, inherit: bool) -> (String, S
|
|||
}
|
||||
|
||||
fn main() {
|
||||
println!("⚠️ Warning: This is an alpha version of the installer. DO NOT USE in PROD");
|
||||
println!(
|
||||
"{}",
|
||||
"⚠️ Warning: This is an alpha version of the installer. DO NOT USE in PROD"
|
||||
.paint(Color::Yellow)
|
||||
);
|
||||
|
||||
let args = args::get_args();
|
||||
|
||||
|
@ -83,12 +92,16 @@ fn main() {
|
|||
Ok(content) => match toml::from_str(&content) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
eprintln!("Error: Could not deserialize TOML file. {e}");
|
||||
eprintln!(
|
||||
"{} {}",
|
||||
"Error: Could not deserialize TOML file.".paint(Color::Red),
|
||||
e.paint(Color::Red)
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
eprintln!("Error: Could not read config file.");
|
||||
eprintln!("{}", "Error: Could not read config file.".paint(Color::Red));
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
@ -104,19 +117,23 @@ fn main() {
|
|||
Ok(content) => match toml::from_str(&content) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
eprintln!("Error: Could not deserialize TOML file. {e}");
|
||||
eprintln!(
|
||||
"{} {}",
|
||||
"Error: Could not deserialize TOML file.".paint(Color::Red),
|
||||
e.paint(Color::Red)
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
eprintln!("Error: Could not read config file.");
|
||||
eprintln!("{}", "Error: Could not read config file.".paint(Color::Red));
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// TODO : Show config
|
||||
println!("Config: {conf:?}");
|
||||
println!("\nDo you want to proceed with this configuration? (yes/no)");
|
||||
print!("\nDo you want to proceed with this configuration? (yes/no) ");
|
||||
|
||||
let mut input = String::new();
|
||||
std::io::stdout().flush().expect("Error flushing stdout.");
|
||||
|
|
24
src/pkg.rs
24
src/pkg.rs
|
@ -1,4 +1,4 @@
|
|||
use crate::{install::str_vec, run_command};
|
||||
use crate::{config::PackageConfig, install::str_vec, run_command};
|
||||
|
||||
pub const DESKTOP_PKG: [&str; 2] = ["plasma", "sddm"];
|
||||
|
||||
|
@ -12,3 +12,25 @@ pub fn install_pkgs(pkg: &[&str]) {
|
|||
|
||||
run_command(&str_vec(cmd), None, true);
|
||||
}
|
||||
|
||||
// PACSTRAP
|
||||
|
||||
pub fn pacstrap(conf: &PackageConfig) {
|
||||
let mut cmd: Vec<String> = vec![
|
||||
"pacstrap".into(),
|
||||
"-K".into(),
|
||||
"/mnt".into(),
|
||||
"base".into(),
|
||||
"linux".into(),
|
||||
"linux-firmware".into(),
|
||||
"linux-headers".into(),
|
||||
"git".into(),
|
||||
"networkmanager".into(),
|
||||
"nano".into(),
|
||||
"doas".into(),
|
||||
];
|
||||
|
||||
cmd.extend(conf.pkg.clone());
|
||||
|
||||
run_command(&cmd, None, true);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue