Add realise and eval
This commit is contained in:
parent
b601d9a1b7
commit
4e3e77171c
2
.envrc
2
.envrc
|
@ -1,2 +1,2 @@
|
|||
source_env ..
|
||||
use flake work#nix_actor
|
||||
use flake syndicate#nix_actor
|
||||
|
|
40
README.md
40
README.md
|
@ -6,26 +6,28 @@ An actor for interacting with the [Nix](https://nixos.org/) daemon via the [Synd
|
|||
|
||||
## Example configuration
|
||||
```
|
||||
; create and publish a dedicated dataspace
|
||||
let ?nixspace = dataspace
|
||||
<nixspace $nixspace>
|
||||
? <nixspace ?nixspace> $nixspace [
|
||||
|
||||
$nixspace [
|
||||
; request a build of nixpkgs#hello
|
||||
? <nix-build "nixpkgs#hello" ?output> [
|
||||
$log ! <log "-" { hello: $output }>
|
||||
? <realise "/nix/store/sv1yikjpf7q8b9w4xszb2ipg0cgcq1xv-imv-4.4.0.drv" ?outputs> [ ]
|
||||
|
||||
? <eval "3 * 4" {} _> []
|
||||
? <eval "builtins.getEnv \"PATH\"" {impure: ""} _> []
|
||||
|
||||
? ?any [
|
||||
$log ! <log "-" { nix: $any }>
|
||||
]
|
||||
|
||||
$config [
|
||||
<require-service <daemon nix_actor>>
|
||||
? <service-object <daemon nix_actor> ?cap> [
|
||||
$cap {
|
||||
dataspace: $nixspace
|
||||
}
|
||||
]
|
||||
<daemon nix_actor {
|
||||
argv: "/usr/local/nix_actor"
|
||||
protocol: application/syndicate
|
||||
}>
|
||||
]
|
||||
]
|
||||
|
||||
; start nix_actor as a daemon
|
||||
<require-service <daemon nix_actor>>
|
||||
<daemon nix_actor {
|
||||
argv: "/run/current-system/sw/bin/nix_actor"
|
||||
protocol: application/syndicate
|
||||
}>
|
||||
|
||||
; hand-off a capablity to the Nix dataspace to the actor
|
||||
? <service-object <daemon nix_actor> ?actor> [
|
||||
$actor <serve $nixspace>
|
||||
]
|
||||
```
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
include ../syndicate-nim/depends.tup
|
||||
NIM_FLAGS += --path:$(TUP_CWD)/../syndicate-nim/src
|
||||
|
||||
NIM_FLAGS += --backend:cpp
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
# Package
|
||||
version = "20230530"
|
||||
author = "Emery Hemingway"
|
||||
description = "Syndicated Nix Actor"
|
||||
license = "Unlicense"
|
||||
srcDir = "src"
|
||||
bin = @["nix_actor"]
|
||||
backend = "cpp"
|
||||
|
||||
version = "20230326"
|
||||
author = "Emery Hemingway"
|
||||
description = "Syndicated Nix Actor"
|
||||
license = "Unlicense"
|
||||
srcDir = "src"
|
||||
bin = @["nix_actor"]
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
requires "nim >= 1.6.10", "syndicate >= 20230326"
|
||||
requires "nim >= 1.6.10", "syndicate >= 20230530"
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
version 1 .
|
||||
|
||||
Build = <nix-build @input string @output any> .
|
||||
Serve = <serve @cap #!any> .
|
||||
|
||||
Realise = <realise @drv string @outputs [string ...]> .
|
||||
|
||||
Eval = <eval @expr string @options {symbol: any ...:...} @result any> .
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
include_rules
|
||||
: nix_actor.nim | $(SYNDICATE_PROTOCOL) ./<protocol> |> !nim_bin |>
|
||||
: nix_actor.nim | $(SYNDICATE_PROTOCOL) ./<protocol> |> !nim_bin |> {bin}
|
||||
: {bin} |> !assert_built |>
|
||||
|
|
|
@ -1,35 +1,67 @@
|
|||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
import std/[asyncdispatch, json, osproc]
|
||||
import std/[asyncdispatch, json, osproc, strutils, tables]
|
||||
import preserves, preserves/jsonhooks
|
||||
import syndicate
|
||||
from syndicate/protocols/dataspace import Observe
|
||||
import ./nix_actor/protocol
|
||||
import ./nix_actor/[main, store]
|
||||
|
||||
type Observe = dataspace.Observe[Ref]
|
||||
type
|
||||
Value = Preserve[void]
|
||||
Options = Table[Symbol, Value]
|
||||
Observe = dataspace.Observe[Ref]
|
||||
|
||||
proc build(spec: string): Build =
|
||||
var execOutput = execProcess("nix", args = ["build", "--json", "--no-link", spec], options = {poUsePath})
|
||||
stderr.writeLine execOutput
|
||||
var js = parseJson(execOutput)
|
||||
Build(input: spec, output: js[0].toPreserve)
|
||||
|
||||
proc realise(realise: Realise): seq[string] =
|
||||
var execlines = execProcess("nix-store", args = ["--realize", realise.drv], options = {poUsePath})
|
||||
split(strip(execlines), '\n')
|
||||
|
||||
proc eval(eval: Eval): Value =
|
||||
var args = @["eval", "--json", "--expr", eval.expr]
|
||||
for sym, val in eval.options:
|
||||
add(args, "--" & $sym)
|
||||
if not val.isString "":
|
||||
var js: JsonNode
|
||||
if fromPreserve(js, val): add(args, $js)
|
||||
else: stderr.writeLine "invalid option ", sym, " ", val
|
||||
var execOutput = strip execProcess("nix", args = args, options = {poUsePath})
|
||||
if execOutput != "":
|
||||
var js = parseJson(execOutput)
|
||||
result = js.toPreserve
|
||||
|
||||
proc bootNixFacet(ds: Ref; turn: var Turn): Facet =
|
||||
# let store = openStore()
|
||||
inFacet(turn) do (turn: var Turn):
|
||||
let storePathObservation = ?Observe(pattern: !Build) ?? {0: grabLit()}
|
||||
during(turn, ds, storePathObservation) do (spec: string):
|
||||
stderr.writeLine "build ", spec
|
||||
let a = build(spec)
|
||||
discard publish(turn, ds, a)
|
||||
result = inFacet(turn) do (turn: var Turn):
|
||||
|
||||
during(turn, ds, ?Observe(pattern: !Build) ?? {0: grabLit()}) do (spec: string):
|
||||
discard publish(turn, ds, build(spec))
|
||||
|
||||
during(turn, ds, ?Observe(pattern: !Realise) ?? {0: grabLit()}) do (drvPath: string):
|
||||
var ass = Realise(drv: drvPath)
|
||||
ass.outputs = realise(ass)
|
||||
discard publish(turn, ds, ass)
|
||||
|
||||
during(turn, ds, ?Observe(pattern: !Eval) ?? {0: grabLit(), 1: grabDict()}) do (e: string, o: Value):
|
||||
var ass = Eval(expr: e)
|
||||
if not fromPreserve(ass.options, unpackLiterals(o)):
|
||||
stderr.writeLine "invalid options ", o
|
||||
else:
|
||||
ass.result = eval(ass)
|
||||
discard publish(turn, ds, ass)
|
||||
|
||||
type Args {.preservesDictionary.} = object
|
||||
dataspace: Ref
|
||||
|
||||
proc bootNixActor(root: Ref; turn: var Turn) =
|
||||
connectStdio(root, turn)
|
||||
during(turn, root, ?Serve) do (ds: Ref):
|
||||
during(turn, root, ?Args) do (ds: Ref):
|
||||
discard bootNixFacet(ds, turn)
|
||||
|
||||
initNix() # Nix lib isn't actually being used but it's nice to know that it links.
|
||||
bootDataspace("main", bootNixActor)
|
||||
runForever()
|
||||
runActor("main", bootNixActor)
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
|
||||
import
|
||||
std/typetraits, preserves
|
||||
preserves, std/tables
|
||||
|
||||
type
|
||||
Serve* {.preservesRecord: "serve".} = object
|
||||
`cap`* {.preservesEmbedded.}: Preserve[void]
|
||||
Eval* {.preservesRecord: "eval".} = object
|
||||
`expr`*: string
|
||||
`options`*: Table[Symbol, Preserve[void]]
|
||||
`result`*: Preserve[void]
|
||||
|
||||
Realise* {.preservesRecord: "realise".} = object
|
||||
`drv`*: string
|
||||
`outputs`*: seq[string]
|
||||
|
||||
Build* {.preservesRecord: "nix-build".} = object
|
||||
`input`*: string
|
||||
`output`*: Preserve[void]
|
||||
|
||||
proc `$`*(x: Serve | Build): string =
|
||||
proc `$`*(x: Eval | Realise | Build): string =
|
||||
`$`(toPreserve(x))
|
||||
|
||||
proc encode*(x: Serve | Build): seq[byte] =
|
||||
proc encode*(x: Eval | Realise | Build): seq[byte] =
|
||||
encode(toPreserve(x))
|
||||
|
|
Loading…
Reference in New Issue