Deployment and lifecycle management for Nix
0
fork

Configure Feed

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

client(services): build and link a profile

+76 -12
+31 -1
cmd/client/commands/main.go
··· 6 6 "log/slog" 7 7 "os" 8 8 "os/exec" 9 + "strings" 9 10 ) 10 11 11 12 func SimpleRun(cmd *exec.Cmd) error { ··· 41 42 42 43 err = cmd.Wait() 43 44 if err != nil { 44 - return fmt.Errorf("failed to download seed: %v", err) 45 + return fmt.Errorf("failed to run command: %v", err) 45 46 } 46 47 47 48 if ioErr != nil { ··· 50 51 51 52 return nil 52 53 } 54 + 55 + func Run(cmd *exec.Cmd) (string, error) { 56 + // Set up the pipes for stderr 57 + stderr, err := cmd.StderrPipe() 58 + if err != nil { 59 + return "", fmt.Errorf("error creating stderr: %v", err) 60 + } 61 + 62 + slog.Debug("Running command", "cmd", cmd.String()) 63 + 64 + var ioErr error 65 + go func() { 66 + _, ioErr = io.Copy(os.Stderr, stderr) // Redirect stderr to terminal's stderr 67 + if ioErr != nil { 68 + slog.Error("failed to configure stderr") 69 + } 70 + }() 71 + 72 + stdout, err := cmd.Output() 73 + if err != nil { 74 + return "", fmt.Errorf("failed to run command: %v", err) 75 + } 76 + 77 + if ioErr != nil { 78 + return "", fmt.Errorf("error copying output: %v", ioErr) 79 + } 80 + 81 + return strings.TrimSpace(string(stdout)), nil 82 + }
+7 -1
cmd/client/main.go
··· 497 497 paths = append(paths, *storePath) 498 498 } 499 499 500 - err = buildServicesEnv(paths) 500 + servicesPath, err := buildServicesEnv(paths) 501 501 if err != nil { 502 502 slog.Error("Failed to build services environment", "error", err) 503 + os.Exit(1) 504 + } 505 + 506 + err = activateServices(servicesPath) 507 + if err != nil { 508 + slog.Error("Failed to activate services environment", "error", err) 503 509 os.Exit(1) 504 510 } 505 511 }
+11 -2
cmd/client/seed.go
··· 24 24 } 25 25 26 26 case client.Nixos: 27 - profileCmd := exec.Command("nix-env", "--set", "--profile", "/nix/var/nix/profiles/system", storePath) 28 - err = commands.SimpleRun(profileCmd) 27 + err = setProfile("/nix/var/nix/profiles/system", storePath) 29 28 if err != nil { 30 29 return fmt.Errorf("failed to set nixos profile: %v", err) 31 30 } ··· 122 121 } else { 123 122 slog.Warn("Reboot needed, but skipping without --yes") 124 123 } 124 + } 125 + 126 + return nil 127 + } 128 + 129 + func setProfile(profile, storePath string) error { 130 + profileCmd := exec.Command("nix-env", "--set", "--profile", profile, storePath) 131 + err := commands.SimpleRun(profileCmd) 132 + if err != nil { 133 + return fmt.Errorf("failed to set profile: %v", err) 125 134 } 126 135 127 136 return nil
+27 -8
cmd/client/services.go
··· 19 19 } 20 20 21 21 // https://github.com/NixOS/nixpkgs/archive/refs/heads/master.zip 22 - func buildServicesEnv(paths []client.StorePath) error { 22 + func buildServicesEnv(paths []client.StorePath) (string, error) { 23 23 slog.Debug("Building services environment", "nixpkgs", nixpkgsref) 24 24 25 25 envTemplate := `{ ··· 47 47 48 48 envFileNix, err := os.CreateTemp("", "services-env") 49 49 if err != nil { 50 - return fmt.Errorf("failed to create tempfile: %v", err) 50 + return "", fmt.Errorf("failed to create tempfile: %v", err) 51 51 } 52 52 defer os.Remove(envFileNix.Name()) 53 53 54 54 templateParser, err := template.New("services-env").Parse(envTemplate) 55 55 if err != nil { 56 - return fmt.Errorf("failed to parse template: %v", err) 56 + return "", fmt.Errorf("failed to parse template: %v", err) 57 57 } 58 58 59 59 err = templateParser.Execute(envFileNix, &EnvTemplate{Paths: paths, Nixpkgsref: nixpkgsref}) 60 60 if err != nil { 61 - return fmt.Errorf("failed to parse template: %v", err) 61 + return "", fmt.Errorf("failed to parse template: %v", err) 62 62 } 63 63 64 - cmd := exec.Command("nix-build", envFileNix.Name()) 65 - err = commands.SimpleRun(cmd) 64 + cmd := exec.Command("nix-build", "--no-out-link", envFileNix.Name()) 65 + stdout, err := commands.Run(cmd) 66 + if err != nil { 67 + return "", fmt.Errorf("failed to build services env file: %v", err) 68 + } 69 + 70 + slog.Debug("Successfully built services environment", "nixpkgs", nixpkgsref, "path", stdout) 71 + 72 + return stdout, nil 73 + } 74 + 75 + func activateServices(storePath string) error { 76 + profileDir := "/nix/var/nix/profiles/sower" 77 + _, err := os.Stat(profileDir) 66 78 if err != nil { 67 - return fmt.Errorf("failed to build services env file: %v", err) 79 + slog.Debug("Creating profile directory", "dir", profileDir) 80 + err = os.Mkdir(profileDir, 0x0755) 81 + if err != nil { 82 + return fmt.Errorf("failed to create sower profile directory: %v", err) 83 + } 68 84 } 69 85 70 - slog.Debug("Successfully built services environment", "nixpkgs", nixpkgsref) 86 + err = setProfile(fmt.Sprintf("%s/services", profileDir), storePath) 87 + if err != nil { 88 + return fmt.Errorf("failed to set services profile: %v", err) 89 + } 71 90 72 91 return nil 73 92 }