Builds the bsdkrun argv (minus the binary and global flags) for a
detached create. Every path ends with -d so create! always yields a
handle.
Options are a plain map with keyword keys mirroring the other SDKs'
create-options shape, discriminated on :os. Mirrors
sdk/ruby/lib/bsdkrun/args.rb 1:1.
Builds the `bsdkrun` argv (minus the binary and global flags) for a detached `create`. Every path ends with `-d` so `create!` always yields a handle. Options are a plain map with keyword keys mirroring the other SDKs' create-options shape, discriminated on `:os`. Mirrors `sdk/ruby/lib/bsdkrun/args.rb` 1:1.
Locates the bsdkrun binary on the host and caches the result.
Resolution order (first match wins):
set-override!BSDKRUN_BIN environment variablebsdkrun on PATH<repo>/target/release/bsdkrun, then
<repo>/target/debug/bsdkruncandidates and resolve both take an optional opts map
(:override, :bsdkrun-bin, :path, :repo-root) so the discovery logic
is unit-testable without mutating real process/environment state — the JVM
has no supported, portable way to change System/getenv for the current
process, unlike Ruby's ENV[...]=. Any key left out of the map falls back
to the real host state (the override atom, $BSDKRUN_BIN, $PATH, and the
monorepo root inferred from this namespace's own source location).
Locates the `bsdkrun` binary on the host and caches the result.
Resolution order (first match wins):
1. an explicit override set via [[set-override!]]
2. the `BSDKRUN_BIN` environment variable
3. `bsdkrun` on `PATH`
4. an in-repo dev build: `<repo>/target/release/bsdkrun`, then
`<repo>/target/debug/bsdkrun`
[[candidates]] and [[resolve]] both take an optional opts map
(`:override`, `:bsdkrun-bin`, `:path`, `:repo-root`) so the discovery logic
is unit-testable without mutating real process/environment state — the JVM
has no supported, portable way to change `System/getenv` for the current
process, unlike Ruby's `ENV[...]=`. Any key left out of the map falls back
to the real host state (the override atom, `$BSDKRUN_BIN`, `$PATH`, and the
monorepo root inferred from this namespace's own source location).A client that talks to a remote bsdkrund daemon's GraphQL API directly —
java.net.http.HttpClient for queries/mutations, its built-in
java.net.http.WebSocket speaking graphql-transport-ws for subscriptions
— instead of shelling out to a local bsdkrun binary the way
bsdkrun.sandbox does.
The wire contract (URL/header shape, error mapping, subscription protocol,
field names) is locked to match the other bsdkrun SDKs
(TypeScript/Python/Ruby/Elixir/Gleam) and the web frontend's
web/src/lib/graphql.ts — see that file for the reference implementation
this one mirrors. Unlike every other SDK here, this one needs no
hand-rolled WebSocket framing: java.net.http.WebSocket is a core JDK API
(Java 11+).
A client is a plain map, matching every other namespace's convention —
{:url ... :token ... :http-client ... :ws-state (atom ...)}. Build one
with new-client or client-from-env; every function below takes it
first.
Example:
(require '[bsdkrun.client :as client])
(def c (client/client-from-env))
(doseq [m (client/list-machines c)] (println (:id m)))
(def result (client/exec! c "abc123" ["uname" "-a"]))
(println (String. (:output result)))
A client that talks to a remote `bsdkrund` daemon's GraphQL API directly —
`java.net.http.HttpClient` for queries/mutations, its built-in
`java.net.http.WebSocket` speaking `graphql-transport-ws` for subscriptions
— instead of shelling out to a local `bsdkrun` binary the way
`bsdkrun.sandbox` does.
The wire contract (URL/header shape, error mapping, subscription protocol,
field names) is locked to match the other bsdkrun SDKs
(TypeScript/Python/Ruby/Elixir/Gleam) and the web frontend's
`web/src/lib/graphql.ts` — see that file for the reference implementation
this one mirrors. Unlike every other SDK here, this one needs no
hand-rolled WebSocket framing: `java.net.http.WebSocket` is a core JDK API
(Java 11+).
A `client` is a plain map, matching every other namespace's convention —
`{:url ... :token ... :http-client ... :ws-state (atom ...)}`. Build one
with [[new-client]] or [[client-from-env]]; every function below takes it
first.
Example:
```clojure
(require '[bsdkrun.client :as client])
(def c (client/client-from-env))
(doseq [m (client/list-machines c)] (println (:id m)))
(def result (client/exec! c "abc123" ["uname" "-a"]))
(println (String. (:output result)))
```The single ex-info convention used by every bsdkrun.* namespace: a
plain ex-info whose ex-data carries a :bsdkrun/error kind key plus
whatever detail a caller needs to case/pattern-match on — no exception
class hierarchy, which would be un-idiomatic Clojure.
Every namespace in this SDK throws these via e.g.
(throw (errors/command-failed {...})) rather than a bare
(throw (Exception. ...)).
The single `ex-info` convention used by every `bsdkrun.*` namespace: a
plain `ex-info` whose `ex-data` carries a `:bsdkrun/error` kind key plus
whatever detail a caller needs to `case`/pattern-match on — no exception
class hierarchy, which would be un-idiomatic Clojure.
Every namespace in this SDK throws these via e.g.
`(throw (errors/command-failed {...}))` rather than a bare
`(throw (Exception. ...))`.Host-level image operations. Mirrors sdk/ruby/lib/bsdkrun/images.rb.
Host-level image operations. Mirrors `sdk/ruby/lib/bsdkrun/images.rb`.
Global-network operations — shared subnets where members reach each other
by IP and by name. Mirrors sdk/ruby/lib/bsdkrun/networks.rb.
Global-network operations — shared subnets where members reach each other by IP and by name. Mirrors `sdk/ruby/lib/bsdkrun/networks.rb`.
Spawns the bsdkrun CLI and captures its output.
Every invocation is prefixed with --log-level <n> (default 0) so the
SDK's captured output stays clean.
Spawns the `bsdkrun` CLI and captures its output. Every invocation is prefixed with `--log-level <n>` (default 0) so the SDK's captured output stays clean.
The machine lifecycle. A "sandbox" here is just a plain map, e.g.
{:id "abc123" :ssh-port 2222} — there is no object, no class. Create
one with create!, reconnect with get, or enumerate with list.
Every function below that acts on a machine takes a ref first: a sandbox
map, or a bare machine id/name string (see id) — bsdkrun itself
resolves a bare id prefix or exact name (core/src/db.rs's
find_machine), so (sandbox/stop! "web-1") needs no lookup first. And
since every ref-taking function returns either its result or (for
lifecycle ops with nothing interesting to return) ref itself, they thread
with ->/doto:
(-> (sandbox/get "web-1")
sandbox/start!
(sandbox/exec! ["uname" "-a"])
:stdout)
(doto (sandbox/get "web-1") ; same vm through every step, vm back at the end
sandbox/start!
(sandbox/exec! ["setup.sh"])
sandbox/stop!)
Mirrors sdk/ruby/lib/bsdkrun/sandbox.rb.
The machine lifecycle. A "sandbox" here is just a plain map, e.g.
`{:id "abc123" :ssh-port 2222}` — there is no object, no class. Create
one with [[create!]], reconnect with [[get]], or enumerate with [[list]].
Every function below that acts on a machine takes a `ref` first: a sandbox
map, or a bare machine id/name string (see [[id]]) — `bsdkrun` itself
resolves a bare id prefix or exact name (`core/src/db.rs`'s
`find_machine`), so `(sandbox/stop! "web-1")` needs no lookup first. And
since every `ref`-taking function returns either its result or (for
lifecycle ops with nothing interesting to return) `ref` itself, they thread
with `->`/`doto`:
```clojure
(-> (sandbox/get "web-1")
sandbox/start!
(sandbox/exec! ["uname" "-a"])
:stdout)
(doto (sandbox/get "web-1") ; same vm through every step, vm back at the end
sandbox/start!
(sandbox/exec! ["setup.sh"])
sandbox/stop!)
```
Mirrors `sdk/ruby/lib/bsdkrun/sandbox.rb`.Host-level toolchain / image operations. Mirrors
sdk/ruby/lib/bsdkrun/system.rb.
Host-level toolchain / image operations. Mirrors `sdk/ruby/lib/bsdkrun/system.rb`.
Pure functions turning a parsed CLI JSON row (a Clojure map with string
keys, as clojure.data.json/read-str produces without :key-fn keyword —
the CLI's JSON is already snake_case) into a kebab-case-keyword map. One
function per row shape, mirroring sdk/ruby/lib/bsdkrun/types.rb.
Also provides the Result-map helpers: since a bsdkrun.sandbox exec/agent
result here is a plain map ({:stdout ... :stderr ... :exit-code ... :command ...}), not an object with methods, ok?, text, json,
lines and throw-if-failed! are given as functions operating on that
map instead.
Pure functions turning a parsed CLI JSON row (a Clojure map with *string*
keys, as `clojure.data.json/read-str` produces without `:key-fn keyword` —
the CLI's JSON is already snake_case) into a kebab-case-keyword map. One
function per row shape, mirroring `sdk/ruby/lib/bsdkrun/types.rb`.
Also provides the `Result`-map helpers: since a bsdkrun.sandbox exec/agent
result here is a plain map (`{:stdout ... :stderr ... :exit-code ...
:command ...}`), not an object with methods, [[ok?]], [[text]], [[json]],
[[lines]] and [[throw-if-failed!]] are given as functions operating on that
map instead.Small helpers shared across the SDK's namespaces.
Small helpers shared across the SDK's namespaces.
Host-level volume operations. Mirrors sdk/ruby/lib/bsdkrun/volumes.rb.
Host-level volume operations. Mirrors `sdk/ruby/lib/bsdkrun/volumes.rb`.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |