This commit is contained in:
everyone 2023-11-08 10:50:41 -08:00
parent 988254359c
commit c406d4fd08
Signed by: everyone
SSH key fingerprint: SHA256:FKcGHdUnp2OocVUUAEJV25QetYQXwbmKPSsblofJOrM
8 changed files with 401 additions and 1 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
**/target

View file

@ -1 +1,6 @@
{}
{
"editor.formatOnSave": true,
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
}

34
archlinux/install.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/env bash
prompt() {
variable=$1
prompt=$2
read -p "> " "${variable?}"
}
invert() {
value=$1
((value ^= 1))
echo $value
}
is_uefi=0
if [[ $(cat /sys/firmware/efi/fw_platform_size) -eq 64 ]]; then
is_uefi=1
fi
mapfile -t devices < <(lsblk --paths --output NAME --noheadings --nodeps)
mapfile -t devices_sizes < <(lsblk --paths --output SIZE --noheadings --nodeps)
paste <(printf "%s\n" "${!devices[@]}") <(printf "%s\n" "${devices[@]}") <(printf "%s\n" "${devices_sizes[@]}")
echo "Which device do you want to be main root drive?"
prompt root_drive
echo "Which device do you want to be used for home? use q to skip and use root drive."
prompt home_drive
echo $root_drive - $home_drive

View file

@ -0,0 +1,3 @@
{
"recommendations": []
}

View file

@ -0,0 +1,6 @@
{
"editor.formatOnSave": true,
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
}

109
archlinux/install/Cargo.lock generated Normal file
View file

@ -0,0 +1,109 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "install"
version = "0.1.0"
dependencies = [
"nix",
"strum",
]
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "nix"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
dependencies = [
"bitflags",
"cfg-if",
"libc",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"

View file

@ -0,0 +1,8 @@
[package]
name = "install"
version = "0.1.0"
edition = "2021"
[dependencies]
nix = { version = "0.27.1", features = ["user"] }
strum = { version = "0.25.0", features = ["derive"] }

View file

@ -0,0 +1,234 @@
#![allow(dead_code, unused_macros)]
use nix::unistd::getuid;
use std::{
net::{Shutdown, TcpStream},
process::Stdio,
};
type Disks = Vec<Vec<String>>;
macro_rules! read {
($type:ty, $($prompts:literal),+) => {{
use std::io::{stdout, stdin, Write};
let r#type = match stringify!($type) {
"bool" => "Boolean",
"usize" => "Integer",
"String" => "String",
_=> panic!("\nunkown type {}", stringify!($type))
};
loop {
let mut result = String::new();
$(println!("\n{}", $prompts);)*
print!("> ");
let _ = stdout().flush();
stdin()
.read_line(&mut result)
.expect("Did not enter a correct string");
if let Some('\n') = result.chars().next_back() {
result.pop();
}
let results = result.parse::<$type>();
match results {
Ok(v) => break v,
Err(_) => println!("\nInput does not match expected type: {}.", r#type),
}
}
}};
}
macro_rules! cmd {
(@replace $($args:expr) +; $($format:tt),*) => {{
let mut args = [$(stringify!($args)), *].join(" ");
$(args = args.replacen("{}", $format.as_str(), 1);)*
args
}};
($command:tt) => {
let _ = std::process::Command::new(stringify!($command))
.spawn()
.expect("Command failed to spawn")
.wait();
};
($command:tt $($args:expr) +) => {
let _ = std::process::Command::new(stringify!($command))
.args([$(stringify!($args).replace("\"", "")),*])
.spawn()
.expect("Command failed to spawn")
.wait();
};
($command:tt $($args:expr) +$(, $format:tt)*) => {
let args = cmd!{@replace $($args) +; $( $format),*}.replace("- -", "--");
let _ = std::process::Command::new(stringify!($command))
.args(args.split_whitespace())
.spawn()
.expect("Command failed to spawn")
.wait();
};
}
fn is_online() -> bool {
let ping = TcpStream::connect("95.217.163.246:80");
match ping {
Ok(val) => {
let _ = val.shutdown(Shutdown::Both);
true
}
Err(_) => panic!("Connect to a network then rerun script"),
}
}
fn is_uefi() -> bool {
let bit = std::fs::read_to_string("/sys/firmware/efi/fw_platform_size");
match bit {
Ok(_) => true,
_ => false,
}
}
fn get_disks() -> Disks {
let process = std::process::Command::new("lsblk")
.args([
"--paths",
"--output",
"NAME,SIZE",
"--noheadings",
"--nodeps",
])
.output();
let output = String::from_utf8(process.unwrap().stdout)
.unwrap()
.trim()
.to_owned();
output
.split("\n")
.map(|disk| {
disk.split_whitespace()
.map(|value| value.to_owned())
.collect()
})
.collect()
}
fn print_disks(disks: &Disks) {
for (i, disk) in disks.iter().enumerate() {
println!("{}\t{}\t{}", i, disk[0], disk[1]);
}
}
#[derive(strum::AsRefStr)]
enum DiskLabel {
GPT,
MBR,
}
fn fdisk(dev: &String, label: DiskLabel, partitions: Vec<&'static str>) {
let label = format!("label: {}", label.as_ref());
let mut process = std::process::Command::new("sfdisk")
// .arg("--quiet")
.arg(dev)
.stdin(Stdio::piped())
.spawn()
.expect("Command failed to spawn");
std::process::Command::new("echo")
.arg([label, partitions.join("\n")].join("\n"))
.stdout(process.stdin.take().unwrap()) // Converted into a Stdio here
.spawn()
.expect("failed echo command");
let _ = process.wait();
}
fn mkfs_fat(dev: &String, part_num: i32, size: i32, label: &'static str) {
let _ = std::process::Command::new("mkfs.fat")
.args(["-n", label])
.args(["-F", &size.to_string()])
.arg(format!("{}{}", dev, part_num))
.spawn()
.expect("Command failed to spawn")
.wait();
}
fn mkfs_btrfs(dev: &String, part_num: i32, label: &'static str) {
let _ = std::process::Command::new("mkfs.btrfs")
.args(["--label", label])
.arg("-f")
.arg(format!("{}{}", dev, part_num))
.spawn()
.expect("Command failed to spawn")
.wait();
}
fn mount(dev: &String, part_num: i32, path: &'static str, options: Option<Vec<&'static str>>) {
let _ = std::process::Command::new("mount")
.arg("--mkdir")
.args(match options {
Some(opts) => vec!["--options".to_string(), opts.join(",")],
None => vec![],
})
.arg(format!("{dev}{part_num}"))
.arg(path)
.spawn()
.expect("Command failed to spawn")
.wait();
}
fn main() {
if !getuid().is_root() {
panic!("Script must be ran as root")
}
is_online();
let _is_uefi = is_uefi();
let disks = get_disks();
// Get info from user.
print_disks(&disks);
let root = read!(usize, "Which device do you want to be root drive?");
let mut fmt_home = false;
let home = if read!(
bool,
"Do you want to store home on another drive? (true|false)"
) {
let home = read!(usize, "Which device do you want to be home drive");
fmt_home = read!(bool, "Do you want to format home? (true|false)");
home
} else {
root
};
let swap = read!(bool, "Do you want a swap space? (true|false)");
let swap_size = if swap {
read!(String, "Swap size. Default is 2g")
} else {
String::from("2g")
};
let swap_size = String::from("2g");
// Act on user info.
{
let boot = ",+1G,C12A7328-F81F-11D2-BA4B-00A0C93EC93B";
let part_root = ",";
fdisk(&disks[root][0], DiskLabel::GPT, vec![boot, part_root]);
mkfs_fat(&disks[root][0], 1, 32, "boot");
mkfs_btrfs(&disks[root][0], 2, "root");
};
if fmt_home {
fdisk(&disks[home][0], DiskLabel::GPT, vec![","]);
mkfs_btrfs(&disks[home][0], 1, "home");
}
mount(&disks[root][0], 2, "/mnt", None);
mount(&disks[root][0], 1, "/mnt/boot", None);
if swap {
cmd! {btrfs subvolume create "/mnt/swap"}
cmd! {echo filesystem mkswapfile --size {} --uuid clear "/mnt/swap/swapfile", swap_size};
cmd! {swapon "/mnt/swap/swapfile"}
}
}