Skip to content

Commit 9a99eff

Browse files
committed
src: split lib into helpers and nixbuild
1 parent 202644f commit 9a99eff

2 files changed

Lines changed: 102 additions & 95 deletions

File tree

src/lib.go renamed to src/helpers.go

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ import (
88
"strings"
99
)
1010

11-
// model 'nix build --json' output.
12-
type BuildResult struct {
13-
Outputs map[string]string `json:"outputs"`
14-
}
15-
1611
// Deployment spec for a single job.
1712
type JobSpec struct {
1813
Output string `json:"output"` // flake output
@@ -21,74 +16,6 @@ type JobSpec struct {
2116
User string `json:"user"` // ssh user
2217
}
2318

24-
func buildClosure(spec JobSpec, drvPath string, builder string) (string, error) {
25-
var buildOut []byte
26-
var err error
27-
28-
// Build the closure locally or on the remote builder
29-
if builder != "localhost" {
30-
buildOut, err = runJSON("nix", "build", "--no-link", "--json", "--store", "ssh-ng://"+builder, drvPath+"^*")
31-
} else {
32-
buildOut, err = runJSON("nix", "build", "--no-link", "--json", drvPath+"^*")
33-
}
34-
if err != nil {
35-
return "", fmt.Errorf("failed to build %s on %s: %w", spec.Output, builder, err)
36-
}
37-
38-
// Parse the output path
39-
var results []BuildResult
40-
if err := json.Unmarshal(buildOut, &results); err != nil {
41-
return "", fmt.Errorf("invalid build JSON for %s: %w\nRaw: %s", spec.Output, err, string(buildOut))
42-
}
43-
if len(results) == 0 {
44-
return "", fmt.Errorf("build result for %s was empty", spec.Output)
45-
}
46-
out, ok := results[0].Outputs["out"]
47-
if !ok {
48-
return "", fmt.Errorf("missing 'out' key in build result for %s", spec.Output)
49-
}
50-
51-
// Step 5: Copy built closure back from builder to local (if needed)
52-
if builder != "localhost" {
53-
if _, err := run("nix", "copy", "--from", "ssh-ng://"+builder, out, "--no-check-sigs"); err != nil {
54-
return "", fmt.Errorf("could not copy from %s: %v", builder, err)
55-
}
56-
}
57-
58-
return out, nil
59-
}
60-
61-
func deployClosure(name string, spec JobSpec, outs map[string]string, op string) error {
62-
target := fmt.Sprintf("%s@%s", spec.User, spec.Hostname)
63-
path := outs[name]
64-
var cmds [][]string
65-
66-
switch spec.Type {
67-
case "darwin":
68-
switch op {
69-
case "switch", "test":
70-
cmds = append(cmds, []string{"ssh", target, "PATH=/run/current-system/sw/bin:$PATH", "sudo", "nix-env", "-p", "/nix/var/nix/profiles/system", "--set", path})
71-
fallthrough // we always want to activate
72-
case "activate":
73-
cmds = append(cmds, []string{"ssh", target, "PATH=/run/current-system/sw/bin:$PATH", "sudo", path + "/activate"})
74-
}
75-
case "nixos":
76-
cmds = append(cmds, []string{"ssh", target, "sudo", path + "/bin/switch-to-configuration", op})
77-
}
78-
79-
if _, err := run("nix", "copy", "--to", "ssh-ng://"+target, path, "--no-check-sigs"); err != nil {
80-
return fmt.Errorf("error copying to %s: %v", target, err)
81-
}
82-
83-
for _, cmd := range cmds {
84-
if _, err := run(cmd[0], cmd[1:]...); err != nil {
85-
return fmt.Errorf("failed to activate on %s: %v", target, err)
86-
}
87-
}
88-
89-
return nil
90-
}
91-
9219
func fatal(format string, args ...any) {
9320
fmt.Fprintf(os.Stderr, "[nynx] Error: "+format+"\n", args...)
9421
os.Exit(1)
@@ -98,28 +25,6 @@ func info(format string, args ...any) {
9825
fmt.Printf("[nynx] "+format+"\n", args...)
9926
}
10027

101-
func instantiateDrvPath(flake string, name string, builder string) (string, error) {
102-
expr := fmt.Sprintf("%s#nynxDeployments.%s.output", flake, name)
103-
drvExpr := expr + ".drvPath"
104-
105-
// Evaluate the .drv path locally
106-
data, err := runJSON("nix", "eval", "--raw", drvExpr)
107-
if err != nil {
108-
return "", fmt.Errorf("failed to evaluate drvPath for job '%s': %w", name, err)
109-
}
110-
111-
drvPath := strings.TrimSpace(string(data))
112-
113-
// Copy the .drv to the remote builder (if needed)
114-
if builder != "localhost" {
115-
if _, err := run("nix", "copy", "--to", "ssh-ng://"+builder, drvPath); err != nil {
116-
return "", fmt.Errorf("failed to copy .drv for job '%s' to %s: %w", name, builder, err)
117-
}
118-
}
119-
120-
return drvPath, nil
121-
}
122-
12328
func loadDeployments(cfg string) (map[string]JobSpec, error) {
12429
flakeReference := fmt.Sprintf("%s#nynxDeployments", cfg)
12530

src/nixbuild.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"strings"
7+
)
8+
9+
// model 'nix build --json' output.
10+
type BuildResult struct {
11+
Outputs map[string]string `json:"outputs"`
12+
}
13+
14+
func buildClosure(spec JobSpec, drvPath string, builder string) (string, error) {
15+
var buildOut []byte
16+
var err error
17+
18+
// Build the closure locally or on the remote builder
19+
if builder != "localhost" {
20+
buildOut, err = runJSON("nix", "build", "--no-link", "--json", "--store", "ssh-ng://"+builder, drvPath+"^*")
21+
} else {
22+
buildOut, err = runJSON("nix", "build", "--no-link", "--json", drvPath+"^*")
23+
}
24+
if err != nil {
25+
return "", fmt.Errorf("failed to build %s on %s: %w", spec.Output, builder, err)
26+
}
27+
28+
// Parse the output path
29+
var results []BuildResult
30+
if err := json.Unmarshal(buildOut, &results); err != nil {
31+
return "", fmt.Errorf("invalid build JSON for %s: %w\nRaw: %s", spec.Output, err, string(buildOut))
32+
}
33+
if len(results) == 0 {
34+
return "", fmt.Errorf("build result for %s was empty", spec.Output)
35+
}
36+
out, ok := results[0].Outputs["out"]
37+
if !ok {
38+
return "", fmt.Errorf("missing 'out' key in build result for %s", spec.Output)
39+
}
40+
41+
// Step 5: Copy built closure back from builder to local (if needed)
42+
if builder != "localhost" {
43+
if _, err := run("nix", "copy", "--from", "ssh-ng://"+builder, out, "--no-check-sigs"); err != nil {
44+
return "", fmt.Errorf("could not copy from %s: %v", builder, err)
45+
}
46+
}
47+
48+
return out, nil
49+
}
50+
51+
func deployClosure(name string, spec JobSpec, outs map[string]string, op string) error {
52+
target := fmt.Sprintf("%s@%s", spec.User, spec.Hostname)
53+
path := outs[name]
54+
var cmds [][]string
55+
56+
switch spec.Type {
57+
case "darwin":
58+
switch op {
59+
case "switch", "test":
60+
cmds = append(cmds, []string{"ssh", target, "PATH=/run/current-system/sw/bin:$PATH", "sudo", "nix-env", "-p", "/nix/var/nix/profiles/system", "--set", path})
61+
fallthrough // we always want to activate
62+
case "activate":
63+
cmds = append(cmds, []string{"ssh", target, "PATH=/run/current-system/sw/bin:$PATH", "sudo", path + "/activate"})
64+
}
65+
case "nixos":
66+
cmds = append(cmds, []string{"ssh", target, "sudo", path + "/bin/switch-to-configuration", op})
67+
}
68+
69+
if _, err := run("nix", "copy", "--to", "ssh-ng://"+target, path, "--no-check-sigs"); err != nil {
70+
return fmt.Errorf("error copying to %s: %v", target, err)
71+
}
72+
73+
for _, cmd := range cmds {
74+
if _, err := run(cmd[0], cmd[1:]...); err != nil {
75+
return fmt.Errorf("failed to activate on %s: %v", target, err)
76+
}
77+
}
78+
79+
return nil
80+
}
81+
82+
func instantiateDrvPath(flake string, name string, builder string) (string, error) {
83+
expr := fmt.Sprintf("%s#nynxDeployments.%s.output", flake, name)
84+
drvExpr := expr + ".drvPath"
85+
86+
// Evaluate the .drv path locally
87+
data, err := runJSON("nix", "eval", "--raw", drvExpr)
88+
if err != nil {
89+
return "", fmt.Errorf("failed to evaluate drvPath for job '%s': %w", name, err)
90+
}
91+
92+
drvPath := strings.TrimSpace(string(data))
93+
94+
// Copy the .drv to the remote builder (if needed)
95+
if builder != "localhost" {
96+
if _, err := run("nix", "copy", "--to", "ssh-ng://"+builder, drvPath); err != nil {
97+
return "", fmt.Errorf("failed to copy .drv for job '%s' to %s: %w", name, builder, err)
98+
}
99+
}
100+
101+
return drvPath, nil
102+
}

0 commit comments

Comments
 (0)