- Nim 98.8%
- jq 0.7%
- Nix 0.5%
|
|
||
|---|---|---|
| doc | ||
| LICENSES | ||
| src | ||
| .gitignore | ||
| config.prs | ||
| default.nix | ||
| file_system.prs | ||
| icmp_rtt_actor.prs | ||
| mpv.config-example.pr | ||
| process_proxy.prs | ||
| README.md | ||
| sbom.json | ||
| syn_agent.prs | ||
| syndicate_utils.nimble | ||
| Tupfile | ||
| Tuprules.jq | ||
| Tuprules.tup | ||
| utils.prs | ||
Syndicate utils
Most utilities accept the --route:ROUTE flag to specify a Syndicate peer with a fallback to $SYNDICATE_ROUTE.
icmp-rtt-actor
See the man page.
process-proxy
The process-proxy utility adds a few process management features not provided by the syndicate-server.
process-proxy will fork a proxy process that communicates with the syndicate-server over stdio and then will exec its argv.
Startup notification is enabled by passing -n $FD before the arguments to exec.
Features
- s6-style startup notification to Syndicate readyness.
- Syndicate messages to Unix signals.
See the process_proxy schema for more information.
Configuration example
#!/usr/bin/env syndicate-server -S --config
<require-service <daemon example>>
<daemon example {
argv: [
# Watch FD 3 for ready notification.
"process-proxy" "-n" "3"
# Use trap from execline to dispatch signals.
"trap"
" SIGUSR1"
# Indicate ready on SIGUSR1 by writing a newline to FD 3.
" fdmove"
" 1"
" 3"
" echo"
" "
" SIGUSR2"
" ps"
" -o"
" ppid,pid,pgid,args"
" "
""
# Pause indefinitely.
"s6-pause"
]
readyOnStart: #f
protocol: application/syndicate
}>
# Get a ref for the process-proxy.
? <service-object <daemon example> ?obj> [
# Subscribe to a ready notification with a rewrite to the config dataspace.
$obj += <notify-ready <* $config [ <rewrite #t <service-state <daemon example> ready>> > ]>
# When the example is started send it SIGUSR1.
? <service-state <daemon example> started> [
$obj ! <signal SIGUSR1>
]
# When the example is ready send it SIGUSR2.
? <service-state <daemon example> ready> [
$obj ! <signal SIGUSR2>
]
]
? <service-state <daemon ?svs> ?state> [
$log ! <log "-" { service: <daemon $svs> line: $state }>
]
syn-agent
An ephemeral Syndicate gatekeeper inspired by ssh-agent.
See the man page.
Syndesizer
A Syndicate multitool that includes a number of different actors that become active via configuration.
Whether you use a single instance for many protocols or many specialized instances is up to you.
Cache
Observes patterns and reässert the values captured for a given lifetime. Takes the argument <cache { dataspace: #!any lifetime: float }>. The lifetime of a cache counts down from moment a value is asserted.
Example configuration:
? <nixspace ?nixspace> [
; Require the nix_actor during observations.
?nixspace> ? <Observe <rec eval _> _> [
$config <require-service <daemon nix_actor>> ]
?nixspace> ? <Observe <rec realise _> _> [
$config <require-service <daemon nix_actor>> ]
; Cache anything captured by observers in the $nixspace for an hour.
; The nix_actor is not required during caching.
$config <require-service <daemon syndesizer>>
$config ? <service-object <daemon syndesizer> ?cap> [
$cap <cache { dataspace: $nixspace lifetime: 3600.0 }> ]
]
File System Usage
Summarize the size of file-system directory. Equivalent to du -s -b.
Query the size of a directory in bytes by observing <file-system-usage "/SOME/PATH" ?size>.
# Configuration example
? <exposed-dataspace ?ds> [
<require-service <daemon syndesizer>>
? <service-object <daemon syndesizer> ?cap> [
$cap <file-system-usage { dataspace: $ds }>
]
]
HTTP driver
Experimental HTTP server that services requests using some version of the http Syndicate protocol schema.
#### Configuration example
let ?not-found = dataspace
$not-found ? <request _ ?res> [
$res ! <status 503 "Service unavailable">
$res ! <done "No binding here.">
]
let ?greeting = dataspace
$greeting ? <request _ ?res> [
$res ! <status 200 "ok">
$res ! <chunk "Hello world">
$res ! <done "!">
]
let ?http = dataspace
$http [
<http-bind #f 80 get [ ] $not-found>
<http-bind #f 80 get [|...|] $not-found>
<http-bind #f 80 get ["hello"] $greeting>
]
? <service-object <daemon http-driver> ?cap> [
$cap <http-driver { dataspace: $http }>
]
<daemon http-driver {
argv: [ "/bin/syndesizer" ]
clearEnv: #t
protocol: application/syndicate
}>
<require-service <daemon http-driver>>
JSON Socket Translator
Communicate with sockets that send and receive lines of JSON using <send …> and <recv …> messages.
Responds to the gatekeeper step <json-socket-translator { socket: <unix "…"> / <tcp "…" … }> $resolver>.
# MPV configuration example
<require-service <daemon mpv-server>>
<daemon mpv-server {
argv: [
"/run/current-system/sw/bin/mpv"
"--really-quiet"
"--idle=yes"
"--no-audio-display"
"--input-ipc-server=/run/user/1000/mpv.sock"
"--volume=75"
]
protocol: none
}>
let ?resolver = dataspace
$resolver ? <accepted ?mpvSpace> $mpvSpace [
# announce the dataspace when the translator is connected
$config <mpv $mpvSpace>
$config <bind <ref { oid: "mpv" key: #x"" }> $mpvSpace #f>
# translate <play-file …> to an MPV command
?? <play-file ?file> [
! <send { "command": ["loadfile" $file "append-play"] }>
]
# clear the playlist on idle so it doesn't grow indefinitely
?? <recv {"event": "idle"}> [
! <send { "command": ["playlist-clear"] }>
]
]
? <service-state <daemon mpv-server> ready> [
<require-service <daemon syndesizer>>
? <service-object <daemon syndesizer> ?cap> [
$cap <resolve <json-socket-translator {
socket: <unix "/run/user/1000/mpv.sock">
}> $resolver>
]
]
JSON Input Adapter
Parse JSON from a open file-descriptor and send as messages.
# Configuration example
<require-service <daemon syndesizer>>
<daemon syndesizer {
argv: [
"redirfd" "-r" "3" "/etc/foo.json"
"syndesizer"
]
protocol: application/syndicate
}>
? <service-object <daemon syndesizer> ?obj> [
$obj <json-input-adapter { input: 3 target: <* $log [<rewrite ?any <log "-" { line: $any }>> ]> }>
]
Pulse proxy
An actor that makes an assertion within a pulsed timeframe. This can be used to implement polling behavior or periodic service scheduling.
#!/usr/bin/env -S syndicate-server --config
let ?destination = dataspace
$destination ? ?x [
$log ! <log "destination" { +: $x }>
?- $log ! <log "destination" { -: $x }>
]
# Request a pulse service.
<q <service pulse {
label: "pulse-demo" # Not used by the pulse service, just here to match to the answer.
assertion: <pulse-active>
target: $destination
frequency: 4.0 # Four hertz pulse cycle.
duty-factor: 0.5 # Assertions forwarded half the time.
dither: 1.0 # Dither the cycle period to a standard deviation of 1 hertz.
}>>
# Start the pulse service on demand.
? <q <service pulse ?detail>> [
<require-service <daemon syndesizer>>
? <service-object <daemon syndesizer> ?obj> [
let ?rewriter = <* $config [<rewrite ?resp <a <service pulse $detail> $resp>>]>
$obj <resolve <pulse $detail> $rewriter>
]
<daemon syndesizer {
argv: "syndesizer"
clearEnv: #t
protocol: application/syndicate
}>
]
# Log if a service request is rejected.
? <a <service ?label ?detail> <rejected ?reason>> [
$log ! <log "service request rejected" { line: $reason label: $label detail: $detail }>
]
XML translator
Translates between Preserves and XML according to the Conventions for Common Data Types.
Examples:
<xml-translation "<foo a=\"1\"> <bar>hello world!</bar></foo>" <foo {"a": 1}<bar "hello world!">>><xml-translation "" [#t #f]><xml-translation "<<</>>" #f>
# Configuration example
? <sharedspace ?ds> [
$ds ? <Observe <rec xml-translation _> _> $config [
$config <require-service <daemon syndesizer>>
$config ? <service-object <daemon syndesizer> ?cap> [
$cap <xml-translator { dataspace: $ds }>
]
]
]
http-client
The inverse of http-driver.
Caveats
- HTTPS is assumed unless the request is to port 80.
- If the request or response sets
Content-Typetoapplication/jsonor…/preservesthe body will be a parsed Preserves value. - No caching or proxying.
- Internal errors propagate using a
400 Internal client errorresponse.
Sample Syndicate server script:
#!/usr/bin/env -S syndicate-server --control --config
# A dataspace for handling the HTTP response.
let ?response-handler = dataspace
$response-handler [
?? <done { "code": "EUR" "exchange_middle": ?middle } > [
$log ! <log "-" { line: <exchange EUR RSD $middle> }>
$control <exit 0>
]
]
# A dataspace for collecting a dataspace from the http-client.
let ?client-resolver = dataspace
$client-resolver ? <accepted ?client> $client [
<request
# Request Dinar to Euro exchange rate.
<http-request 0 "kurs.resenje.org" 443
get ["api" "v1" "currencies" "eur" "rates" "today"]
{content-type: "application/json"} {} #f
>
$response-handler
>
]
# Pass the resolver dataspace to the client.
? <service-object <daemon http-client> ?cap> [
$cap <resolve <http-client { response-content-type-override: "" }> $client-resolver>
]
<require-service <daemon http-client>>
<daemon http-client {
argv: [ "/bin/http-client" ]
clearEnv: #t
env: {
BUILD_SUM: $sum
}
protocol: application/syndicate
}>
mintsturdyref
A utility for minting Sturdyrefs.
msg
A utility that parses its command-line arguments as Preserves and send them as messages to $SYNDICATE_ROUTE.
When called as assert (by a symlink or a rename) it will make assertions instead.
preserve_process_environment
This utility serializes it's process environment to Preserves and prints it to stdout. It can be used to feed the environment variables of a nested child of the Syndicate server back to the server. For example, to retreive the environmental variables that a desktop manager passed on to its children.
syndump
Utility for printing assertions and messages. Parses the command-line arguments as a pattern, connects a dataspace via $SYNDICATE_ROUTE, and writes observations to standard-output. Published assertions are prefixed by the + character, retractions by -, and messages by !.
Accepts the following options:
--json-jOutput in a JSON compatible syntax if possible.--caveat:CAVEATRewrite respones by CAVEAT. Caveats are applied before paths.--path:PATHProject responses by Preserves PATH.--exitExit after receiving responses.
Example
# Print patterns in use, filter down with AWK to only the published patterns.
$ FS=':' syndump '<Observe ? _>' | awk -F : '/^+/ { print $2 }'
synqa
Utility for the question and answer pattern.
Command-line arguments are published in <q> records to $SYNDICATE_ROUTE and the corresponding <a> responses are written to stdout.
Accepts the following options:
--json-jOutput in a JSON compatible syntax if possible.--caveat:CAVEATRewrite respones by CAVEAT. Caveats are applied before paths.--path:PATHProject responses by Preserves PATH.--exitExit after receiving responses.