updated the installer so that it should actually work
Some checks failed
Build / build (push) Failing after 5m23s

This commit is contained in:
tumillanino
2025-11-11 18:57:02 +11:00
parent a7bd4d9457
commit 33dd952ad4
583 changed files with 161651 additions and 67 deletions

View File

@@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
"time"
@@ -58,6 +59,11 @@ type installProgressMsg struct {
func (m InstallModel) startInstall() tea.Cmd {
return func() tea.Msg {
// Save archinstall configuration files
if err := m.saveConfigurationFiles(); err != nil {
return installCompleteMsg{err: fmt.Errorf("failed to save configuration files: %w", err)}
}
if err := m.performInstall(); err != nil {
return installCompleteMsg{err: err}
}
@@ -115,6 +121,27 @@ func (m InstallModel) updateProgress(step int, message string) {
time.Sleep(100 * time.Millisecond)
}
func (m InstallModel) saveConfigurationFiles() error {
m.updateProgress(0, "Saving configuration files...")
// Save user configuration
if err := m.config.SaveArchInstallConfig("/tmp/user_configuration.json"); err != nil {
return fmt.Errorf("failed to save user configuration: %w", err)
}
// Save user credentials
if err := m.config.SaveUserCredentials("/tmp/user_credentials.json"); err != nil {
return fmt.Errorf("failed to save user credentials: %w", err)
}
// Copy configuration files to target system
os.MkdirAll("/mnt/var/log/archinstall", 0755)
exec.Command("cp", "/tmp/user_configuration.json", "/mnt/var/log/archinstall/").Run()
exec.Command("cp", "/tmp/user_credentials.json", "/mnt/var/log/archinstall/").Run()
return nil
}
func (m InstallModel) partitionDisk() error {
disk := m.config.Disk
@@ -239,17 +266,24 @@ func (m InstallModel) mountFilesystems() error {
}
func (m InstallModel) installBase() error {
// Base Miasma OS packages with security hardening
packages := []string{
"base",
"base-devel",
"linux-hardened",
"linux-firmware",
"btrfs-progs",
"neovim",
"neovim", // Default text editor as specified in product description
"zsh", // Default shell as specified in product description
"alacritty", // Default terminal as specified in product description
"tmux",
"git",
"networkmanager",
"sudo",
"opendoas", // Replace sudo with doas as specified in product description
"firejail",
"apparmor",
"nftables", // Using nftables instead of ufw as requested
"hardened-malloc", // Hardened malloc by GrapheneOS
}
pacstrap := exec.Command("pacstrap", append([]string{"/mnt"}, packages...)...)
@@ -286,7 +320,8 @@ func (m InstallModel) configureSystem() error {
chroot([]string{"ln", "-sf", "/usr/share/zoneinfo/UTC", "/etc/localtime"})
chroot([]string{"hwclock", "--systohc"})
useraddCmd := fmt.Sprintf("useradd -m -G wheel -s /bin/bash %s", m.config.Username)
// Create user with zsh as default shell
useraddCmd := fmt.Sprintf("useradd -m -G wheel -s /bin/zsh %s", m.config.Username)
if _, err := chroot([]string{"sh", "-c", useraddCmd}); err != nil {
return fmt.Errorf("useradd failed: %w", err)
}
@@ -296,6 +331,7 @@ func (m InstallModel) configureSystem() error {
return fmt.Errorf("user password set failed: %w", err)
}
// Set root password
rootPasswd := m.config.RootPassword
if rootPasswd == "" {
rootPasswd = m.config.UserPassword
@@ -305,11 +341,157 @@ func (m InstallModel) configureSystem() error {
return fmt.Errorf("root password set failed: %w", err)
}
// Configure doas instead of sudo
doasConf := fmt.Sprintf("permit persist :wheel\npermit nopass root\n")
os.WriteFile("/mnt/etc/doas.conf", []byte(doasConf), 0600)
// Configure sudoers for compatibility (limited use)
sudoers := "%wheel ALL=(ALL:ALL) ALL\n"
os.WriteFile("/mnt/etc/sudoers.d/wheel", []byte(sudoers), 0440)
if _, err := chroot([]string{"systemctl", "enable", "NetworkManager"}); err != nil {
return fmt.Errorf("failed to enable NetworkManager: %w", err)
// Enable required services
services := []string{
"NetworkManager",
"ufw",
"apparmor",
}
for _, service := range services {
if _, err := chroot([]string{"systemctl", "enable", service}); err != nil {
return fmt.Errorf("failed to enable %s: %w", service, err)
}
}
// Apply system hardening
if err := m.applySystemHardening(); err != nil {
return fmt.Errorf("system hardening failed: %w", err)
}
// Configure default shell and applications
if err := m.configureDefaults(); err != nil {
return fmt.Errorf("default configuration failed: %w", err)
}
return nil
}
func (m InstallModel) applySystemHardening() error {
// Configure kernel parameters for hardening
sysctlConf := `# Miasma OS Security Hardening
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.unprivileged_bpf_disabled = 1
net.core.bpf_jit_harden = 2
kernel.yama.ptrace_scope = 2
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_echo_ignore_all = 1
`
if err := os.WriteFile("/mnt/etc/sysctl.d/99-hardening.conf", []byte(sysctlConf), 0644); err != nil {
return fmt.Errorf("failed to write sysctl config: %w", err)
}
// Configure nftables (replacing ufw)
if _, err := chroot([]string{"pacman", "-Sy", "--noconfirm", "nftables"}); err != nil {
return fmt.Errorf("failed to install nftables: %w", err)
}
// Set secure umask
profileAppend := "\n# Secure umask\numask 077\n"
f, err := os.OpenFile("/mnt/etc/profile", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("failed to open profile: %w", err)
}
defer f.Close()
if _, err := f.WriteString(profileAppend); err != nil {
return fmt.Errorf("failed to append to profile: %w", err)
}
// Disable core dumps
limitsAppend := "\n# Disable core dumps\n* hard core 0\n"
f2, err := os.OpenFile("/mnt/etc/security/limits.conf", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("failed to open limits.conf: %w", err)
}
defer f2.Close()
if _, err := f2.WriteString(limitsAppend); err != nil {
return fmt.Errorf("failed to append to limits.conf: %w", err)
}
return nil
}
func (m InstallModel) configureDefaults() error {
// Install and configure Ungoogled Chromium with Wayland support
chromiumPackages := []string{
"ungoogled-chromium",
"chromium-web-store", // For extension installation
}
for _, pkg := range chromiumPackages {
if _, err := chroot([]string{"pacman", "-Sy", "--noconfirm", pkg}); err != nil {
return fmt.Errorf("failed to install %s: %w", pkg, err)
}
}
// Configure default applications for the user
userHome := fmt.Sprintf("/home/%s", m.config.Username)
chromiumDir := fmt.Sprintf("/mnt%s/.config/chromium", userHome)
os.MkdirAll(chromiumDir, 0755)
if err := os.WriteFile(fmt.Sprintf("%s/Local State", chromiumDir), []byte("{}"), 0644); err != nil {
return fmt.Errorf("failed to create chromium config: %w", err)
}
// Set up LazyVim configuration for Neovim
lazyVimConfig := `return {
colorscheme = "kanagawa-dragon",
defaults = {
indent = 2,
tabstop = 2,
shiftwidth = 2,
},
}
`
lazyDir := fmt.Sprintf("/mnt%s/.config/nvim", userHome)
os.MkdirAll(lazyDir, 0755)
if err := os.WriteFile(fmt.Sprintf("%s/lazyvim.json", lazyDir), []byte(lazyVimConfig), 0644); err != nil {
return fmt.Errorf("failed to create lazyvim config: %w", err)
}
// Set up Zsh configuration with Kanagawa theme
zshrc := fmt.Sprintf(`# Miasma OS Zsh Configuration
export ZSH="/home/%s/.oh-my-zsh"
ZSH_THEME="kanagawa"
plugins=(git sudo extract)
source $ZSH/oh-my-zsh.sh
# Aliases
alias ls="ls --color=auto"
alias la="ls -la"
alias vi="nvim"
alias vim="nvim"
# Default applications
export EDITOR="nvim"
export TERMINAL="alacritty"
`, m.config.Username)
zshrcPath := fmt.Sprintf("/mnt%s/.zshrc", userHome)
if err := os.WriteFile(zshrcPath, []byte(zshrc), 0644); err != nil {
return fmt.Errorf("failed to create zshrc: %w", err)
}
// Set proper ownership for user files
chownCmd := fmt.Sprintf("chown -R %s:%s /home/%s", m.config.Username, m.config.Username, m.config.Username)
if _, err := chroot([]string{"sh", "-c", chownCmd}); err != nil {
return fmt.Errorf("failed to set user ownership: %w", err)
}
return nil
@@ -383,6 +565,7 @@ options %s
}
func (m InstallModel) installDesktop() error {
// Install Cosmic Desktop as the only supported desktop environment
cosmicPackages := []string{
"cosmic-session",
"cosmic-greeter",
@@ -392,6 +575,7 @@ func (m InstallModel) installDesktop() error {
"cosmic-store",
"cosmic-settings",
"xorg-xwayland",
"xwayland-satellite", // XWayland-Satellite for better X11 app isolation
}
for _, pkg := range cosmicPackages {
@@ -400,14 +584,33 @@ func (m InstallModel) installDesktop() error {
}
}
if _, err := chroot([]string{"systemctl", "enable", "cosmic-greeter"}); err != nil {
return fmt.Errorf("failed to enable cosmic-greeter: %w", err)
// Enable Cosmic services
services := []string{
"cosmic-greeter",
"NetworkManager",
}
for _, service := range services {
if _, err := chroot([]string{"systemctl", "enable", service}); err != nil {
return fmt.Errorf("failed to enable %s: %w", service, err)
}
}
return nil
}
func (m InstallModel) runPostInstallScripts() error {
// Copy overlay files if they exist
overlayDir := "./overlay"
if _, err := os.Stat(overlayDir); err == nil {
fmt.Println("Applying system overlays...")
cp := exec.Command("cp", "-r", overlayDir+"/.", "/mnt/")
if output, err := cp.CombinedOutput(); err != nil {
return fmt.Errorf("overlay copy failed: %w\nOutput: %s", err, output)
}
}
// Run post-install scripts
scriptsDir := "./scripts"
entries, err := os.ReadDir(scriptsDir)
if err != nil {
@@ -417,6 +620,11 @@ func (m InstallModel) runPostInstallScripts() error {
return err
}
// Sort scripts to ensure they run in order
sort.Slice(entries, func(i, j int) bool {
return entries[i].Name() < entries[j].Name()
})
for _, entry := range entries {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".sh") {
continue
@@ -428,13 +636,16 @@ func (m InstallModel) runPostInstallScripts() error {
return err
}
// Copy script to chroot environment
chrootScript := "/tmp/" + entry.Name()
os.WriteFile("/mnt"+chrootScript, scriptContent, 0755)
if output, err := chroot([]string{chrootScript}); err != nil {
// Run script in chroot environment
if output, err := chroot([]string{"sh", chrootScript}); err != nil {
return fmt.Errorf("script %s failed: %w\nOutput: %s", entry.Name(), err, output)
}
// Clean up script
os.Remove("/mnt" + chrootScript)
}