Compare commits
5 commits
753f53d4da
...
f235867600
Author | SHA1 | Date | |
---|---|---|---|
f235867600 | |||
05cf6cf9da | |||
33a8fed192 | |||
12b2cf4a96 | |||
227b97b27f |
17 changed files with 250 additions and 90 deletions
|
@ -33,6 +33,12 @@ hostname = "navos"
|
|||
# Root password
|
||||
root_password = "root"
|
||||
|
||||
# Enable Bluetooth
|
||||
bluetooth = true
|
||||
|
||||
# GPU Video Drivers
|
||||
gpu_driver = "NVIDIA"
|
||||
|
||||
[pkg]
|
||||
# Additional packages
|
||||
pkg = [
|
||||
|
@ -49,5 +55,5 @@ name = "u"
|
|||
# User password
|
||||
password = "pass"
|
||||
|
||||
# Allow user to use `doas` as root
|
||||
doas_root= true
|
||||
# Add user to wheel group
|
||||
wheel = true
|
||||
|
|
|
@ -33,6 +33,12 @@ hostname = "navos"
|
|||
# Root password
|
||||
root_password = "root"
|
||||
|
||||
# Enable Bluetooth
|
||||
bluetooth = true
|
||||
|
||||
# GPU Video Drivers
|
||||
gpu_driver = "NVIDIA"
|
||||
|
||||
[pkg]
|
||||
# Additional packages
|
||||
pkg = [
|
||||
|
@ -66,8 +72,8 @@ home_dir = "/home/u"
|
|||
# Set the shell of the user
|
||||
shell = "/bin/bash"
|
||||
|
||||
# Allow user to use `doas` as root
|
||||
doas_root= true
|
||||
# Add user to wheel group
|
||||
wheel = true
|
||||
|
||||
# Add user to Docker group
|
||||
docker = true
|
||||
|
|
|
@ -52,8 +52,8 @@ name = "u"
|
|||
# User password
|
||||
password = "pass"
|
||||
|
||||
# Allow user to use `doas` as root
|
||||
doas_root= true
|
||||
# Add user to wheel group
|
||||
wheel = true
|
||||
|
||||
# Add user to Docker group
|
||||
docker = true
|
||||
|
|
|
@ -44,7 +44,7 @@ pub struct UserConfig {
|
|||
pub uid: Option<u32>,
|
||||
pub home_dir: Option<String>,
|
||||
pub shell: Option<String>,
|
||||
pub doas_root: Option<bool>,
|
||||
pub wheel: Option<bool>,
|
||||
pub docker: Option<bool>,
|
||||
pub virtualization: Option<bool>,
|
||||
}
|
||||
|
@ -85,6 +85,17 @@ pub struct GeneralConfig {
|
|||
pub hostname: String,
|
||||
// Root password
|
||||
pub root_password: Option<String>,
|
||||
// Enable Bluetooth
|
||||
pub bluetooth: Option<bool>,
|
||||
/// Install Video Driver
|
||||
pub gpu_driver: Option<GPUVendor>
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub enum GPUVendor {
|
||||
AMD,
|
||||
NVIDIA,
|
||||
INTEL
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
|
|
8
src/install/bluetooth.rs
Normal file
8
src/install/bluetooth.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
use crate::{linux::systemd_service_enable, pkg::install_pkgs, print_status};
|
||||
|
||||
/// Enable Bluetooth
|
||||
pub fn setup_bluetooth() {
|
||||
print_status("Setting up Bluetooth");
|
||||
install_pkgs(&["bluez", "bluez-utils"]);
|
||||
systemd_service_enable("bluetooth.service");
|
||||
}
|
29
src/install/desktop.rs
Normal file
29
src/install/desktop.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use crate::{
|
||||
config::InstallConfig,
|
||||
linux::install_file,
|
||||
pkg::{self, install_pkgs},
|
||||
print_status,
|
||||
};
|
||||
|
||||
use super::navos::setup_navos;
|
||||
|
||||
pub fn setup_desktop(conf: &InstallConfig) {
|
||||
setup_navos();
|
||||
install_pkgs(&pkg::DESKTOP_PKG);
|
||||
print_status("Enable SDDM");
|
||||
print_status("Set keyboard layout for SDDM");
|
||||
install_file(
|
||||
"/mnt/usr/share/sddm/scripts/Xsetup",
|
||||
&format!(
|
||||
"#!/bin/sh\n# Xsetup\nsetxkbmap {},us\n",
|
||||
conf.general.keyboard_layout
|
||||
),
|
||||
0o644,
|
||||
);
|
||||
|
||||
std::os::unix::fs::symlink(
|
||||
"/usr/lib/systemd/system/sddm.service",
|
||||
"/mnt/etc/systemd/system/display-manager.service",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
24
src/install/firmware.rs
Normal file
24
src/install/firmware.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use crate::{linux::systemd_service_enable, pkg::install_pkgs, print_status};
|
||||
|
||||
pub fn setup_fwupd() {
|
||||
print_status("Enabling firmware updates");
|
||||
install_pkgs(&["fwupd"]);
|
||||
systemd_service_enable("fwupd-refresh.timer");
|
||||
}
|
||||
|
||||
pub fn setup_microcode() {
|
||||
print_status("Installing CPU Microcode");
|
||||
let cpuinfo = std::fs::read_to_string("/proc/cpuinfo").unwrap();
|
||||
|
||||
for line in cpuinfo.lines() {
|
||||
if line.starts_with("vendor_id") {
|
||||
if line.contains("GenuineIntel") {
|
||||
install_pkgs(&["intel-ucode"]);
|
||||
}
|
||||
|
||||
if line.contains("AuthenticAMD") {
|
||||
install_pkgs(&["amd-ucode"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use crate::{
|
||||
config::GeneralConfig,
|
||||
linux::{arch_chroot, run_command, systemd_service_enable},
|
||||
linux::{arch_chroot, install_file, run_command, systemd_service_enable},
|
||||
print_status,
|
||||
};
|
||||
|
||||
|
@ -45,6 +45,8 @@ pub fn first_boot_values(conf: &GeneralConfig) {
|
|||
print_status("Writing /etc/hostname");
|
||||
std::fs::write("/mnt/etc/hostname", format!("{}\n", conf.hostname)).unwrap();
|
||||
|
||||
install_file("/mnt/etc/hosts", &format!("127.0.0.1 localhost\n::1 localhost\n127.0.1.1 {}\n", conf.hostname), 0o644);
|
||||
|
||||
// LOCALE
|
||||
print_status("Setting locale");
|
||||
uncomment_first_value_of(&conf.locale, "/mnt/etc/locale.gen");
|
||||
|
|
15
src/install/gpu.rs
Normal file
15
src/install/gpu.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use crate::{config::GPUVendor, pkg::install_pkgs};
|
||||
|
||||
pub fn setup_video_drivers(vendor: &GPUVendor) {
|
||||
match vendor {
|
||||
GPUVendor::AMD => {
|
||||
install_pkgs(&["xf86-video-amdgpu", "mesa", "lib32-mesa", "vulkan-radeon", "lib32-vulkan-radeon"]);
|
||||
},
|
||||
GPUVendor::NVIDIA => {
|
||||
install_pkgs(&["nvidia", "nvidia-utils", "lib32-nvidia-utils"]);
|
||||
},
|
||||
GPUVendor::INTEL => {
|
||||
install_pkgs(&["xf86-video-intel2", "mesa", "lib32-mesa", "vulkan-intel", "lib32-vulkan-intel"]);
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,12 +1,17 @@
|
|||
// TODO : Autojoin docker swarm
|
||||
// TODO : Autojoin teleport
|
||||
// TODO : Firewall
|
||||
|
||||
// DRIVE SELECTION
|
||||
|
||||
use bluetooth::setup_bluetooth;
|
||||
use boot::setup_bootloader;
|
||||
use desktop::setup_desktop;
|
||||
use docker::setup_docker;
|
||||
use drives::{format_drives, mount_drives};
|
||||
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;
|
||||
|
@ -14,10 +19,13 @@ use security::{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 first_boot;
|
||||
|
@ -28,13 +36,14 @@ pub mod security;
|
|||
pub mod skel;
|
||||
pub mod ssh;
|
||||
pub mod user;
|
||||
pub mod virt;
|
||||
pub mod zram;
|
||||
pub mod firmware;
|
||||
pub mod gpu;
|
||||
|
||||
use crate::{
|
||||
config::{InstallConfig, InstallMode},
|
||||
linux::{arch_chroot, install_file, systemd_service_enable},
|
||||
config::InstallConfig,
|
||||
pkg::{self, install_pkgs, pacstrap},
|
||||
print_status,
|
||||
};
|
||||
|
||||
pub fn uncomment_first_value_of(value: &str, file: &str) {
|
||||
|
@ -91,31 +100,14 @@ pub fn install(conf: InstallConfig) {
|
|||
setup_skel(&conf.general);
|
||||
setup_users(&conf.user.as_ref().unwrap_or(&Vec::new()));
|
||||
|
||||
setup_ssh(conf.ssh);
|
||||
setup_ssh(&conf.ssh);
|
||||
|
||||
setup_bootloader();
|
||||
|
||||
match conf.general.mode {
|
||||
crate::config::InstallMode::Base => {}
|
||||
crate::config::InstallMode::Desktop => {
|
||||
setup_navos();
|
||||
install_pkgs(&pkg::DESKTOP_PKG);
|
||||
print_status("Enable SDDM");
|
||||
print_status("Set keyboard layout for SDDM");
|
||||
install_file(
|
||||
"/mnt/usr/share/sddm/scripts/Xsetup",
|
||||
&format!(
|
||||
"#!/bin/sh\n# Xsetup\nsetxkbmap {},us\n",
|
||||
conf.general.keyboard_layout
|
||||
),
|
||||
0o644,
|
||||
);
|
||||
|
||||
std::os::unix::fs::symlink(
|
||||
"/usr/lib/systemd/system/sddm.service",
|
||||
"/mnt/etc/systemd/system/display-manager.service",
|
||||
)
|
||||
.unwrap();
|
||||
setup_desktop(&conf);
|
||||
}
|
||||
crate::config::InstallMode::Server => {
|
||||
setup_navos();
|
||||
|
@ -127,29 +119,7 @@ pub fn install(conf: InstallConfig) {
|
|||
}
|
||||
|
||||
if conf.pkg.virtualization.unwrap_or_default() {
|
||||
let user_conf = if let Some(user_conf) = &conf.user {
|
||||
user_conf.clone()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
install_pkgs(&["libvirt"]);
|
||||
|
||||
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_virtualization(&conf);
|
||||
}
|
||||
|
||||
if conf.pkg.docker.unwrap_or_default() {
|
||||
|
@ -167,6 +137,17 @@ pub fn install(conf: InstallConfig) {
|
|||
}
|
||||
|
||||
setup_zram();
|
||||
|
||||
if conf.general.bluetooth.unwrap_or_default() {
|
||||
setup_bluetooth();
|
||||
}
|
||||
|
||||
setup_vm();
|
||||
if let Some(gpu_vendor) = &conf.general.gpu_driver {
|
||||
setup_video_drivers(gpu_vendor);
|
||||
}
|
||||
setup_fwupd();
|
||||
setup_microcode();
|
||||
setup_mkinitcpio(&conf.drive);
|
||||
setup_secure_boot();
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::io::Write;
|
|||
/// Setup SSH on the system
|
||||
///
|
||||
/// This should be done after `setup_users()` to ensure that the users directories exist.
|
||||
pub fn setup_ssh(conf: Option<SSHConfig>) {
|
||||
pub fn setup_ssh(conf: &Option<SSHConfig>) {
|
||||
if let Some(conf) = conf {
|
||||
install_pkgs(&["openssh"]);
|
||||
|
||||
|
@ -14,7 +14,7 @@ pub fn setup_ssh(conf: Option<SSHConfig>) {
|
|||
install_file("/mnt/etc/ssh/sshd_config", &content, 0o644);
|
||||
}
|
||||
|
||||
for key in &conf.key.unwrap_or_default() {
|
||||
for key in conf.key.as_ref().unwrap_or(&Vec::new()) {
|
||||
for user in &key.users {
|
||||
let path = if user == "root" {
|
||||
std::fs::create_dir_all("/root/.ssh").unwrap();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use crate::{
|
||||
config::UserConfig,
|
||||
linux::{arch_chroot, install_file},
|
||||
print_status,
|
||||
config::UserConfig, linux::{arch_chroot, install_file}, pkg::install_pkgs, print_status
|
||||
};
|
||||
|
||||
pub fn change_passwd(user: &str, pw: &str) {
|
||||
|
@ -10,7 +8,10 @@ pub fn change_passwd(user: &str, pw: &str) {
|
|||
|
||||
/// Setup the users of the system
|
||||
pub fn setup_users(conf: &[UserConfig]) {
|
||||
let mut doas_conf = String::new();
|
||||
if !conf.is_empty() {
|
||||
install_pkgs(&["doas"]);
|
||||
install_file("/mnt/etc/doas.conf", "permit persist :wheel as root", 0o644);
|
||||
}
|
||||
|
||||
for user in conf {
|
||||
let mut cmd = vec!["useradd"];
|
||||
|
@ -45,11 +46,13 @@ pub fn setup_users(conf: &[UserConfig]) {
|
|||
|
||||
change_passwd(&user.name, &user.password);
|
||||
|
||||
if user.doas_root.unwrap_or_default() {
|
||||
print_status(&format!("Allowing root doas for {}", user.name));
|
||||
doas_conf.push_str(&format!("permit {} as root\n", user.name));
|
||||
if user.wheel.unwrap_or_default() {
|
||||
print_status(&format!("Adding {} to wheel", user.name));
|
||||
arch_chroot(
|
||||
&vec!["usermod", "-a", "-G", "wheel", user.name.as_str()],
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
install_file("/mnt/etc/doas.conf", &doas_conf, 0o644);
|
||||
}
|
||||
|
|
35
src/install/virt.rs
Normal file
35
src/install/virt.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use crate::{
|
||||
config::{InstallConfig, InstallMode},
|
||||
linux::{arch_chroot, systemd_service_enable},
|
||||
pkg::install_pkgs,
|
||||
};
|
||||
|
||||
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"]);
|
||||
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_vm() {
|
||||
// TODO : Install guest tools if in virt with systemd-detect-virt
|
||||
}
|
|
@ -75,6 +75,7 @@ pub fn install_file(path: &str, content: &str, permissions: u32) {
|
|||
file.write_all(content.as_bytes()).unwrap();
|
||||
|
||||
let permissions = std::fs::Permissions::from_mode(permissions);
|
||||
// TODO : Fix permission format
|
||||
print_status(&format!("Wrote file {path} [{permissions:#?}]"));
|
||||
std::fs::set_permissions(path, permissions).unwrap();
|
||||
}
|
||||
|
|
32
src/pkg.rs
32
src/pkg.rs
|
@ -3,7 +3,31 @@ use crate::{
|
|||
linux::{arch_chroot, run_command},
|
||||
};
|
||||
|
||||
pub const DESKTOP_PKG: [&str; 5] = ["plasma", "sddm", "konsole", "dolphin", "navos/navos"];
|
||||
pub const DESKTOP_PKG: [&str; 16] = [
|
||||
// Desktop
|
||||
"plasma",
|
||||
"sddm",
|
||||
|
||||
// Sound
|
||||
"pipewire",
|
||||
"pipewire-alsa",
|
||||
"pipewire-pulse",
|
||||
"pipewire-jack",
|
||||
"wireplumber",
|
||||
|
||||
// Applications
|
||||
"konsole",
|
||||
"dolphin",
|
||||
"ffmpegthumbs",
|
||||
"kate",
|
||||
"okular",
|
||||
"gwenview",
|
||||
"ark",
|
||||
"flatpak",
|
||||
|
||||
// Misc
|
||||
"navos/navos"
|
||||
];
|
||||
|
||||
pub const SERVER_PKG: [&str; 2] = ["tmux", "navos/navos"];
|
||||
|
||||
|
@ -32,7 +56,11 @@ pub fn pacstrap(conf: &PackageConfig) {
|
|||
"git",
|
||||
"networkmanager",
|
||||
"nano",
|
||||
"doas",
|
||||
"openssh",
|
||||
"zsh",
|
||||
"zsh-completions",
|
||||
"zsh-autosuggestions",
|
||||
"man"
|
||||
];
|
||||
|
||||
cmd.extend(
|
||||
|
|
27
src/print.rs
27
src/print.rs
|
@ -58,11 +58,17 @@ pub fn print_config(conf: &InstallConfig) {
|
|||
conf.general.timezone
|
||||
));
|
||||
if conf.general.root_password.is_some() {
|
||||
general_info.add_str(format!(
|
||||
"🔑 {} {}",
|
||||
"Root Password".paint(Color::Yellow),
|
||||
"✔️".paint(Color::Green)
|
||||
));
|
||||
general_info.add_str(format!("🔑 Root Password {}", "✔️".paint(Color::Green)));
|
||||
}
|
||||
if conf.general.bluetooth.unwrap_or_default() {
|
||||
general_info.add_str(format!("🌀 Bluetooth {}", "✔️".paint(Color::Green)));
|
||||
}
|
||||
if let Some(vendor) = &conf.general.gpu_driver {
|
||||
match vendor {
|
||||
crate::config::GPUVendor::AMD => general_info.add_str(format!("🟥 AMD GPU {}", "✔️".paint(Color::Green))),
|
||||
crate::config::GPUVendor::INTEL => general_info.add_str(format!("🟦 Intel GPU {}", "✔️".paint(Color::Green))),
|
||||
crate::config::GPUVendor::NVIDIA => general_info.add_str(format!("🟩 NVIDIA GPU {}", "✔️".paint(Color::Green))),
|
||||
}
|
||||
}
|
||||
|
||||
root_info.add_tree("🔨 General", general_info);
|
||||
|
@ -79,7 +85,8 @@ pub fn print_config(conf: &InstallConfig) {
|
|||
|
||||
if !conf.pkg.pkg.is_empty() {
|
||||
pkg_info.add_str(format!(
|
||||
"📦 Additional packages: {}",
|
||||
"📦 {} {}",
|
||||
"Additional packages:".paint(Color::Yellow),
|
||||
conf.pkg.pkg.join(" ")
|
||||
));
|
||||
}
|
||||
|
@ -94,7 +101,7 @@ pub fn print_config(conf: &InstallConfig) {
|
|||
for user in user_conf {
|
||||
let mut groups = Vec::new();
|
||||
|
||||
if user.doas_root.unwrap_or_default() {
|
||||
if user.wheel.unwrap_or_default() {
|
||||
groups.push("🔑");
|
||||
}
|
||||
|
||||
|
@ -145,7 +152,11 @@ pub fn print_config(conf: &InstallConfig) {
|
|||
}
|
||||
|
||||
if let Some(models) = &ai_conf.models {
|
||||
ai_info.add_str(format!("⬇️ Pull Models: {}", models.join(", ")));
|
||||
ai_info.add_str(format!(
|
||||
"⬇️ {} {}",
|
||||
"Pull Models:".paint(Color::Yellow),
|
||||
models.join(", ")
|
||||
));
|
||||
}
|
||||
|
||||
root_info.add_tree("🦙 Ollama", ai_info);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue