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:
252
config/config.go
252
config/config.go
@@ -1,5 +1,11 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type InstallConfig struct {
|
||||
Disk string
|
||||
EnableLUKS bool
|
||||
@@ -12,21 +18,68 @@ type InstallConfig struct {
|
||||
}
|
||||
|
||||
type ArchInstallConfig struct {
|
||||
Bootloader string `json:"bootloader"`
|
||||
Kernels []string `json:"kernels"`
|
||||
Filesystem string `json:"filesystem"`
|
||||
Disk string `json:"disk"`
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
Hostname string `json:"hostname"`
|
||||
Timezone string `json:"timezone"`
|
||||
Locale string `json:"locale"`
|
||||
Desktop string `json:"desktop"`
|
||||
Users []User `json:"users"`
|
||||
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 Encryption struct {
|
||||
Type string `json:"type"`
|
||||
Password string `json:"password"`
|
||||
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 {
|
||||
@@ -36,30 +89,163 @@ type User struct {
|
||||
}
|
||||
|
||||
func (c *InstallConfig) ToArchInstall() *ArchInstallConfig {
|
||||
ac := &ArchInstallConfig{
|
||||
Bootloader: "systemd-boot",
|
||||
Kernels: []string{"linux-hardened"},
|
||||
Filesystem: "btrfs",
|
||||
Disk: c.Disk,
|
||||
Hostname: c.Hostname,
|
||||
Timezone: c.Timezone,
|
||||
Locale: c.Locale,
|
||||
Desktop: "cosmic",
|
||||
Users: []User{
|
||||
{
|
||||
Username: c.Username,
|
||||
Password: c.UserPassword,
|
||||
Sudo: true,
|
||||
},
|
||||
// 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",
|
||||
},
|
||||
}
|
||||
|
||||
if c.EnableLUKS {
|
||||
ac.Encryption = &Encryption{
|
||||
Type: "luks2",
|
||||
Password: c.RootPassword,
|
||||
}
|
||||
// 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
|
||||
"hardened-malloc",
|
||||
|
||||
// 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, 0644)
|
||||
}
|
||||
|
||||
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, 0600)
|
||||
}
|
||||
|
||||
145
config/config_test.go
Normal file
145
config/config_test.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestArchInstallConfigGeneration(t *testing.T) {
|
||||
config := &InstallConfig{
|
||||
Disk: "/dev/sda",
|
||||
EnableLUKS: true,
|
||||
Hostname: "miasma-test",
|
||||
Username: "testuser",
|
||||
RootPassword: "rootpass",
|
||||
UserPassword: "userpass",
|
||||
Timezone: "UTC",
|
||||
Locale: "en_US.UTF-8",
|
||||
}
|
||||
|
||||
archConfig := config.ToArchInstall()
|
||||
|
||||
// Test that the config has the expected structure
|
||||
if archConfig.Version == "" {
|
||||
t.Error("Version should not be empty")
|
||||
}
|
||||
|
||||
if archConfig.Bootloader != "Systemd-boot" {
|
||||
t.Errorf("Expected bootloader to be 'Systemd-boot', got '%s'", archConfig.Bootloader)
|
||||
}
|
||||
|
||||
if len(archConfig.Kernels) != 1 || archConfig.Kernels[0] != "linux-hardened" {
|
||||
t.Errorf("Expected kernels to contain 'linux-hardened', got %v", archConfig.Kernels)
|
||||
}
|
||||
|
||||
if archConfig.Hostname != "miasma-test" {
|
||||
t.Errorf("Expected hostname 'miasma-test', got '%s'", archConfig.Hostname)
|
||||
}
|
||||
|
||||
// Test disk configuration
|
||||
if len(archConfig.DiskConfig.DeviceModifications) != 1 {
|
||||
t.Errorf("Expected 1 device modification, got %d", len(archConfig.DiskConfig.DeviceModifications))
|
||||
}
|
||||
|
||||
deviceMod := archConfig.DiskConfig.DeviceModifications[0]
|
||||
if deviceMod.Device != "/dev/sda" {
|
||||
t.Errorf("Expected device '/dev/sda', got '%s'", deviceMod.Device)
|
||||
}
|
||||
|
||||
if len(deviceMod.Partitions) != 2 {
|
||||
t.Errorf("Expected 2 partitions, got %d", len(deviceMod.Partitions))
|
||||
}
|
||||
|
||||
// Test profile configuration
|
||||
if archConfig.ProfileConfig.Profile.Main != "Desktop" {
|
||||
t.Errorf("Expected profile main 'Desktop', got '%s'", archConfig.ProfileConfig.Profile.Main)
|
||||
}
|
||||
|
||||
// Test user configuration
|
||||
if len(archConfig.AuthConfig.Users) != 1 {
|
||||
t.Errorf("Expected 1 user, got %d", len(archConfig.AuthConfig.Users))
|
||||
}
|
||||
|
||||
user := archConfig.AuthConfig.Users[0]
|
||||
if user.Username != "testuser" {
|
||||
t.Errorf("Expected username 'testuser', got '%s'", user.Username)
|
||||
}
|
||||
|
||||
// Test package list
|
||||
expectedPackages := []string{
|
||||
"base", "base-devel", "linux-hardened", "linux-firmware", "btrfs-progs",
|
||||
"neovim", "zsh", "alacritty", "tmux", "git", "opendoas",
|
||||
"firejail", "apparmor", "nftables", "hardened-malloc",
|
||||
"chromium", "xwayland-satellite",
|
||||
"cosmic-session", "cosmic-greeter", "cosmic-files",
|
||||
"cosmic-edit", "cosmic-term", "cosmic-store", "cosmic-settings",
|
||||
}
|
||||
|
||||
for _, pkg := range expectedPackages {
|
||||
found := false
|
||||
for _, installedPkg := range archConfig.Packages {
|
||||
if installedPkg == pkg {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected package '%s' in package list", pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaveConfigurationFiles(t *testing.T) {
|
||||
config := &InstallConfig{
|
||||
Disk: "/dev/sda",
|
||||
EnableLUKS: false,
|
||||
Hostname: "miasma-test",
|
||||
Username: "testuser",
|
||||
RootPassword: "rootpass",
|
||||
UserPassword: "userpass",
|
||||
Timezone: "UTC",
|
||||
Locale: "en_US.UTF-8",
|
||||
}
|
||||
|
||||
// Test saving configuration
|
||||
err := config.SaveArchInstallConfig("/tmp/test_user_config.json")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to save user configuration: %v", err)
|
||||
}
|
||||
|
||||
// Test saving credentials
|
||||
err = config.SaveUserCredentials("/tmp/test_user_creds.json")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to save user credentials: %v", err)
|
||||
}
|
||||
|
||||
// Verify the files were created
|
||||
if _, err := os.Stat("/tmp/test_user_config.json"); os.IsNotExist(err) {
|
||||
t.Error("User configuration file was not created")
|
||||
}
|
||||
|
||||
if _, err := os.Stat("/tmp/test_user_creds.json"); os.IsNotExist(err) {
|
||||
t.Error("User credentials file was not created")
|
||||
}
|
||||
|
||||
// Verify the configuration file content
|
||||
data, err := os.ReadFile("/tmp/test_user_config.json")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read configuration file: %v", err)
|
||||
}
|
||||
|
||||
var parsedConfig ArchInstallConfig
|
||||
err = json.Unmarshal(data, &parsedConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse configuration file: %v", err)
|
||||
}
|
||||
|
||||
if parsedConfig.Hostname != "miasma-test" {
|
||||
t.Errorf("Expected hostname 'miasma-test', got '%s'", parsedConfig.Hostname)
|
||||
}
|
||||
|
||||
// Clean up test files
|
||||
os.Remove("/tmp/test_user_config.json")
|
||||
os.Remove("/tmp/test_user_creds.json")
|
||||
}
|
||||
Reference in New Issue
Block a user