Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions internal/executor/nix_flake.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ type Derivation struct {
Outputs Output `json:"outputs"`
}

type DerivationOutput struct {
Version int `json:"version"`
Derivations map[string]Derivation `json:"derivations"`
}

type Show struct {
NixosConfigurations map[string]struct{} `json:"nixosConfigurations"`
DarwinConfigurations map[string]struct{} `json:"darwinConfigurations"`
Expand Down
46 changes: 28 additions & 18 deletions internal/executor/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,26 +115,19 @@ func showDerivationWithNix(ctx context.Context, directory, systemAttr string) (d
return
}

func showDerivationWithFlake(ctx context.Context, flakeUrl, hostname, systemAttr string) (drvPath string, outPath string, err error) {
installable := fmt.Sprintf("%s#%s.\"%s\".config.system.build.toplevel", flakeUrl, systemAttr, hostname)
args := []string{
"derivation",
"show",
installable,
"-L",
"--show-trace",
}
var stdout bytes.Buffer
err = runNixFlakeCommand(ctx, args, &stdout, os.Stderr)
if err != nil {
return
}

func parseDerivationWithFlake(buf bytes.Buffer) (drvPath string, outPath string, err error) {
var output map[string]Derivation
err = json.Unmarshal(stdout.Bytes(), &output)
if err != nil {
return
var wrapper DerivationOutput
if err := json.Unmarshal(buf.Bytes(), &wrapper); err == nil && wrapper.Derivations != nil {
output = wrapper.Derivations
} else {
// fallback to legacy format (Nix < 2.33)
// TODO: we should use the derivation format version
if err := json.Unmarshal(buf.Bytes(), &output); err != nil {
return "", "", fmt.Errorf("failed to unmarshal JSON in both formats: %w", err)
}
}

keys := make([]string, 0, len(output))
for key := range output {
keys = append(keys, key)
Expand All @@ -156,6 +149,23 @@ func showDerivationWithFlake(ctx context.Context, flakeUrl, hostname, systemAttr
return
}

func showDerivationWithFlake(ctx context.Context, flakeUrl, hostname, systemAttr string) (drvPath string, outPath string, err error) {
installable := fmt.Sprintf("%s#%s.\"%s\".config.system.build.toplevel", flakeUrl, systemAttr, hostname)
args := []string{
"derivation",
"show",
installable,
"-L",
"--show-trace",
}
var stdout bytes.Buffer
err = runNixFlakeCommand(ctx, args, &stdout, os.Stderr)
if err != nil {
return
}
return parseDerivationWithFlake(stdout)
}

func buildWithFlake(ctx context.Context, drvPath string) (err error) {
args := []string{
"build",
Expand Down
71 changes: 71 additions & 0 deletions internal/executor/utils_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,83 @@
package executor

import (
"bytes"
"context"
"testing"

"github.com/stretchr/testify/assert"
)

const drv_nix_2_33 string = `{
"derivations": {
"6bidfy5ckghrp1mra47i1b9j5whld606-nixos-system-bucatini-26.05.20260121.88d3861.drv": {
"args": [],
"builder": "/nix/store/lw117lsr8d585xs63kx5k233impyrq7q-bash-5.3p3/bin/bash",
"env": {},
"inputs": {
"drvs": {
"37j2jc708n38xfvhx1wffm0pbrixnnr3-initrd-linux-hardened-6.12.66.drv": {
"dynamicOutputs": {},
"outputs": ["out"]
}
},
"srcs": [
"l622p70vy8k5sh7y5wizi5f2mic6ynpg-source-stdenv.sh"
]
},
"name": "nixos-system-bucatini-26.05.20260121.88d3861",
"outputs": {
"out": {
"path": "ysdrf7krk4q64sgd1q7z3b42l3plpgw8-nixos-system-bucatini-26.05.20260121.88d3861"
}
},
"system": "x86_64-linux",
"version": 4
}
},
"version": 4
}
`

const drv_nix_2_31 string = `{
"/nix/store/plbm2vvs61q9868g8wh3m191dslvpgwi-nixos-system-tilia-25.11.20260122.078d69f.drv": {
"args": [],
"builder": "/nix/store/j8645yndikbrvn292zgvyv64xrrmwdcb-bash-5.3p3/bin/bash",
"env": {},
"inputDrvs": {
"/nix/store/05hi8vkdi5d9q4rdgpnnimp3x5s3ja50-make-shell-wrapper-hook.drv": {
"dynamicOutputs": {},
"outputs": [
"out"
]
}
},
"inputSrcs": [],
"name": "nixos-system-tilia-25.11.20260122.078d69f",
"outputs": {
"out": {
"path": "/nix/store/wc14lijvyzacwf6by6dfj4hq1qx8s745-nixos-system-tilia-25.11.20260122.078d69f"
}
},
"system": "x86_64-linux"
}
}
`

func TestParseDerivationWithFlake(t *testing.T) {
var buf = bytes.NewBufferString(drv_nix_2_33)
drvPath, outPath, err := parseDerivationWithFlake(*buf)
assert.Equal(t, "/nix/store/6bidfy5ckghrp1mra47i1b9j5whld606-nixos-system-bucatini-26.05.20260121.88d3861.drv", drvPath)
assert.Equal(t, "/nix/store/ysdrf7krk4q64sgd1q7z3b42l3plpgw8-nixos-system-bucatini-26.05.20260121.88d3861", outPath)
assert.Nil(t, err)

buf = bytes.NewBufferString(drv_nix_2_31)
drvPath, outPath, err = parseDerivationWithFlake(*buf)
assert.Equal(t, "/nix/store/plbm2vvs61q9868g8wh3m191dslvpgwi-nixos-system-tilia-25.11.20260122.078d69f.drv", drvPath)
assert.Equal(t, "/nix/store/wc14lijvyzacwf6by6dfj4hq1qx8s745-nixos-system-tilia-25.11.20260122.078d69f", outPath)
assert.Nil(t, err)
}

func TestGetExpectedMachineId(t *testing.T) {
tests := []struct {
name string
Expand Down
Loading