package config import ( "encoding/json" "fmt" "os" ) type InstallConfig struct { Disk string EnableLUKS bool Hostname string Username string RootPassword string UserPassword string Timezone string Locale string } type ArchInstallConfig struct { Version string `json:"version"` Script string `json:"script"` ArchinstallLanguage string `json:"archinstall-language"` Bootloader string `json:"bootloader"` Kernels []string `json:"kernels"` Hostname string `json:"hostname"` Timezone string `json:"timezone"` LocaleConfig LocaleConfig `json:"locale_config"` DiskConfig DiskConfig `json:"disk_config"` ProfileConfig ProfileConfig `json:"profile_config"` AuthConfig AuthConfig `json:"auth_config"` Packages []string `json:"packages"` Services []string `json:"services"` } type LocaleConfig struct { KbLayout string `json:"kb_layout"` SysEnc string `json:"sys_enc"` SysLang string `json:"sys_lang"` } type DiskConfig struct { ConfigType string `json:"config_type"` DeviceModifications []DeviceModification `json:"device_modifications"` } type DeviceModification struct { Device string `json:"device"` Partitions []Partition `json:"partitions"` Wipe bool `json:"wipe"` } type Partition struct { Btrfs []interface{} `json:"btrfs"` Flags []string `json:"flags,omitempty"` FsType string `json:"fs_type"` Size Size `json:"size"` MountOptions []string `json:"mount_options"` Mountpoint string `json:"mountpoint,omitempty"` ObjId string `json:"obj_id"` Start Size `json:"start"` Status string `json:"status"` Type string `json:"type"` } type Size struct { SectorSize *int `json:"sector_size"` Unit string `json:"unit"` Value float64 `json:"value"` } type ProfileConfig struct { Profile Profile `json:"profile"` } type Profile struct { Main string `json:"main"` Details []string `json:"details,omitempty"` } type AuthConfig struct { Users []User `json:"users"` } type User struct { Username string `json:"username"` Password string `json:"password"` Sudo bool `json:"sudo"` } func (c *InstallConfig) ToArchInstall() *ArchInstallConfig { // Create partitions for EFI and root partitions := []Partition{ { Btrfs: []interface{}{}, Flags: []string{"boot"}, FsType: "fat32", Size: Size{SectorSize: nil, Unit: "MiB", Value: 512}, MountOptions: []string{}, Mountpoint: "/boot", ObjId: "efi-partition-id", Start: Size{SectorSize: nil, Unit: "MiB", Value: 1}, Status: "create", Type: "primary", }, { Btrfs: []interface{}{}, Flags: []string{}, FsType: "btrfs", Size: Size{SectorSize: nil, Unit: "Percent", Value: 100}, MountOptions: []string{}, Mountpoint: "/", ObjId: "root-partition-id", Start: Size{SectorSize: nil, Unit: "MiB", Value: 513}, Status: "create", Type: "primary", }, } // Miasma OS specific packages based on ProductDescription.md miasmaPackages := []string{ // Base system "base", "base-devel", "linux-hardened", "linux-firmware", "btrfs-progs", // Text editors "neovim", // Shell "zsh", // Terminal "alacritty", // System tools "tmux", "git", "networkmanager", // Security tools "opendoas", "firejail", "apparmor", "nftables", // Using nftables instead of ufw as requested // Browsers "chromium", // Using regular chromium instead of ungoogled-chromium as requested // Wayland support "xwayland-satellite", // Cosmic Desktop "cosmic-session", "cosmic-greeter", "cosmic-files", "cosmic-edit", "cosmic-term", "cosmic-store", "cosmic-settings", } ac := &ArchInstallConfig{ Version: "2.8.6", // Match archinstall version Script: "guided", ArchinstallLanguage: "English", Bootloader: "Systemd-boot", Kernels: []string{"linux-hardened"}, Hostname: c.Hostname, Timezone: c.Timezone, LocaleConfig: LocaleConfig{ KbLayout: "us", SysEnc: "UTF-8", SysLang: "en_US", }, DiskConfig: DiskConfig{ ConfigType: "default_layout", DeviceModifications: []DeviceModification{ { Device: c.Disk, Partitions: partitions, Wipe: true, }, }, }, ProfileConfig: ProfileConfig{ Profile: Profile{ Main: "Desktop", Details: []string{"Cosmic"}, }, }, AuthConfig: AuthConfig{ Users: []User{ { Username: c.Username, Password: c.UserPassword, Sudo: true, }, }, }, Packages: miasmaPackages, Services: []string{ "NetworkManager", "nftables", "apparmor", "cosmic-greeter", }, } return ac } func (c *InstallConfig) SaveArchInstallConfig(filepath string) error { archConfig := c.ToArchInstall() data, err := json.MarshalIndent(archConfig, "", " ") if err != nil { return fmt.Errorf("failed to marshal config: %w", err) } return os.WriteFile(filepath, data, 0o644) } func (c *InstallConfig) SaveUserCredentials(filepath string) error { // For credentials, we only save the sensitive information creds := map[string]interface{}{} if c.EnableLUKS && c.RootPassword != "" { creds["encryption_password"] = c.RootPassword } creds["users"] = []map[string]string{ { "username": c.Username, "password": c.UserPassword, }, } if c.RootPassword != "" { creds["root_enc_password"] = c.RootPassword } data, err := json.MarshalIndent(creds, "", " ") if err != nil { return fmt.Errorf("failed to marshal credentials: %w", err) } return os.WriteFile(filepath, data, 0o600) }