Compare commits

...

2 Commits
trunk ... rrd

Author SHA1 Message Date
Emery Hemingway 8b927b8ff7 WiP! RRD support 2024-01-10 07:55:33 +02:00
Emery Hemingway 651efc1e6b syndesizer: add file-system-usage 2024-01-09 20:49:54 +02:00
10 changed files with 125 additions and 1 deletions

View File

@ -28,6 +28,23 @@ Example configuration:
$cap <cache { dataspace: $nixspace lifetime: 3600.0 }> ] $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 }>
]
]
```
### JSON Socket Translator ### JSON Socket Translator

3
assertions.prs Normal file
View File

@ -0,0 +1,3 @@
version 1.
FileSystemUsage = <file-system-usage @path string @size int>.

View File

@ -6,6 +6,10 @@ CacheArguments = <cache {
lifetime: float lifetime: float
}>. }>.
FileSystemUsageArguments = <file-system-usage {
dataspace: #!any
}>.
JsonTranslatorArguments = <json-stdio-translator { JsonTranslatorArguments = <json-stdio-translator {
argv: [string ...] argv: [string ...]
dataspace: #!any dataspace: #!any
@ -18,6 +22,8 @@ JsonSocketTranslatorArguments = <json-socket-translator {
socket: string socket: string
}>. }>.
RrdArguments = <rrd { dataspace: #!any }>.
SqliteArguments = <sqlite { SqliteArguments = <sqlite {
database: string database: string
dataspace: #!any dataspace: #!any

3
rrd.prs Normal file
View File

@ -0,0 +1,3 @@
version 1.
RRDaction = <rrd @verb symbol @args [string...]>.

View File

@ -3,5 +3,5 @@
pkgs.buildNimPackage { pkgs.buildNimPackage {
name = "dummy"; name = "dummy";
propagatedNativeBuildInputs = [ pkgs.pkg-config ]; propagatedNativeBuildInputs = [ pkgs.pkg-config ];
propagatedBuildInputs = [ pkgs.sqlite ]; propagatedBuildInputs = [ pkgs.rrdtool pkgs.sqlite ];
} }

View File

@ -27,6 +27,12 @@ type
JsonSocketTranslatorArguments* {.preservesRecord: "json-socket-translator".} = object JsonSocketTranslatorArguments* {.preservesRecord: "json-socket-translator".} = object
`field0`*: JsonSocketTranslatorArgumentsField0 `field0`*: JsonSocketTranslatorArgumentsField0
RrdArgumentsField0* {.preservesDictionary.} = object
`dataspace`* {.preservesEmbedded.}: EmbeddedRef
RrdArguments* {.preservesRecord: "rrd".} = object
`field0`*: RrdArgumentsField0
WebhooksArgumentsField0* {.preservesDictionary.} = object WebhooksArgumentsField0* {.preservesDictionary.} = object
`endpoints`*: Table[seq[string], EmbeddedRef] `endpoints`*: Table[seq[string], EmbeddedRef]
`listen`*: Tcp `listen`*: Tcp
@ -34,6 +40,12 @@ type
WebhooksArguments* {.preservesRecord: "webhooks".} = object WebhooksArguments* {.preservesRecord: "webhooks".} = object
`field0`*: WebhooksArgumentsField0 `field0`*: WebhooksArgumentsField0
FileSystemUsageArgumentsField0* {.preservesDictionary.} = object
`dataspace`* {.preservesEmbedded.}: EmbeddedRef
FileSystemUsageArguments* {.preservesRecord: "file-system-usage".} = object
`field0`*: FileSystemUsageArgumentsField0
SqliteArgumentsField0* {.preservesDictionary.} = object SqliteArgumentsField0* {.preservesDictionary.} = object
`database`*: string `database`*: string
`dataspace`* {.preservesEmbedded.}: EmbeddedRef `dataspace`* {.preservesEmbedded.}: EmbeddedRef
@ -55,7 +67,9 @@ type
proc `$`*(x: WebsocketArguments | JsonTranslatorArguments | proc `$`*(x: WebsocketArguments | JsonTranslatorArguments |
JsonTranslatorConnected | JsonTranslatorConnected |
JsonSocketTranslatorArguments | JsonSocketTranslatorArguments |
RrdArguments |
WebhooksArguments | WebhooksArguments |
FileSystemUsageArguments |
SqliteArguments | SqliteArguments |
CacheArguments | CacheArguments |
Tcp): string = Tcp): string =
@ -64,7 +78,9 @@ proc `$`*(x: WebsocketArguments | JsonTranslatorArguments |
proc encode*(x: WebsocketArguments | JsonTranslatorArguments | proc encode*(x: WebsocketArguments | JsonTranslatorArguments |
JsonTranslatorConnected | JsonTranslatorConnected |
JsonSocketTranslatorArguments | JsonSocketTranslatorArguments |
RrdArguments |
WebhooksArguments | WebhooksArguments |
FileSystemUsageArguments |
SqliteArguments | SqliteArguments |
CacheArguments | CacheArguments |
Tcp): seq[byte] = Tcp): seq[byte] =

14
src/schema/rrd.nim Normal file
View File

@ -0,0 +1,14 @@
import
preserves
type
RRDaction* {.preservesRecord: "rrd".} = object
`verb`*: Symbol
`args`*: seq[string]
proc `$`*(x: RRDaction): string =
`$`(toPreserves(x))
proc encode*(x: RRDaction): seq[byte] =
encode(toPreserves(x))

View File

@ -7,8 +7,10 @@ import syndicate, syndicate/relays, syndicate/actors/timers
import ./syndesizer/[ import ./syndesizer/[
cache_actor, cache_actor,
file_system_usage,
json_socket_translator, json_socket_translator,
json_translator, json_translator,
rrd,
sqlite_actor, sqlite_actor,
webhooks, webhooks,
websockets] websockets]
@ -17,9 +19,12 @@ runActor("syndesizer") do (turn: var Turn; root: Cap):
connectStdio(turn, root) connectStdio(turn, root)
discard spawnTimers(turn, root) discard spawnTimers(turn, root)
discard spawnCacheActor(turn, root) discard spawnCacheActor(turn, root)
discard spawnFileSystemUsageActor(turn, root)
discard spawnJsonSocketTranslator(turn, root) discard spawnJsonSocketTranslator(turn, root)
discard spawnJsonStdioTranslator(turn, root) discard spawnJsonStdioTranslator(turn, root)
discard spawnWebhookActor(turn, root) discard spawnWebhookActor(turn, root)
discard spawnWebsocketActor(turn, root) discard spawnWebsocketActor(turn, root)
when withLibrrd:
discard spawnRrdActor(turn, root)
when withSqlite: when withSqlite:
discard spawnSqliteActor(turn, root) discard spawnSqliteActor(turn, root)

View File

@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[dirs, os, paths]
import preserves
import syndicate, syndicate/relays
import ../schema/[assertions, config]
proc spawnFileSystemUsageActor*(turn: var Turn; root: Cap): Actor {.discardable.} =
spawn("file-system-usage", turn) do (turn: var Turn):
during(turn, root, ?:FileSystemUsageArguments) do (ds: Cap):
var pat = ?Observe(pattern: !FileSystemUsage) ?? { 0: grab() }
during(turn, ds, pat) do (lit: Literal[string]):
var ass = FileSystemUsage(path: lit.value)
if fileExists(ass.path): ass.size = getFileSize(ass.path)
else:
for fp in walkDirRec(paths.Path(lit.value), yieldFilter={pcFile}):
var fs = getFileSize(string fp)
inc(ass.size, fs)
discard publish(turn, ds, ass)
# TODO: updates?
when isMainModule:
runActor("main") do (turn: var Turn; root: Cap):
connectStdio(turn, root)
discard spawnFileSystemUsageActor(turn, root)

33
src/syndesizer/rrd.nim Normal file
View File

@ -0,0 +1,33 @@
# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
const withLibrrd* {.booldefine.}: bool = true
when withLibrrd:
import preserves, syndicate, syndicate/relays
import ../schema/[config, rrd]
{.passC: staticExec("pkg-config --cflags librrd").}
{.passL: staticExec("pkg-config --libs librrd").}
{.pragma: librrd, header: "rrd.h", importc.}
proc rrd_update(a1: cint; a2: cstringArray): cint {.librrd.}
proc rrd_get_error(): cstring {.librrd.}
proc rrd_clear_error() {.librrd.}
proc spawnRrdActor*(turn: var Turn; root: Cap): Actor {.discardable.} =
spawn("rrd-actor", turn) do (turn: var Turn):
during(turn, root, ?:RrdArguments) do (ds: Cap):
let updatePattern = RRDaction ?: {0: ?Symbol"update", 1: grab()}
onMessage(turn, ds, updatePattern) do (args: seq[string]):
var argv = allocCStringArray(args)
if rrd_update(args.len.cint, argv) != 0:
stderr.writeLine(rrd_get_error())
rrd_clear_error()
deallocCStringArray(argv)
when isMainModule:
runActor("main") do (turn: var Turn; root: Cap):
connectStdio(turn, root)
spawnRrdActor(turn, root)