features
This commit is contained in:
parent
31110447da
commit
5f56b7fb77
23 changed files with 555 additions and 352 deletions
145
src/args.rs
145
src/args.rs
|
@ -1,41 +1,108 @@
|
|||
use clap::{ArgAction, arg, command};
|
||||
use argh::FromArgs;
|
||||
|
||||
pub fn get_args() -> clap::ArgMatches {
|
||||
command!()
|
||||
.about("navOS Installer")
|
||||
.subcommand(
|
||||
command!("create-iso")
|
||||
.about("Create a new installation medium ISO")
|
||||
.arg(arg!(--without_gui "Create ISO with just terminal"))
|
||||
.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(
|
||||
command!()
|
||||
.name("install")
|
||||
.about("Install a system according to configuration")
|
||||
.arg(arg!(-f --force "Install without confirming config"))
|
||||
.arg(arg!([config] "Config file").required(true)),
|
||||
)
|
||||
.subcommand(
|
||||
command!()
|
||||
.name("create-tar")
|
||||
.arg(arg!([dir] "root fs dir").required(true))
|
||||
.about("Create a container tar image"),
|
||||
)
|
||||
.subcommand(
|
||||
command!()
|
||||
.name("create-img")
|
||||
.about("Create an install on a disk image for VMs or embedded devices")
|
||||
.arg(arg!(--gpt "Use modern disk format"))
|
||||
.arg(arg!([config] "Config file").required(true))
|
||||
.arg(arg!([image] "Image file").required(true))
|
||||
)
|
||||
.get_matches()
|
||||
use crate::fx::Features;
|
||||
|
||||
#[derive(FromArgs)]
|
||||
/// navOS Installer
|
||||
pub struct NavinstallArgs {
|
||||
#[argh(subcommand)]
|
||||
pub cmd: NavinstallCommands,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand)]
|
||||
pub enum NavinstallCommands {
|
||||
CreateISO(CreateISOCommand),
|
||||
Install(InstallCommand),
|
||||
CreateTar(CreateTarCommand),
|
||||
CreateImage(CreateImageCommand),
|
||||
Feature(FeatureCommand),
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "create-iso")]
|
||||
/// Create a new installation medium ISO
|
||||
pub struct CreateISOCommand {
|
||||
#[argh(switch)]
|
||||
/// create ISO with just terminal
|
||||
pub without_gui: bool,
|
||||
|
||||
#[argh(switch)]
|
||||
/// create ISO on disk
|
||||
pub no_tmp: bool,
|
||||
|
||||
#[argh(option)]
|
||||
/// create ISO with this keyboard layout
|
||||
pub kb_layout: Option<String>,
|
||||
|
||||
#[argh(option)]
|
||||
/// create ISO with this keyboard layout variant
|
||||
pub kb_variant: Option<String>,
|
||||
|
||||
#[argh(option)]
|
||||
/// change the system user
|
||||
pub user: Option<String>,
|
||||
|
||||
#[argh(option)]
|
||||
/// change the system users password
|
||||
pub pass: Option<String>,
|
||||
|
||||
#[argh(option)]
|
||||
/// change the system user UID
|
||||
pub uid: Option<u16>,
|
||||
|
||||
#[argh(option)]
|
||||
/// include a systemd unit
|
||||
pub unit: Vec<String>,
|
||||
|
||||
#[argh(option)]
|
||||
/// create ISO which automatically installs <CONFIG> upon boot.
|
||||
pub install: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "install")]
|
||||
/// Install a system according to configuration
|
||||
pub struct InstallCommand {
|
||||
#[argh(switch, short = 'f')]
|
||||
/// install without confirming config
|
||||
pub force: bool,
|
||||
|
||||
#[argh(positional)]
|
||||
/// config file
|
||||
pub config: String,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "create-tar")]
|
||||
/// Create a container rootfs
|
||||
pub struct CreateTarCommand {
|
||||
#[argh(positional)]
|
||||
/// rootfs dir
|
||||
pub dir: String,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "create-img")]
|
||||
/// Create an install on a disk image for VMs or embedded devices
|
||||
pub struct CreateImageCommand {
|
||||
#[argh(switch)]
|
||||
/// use modern disk format
|
||||
pub gpt: bool,
|
||||
|
||||
#[argh(positional)]
|
||||
/// config file
|
||||
pub config: String,
|
||||
|
||||
#[argh(positional)]
|
||||
/// image file
|
||||
pub image: String,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "fx")]
|
||||
/// Enable or disable features
|
||||
pub struct FeatureCommand {
|
||||
#[argh(subcommand)]
|
||||
pub cmd: Features,
|
||||
}
|
||||
|
|
|
@ -123,8 +123,10 @@ pub struct GeneralConfig {
|
|||
pub secure_boot: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[derive(Debug, Clone, Deserialize, Default)]
|
||||
pub enum GPUVendor {
|
||||
#[default]
|
||||
NONE,
|
||||
AMD,
|
||||
NVIDIA,
|
||||
INTEL,
|
||||
|
|
|
@ -5,7 +5,7 @@ use yansi::{Color, Paint};
|
|||
use crate::{expect_yes, install::uncomment_tag, linux::is_root, linux::run_command, print_status};
|
||||
|
||||
/// Build the `kxkbrc` file for the given `layout` and `variant
|
||||
pub fn build_kxkbrc(layout: &str, variant: Option<&str>) -> String {
|
||||
pub fn build_kxkbrc(layout: &str, variant: Option<String>) -> String {
|
||||
let mut res = String::from("[Layout]\nUse=true\n");
|
||||
res.push_str(&format!("LayoutList={layout}\n"));
|
||||
if let Some(variant) = variant {
|
||||
|
@ -19,10 +19,10 @@ pub fn create_iso(
|
|||
without_gui: bool,
|
||||
no_tmp: bool,
|
||||
kb_layout: &str,
|
||||
kb_variant: Option<&str>,
|
||||
kb_variant: Option<String>,
|
||||
user: Option<(String, String, u16)>,
|
||||
systemd_units: Vec<String>,
|
||||
install: Option<&String>,
|
||||
install: Option<String>,
|
||||
) {
|
||||
if !is_root() {
|
||||
eprintln!("Error: You need root to create an ISO");
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
use argh::FromArgs;
|
||||
|
||||
use crate::{linux::systemd_service_enable, pkg::install_pkgs, print_status};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "bluetooth")]
|
||||
/// Enable Bluetooth support
|
||||
pub struct BluetoothFeature {}
|
||||
|
||||
/// Enable Bluetooth
|
||||
pub fn setup_bluetooth() {
|
||||
print_status("Setting up Bluetooth");
|
32
src/fx/docker.rs
Normal file
32
src/fx/docker.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use argh::FromArgs;
|
||||
|
||||
use crate::{
|
||||
linux::{arch_chroot, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
print_status,
|
||||
};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "docker")]
|
||||
/// Enable docker
|
||||
pub struct DockerFeature {
|
||||
#[argh(positional)]
|
||||
/// assign user to docker group
|
||||
pub user: Vec<String>,
|
||||
}
|
||||
|
||||
/// Setup docker on the system
|
||||
pub fn setup_docker(conf: &[String]) {
|
||||
print_status("Setting up Docker");
|
||||
install_pkgs(&["docker", "docker-compose"]);
|
||||
|
||||
systemd_service_enable("docker.service");
|
||||
|
||||
for user in conf {
|
||||
arch_chroot(
|
||||
&vec!["usermod", "-a", "-G", "docker", user.as_str()],
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,20 @@
|
|||
use argh::FromArgs;
|
||||
|
||||
use crate::{
|
||||
linux::{arch_chroot, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
print_status,
|
||||
};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "firewall")]
|
||||
/// Install firewall
|
||||
pub struct FirewallFeature {
|
||||
#[argh(switch)]
|
||||
/// allow SSH
|
||||
pub ssh: bool,
|
||||
}
|
||||
|
||||
/// Setup UFW
|
||||
pub fn setup_firewall(ssh: bool) {
|
||||
print_status("Enabling firewall");
|
|
@ -1,5 +1,16 @@
|
|||
use argh::FromArgs;
|
||||
|
||||
use crate::{config::GPUVendor, pkg::install_pkgs};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "gpu")]
|
||||
/// Install GPU drivers
|
||||
pub struct GPUFeature {
|
||||
#[argh(positional)]
|
||||
/// GPU vendor
|
||||
pub vendor: String,
|
||||
}
|
||||
|
||||
/// Setup GPU video drivers
|
||||
pub fn setup_video_drivers(vendor: &GPUVendor) {
|
||||
match vendor {
|
||||
|
@ -24,5 +35,6 @@ pub fn setup_video_drivers(vendor: &GPUVendor) {
|
|||
"lib32-vulkan-intel",
|
||||
]);
|
||||
}
|
||||
GPUVendor::NONE => {}
|
||||
}
|
||||
}
|
73
src/fx/mod.rs
Normal file
73
src/fx/mod.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
use argh::FromArgs;
|
||||
use bluetooth::BluetoothFeature;
|
||||
use docker::DockerFeature;
|
||||
use firewall::FirewallFeature;
|
||||
use gpu::GPUFeature;
|
||||
use ollama::OllamaFeature;
|
||||
use ssh::SSHFeature;
|
||||
use virt::{VirtFeature, VirtGuestFeature};
|
||||
use zram::ZramFeature;
|
||||
|
||||
pub mod bluetooth;
|
||||
pub mod docker;
|
||||
pub mod firewall;
|
||||
pub mod gpu;
|
||||
pub mod ollama;
|
||||
pub mod ssh;
|
||||
pub mod virt;
|
||||
pub mod zram;
|
||||
|
||||
pub struct OptionSet {
|
||||
values: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
impl OptionSet {
|
||||
pub fn new(values: Vec<String>) -> Self {
|
||||
Self {
|
||||
values: values
|
||||
.into_iter()
|
||||
.map(|x| {
|
||||
let s = x.split_once('=').unwrap();
|
||||
(s.0.to_owned(), s.1.to_owned())
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, key: &str) -> Option<&String> {
|
||||
self.values.iter().find(|x| x.0 == key).map(|x| &x.1)
|
||||
}
|
||||
|
||||
pub fn get_many(&self, key: &str) -> Vec<String> {
|
||||
self.values
|
||||
.iter()
|
||||
.filter_map(|x| if x.0 == key { Some(x.1.clone()) } else { None })
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_flag(&self, key: &str) -> Option<bool> {
|
||||
if let Some(val) = self.get(key) {
|
||||
if val == "true" || val == "1" {
|
||||
return Some(true);
|
||||
} else {
|
||||
return Some(false);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand)]
|
||||
pub enum Features {
|
||||
Bluetooth(BluetoothFeature),
|
||||
GPU(GPUFeature),
|
||||
Docker(DockerFeature),
|
||||
Firewall(FirewallFeature),
|
||||
Ollama(OllamaFeature),
|
||||
SSH(SSHFeature),
|
||||
Virt(VirtFeature),
|
||||
VirtGuest(VirtGuestFeature),
|
||||
Zram(ZramFeature),
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use argh::FromArgs;
|
||||
|
||||
use crate::{
|
||||
config::OllamaConfig,
|
||||
linux::{arch_chroot, systemd_service_enable},
|
||||
|
@ -7,6 +9,28 @@ use crate::{
|
|||
print_status,
|
||||
};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "ollama")]
|
||||
/// Enable ollama AI
|
||||
pub struct OllamaFeature {
|
||||
#[argh(option)]
|
||||
/// pull model
|
||||
pub model: Vec<String>,
|
||||
|
||||
#[argh(switch)]
|
||||
/// enable CUDA
|
||||
pub gpu: bool,
|
||||
}
|
||||
|
||||
impl OllamaFeature {
|
||||
pub fn into_config(self) -> OllamaConfig {
|
||||
OllamaConfig {
|
||||
models: Some(self.model),
|
||||
gpu: self.gpu,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup Ollama AI Service
|
||||
pub fn setup_ollama(conf: &OllamaConfig) {
|
||||
if conf.gpu {
|
|
@ -1,11 +1,50 @@
|
|||
use argh::FromArgs;
|
||||
|
||||
use crate::{
|
||||
config::SSHConfig,
|
||||
config::{SSHConfig, SSHKey},
|
||||
linux::{install_file, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
print_status,
|
||||
};
|
||||
use std::io::Write;
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "ssh")]
|
||||
/// Enable SSH
|
||||
pub struct SSHFeature {
|
||||
#[argh(option)]
|
||||
/// copy sshd config
|
||||
pub sshd: Option<String>,
|
||||
|
||||
#[argh(option)]
|
||||
/// add SSH key in the format 'user1,user2:key'
|
||||
pub key: Vec<String>,
|
||||
}
|
||||
|
||||
impl SSHFeature {
|
||||
pub fn into_config(self) -> SSHConfig {
|
||||
SSHConfig {
|
||||
sshd_config: self.sshd,
|
||||
key: Some(
|
||||
self.key
|
||||
.into_iter()
|
||||
.map(|x| {
|
||||
let (users, key) = x.split_once(':').unwrap();
|
||||
let users: Vec<_> = users
|
||||
.split(',')
|
||||
.map(std::string::ToString::to_string)
|
||||
.collect();
|
||||
SSHKey {
|
||||
key: key.to_string(),
|
||||
users: users,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup SSH on the system
|
||||
///
|
||||
/// This should be done after `setup_users()` to ensure that the users directories exist.
|
63
src/fx/virt.rs
Normal file
63
src/fx/virt.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use argh::FromArgs;
|
||||
|
||||
use crate::{
|
||||
linux::{arch_chroot, run_command_noerr, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
print_status,
|
||||
};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "virt-guest")]
|
||||
/// Install VM guest utils
|
||||
pub struct VirtGuestFeature {}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "virt")]
|
||||
/// Enable virtualization
|
||||
pub struct VirtFeature {
|
||||
#[argh(switch)]
|
||||
/// enable virt-manager GUI
|
||||
pub gui: bool,
|
||||
|
||||
#[argh(option)]
|
||||
/// add user to libvirt group
|
||||
pub user: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn setup_virtualization(conf: &VirtFeature) {
|
||||
install_pkgs(&["libvirt", "swtpm", "qemu-base"]);
|
||||
|
||||
if conf.gui {
|
||||
install_pkgs(&["virt-manager"]);
|
||||
}
|
||||
|
||||
systemd_service_enable("libvirtd.service");
|
||||
|
||||
for user in &conf.user {
|
||||
arch_chroot(
|
||||
&vec!["usermod", "-a", "-G", "libvirt", user.as_str()],
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_vm_guest() {
|
||||
print_status("Detected KVM. Installing utils");
|
||||
install_pkgs(&["qemu-guest-agent", "spice-vdagent"]);
|
||||
systemd_service_enable("qemu-guest-agent.service");
|
||||
systemd_service_enable("spice-vdagentd.service");
|
||||
}
|
||||
|
||||
/// Setup guest utils if running inside a VM
|
||||
pub fn try_setup_vm_guest() {
|
||||
let res = run_command_noerr(&["systemd-detect-virt", "--vm"], None, false);
|
||||
let is_vm = res.0.trim();
|
||||
|
||||
match is_vm {
|
||||
"qemu" | "kvm" => {
|
||||
setup_vm_guest();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,16 @@
|
|||
use argh::FromArgs;
|
||||
|
||||
use crate::{
|
||||
linux::{install_file, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
print_status,
|
||||
};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "zram")]
|
||||
/// Enable ZRAM
|
||||
pub struct ZramFeature {}
|
||||
|
||||
/// Setup the ZRAM feature
|
||||
pub fn setup_zram() {
|
||||
install_pkgs(&["zram-generator"]);
|
|
@ -1,24 +0,0 @@
|
|||
use crate::{
|
||||
config::UserConfig,
|
||||
linux::{arch_chroot, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
print_status,
|
||||
};
|
||||
|
||||
/// Setup docker on the system
|
||||
pub fn setup_docker(conf: &[UserConfig]) {
|
||||
print_status("Setting up Docker");
|
||||
install_pkgs(&["docker", "docker-compose"]);
|
||||
|
||||
systemd_service_enable("docker.service");
|
||||
|
||||
for user in conf {
|
||||
if user.docker.unwrap_or_default() {
|
||||
arch_chroot(
|
||||
&vec!["usermod", "-a", "-G", "docker", user.name.as_str()],
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use crate::{
|
||||
config::GeneralConfig,
|
||||
linux::{arch_chroot, install_file, run_command, systemd_service_enable},
|
||||
linux::{arch_chroot, install_file, run_command},
|
||||
print_status,
|
||||
};
|
||||
|
||||
|
|
|
@ -6,44 +6,36 @@
|
|||
|
||||
// DRIVE SELECTION
|
||||
|
||||
use bluetooth::setup_bluetooth;
|
||||
use crate::config::InstallMode;
|
||||
use crate::fx::docker::setup_docker;
|
||||
use crate::fx::firewall::setup_firewall;
|
||||
use crate::fx::gpu::setup_video_drivers;
|
||||
use crate::fx::ollama::setup_ollama;
|
||||
use crate::fx::ssh::setup_ssh;
|
||||
use crate::fx::virt::{VirtFeature, setup_virtualization, try_setup_vm_guest};
|
||||
use crate::fx::zram::setup_zram;
|
||||
use boot::setup_bootloader;
|
||||
use desktop::setup_desktop;
|
||||
use docker::setup_docker;
|
||||
use drives::{format_drives, mount_drives, setup_fstrim};
|
||||
use firewall::setup_firewall;
|
||||
use firmware::{setup_fwupd, setup_microcode};
|
||||
use first_boot::{first_boot_values, genfstab};
|
||||
use gpu::setup_video_drivers;
|
||||
use kernel::setup_mkinitcpio;
|
||||
use navos::setup_navos;
|
||||
use ollama::setup_ollama;
|
||||
use security::{has_secure_boot, setup_secure_boot, setup_tpm_unlock};
|
||||
use skel::setup_skel;
|
||||
use ssh::setup_ssh;
|
||||
use user::setup_users;
|
||||
use virt::{setup_virtualization, setup_vm};
|
||||
use yansi::{Color, Paint};
|
||||
use zram::setup_zram;
|
||||
|
||||
pub mod bluetooth;
|
||||
pub mod boot;
|
||||
pub mod desktop;
|
||||
pub mod docker;
|
||||
pub mod drives;
|
||||
pub mod firewall;
|
||||
pub mod firmware;
|
||||
pub mod first_boot;
|
||||
pub mod gpu;
|
||||
pub mod kernel;
|
||||
pub mod navos;
|
||||
pub mod ollama;
|
||||
pub mod security;
|
||||
pub mod skel;
|
||||
pub mod ssh;
|
||||
pub mod user;
|
||||
pub mod virt;
|
||||
pub mod zram;
|
||||
|
||||
// TODO : error handling
|
||||
// TODO : Power profile daemon
|
||||
|
@ -51,6 +43,7 @@ pub mod zram;
|
|||
|
||||
use crate::{
|
||||
config::{InstallConfig, WlanConfig},
|
||||
fx::bluetooth::setup_bluetooth,
|
||||
linux::run_command,
|
||||
pkg::{self, install_pkgs, pacstrap_at, setup_kernel},
|
||||
print_status,
|
||||
|
@ -209,7 +202,25 @@ pub fn install_mnt(conf: InstallConfig, bare: bool) {
|
|||
// Applications
|
||||
|
||||
if conf.pkg.virtualization.unwrap_or_default() {
|
||||
setup_virtualization(&conf);
|
||||
setup_virtualization(&VirtFeature {
|
||||
gui: matches!(conf.general.mode, InstallMode::Desktop),
|
||||
user: conf
|
||||
.user
|
||||
.as_ref()
|
||||
.map(|users| {
|
||||
users
|
||||
.into_iter()
|
||||
.filter_map(|x| {
|
||||
if x.virtualization.unwrap_or_default() {
|
||||
Some(x.name.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
});
|
||||
}
|
||||
|
||||
if conf.pkg.docker.unwrap_or_default() {
|
||||
|
@ -219,7 +230,17 @@ pub fn install_mnt(conf: InstallConfig, bare: bool) {
|
|||
Vec::new()
|
||||
};
|
||||
|
||||
setup_docker(&user_conf);
|
||||
let docker_users: Vec<_> = user_conf
|
||||
.iter()
|
||||
.filter_map(|x| {
|
||||
if x.docker.unwrap_or_default() {
|
||||
Some(x.name.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
setup_docker(&docker_users);
|
||||
}
|
||||
|
||||
if let Some(ai) = conf.ai {
|
||||
|
@ -237,7 +258,7 @@ pub fn install_mnt(conf: InstallConfig, bare: bool) {
|
|||
|
||||
// System
|
||||
setup_zram();
|
||||
setup_vm();
|
||||
try_setup_vm_guest();
|
||||
if let Some(gpu_vendor) = &conf.general.gpu_driver {
|
||||
setup_video_drivers(gpu_vendor);
|
||||
}
|
||||
|
|
|
@ -5,10 +5,7 @@ pub fn setup_skel(conf: &GeneralConfig) {
|
|||
std::fs::create_dir_all("/mnt/etc/skel/.config").unwrap();
|
||||
install_file(
|
||||
"/mnt/etc/skel/.config/kxkbrc",
|
||||
&build_kxkbrc(
|
||||
conf.keyboard_layout.as_str(),
|
||||
conf.keyboard_variant.as_ref().map(|x| x.as_str()),
|
||||
),
|
||||
&build_kxkbrc(conf.keyboard_layout.as_str(), conf.keyboard_variant.clone()),
|
||||
0o644,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
use crate::{
|
||||
config::{InstallConfig, InstallMode},
|
||||
linux::{arch_chroot, run_command_noerr, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
print_status,
|
||||
};
|
||||
|
||||
pub fn setup_virtualization(conf: &InstallConfig) {
|
||||
let user_conf = if let Some(user_conf) = &conf.user {
|
||||
user_conf.clone()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
install_pkgs(&["libvirt", "swtpm", "qemu-base"]);
|
||||
|
||||
if matches!(conf.general.mode, InstallMode::Desktop) {
|
||||
install_pkgs(&["virt-manager"]);
|
||||
}
|
||||
|
||||
systemd_service_enable("libvirtd.service");
|
||||
|
||||
for user in user_conf {
|
||||
if user.virtualization.unwrap_or_default() {
|
||||
arch_chroot(
|
||||
&vec!["usermod", "-a", "-G", "libvirt", user.name.as_str()],
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup guest utils if running inside a VM
|
||||
pub fn setup_vm() {
|
||||
let res = run_command_noerr(&["systemd-detect-virt", "--vm"], None, false);
|
||||
let is_vm = res.0.trim();
|
||||
|
||||
match is_vm {
|
||||
"qemu" | "kvm" => {
|
||||
print_status("Detected KVM. Installing utils");
|
||||
install_pkgs(&["qemu-guest-agent", "spice-vdagent"]);
|
||||
systemd_service_enable("qemu-guest-agent.service");
|
||||
systemd_service_enable("spice-vdagentd.service");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
pub mod args;
|
||||
pub mod config;
|
||||
pub mod create_iso;
|
||||
pub mod fx;
|
||||
pub mod install;
|
||||
pub mod linux;
|
||||
pub mod pkg;
|
||||
|
|
119
src/main.rs
119
src/main.rs
|
@ -1,4 +1,12 @@
|
|||
use navinstall::config::InstallConfig;
|
||||
use navinstall::fx::bluetooth::setup_bluetooth;
|
||||
use navinstall::fx::docker::setup_docker;
|
||||
use navinstall::fx::firewall::setup_firewall;
|
||||
use navinstall::fx::gpu::setup_video_drivers;
|
||||
use navinstall::fx::ollama::setup_ollama;
|
||||
use navinstall::fx::ssh::setup_ssh;
|
||||
use navinstall::fx::virt::{setup_virtualization, setup_vm_guest};
|
||||
use navinstall::fx::zram::setup_zram;
|
||||
use navinstall::install::navos::setup_navos;
|
||||
use navinstall::install::{
|
||||
drives::setup_disk_image, install, install_mnt, security::ensure_secure_boot,
|
||||
|
@ -24,69 +32,40 @@ fn main() {
|
|||
.paint(Color::Yellow)
|
||||
);
|
||||
|
||||
let args = navinstall::args::get_args();
|
||||
let args: navinstall::args::NavinstallArgs = argh::from_env();
|
||||
|
||||
match args.subcommand() {
|
||||
Some(("create-iso", iso_args)) => {
|
||||
let without_gui = iso_args.get_flag("without_gui");
|
||||
let no_tmp = iso_args.get_flag("no_tmp");
|
||||
match args.cmd {
|
||||
navinstall::args::NavinstallCommands::CreateISO(create_isocommand) => {
|
||||
let kb_layout_default = "us".to_string();
|
||||
let kb_layout: &String = iso_args.get_one("kb_layout").unwrap_or(&kb_layout_default);
|
||||
let kb_variant: Option<&str> =
|
||||
iso_args.get_one("kb_variant").map(|x: &String| x.as_str());
|
||||
let auto_install_config: Option<&String> = iso_args.get_one("install");
|
||||
let kb_layout = create_isocommand.kb_layout.unwrap_or(kb_layout_default);
|
||||
|
||||
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() {
|
||||
let user = if create_isocommand.user.is_some() && create_isocommand.pass.is_some() {
|
||||
Some((
|
||||
user.unwrap().to_string(),
|
||||
pass.unwrap().to_string(),
|
||||
uid.map(|x| x.parse().unwrap()).unwrap_or(1000),
|
||||
create_isocommand.user.unwrap().to_string(),
|
||||
create_isocommand.pass.unwrap().to_string(),
|
||||
create_isocommand.uid.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,
|
||||
create_isocommand.without_gui,
|
||||
create_isocommand.no_tmp,
|
||||
&kb_layout,
|
||||
create_isocommand.kb_variant,
|
||||
user,
|
||||
units.into_iter().map(|x: &String| x.to_string()).collect(),
|
||||
auto_install_config,
|
||||
create_isocommand.unit,
|
||||
create_isocommand.install,
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
||||
Some(("create-tar", tar_options)) => {
|
||||
ensure_root();
|
||||
let dir: &String = tar_options.get_one("dir").unwrap();
|
||||
print_status("Pacstrapping root fs");
|
||||
pacstrap_at(&dir, &[]);
|
||||
setup_navos(dir.as_str());
|
||||
}
|
||||
Some(("create-img", install_args)) => {
|
||||
let config_file: &String = install_args.get_one("config").unwrap();
|
||||
let conf = read_conf(config_file);
|
||||
let img_file: &String = install_args.get_one("image").unwrap();
|
||||
let gpt = install_args.get_flag("gpt");
|
||||
|
||||
setup_disk_image(img_file.as_str(), gpt);
|
||||
install_mnt(conf, false);
|
||||
}
|
||||
Some(("install", install_args)) => {
|
||||
navinstall::args::NavinstallCommands::Install(install_command) => {
|
||||
ensure_root();
|
||||
|
||||
let config_file: &String = install_args.get_one("config").unwrap();
|
||||
let force = install_args.get_flag("force");
|
||||
let conf = read_conf(config_file);
|
||||
let conf = read_conf(&install_command.config);
|
||||
|
||||
if !force {
|
||||
if !install_command.force {
|
||||
print_config(&conf);
|
||||
print!("Do you want to proceed with this configuration? (yes/no) ");
|
||||
expect_yes();
|
||||
|
@ -99,7 +78,53 @@ fn main() {
|
|||
// Run the
|
||||
install(conf, true);
|
||||
}
|
||||
_ => {}
|
||||
navinstall::args::NavinstallCommands::CreateTar(create_tar_command) => {
|
||||
ensure_root();
|
||||
print_status("Pacstrapping root fs");
|
||||
pacstrap_at(&create_tar_command.dir, &[]);
|
||||
setup_navos(&create_tar_command.dir.as_str());
|
||||
}
|
||||
navinstall::args::NavinstallCommands::CreateImage(create_image_command) => {
|
||||
let conf = read_conf(&create_image_command.config);
|
||||
setup_disk_image(
|
||||
&create_image_command.image.as_str(),
|
||||
create_image_command.gpt,
|
||||
);
|
||||
install_mnt(conf, false);
|
||||
}
|
||||
navinstall::args::NavinstallCommands::Feature(feature_command) => {
|
||||
match feature_command.cmd {
|
||||
navinstall::fx::Features::Bluetooth(_) => setup_bluetooth(),
|
||||
navinstall::fx::Features::GPU(gpufeature) => {
|
||||
let vendor = match gpufeature.vendor.to_lowercase().as_str() {
|
||||
"amd" => navinstall::config::GPUVendor::AMD,
|
||||
"intel" => navinstall::config::GPUVendor::INTEL,
|
||||
"nvidia" => navinstall::config::GPUVendor::NVIDIA,
|
||||
_ => {
|
||||
println!("{} is no GPU vendor", gpufeature.vendor);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
setup_video_drivers(&vendor);
|
||||
}
|
||||
navinstall::fx::Features::Docker(docker_feature) => {
|
||||
setup_docker(&docker_feature.user);
|
||||
}
|
||||
navinstall::fx::Features::Firewall(firewall_feature) => {
|
||||
setup_firewall(firewall_feature.ssh)
|
||||
}
|
||||
navinstall::fx::Features::Ollama(ollama_feature) => {
|
||||
setup_ollama(&ollama_feature.into_config())
|
||||
}
|
||||
navinstall::fx::Features::SSH(sshfeature) => {
|
||||
setup_ssh(&Some(sshfeature.into_config()))
|
||||
}
|
||||
navinstall::fx::Features::Virt(virt_feature) => setup_virtualization(&virt_feature),
|
||||
navinstall::fx::Features::VirtGuest(_) => setup_vm_guest(),
|
||||
navinstall::fx::Features::Zram(_) => setup_zram(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ pub fn setup_kernel(kernel: Option<String>) {
|
|||
|
||||
/// Initial system pacstrap
|
||||
pub fn pacstrap_at(dir: &str, pkg: &[String]) {
|
||||
// TODO : rearrange pkgs + minify
|
||||
let mut cmd: Vec<&str> = vec!["pacstrap", "-K", dir, "base"];
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
|
|
|
@ -79,6 +79,7 @@ pub fn print_config(conf: &InstallConfig) {
|
|||
crate::config::GPUVendor::NVIDIA => {
|
||||
general_info.add_str(format!("🟩 NVIDIA GPU {}", "✔️".paint(Color::Green)))
|
||||
}
|
||||
crate::config::GPUVendor::NONE => {}
|
||||
}
|
||||
}
|
||||
if conf.general.firewall.unwrap_or(true) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue