updated the installer so that it should actually work
Some checks failed
Build / build (push) Failing after 5m23s
Some checks failed
Build / build (push) Failing after 5m23s
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user