omnyserver 0.4.0 copy "omnyserver: ^0.4.0" to clipboard
omnyserver: ^0.4.0 copied to clipboard

Distributed server orchestration platform written in pure Dart. A central Hub manages a fleet of Node agents over WebSocket-on-TLS: live monitoring, capability detection, presets, formulas and desired [...]

omnyserver #

pub package Null Safety Dart CI GitHub Tag New Commits Last Commits Pull Requests Code size License

A distributed server-orchestration platform written in pure Dart. A central Hub manages a fleet of Node agents — a cloud-like view of every server's status, resources, capabilities, services and deployments, driven from one place.

Nodes dial the Hub outbound over WebSocket-on-TLS (wss) — the same identity-centric, NAT-friendly model as its sibling omnyshell: you address servers by node identity, not host:port. A node behind NAT needs no inbound port, and the Hub needs exactly one: the node channel and the REST API share a single TLS listener.

                       :8443 (TLS)
        ┌──────────────────┴──────────────────┐
        │  /node      → node control channel  │
        │  /shell     → OmnyShell broker      │
   ────►│  /api/v1    → REST API              │◄────  CLI / REST client
        │  /metrics   → Prometheus            │
        └──────────────────┬──────────────────┘
                          HUB
                ▲          ▲          ▲
              wss│       wss│       wss│      (outbound; NAT-friendly)
              Node       Node       Node
omnyserver cert gen --out certs
omnyserver hub start  --cert certs/server.crt --key certs/server.key \
                      --api-token api-secret --grant node-account:node-token:node
omnyserver node start --hub wss://hub:8443 --id worker-01 \
                      --principal node-account --token node-token --ca certs/ca.crt
omnyserver nodes list --api https://hub:8443 --ca certs/ca.crt --token api-secret

Remote shell, from the same Hub #

Add --shell and the Hub also brokers OmnyShell sessions — same port, same certificate, same credentials. A node becomes shell-capable with --with-shell, in the same process:

omnyserver hub start  … --shell
omnyserver node start … --with-shell --shell-label allow-roles=admin

omnyshell exec worker-01 'uptime' --hub wss://hub:8443/shell \
                                  --principal alice --token admin-token --ca certs/ca.crt

A standalone OmnyShell node or service can attach to the same Hub just as well — point it at the shell mount:

omnyshell service install node --hub wss://hub:8443/shell --id worker-01 --token …

Everything is available both as first-class Dart APIs and as the omnyserver CLI and a versioned REST API (/api/v1) ready for a future Web UI. Runs on Linux, macOS and Windows.

Built on omnyhub — the transport, node registry, heartbeat watchdog, RPC correlation and HTTP routing are the framework's, so OmnyServer is only what is actually its own.

API Documentation #

See the API Documentation for the full list of classes and APIs.

Features #

  • Hub orchestrator — node registration, discovery, authentication, live monitoring, audit and event aggregation, with a live model of every node.
  • Node agents — connect, heartbeat, report status & capabilities, execute commands/formulas/presets, and reconnect automatically.
  • Live monitoring — CPU, memory, storage, OS, processes and logs, designed for real-time dashboards.
  • Capability detection — Docker, Podman, Dart, Python, Java, Node.js, Git, SSH, CUDA, Metal, OpenCL — detected dynamically.
  • Formulas & presets — idempotent, cross-platform install/manage procedures, composed into presets, with desired-state reconciliation.
  • Service management — install Hub/agent as systemd / launchd / Windows services via dart_service_manager.
  • Security — token & Ed25519 public-key auth, role-based authorization, content-derived identity, audit log; RBAC/multi-tenant ready.
  • Persistence — repository abstractions with in-memory, JSON-directory and SQLite backends (PostgreSQL/distributed ready).
  • HTTP API & metrics — versioned REST API with OpenAPI, structured errors, and Prometheus/OpenTelemetry-ready /metrics, served on the Hub's own TLS port beside the node channel — one port to open, one certificate to manage.
  • EventsNodeConnected, HeartbeatReceived, FormulaFinished, PresetApplied, … with subscriptions and streaming.
  • Remote shell — the Hub can also broker OmnyShell sessions on the same port and credentials (--shell), and a node can be both an OmnyServer agent and an OmnyShell node in one process (--with-shell).

Architecture #

OmnyServer is a single package with role-based export libraries over a layered lib/src (domain → application → infrastructure, plus protocol and shared).

lib/
  omnyserver.dart        core: models, protocol, contracts
  omnyserver_hub.dart    Hub runtime + server infra + persistence + HTTP API + metrics
  omnyserver_node.dart   Node agent + monitors + capabilities + formulas + services
  omnyserver_cli.dart    CLI as a library (buildRunner, HubApiClient)
  src/
    domain/         value objects, entities, Formula, auth & repository contracts, events
    application/    OmnyServerHub, NodeAgent, NodeFormulaService, EventAggregator
    infrastructure/ auth, monitors, capabilities, persistence, http, metrics
    protocol/       handshake messages + codec, operation payloads
    shared/         errors, json helpers, clock, ids

See doc/architecture.md, doc/protocol.md, doc/security.md, doc/formulas.md and doc/deployment.md.

Getting started #

dependencies:
  omnyserver: ^0.3.0

Or install the CLI:

dart pub global activate omnyserver

Supported platforms: Linux, macOS, Windows. Requires the Dart SDK 3.12+.

Usage #

Quick start (embedded Hub + Node) #

The fastest way to see the whole stack work is the embedded example, which starts a Hub and a Node in one process and prints the node's live status:

dart run example/omnyserver_embedded_example.dart
final hub = OmnyServerHub(HubConfig(
  host: '127.0.0.1', port: 0,
  securityContext: SecurityContext()
    ..useCertificateChain(certs.serverCert)
    ..usePrivateKey(certs.serverKey),
  authenticator: TokenAuthenticator({
    'node-token': TokenGrant(principal: PrincipalId('node-account'), roles: {'node'}),
  }),
));
await hub.start();

final agent = NodeAgent(NodeAgentConfig(
  hubUri: Uri.parse('wss://127.0.0.1:${hub.port}'),
  nodeId: 'demo-node',
  credentials: const TokenCredentialProvider(principal: 'node-account', token: 'node-token'),
  securityContext: SecurityContext(withTrustedRoots: false)..setTrustedCertificates(certs.caCert),
  statusProvider: const SystemMonitor().snapshot,
  capabilityProvider: CapabilityScanner.standard().scan,
));
await agent.start();

// The node pushes a status snapshot as it registers, but it still has to reach
// the Hub — give it a moment before reading.
await Future<void>.delayed(const Duration(seconds: 1));

final status = hub.getStatus(NodeId('demo-node'));
print('${status?.cpu.coreCount} cores, ${status?.cpu.usagePercent}% used');

Run a Hub #

dart run bin/omnyserver.dart cert gen --out certs
./run-hub.sh

The Hub only speaks wss and requires a certificate chain + key. Dart's TLS stack rejects a bare self-signed leaf, so cert gen builds a CA → leaf chain; nodes trust the CA with --ca.

With a real certificate (LetsEncrypt, cert-manager, a mounted secret), point the Hub at the directory instead of the two files:

omnyserver hub start --tls-dir /etc/letsencrypt/live/hub.example.com \
                     --api-token api-secret --grant node-account:node-token:node

--tls-dir reads fullchain.pem + privkey.pem and re-checks them periodically: when the certificate is renewed the Hub rebinds its listener with the fresh one — no restart, and established connections drain on the old listener. It replaces --cert/--key; passing both is an error.

Run a Node #

dart run bin/omnyserver.dart node start \
  --hub wss://hub:8443 --id worker-01 \
  --principal node-account --token node-token --ca certs/ca.crt

Discover and operate (via the REST API) #

omnyserver nodes list                 --api https://hub:8443 --ca certs/ca.crt --token api-secret
omnyserver node status  worker-01     --api https://hub:8443 --ca certs/ca.crt --token api-secret
omnyserver node restart worker-01     --api https://hub:8443 --ca certs/ca.crt --token api-secret
omnyserver formula run docker worker-01 --action verify --api https://hub:8443 --ca certs/ca.crt --token api-secret
omnyserver preset apply docker-host.json worker-01 --api https://hub:8443 --ca certs/ca.crt --token api-secret

The CLI's operational commands call the Hub's HTTP API — exactly the surface any other client uses.

HTTP API #

Served over HTTPS on the Hub's own port, alongside the node control channel — one TLS listener, two surfaces. Versioned under /api/v1:

Method & path Description
GET /nodes list registered nodes
GET /nodes/{id} node descriptor
GET /nodes/{id}/status live status snapshot
GET /nodes/{id}/capabilities advertised capabilities
POST /nodes/{id}/restart · /shutdown · /update node control
POST /nodes/{id}/formula run a formula action
POST /presets/apply apply a preset to a node
GET /events · /audit recent events / audit
GET /openapi.json OpenAPI document
GET /metrics (root) Prometheus exposition

How it works #

OmnyServer is built on omnyhub: the transport, node registry, heartbeat watchdog, RPC correlation and HTTP routing are the framework's. What OmnyServer adds is what is actually its own — identity, capability detection, formulas, presets, reconciliation, auditing and persistence.

Connection flow #

  1. A Node dials the Hub over wss at /node and sends Hello.
  2. The Hub issues a challenge nonce; the Node answers with a token or a signed nonce. On success the Hub returns the resolved principal and roles.
  3. The Node registers its descriptor (identity, platform, capabilities, labels). The Hub authorizes the registration — a node credential may enrol a node and nothing else — then adds it to the live registry and begins receiving heartbeats, each carrying a live status snapshot.
  4. The Hub dispatches operations (formula, preset, restart, …) as RPCs over the same connection and correlates the replies.

Security envelope #

All transport is TLS. Authentication is pluggable (token / Ed25519 public key); authorization is role-based and fail-closed; identity is content-derived; every sensitive action is audited. See doc/security.md.

The OmnyGrid ecosystem #

OmnyServer is one of four packages sharing the same identity-centric, NAT-friendly model — nodes dial a Hub outbound, and you address them by identity rather than host:port.

Package What it does
omnyhub The HUB framework everything below is built on: transport, routing, auth, node registry and control plane.
omnyserver (this) Fleet orchestration — monitoring, capabilities, formulas, presets, desired-state reconciliation.
omnyshell Remote shell — SSH-like sessions brokered to a node by identity. An OmnyServer Hub can host its broker (--shell).
omnydrive File & git drive synchronization.

Roadmap #

  • Remote agent self-update and OS-update orchestration.
  • Additional transports (gRPC, QUIC, message bus) behind omnyhub's Transport.
  • PostgreSQL and distributed persistence backends.
  • Richer reconciliation (dependency ordering, version comparison).
  • Web UI on top of the REST API; RBAC / multi-tenant authorization.
  • Kubernetes orchestration and AI-workload scheduling.

Running the example and tests #

dart pub get
dart analyze
dart test
dart run example/omnyserver_embedded_example.dart

Author #

Graciliano M. Passos: gmpassos@GitHub.

License #

Apache License - Version 2.0.

0
likes
0
points
391
downloads

Publisher

unverified uploader

Weekly Downloads

Distributed server orchestration platform written in pure Dart. A central Hub manages a fleet of Node agents over WebSocket-on-TLS: live monitoring, capability detection, presets, formulas and desired-state reconciliation, exposed both as first-class Dart APIs and a REST HTTP API. Ships Hub, Node and CLI implementations.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

args, cryptography, dart_service_manager, meta, omnyhub, omnyshell, path, sqlite3, uuid

More

Packages that depend on omnyserver