✨ iso with custom user, pass, uid + systemd units
All checks were successful
ci/woodpecker/push/build Pipeline was successful
All checks were successful
ci/woodpecker/push/build Pipeline was successful
This commit is contained in:
parent
93b254055a
commit
fa6439bce8
3 changed files with 77 additions and 1 deletions
|
@ -1,4 +1,4 @@
|
|||
use clap::{arg, command};
|
||||
use clap::{ArgAction, arg, command};
|
||||
|
||||
pub fn get_args() -> clap::ArgMatches {
|
||||
command!()
|
||||
|
@ -10,6 +10,10 @@ pub fn get_args() -> clap::ArgMatches {
|
|||
.arg(arg!(--no_tmp "Create ISO on disk"))
|
||||
.arg(arg!(--kb_layout <LAYOUT> "Create ISO with this keyboard layout"))
|
||||
.arg(arg!(--kb_variant <VARIANT> "Create ISO with this keyboard layout variant"))
|
||||
.arg(arg!(--user <USER> "Change the system user"))
|
||||
.arg(arg!(--pass <PASS> "Change the system users password"))
|
||||
.arg(arg!(--uid <UID> "Change the system users UID"))
|
||||
.arg(arg!(--unit <UNIT> "Include a systemd unit").action(ArgAction::Append))
|
||||
.arg(arg!(--install <CONFIG> "Create ISO which automatically installs <CONFIG> upon boot."))
|
||||
)
|
||||
.subcommand(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::os::unix::fs::symlink;
|
||||
|
||||
use yansi::{Color, Paint};
|
||||
|
||||
use crate::{expect_yes, install::uncomment_tag, linux::is_root, linux::run_command, print_status};
|
||||
|
@ -18,6 +20,8 @@ pub fn create_iso(
|
|||
no_tmp: bool,
|
||||
kb_layout: &str,
|
||||
kb_variant: Option<&str>,
|
||||
user: Option<(String, String, u16)>,
|
||||
systemd_units: Vec<String>,
|
||||
install: Option<&String>,
|
||||
) {
|
||||
if !is_root() {
|
||||
|
@ -50,6 +54,56 @@ pub fn create_iso(
|
|||
setup_auto_install(&install_conf);
|
||||
}
|
||||
|
||||
if let Some((user, pass, uid)) = user {
|
||||
print_status(&format!("Setting user {user}"));
|
||||
let hashed_pw = run_command(
|
||||
&["openssl", "passwd", "-6"],
|
||||
Some(&format!("{pass}\n{pass}\n")),
|
||||
false,
|
||||
)
|
||||
.0;
|
||||
std::fs::write(
|
||||
"./iso/airootfs/etc/doas.conf",
|
||||
format!("permit persist {user} as root\n"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
std::fs::write("./iso/airootfs/etc/passwd", format!("root:x:0:0:root:/root:/usr/bin/zsh\n{user}:x:{uid}:{uid}::/home/{user}:/usr/bin/zsh\n")).unwrap();
|
||||
std::fs::write(
|
||||
"./iso/airootfs/etc/shadow",
|
||||
format!("root::14871::::::\n{user}:{hashed_pw}"),
|
||||
)
|
||||
.unwrap();
|
||||
std::fs::write(
|
||||
"./iso/airootfs/etc/sddm.conf.d/autologin.conf",
|
||||
format!("[Autologin]\nUser={user}\nSession=plasma\nRelogin=true\n"),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
for unit in systemd_units {
|
||||
print_status("Including unit file {unit}");
|
||||
let file_name = std::path::Path::new(&unit)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
let target_dir = std::path::Path::new("./iso/airootfs/etc/systemd/system");
|
||||
let target_path = target_dir.join(file_name);
|
||||
|
||||
// Copy unit file to target systemd directory
|
||||
std::fs::create_dir_all(target_dir).expect("Failed to create systemd directory");
|
||||
std::fs::copy(&unit, &target_path).expect("Failed to copy unit file");
|
||||
|
||||
// Enable the unit by symlinking it to multi-user.target.wants/
|
||||
let wants_dir = target_dir.join("multi-user.target.wants");
|
||||
std::fs::create_dir_all(&wants_dir).expect("Failed to create wants directory");
|
||||
|
||||
let symlink_path = wants_dir.join(file_name);
|
||||
symlink(&target_path, &symlink_path).expect("Failed to create symlink");
|
||||
}
|
||||
|
||||
print_status("Setting keyboard layout");
|
||||
std::fs::create_dir_all("./iso/airootfs/etc/skel/.config").unwrap();
|
||||
std::fs::write(
|
||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -26,11 +26,29 @@ fn main() {
|
|||
iso_args.get_one("kb_variant").map(|x: &String| x.as_str());
|
||||
let auto_install_config: Option<&String> = iso_args.get_one("install");
|
||||
|
||||
let user: Option<&String> = iso_args.get_one("user");
|
||||
let pass: Option<&String> = iso_args.get_one("pass");
|
||||
let uid: Option<&String> = iso_args.get_one("uid");
|
||||
|
||||
let user = if user.is_some() && pass.is_some() {
|
||||
Some((
|
||||
user.unwrap().to_string(),
|
||||
pass.unwrap().to_string(),
|
||||
uid.map(|x| x.parse().unwrap()).unwrap_or(1000),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let units: Vec<_> = iso_args.get_many("unit").unwrap_or_default().collect();
|
||||
|
||||
create_iso(
|
||||
without_gui,
|
||||
no_tmp,
|
||||
kb_layout,
|
||||
kb_variant,
|
||||
user,
|
||||
units.into_iter().map(|x: &String| x.to_string()).collect(),
|
||||
auto_install_config,
|
||||
);
|
||||
std::process::exit(0);
|
||||
|
|
Loading…
Add table
Reference in a new issue