mirror of
https://github.com/daylinmorgan/oizys.git
synced 2025-02-23 03:45:50 -06:00
nix-eval-jobs!
this reduces the number of things to do and relies heavily on nix-eval-jobs built by `lix` which now I realize I'll need to have an existing `nix-eval-jobs`
This commit is contained in:
parent
47ee52fcb5
commit
8771c2d910
3 changed files with 124 additions and 88 deletions
|
@ -89,6 +89,17 @@ let
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
formatter = forAllSystems (pkgs: (evalTreeFmt pkgs).config.build.wrapper);
|
formatter = forAllSystems (pkgs: (evalTreeFmt pkgs).config.build.wrapper);
|
||||||
|
systemPaths =
|
||||||
|
(readDir ../hosts)
|
||||||
|
|> mapAttrs (
|
||||||
|
name: _:
|
||||||
|
self.nixosConfigurations.othalan.config.environment.systemPackages
|
||||||
|
|> map (pkg: {
|
||||||
|
name = pkg.name;
|
||||||
|
value = pkg;
|
||||||
|
})
|
||||||
|
|> listToAttrs
|
||||||
|
);
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -144,7 +144,7 @@ hwylCli:
|
||||||
if minimal and system:
|
if minimal and system:
|
||||||
echo "--minimal and --system are mutually exclusive"
|
echo "--minimal and --system are mutually exclusive"
|
||||||
elif minimal:
|
elif minimal:
|
||||||
echo missingDerivations().fmtDrvsForNix()
|
echo missingDrvNixEvalJobs().fmtDrvsForNix()
|
||||||
else:
|
else:
|
||||||
echo nixosAttrs(
|
echo nixosAttrs(
|
||||||
if system: "path"
|
if system: "path"
|
||||||
|
|
|
@ -13,6 +13,28 @@ type
|
||||||
`extra-substituters`: seq[string]
|
`extra-substituters`: seq[string]
|
||||||
`extra-trusted-public-keys`: seq[string]
|
`extra-trusted-public-keys`: seq[string]
|
||||||
|
|
||||||
|
NixosRebuildSubcmd* = enum
|
||||||
|
switch, boot, test, build, `dry-build`,`dry-activate`, `edit`,
|
||||||
|
repl, `build-vm`, `build-vm-with-bootloader`, `list-generations`
|
||||||
|
|
||||||
|
# should I just convert these to NixDerivation?
|
||||||
|
NixEvalOutput = object
|
||||||
|
name: string
|
||||||
|
drvPath: string
|
||||||
|
isCached: bool
|
||||||
|
outputs: Table[string, string]
|
||||||
|
|
||||||
|
DerivationOutput = object
|
||||||
|
path*: string
|
||||||
|
# hashAlgo: string
|
||||||
|
# hash: string
|
||||||
|
NixDerivation = object
|
||||||
|
inputDrvs*: Table[string, JsonNode]
|
||||||
|
name*: string
|
||||||
|
outputs*: Table[string, DerivationOutput]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: replace with nim string defines?
|
# TODO: replace with nim string defines?
|
||||||
func makeSubFlags(): seq[string] =
|
func makeSubFlags(): seq[string] =
|
||||||
let subs = slurp("substituters.json").fromJson(Substituters)
|
let subs = slurp("substituters.json").fromJson(Substituters)
|
||||||
|
@ -46,11 +68,6 @@ proc nixosAttrs*(
|
||||||
for host in getHosts():
|
for host in getHosts():
|
||||||
result.add nixosAttr(host, attr)
|
result.add nixosAttr(host, attr)
|
||||||
|
|
||||||
type
|
|
||||||
NixosRebuildSubcmd* = enum
|
|
||||||
switch, boot, test, build, `dry-build`,`dry-activate`, `edit`,
|
|
||||||
repl, `build-vm`, `build-vm-with-bootloader`, `list-generations`
|
|
||||||
|
|
||||||
proc handleRebuildArgs(subcmd: NixosRebuildSubcmd, args: openArray[string], remote: bool): string =
|
proc handleRebuildArgs(subcmd: NixosRebuildSubcmd, args: openArray[string], remote: bool): string =
|
||||||
if not remote: result.add "sudo"
|
if not remote: result.add "sudo"
|
||||||
result.addArgs "nixos-rebuild"
|
result.addArgs "nixos-rebuild"
|
||||||
|
@ -159,16 +176,6 @@ proc toBuildNixosConfiguration(): seq[string] =
|
||||||
let output = parseDryRunOutput err
|
let output = parseDryRunOutput err
|
||||||
return output.toBuild.mapIt(it.path)
|
return output.toBuild.mapIt(it.path)
|
||||||
|
|
||||||
type
|
|
||||||
DerivationOutput = object
|
|
||||||
path*: string
|
|
||||||
# hashAlgo: string
|
|
||||||
# hash: string
|
|
||||||
NixDerivation = object
|
|
||||||
inputDrvs*: Table[string, JsonNode]
|
|
||||||
name*: string
|
|
||||||
outputs*: Table[string, DerivationOutput]
|
|
||||||
|
|
||||||
# here a results var would be nice...
|
# here a results var would be nice...
|
||||||
proc narHash*(s: string): string =
|
proc narHash*(s: string): string =
|
||||||
## get hash from nix store path
|
## get hash from nix store path
|
||||||
|
@ -200,9 +207,8 @@ func getIgnoredPackages(): seq[string] =
|
||||||
if not l.startsWith("#"):
|
if not l.startsWith("#"):
|
||||||
result.add l
|
result.add l
|
||||||
|
|
||||||
func isIgnored(drv: string): bool =
|
func isIgnored(name: string): bool =
|
||||||
const ignoredPackages = getIgnoredPackages()
|
const ignoredPackages = getIgnoredPackages()
|
||||||
let name = drv.split("-", 1)[1].replace(".drv","")
|
|
||||||
result = name in ignoredPackages
|
result = name in ignoredPackages
|
||||||
if not result:
|
if not result:
|
||||||
for pkg in ignoredPackages:
|
for pkg in ignoredPackages:
|
||||||
|
@ -218,14 +224,34 @@ proc getSystemPathInputDrvs*(): seq[string] =
|
||||||
for inputDrv, _ in drv.inputDrvs:
|
for inputDrv, _ in drv.inputDrvs:
|
||||||
inputDrv
|
inputDrv
|
||||||
|
|
||||||
proc missingDerivations*():Table[string, NixDerivation] =
|
proc missingDrvNixEvalJobs*(): seq[NixEvalOutput] =
|
||||||
let
|
## get all derivations not cached using nix-eval-jobs
|
||||||
toBuildDrvs = toBuildNixosConfiguration()
|
var cmd = ("nix-eval-jobs")
|
||||||
systemPathInputDrvs = getSystemPathInputDrvs()
|
cmd.addArgs "--flake", "--check-cache-status"
|
||||||
toActullyBuildDrvs = systemPathInputDrvs.filterIt(it in toBuildDrvs and not isIgnored(it))
|
cmd.addArgs getHosts().mapIt(".#systemPaths." & it)
|
||||||
|
|
||||||
for path , drv in nixDerivationShow(toActullyBuildDrvs):
|
let (output, _) = runCmdCaptWithSpinner(
|
||||||
result[path] = drv
|
cmd,
|
||||||
|
bb"running [b]nix-eval-jobs[/] for system paths: " & (getHosts().join(" ").bb("bold")),
|
||||||
|
)
|
||||||
|
|
||||||
|
var cached: seq[NixEvalOutput]
|
||||||
|
var ignored: seq[NixEvalOutput]
|
||||||
|
|
||||||
|
for line in output.strip().splitLines():
|
||||||
|
let output = line.fromJson(NixEvalOutput)
|
||||||
|
if output.isCached:
|
||||||
|
cached.add output
|
||||||
|
elif output.name.isIgnored():
|
||||||
|
ignored.add output
|
||||||
|
else:
|
||||||
|
result.add output
|
||||||
|
|
||||||
|
debug "cached derivations: ", bb($cached.len, "yellow")
|
||||||
|
debug "ignored derivations: ", bb($ignored.len, "yellow")
|
||||||
|
|
||||||
|
func fmtDrvsForNix*(drvs: seq[NixEvalOutput]): string {.inline.} =
|
||||||
|
drvs.mapIt(it.drvPath & "^*").join(" ")
|
||||||
|
|
||||||
func fmtDrvsForNix*(drvs: seq[string]): string {.inline.} =
|
func fmtDrvsForNix*(drvs: seq[string]): string {.inline.} =
|
||||||
drvs.mapIt(it & "^*").join(" ")
|
drvs.mapIt(it & "^*").join(" ")
|
||||||
|
@ -246,7 +272,7 @@ proc nixBuild*(minimal: bool, nom: bool, rest: seq[string]) =
|
||||||
var cmd = nixCommand("build", nom)
|
var cmd = nixCommand("build", nom)
|
||||||
if minimal:
|
if minimal:
|
||||||
debug "populating args with derivations not built/cached"
|
debug "populating args with derivations not built/cached"
|
||||||
let drvs = missingDerivations()
|
let drvs = missingDrvNixEvalJobs()
|
||||||
if drvs.len == 0:
|
if drvs.len == 0:
|
||||||
info "nothing to build"
|
info "nothing to build"
|
||||||
quit "exiting...", QuitSuccess
|
quit "exiting...", QuitSuccess
|
||||||
|
@ -261,7 +287,7 @@ proc nixBuildHostDry*(minimal: bool, rest: seq[string]) =
|
||||||
var cmd = nixCommand("build")
|
var cmd = nixCommand("build")
|
||||||
if minimal:
|
if minimal:
|
||||||
debug "populating args with derivations not built/cached"
|
debug "populating args with derivations not built/cached"
|
||||||
let drvs = missingDerivations()
|
let drvs = missingDrvNixEvalJobs()
|
||||||
if drvs.len == 0:
|
if drvs.len == 0:
|
||||||
info "nothing to build"
|
info "nothing to build"
|
||||||
quit "exiting...", QuitSuccess
|
quit "exiting...", QuitSuccess
|
||||||
|
@ -295,57 +321,6 @@ func formatDuration(d: Duration): string =
|
||||||
result.add " and "
|
result.add " and "
|
||||||
result.add $(seconds mod 60) & " seconds"
|
result.add $(seconds mod 60) & " seconds"
|
||||||
|
|
||||||
# TODO: by default collect the build result
|
|
||||||
proc build(path: string, drv: NixDerivation, rest: seq[string]): BuildResult =
|
|
||||||
let startTime = now()
|
|
||||||
var cmd = "nix build"
|
|
||||||
cmd.addArgs path & "^*", "--no-link"
|
|
||||||
cmd.addArgs rest
|
|
||||||
|
|
||||||
let (stdout, stderr, buildCode) =
|
|
||||||
if "-L" in rest or "--print-build-logs" in rest: ("","", runCmd(cmd))
|
|
||||||
else: runCmdCapt(cmd, {CaptStderr})
|
|
||||||
|
|
||||||
result.duration = now() - startTime
|
|
||||||
|
|
||||||
# result.stdout = stdout
|
|
||||||
# result.stderr = stderr
|
|
||||||
if buildCode == 0:
|
|
||||||
result.successful = true
|
|
||||||
info "succesfully built: " & splitDrv(path).name
|
|
||||||
else:
|
|
||||||
error "failed to build: " & splitDrv(path).name
|
|
||||||
error "\n" & formatStdoutStderr(stdout, stderr)
|
|
||||||
|
|
||||||
info "-> duration: " & formatDuration(result.duration)
|
|
||||||
|
|
||||||
func outputsPaths(drv: NixDerivation): seq[string] =
|
|
||||||
for _, output in drv.outputs:
|
|
||||||
result.add output.path
|
|
||||||
|
|
||||||
proc reportResults(results: seq[(string, NixDerivation, BuildResult)]) =
|
|
||||||
let rows = collect(
|
|
||||||
for (path, drv, res) in results:
|
|
||||||
let (name, hash) = splitDrv(path)
|
|
||||||
fmt"| {name} | `{hash}` | " & (
|
|
||||||
if res.successful: ":white_check_mark:"
|
|
||||||
else: ":x:"
|
|
||||||
) & " |" & $(res.duration)
|
|
||||||
)
|
|
||||||
let summaryFilePath = getEnv("GITHUB_STEP_SUMMARY")
|
|
||||||
if summaryFilePath == "": fatalQuit "no github step summary found"
|
|
||||||
let output = open(summaryFilePath, fmAppend)
|
|
||||||
output.writeLine "| derivation | hash | build | time |"
|
|
||||||
output.writeLine "|---|---|---|---|"
|
|
||||||
output.writeLine rows.join("\n")
|
|
||||||
close output
|
|
||||||
|
|
||||||
|
|
||||||
proc prettyDerivation*(path: string): BbString =
|
|
||||||
const maxLen = 40
|
|
||||||
let drv = path.toDerivation()
|
|
||||||
drv.name.trunc(maxLen) & " " & drv.hash.bb("faint")
|
|
||||||
|
|
||||||
|
|
||||||
type NixCacheKind = enum
|
type NixCacheKind = enum
|
||||||
Store ## Nix-serve-ng, Harmonia
|
Store ## Nix-serve-ng, Harmonia
|
||||||
|
@ -387,33 +362,83 @@ proc pushPathsToCache(cache: NixCache, paths: openArray[string], jobs: int) =
|
||||||
if pushErr != 0:
|
if pushErr != 0:
|
||||||
errorQuit "failed to push build to cache"
|
errorQuit "failed to push build to cache"
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: by default collect the build result
|
||||||
|
proc build(drv: NixEvalOutput, rest: seq[string]): BuildResult =
|
||||||
|
let startTime = now()
|
||||||
|
var cmd = "nix build"
|
||||||
|
cmd.addArgs drv.drvPath & "^*", "--no-link"
|
||||||
|
cmd.addArgs rest
|
||||||
|
|
||||||
|
let (stdout, stderr, buildCode) =
|
||||||
|
if "-L" in rest or "--print-build-logs" in rest: ("","", runCmd(cmd))
|
||||||
|
else: runCmdCapt(cmd, {CaptStderr})
|
||||||
|
|
||||||
|
result.duration = now() - startTime
|
||||||
|
|
||||||
|
if buildCode == 0:
|
||||||
|
result.successful = true
|
||||||
|
info "succesfully built: " & drv.name
|
||||||
|
else:
|
||||||
|
error "failed to build: " & drv.name
|
||||||
|
error "\n" & formatStdoutStderr(stdout, stderr)
|
||||||
|
|
||||||
|
info "-> duration: " & formatDuration(result.duration)
|
||||||
|
|
||||||
|
func outputsPaths(drv: NixDerivation): seq[string] =
|
||||||
|
for _, output in drv.outputs:
|
||||||
|
result.add output.path
|
||||||
|
|
||||||
|
proc reportResults(results: seq[(NixEvalOutput, BuildResult)]) =
|
||||||
|
let rows = collect(
|
||||||
|
for (drv, res) in results:
|
||||||
|
let (name, hash) = splitDrv(drv.drvPath)
|
||||||
|
fmt"| {name} | `{hash}` | " & (
|
||||||
|
if res.successful: ":white_check_mark:"
|
||||||
|
else: ":x:"
|
||||||
|
) & " |" & $(res.duration)
|
||||||
|
)
|
||||||
|
let summaryFilePath = getEnv("GITHUB_STEP_SUMMARY")
|
||||||
|
if summaryFilePath == "": fatalQuit "no github step summary found"
|
||||||
|
let output = open(summaryFilePath, fmAppend)
|
||||||
|
output.writeLine "| derivation | hash | build | time |"
|
||||||
|
output.writeLine "|---|---|---|---|"
|
||||||
|
output.writeLine rows.join("\n")
|
||||||
|
close output
|
||||||
|
|
||||||
|
|
||||||
|
proc prettyDerivation*(path: string): BbString =
|
||||||
|
const maxLen = 40
|
||||||
|
let drv = path.toDerivation()
|
||||||
|
drv.name.trunc(maxLen) & " " & drv.hash.bb("faint")
|
||||||
|
|
||||||
|
|
||||||
proc nixBuildWithCache*(name: string, rest: seq[string], service: string, jobs: int, dry: bool) =
|
proc nixBuildWithCache*(name: string, rest: seq[string], service: string, jobs: int, dry: bool) =
|
||||||
## build individual derivations not cached and push to cache
|
## build individual derivations not cached and push to cache
|
||||||
|
|
||||||
let cache = toCache(service, name)
|
let cache = toCache(service, name)
|
||||||
debug "determining missing cache hits"
|
debug "determining missing cache hits"
|
||||||
|
|
||||||
let drvs = missingDerivations()
|
let missing = missingDrvNixEvalJobs()
|
||||||
if drvs.len == 0:
|
|
||||||
info "nothing to build"
|
info "derivations to build: ", bb($missing.len, "yellow")
|
||||||
|
if missing.len == 0:
|
||||||
quit "exiting...", QuitSuccess
|
quit "exiting...", QuitSuccess
|
||||||
|
|
||||||
info fmt("need to build {drvs.len} dervations")
|
info "derivations:\n" & missing.mapIt(" " & prettyDerivation(it.outputs["out"])).join("\n")
|
||||||
for _, drv in drvs:
|
|
||||||
info prettyDerivation(" " & drv.outputs["out"].path)
|
|
||||||
|
|
||||||
if dry:
|
if dry:
|
||||||
quit "exiting...", QuitSuccess
|
quit "exiting...", QuitSuccess
|
||||||
|
|
||||||
let results =
|
let results =
|
||||||
collect:
|
collect:
|
||||||
for path, drv in drvs:
|
for drv in missing:
|
||||||
(path, drv, build(path, drv, rest))
|
(drv, build(drv, rest))
|
||||||
|
|
||||||
var outs: seq[string]
|
var outs: seq[string]
|
||||||
for (path, drv, res) in results:
|
for (drv, res) in results:
|
||||||
if res.successful:
|
if res.successful:
|
||||||
outs &= drv.outputsPaths
|
outs &= drv.outputs.values.toSeq
|
||||||
|
|
||||||
if isCi():
|
if isCi():
|
||||||
reportResults(results)
|
reportResults(results)
|
||||||
|
|
Loading…
Add table
Reference in a new issue