mirror of
https://github.com/philmmanjaro/alma.git
synced 2025-07-26 06:59:28 +02:00
Add presets support
This commit is contained in:
parent
91215703bf
commit
ffbd34e14f
31
Cargo.lock
generated
31
Cargo.lock
generated
@ -7,9 +7,11 @@ dependencies = [
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -397,6 +399,24 @@ name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simplelog"
|
||||
version = "0.5.3"
|
||||
@ -505,6 +525,14 @@ dependencies = [
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.3.0"
|
||||
@ -606,6 +634,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
|
||||
"checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288"
|
||||
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||
"checksum serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be"
|
||||
"checksum serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "46a3223d0c9ba936b61c0d2e3e559e3217dbfb8d65d06d26e8b3c25de38bae3e"
|
||||
"checksum simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e95345f185d5adeb8ec93459d2dc99654e294cc6ccf5b75414d8ea262de9a13"
|
||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
"checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1"
|
||||
@ -617,6 +647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea"
|
||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039"
|
||||
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
|
||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
@ -12,3 +12,5 @@ structopt = "0.2.14"
|
||||
simplelog = "0.5.3"
|
||||
tempfile = "3.0.5"
|
||||
nix = "0.12.0"
|
||||
serde = { version = "1.0.92", features = ["derive"] }
|
||||
toml = "0.5.1"
|
||||
|
@ -41,6 +41,10 @@ pub struct CreateCommand {
|
||||
/// Encrypt the root partition
|
||||
#[structopt(short = "e", long = "encrypted-root")]
|
||||
pub encrypted_root: bool,
|
||||
|
||||
/// Path to preset files
|
||||
#[structopt(long = "presets")]
|
||||
pub presets: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
|
@ -6,7 +6,7 @@ pub struct Error {
|
||||
inner: Context<ErrorKind>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)]
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
|
||||
pub enum ErrorKind {
|
||||
#[fail(display = "Error quering information about the block device")]
|
||||
DeviceQuery,
|
||||
@ -73,6 +73,12 @@ pub enum ErrorKind {
|
||||
|
||||
#[fail(display = "Failed launching Qemu")]
|
||||
Qemu,
|
||||
|
||||
#[fail(display = "Error loading preset \"{}\"", _0)]
|
||||
Preset(String),
|
||||
|
||||
#[fail(display = "Error executing preset script")]
|
||||
PresetScript,
|
||||
}
|
||||
|
||||
impl Fail for Error {
|
||||
|
56
src/main.rs
56
src/main.rs
@ -1,5 +1,6 @@
|
||||
mod args;
|
||||
mod error;
|
||||
mod presets;
|
||||
mod process;
|
||||
mod storage;
|
||||
mod tool;
|
||||
@ -13,9 +14,10 @@ use failure::{Fail, ResultExt};
|
||||
use log::{debug, error, info, warn};
|
||||
use nix::sys::signal;
|
||||
use simplelog::*;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::os::unix::process::CommandExt as UnixCommandExt;
|
||||
use std::os::unix::{fs::PermissionsExt, process::CommandExt as UnixCommandExt};
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use std::thread;
|
||||
@ -74,6 +76,8 @@ fn fix_fstab(fstab: &str) -> String {
|
||||
}
|
||||
|
||||
fn create(command: CreateCommand) -> Result<(), Error> {
|
||||
let presets = presets::Presets::load(&command.presets)?;
|
||||
|
||||
let sgdisk = Tool::find("sgdisk")?;
|
||||
let pacstrap = Tool::find("pacstrap")?;
|
||||
let arch_chroot = Tool::find("arch-chroot")?;
|
||||
@ -141,19 +145,26 @@ fn create(command: CreateCommand) -> Result<(), Error> {
|
||||
|
||||
let mount_stack = mount(mount_point.path(), &boot_filesystem, &root_filesystem)?;
|
||||
|
||||
let mut packages: HashSet<String> = [
|
||||
"base",
|
||||
"grub",
|
||||
"efibootmgr",
|
||||
"intel-ucode",
|
||||
"networkmanager",
|
||||
"broadcom-wl",
|
||||
]
|
||||
.iter()
|
||||
.map(|s| String::from(*s))
|
||||
.collect();
|
||||
|
||||
packages.extend(presets.packages);
|
||||
|
||||
info!("Bootstrapping system");
|
||||
pacstrap
|
||||
.execute()
|
||||
.arg("-c")
|
||||
.arg(mount_point.path())
|
||||
.args(&[
|
||||
"base",
|
||||
"grub",
|
||||
"efibootmgr",
|
||||
"intel-ucode",
|
||||
"networkmanager",
|
||||
"broadcom-wl",
|
||||
])
|
||||
.args(packages)
|
||||
.args(&command.extra_packages)
|
||||
.run(ErrorKind::Pacstrap)?;
|
||||
|
||||
@ -167,6 +178,33 @@ fn create(command: CreateCommand) -> Result<(), Error> {
|
||||
debug!("fstab:\n{}", fstab);
|
||||
fs::write(mount_point.path().join("etc/fstab"), fstab).context(ErrorKind::Fstab)?;
|
||||
|
||||
if !presets.scripts.is_empty() {
|
||||
info!("Running custom scripts");
|
||||
}
|
||||
|
||||
for script in presets.scripts {
|
||||
let mut script_file =
|
||||
tempfile::NamedTempFile::new_in(mount_point.path()).context(ErrorKind::PresetScript)?;
|
||||
script_file
|
||||
.write_all(script.as_bytes())
|
||||
.and_then(|_| script_file.as_file_mut().metadata())
|
||||
.and_then(|metadata| {
|
||||
let mut permissions = metadata.permissions();
|
||||
permissions.set_mode(0o755);
|
||||
fs::set_permissions(script_file.path(), permissions)
|
||||
})
|
||||
.context(ErrorKind::PresetScript)?;
|
||||
|
||||
let script_path = script_file.into_temp_path();
|
||||
arch_chroot
|
||||
.execute()
|
||||
.arg(mount_point.path())
|
||||
.arg(Path::new("/").join(script_path.file_name().unwrap()))
|
||||
.run(ErrorKind::PostInstallation)?;
|
||||
}
|
||||
|
||||
info!("Performing post installation tasks");
|
||||
|
||||
arch_chroot
|
||||
.execute()
|
||||
.arg(mount_point.path())
|
||||
|
50
src/presets.rs
Normal file
50
src/presets.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use failure::ResultExt;
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use toml;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
||||
struct Preset {
|
||||
packages: Option<Vec<String>>,
|
||||
script: Option<String>,
|
||||
}
|
||||
|
||||
impl Preset {
|
||||
fn load(path: &Path) -> Result<Self, Error> {
|
||||
let data = fs::read_to_string(path)
|
||||
.with_context(|_| ErrorKind::Preset(format!("{}", path.display())))?;
|
||||
Ok(toml::from_str(&data)
|
||||
.with_context(|_| ErrorKind::Preset(format!("{}", path.display())))?)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Presets {
|
||||
pub packages: HashSet<String>,
|
||||
pub scripts: Vec<String>,
|
||||
}
|
||||
|
||||
impl Presets {
|
||||
pub fn load(list: &[PathBuf]) -> Result<Self, Error> {
|
||||
let mut packages = HashSet::new();
|
||||
let mut scripts = Vec::new();
|
||||
|
||||
for preset in list {
|
||||
let Preset {
|
||||
script,
|
||||
packages: preset_packages,
|
||||
} = Preset::load(&preset)?;
|
||||
|
||||
if let Some(preset_packages) = preset_packages {
|
||||
packages.extend(preset_packages);
|
||||
}
|
||||
|
||||
scripts.extend(script);
|
||||
}
|
||||
|
||||
Ok(Self { packages, scripts })
|
||||
}
|
||||
}
|
@ -20,32 +20,32 @@ pub trait CommandExt {
|
||||
|
||||
impl CommandExt for Command {
|
||||
fn run(&mut self, context: ErrorKind) -> Result<(), Error> {
|
||||
let exit_status = self.spawn().context(context)?.wait().context(context)?;
|
||||
let exit_status = self
|
||||
.spawn()
|
||||
.with_context(|_| context.clone())?
|
||||
.wait()
|
||||
.with_context(|_| context.clone())?;
|
||||
|
||||
if !exit_status.success() {
|
||||
return Err(ProcessError::BadExitCode(exit_status)
|
||||
.context(context)
|
||||
.into());
|
||||
Err(ProcessError::BadExitCode(exit_status)).with_context(|_| context.clone())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_text_output(&mut self, context: ErrorKind) -> Result<String, Error> {
|
||||
let output = self.output().context(context)?;
|
||||
let output = self.output().with_context(|_| context.clone())?;
|
||||
|
||||
if !output.status.success() {
|
||||
let error = str::from_utf8(&output.stderr).unwrap_or("[INVALID UTF8]");
|
||||
error!("{}", error);
|
||||
return Err(ProcessError::BadExitCode(output.status)
|
||||
.context(context)
|
||||
.into());
|
||||
Err(ProcessError::BadExitCode(output.status)).with_context(|_| context.clone())?;
|
||||
}
|
||||
|
||||
Ok(String::from(
|
||||
str::from_utf8(&output.stdout)
|
||||
.map_err(|_| ProcessError::InvalidUtf8)
|
||||
.context(context)?,
|
||||
.with_context(|_| context.clone())?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user