this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(nixos): build the installer

Khue Doan 25ed1cc0 73188ee8

+97 -2
+1 -1
Makefile
··· 8 8 9 9 dev: 10 10 nix run . -- \ 11 - --installer ./examples#installer \ 11 + --installer ./examples#nixosConfigurations.installer \ 12 12 --flake ./examples \ 13 13 --hosts ./examples/hosts.json \ 14 14 --ssh-key ~/.ssh/id_ed25519 \
+13 -1
cmd/nixie/main.go
··· 1 1 package main 2 2 3 3 import ( 4 + "context" 4 5 "flag" 5 6 6 7 "code.khuedoan.com/nixie/internal/hosts" 8 + "code.khuedoan.com/nixie/internal/nixos" 7 9 8 10 "github.com/charmbracelet/log" 9 11 ) ··· 24 26 flag.StringVar(&flags.Address, "address", "0.0.0.0", "Address to listen on") 25 27 flag.StringVar(&flags.Flake, "flake", "", "NixOS configuration flake (for example, .)") 26 28 flag.StringVar(&flags.HostsFile, "hosts", "", "Path to hosts.json file (for example, ./hosts.json)") 27 - flag.StringVar(&flags.Installer, "installer", "", "NixOS installer flake output (for example, .#installer)") 29 + flag.StringVar(&flags.Installer, "installer", "", "NixOS installer flake output (for example, .#nixosConfigurations.installer)") 28 30 flag.StringVar(&flags.SSHKey, "ssh-key", "", "Path to the SSH private key (for example, ~/.ssh/id_ed25519)") 29 31 30 32 flag.Parse() ··· 52 54 log.Fatal("failed to load hosts config", "error", err) 53 55 } 54 56 log.Debug("parsed hosts config", "hosts", hostsConfig) 57 + 58 + ctx, cancel := context.WithCancel(context.Background()) 59 + defer cancel() 60 + 61 + log.Info("building installer", "installer", flags.Installer) 62 + installerComponents, err := nixos.BuildInstaller(ctx, flags.Installer, flags.Debug) 63 + if err != nil { 64 + log.Fatal("failed to build the installer", "error", err) 65 + } 66 + log.Debug("installer components", "kernel", installerComponents.Kernel, "initrd", installerComponents.Initrd, "init", installerComponents.Init) 55 67 }
+83
internal/nixos/installer.go
··· 1 + package nixos 2 + 3 + import ( 4 + "bytes" 5 + "context" 6 + "fmt" 7 + "io" 8 + "os" 9 + "os/exec" 10 + "path/filepath" 11 + "strings" 12 + ) 13 + 14 + type InstallerComponents struct { 15 + Kernel string 16 + Initrd string 17 + Init string 18 + } 19 + 20 + func nixBuild(ctx context.Context, flakeOutput string, debug bool) (string, error) { 21 + cmd := exec.CommandContext(ctx, "nix", "build", "--no-link", "--print-out-paths", flakeOutput) 22 + 23 + var stdout bytes.Buffer 24 + stdoutWriters := []io.Writer{&stdout} 25 + if debug { 26 + stdoutWriters = append(stdoutWriters, os.Stdout) 27 + } 28 + 29 + cmd.Stdout = io.MultiWriter(stdoutWriters...) 30 + cmd.Stderr = os.Stderr 31 + 32 + if err := cmd.Run(); err != nil { 33 + return "", fmt.Errorf("nix build failed for %q: %w", flakeOutput, err) 34 + } 35 + 36 + outPath := strings.TrimSpace(stdout.String()) 37 + return outPath, nil 38 + } 39 + 40 + func BuildInstaller(ctx context.Context, flakeRef string, debug bool) (InstallerComponents, error) { 41 + kernelOut, err := nixBuild( 42 + ctx, 43 + flakeRef+".config.system.build.kernel", 44 + debug, 45 + ) 46 + if err != nil { 47 + return InstallerComponents{}, fmt.Errorf("failed to build kernel: %w", err) 48 + } 49 + 50 + initrdOut, err := nixBuild( 51 + ctx, 52 + flakeRef+".config.system.build.netbootRamdisk", 53 + debug, 54 + ) 55 + 56 + if err != nil { 57 + return InstallerComponents{}, fmt.Errorf("failed to build initrd: %w", err) 58 + } 59 + toplevelOut, err := nixBuild( 60 + ctx, 61 + flakeRef+".config.system.build.toplevel", 62 + debug, 63 + ) 64 + 65 + if err != nil { 66 + return InstallerComponents{}, fmt.Errorf("failed to build toplevel: %w", err) 67 + } 68 + 69 + components := InstallerComponents{ 70 + Kernel: filepath.Join(kernelOut, "bzImage"), 71 + Initrd: filepath.Join(initrdOut, "initrd"), 72 + Init: filepath.Join(toplevelOut, "init"), 73 + } 74 + 75 + // Be defensive and check if the files exist 76 + for _, p := range []string{components.Kernel, components.Initrd, components.Init} { 77 + if _, err := os.Stat(p); err != nil { 78 + return InstallerComponents{}, fmt.Errorf("missing installer file: %s", p) 79 + } 80 + } 81 + 82 + return components, nil 83 + }