bunops

0

Описание

Языки

  • TypeScript99,9%
  • Dockerfile0,1%
README.md

bunops

Minimal bun CLI scaffold.

Localizations

  • Russian:
    docs/ru/README.md

Quality Checks

Usage

Git source

For git source, provide a repo URL via

--source
or
BUNOPS_GIT_REPO
. Optional
--rev
selects a branch, tag, or commit. If omitted, the default remote branch is used.

SSH/credentials are handled by git itself. Use your normal setup, for example:

S3 source

Uses Bun's built-in S3 client.

You can also use explicit flags:

Credentials and endpoint can be provided via environment variables:

State

State is written to

.bunops/state.json
by default (override with
BUNOPS_STATE_PATH
). Agent node status is written to
.bunops/node-state.json
by default (override with
BUNOPS_NODE_STATE_PATH
). Node ID defaults to hostname (override via
--node-id
or
BUNOPS_NODE_ID
). Default mode for node-state file is
0640
(override with
BUNOPS_NODE_STATE_MODE
, e.g.
0644
). Durability fsync for node-state writes is disabled by default for performance. Enable with
BUNOPS_NODE_STATE_FSYNC=true
when strict crash-consistency is required.

Example:

Locking

To prevent concurrent runs, a lockfile is created at

.bunops/lock.json
by default. Override with
BUNOPS_LOCK_PATH
and TTL (stale detection) with
BUNOPS_LOCK_TTL_MS
. If a stale lock is detected, it will be removed and the run will continue.

Reconcile

run-once
runs a single reconcile cycle.
agent
runs continuously on an interval (default
60s
, override with
--interval 5m
).

Fleet directives

Agent reads fleet directives from

/var/lib/bunops/fleet-directives.json
by default (override with
BUNOPS_DIRECTIVES_PATH
).

Supported payload fields:

  • freeze
    (
    bool
    ): skip reconcile and publish
    status=frozen
  • desiredRevision
    (
    string
    ): overrides
    --rev
  • pause
    (
    bool
    ): sync source, do not apply tasks (
    check
    mode)
  • reconcileIntervalOverride
    (
    duration
    ): overrides agent loop interval
  • mode
    (
    report|enforce
    ):
    report
    forces
    check
    mode
  • rolloutWave
    ,
    rolloutId
    (
    string
    ): propagated into
    node-state.json

Precedence:

  • directives override CLI/config (
    desiredRevision
    over
    --rev
    , interval override over
    --interval
    )
  • pause=true
    or
    mode=report
    force no-apply reconcile (
    check
    )

Safety:

  • missing directives file => defaults
  • invalid JSON => warning + defaults (agent continues)

Orchestrator CLI (SSH)

bunops orch
manages fleet nodes over SSH using file backend (
node-state.json
/
fleet-directives.json
).

Commands:

  • orch status --inventory <...>
  • orch freeze --inventory <...> [--limit ...]
  • orch unfreeze --inventory <...> [--limit ...]
  • orch pin --inventory <...> --revision <sha> [--limit ...]
  • orch unpin --inventory <...> [--limit ...]
  • orch set --inventory <...> --file directives.json [--limit ...]

Common options:

  • --parallel <n>
    : parallel hosts (default
    10
    )
  • --timeout-ms <n>
    : timeout per host (default
    10000
    )
  • --user
    ,
    --port
    ,
    --identity
    : SSH connection options
  • --limit
    :
    host-1,host-2,@group

Status output options:

  • --json
    : machine-readable output for CI
  • --only failed|drift|frozen
    : filter rows
  • --columns host,nodeId,status,currentRevision,desiredRevision,lastRun,drift,error
    : custom table columns

Remote file paths:

  • --node-state-path
    (status), default
    /var/lib/bunops/node-state.json
  • --directives-path
    (write commands), default
    /var/lib/bunops/fleet-directives.json

Playbook is read from

playbook.yml
inside the synced source directory (override with
BUNOPS_PLAYBOOK
).

You can set a root path inside the repo for all relative lookups:

Then

BUNOPS_PLAYBOOK=vm-playbook.yml
resolves to
<repo>/examples/vm-playbook.yml
, and roles/templates/files/inventory resolve relative to that root.

Minimal playbook example:

Supported tasks:

  • shell
    :
    command
    , optional
    timeoutMs
    ,
    cwd
  • copy
    :
    src
    ,
    dest
    , optional
    mode
    ,
    owner
    ,
    group
  • template
    :
    src
    ,
    dest
    , optional
    mode
    ,
    owner
    ,
    group
  • package
    :
    name
    , optional
    state
    (present/latest/absent),
    manager
    (apt/dnf/yum),
    sudo
  • service
    :
    name
    , optional
    state
    (started/stopped/restarted),
    enabled
    ,
    sudo
  • user
    :
    name
    , optional
    state
    (present/absent),
    shell
    ,
    home
    ,
    groups
    ,
    sudo
  • group
    :
    name
    , optional
    state
    (present/absent),
    sudo

Shell commands run via Bun Shell (pipes and redirects supported).

Handlers

Tasks can notify handlers. Handlers run once per reconcile cycle, even if multiple tasks notify them.

notify
can be a string or a list of handler names.

Plugins

Custom modules are discovered from:

  • plugins/modules/*.js
  • modules.d/*.js

Plugin contract:

  • export
    default
    object with
    type
    and
    run(context)
  • run
    returns
    { changed: boolean, stdout?: string, stderr?: string }

Example plugin and playbook are in:

  • examples/plugins/modules/line_append.js
  • examples/plugin-playbook.yml

Details:

docs/plugins.md

Variables

Sources (lowest -> highest precedence):

  1. Role defaults/vars (reserved for roles support)
  2. Inventory vars (reserved for inventory support)
  3. Play vars (
    vars:
    in playbook)
  4. Task vars (
    vars:
    in task)
  5. Environment (
    BUNOPS_VAR_*
    or
    BUNOPS_VARS_JSON
    )
  6. Var files (
    --var-file
    ), later files override earlier
  7. CLI vars (
    --var key=value
    )

Examples:

Env:

Inventory

Supports YAML or INI inventory. Use

--inventory
to point to a file or directory. Group/host vars are read from
inventory/group_vars/*.yml
and
inventory/host_vars/*.yml
in the repo.

Example YAML inventory:

Example INI inventory:

Use flags to select host/group vars:

Template supports variables via

vars
in playbook:

Roles

Supports Ansible-like roles:

  • roles/<name>/tasks/main.yml
  • roles/<name>/templates/
  • roles/<name>/files/

Playbook can include roles:

Or inline:

Logging

Set

BUNOPS_LOG=json
for JSON logs. Default is pretty logs.

Tutorial

  1. Prepare a repo with
    playbook.yml
    and any referenced files/templates.
  2. Run one cycle:
  1. Run as daemon:

Example playbook and assets are in

examples/
.

Подробная документация по модулям:

docs/modules/README.md
.

systemd example

Build

build:bin
produces a native binary at
dist/bunops
using
bun build --compile
.