2026-04-11 23:18:01 +07:00
2026-04-07 01:46:58 +07:00
2026-04-12 00:45:32 +07:00
2026-04-12 00:45:32 +07:00
ahh
2026-04-08 08:57:44 +07:00
2026-04-12 01:39:18 +07:00
2026-04-12 00:22:45 +07:00
2026-04-06 17:42:04 +07:00
2026-04-12 02:00:01 +07:00
2026-04-12 01:43:14 +07:00
2026-04-06 05:43:37 +07:00
2026-04-06 06:11:58 +07:00
2025-08-25 06:21:12 +07:00
2026-04-12 02:00:01 +07:00
2026-04-12 01:43:14 +07:00
2025-08-25 06:21:12 +07:00
2026-04-12 02:00:01 +07:00

wakey

wakey is a Wake-on-LAN and LAN-observability tool for a Linux router.

It started as a small web UI running on-device. It is now being reshaped into a service-first project with:

  • a reusable core model
  • a Linux/OpenWrt adapter layer
  • a CLI for operators
  • an outbound agent plus control-plane model

What it does

wakey currently focuses on a small set of router-side jobs:

  • inspect LAN neighbor state
  • read DHCP lease data
  • merge those facts into a higher-level device inventory
  • list useful interface/broadcast information
  • send Wake-on-LAN packets

In practice that means commands like:

wakey status bedroom-pc
wakey leases --include-state
wakey devs
wakey wake bedroom-pc
wakey wake --mac aa:bb:cc:dd:ee:ff

Workspace layout

  • wakey-core
    • shared types and parsing
    • device, neighbor, DHCP, interface, and wake models
  • wakey-linux
    • Linux/OpenWrt adapter
    • DHCP lease loading, interface summaries, neighbor lookup, WoL sending
  • wakey
    • service layer and operator CLI
  • wakey-agent
    • outbound router daemon, enrollment, websocket command execution
  • wakey-control-plane
    • enrollment endpoint, connected-agent registry, command relay API
  • ipjs
    • typed wrappers around Linux ip -j ... data
    • JSON-first, with optional experimental netlink backends

Current architecture

Inside the wakey crate:

  • src/service
    • the real use-case layer
    • status, leases, inventory, interfaces, wake, and query resolution

The long-term direction is:

  • keep the service layer stable
  • keep the local CLI stable for operators
  • run remote control via outbound agent + control-plane relay

Future direction

The project now uses:

  • wakey for local operator workflows and shared service behavior
  • wakey-agent for outbound enrollment and websocket execution
  • wakey-control-plane for enrollment, registry, and command relay

Logging and troubleshooting

Both daemons emit structured tracing logs to stderr. If you are not seeing enrollment/command activity, run with increased verbosity.

Control-plane also supports a config file at /etc/wakey-control-plane/config.toml (override with --config-file) so you can persist telemetry settings instead of passing flags.

You can scaffold this file with:

wakey-control-plane init-config

Or bootstrap once during serve (writes only if config is missing):

wakey-control-plane serve --bootstrap-config

Inspect current persisted state:

wakey-control-plane state-stats

List/revoke enroll tokens from CLI:

wakey-control-plane list-enroll-tokens --include-expired
wakey-control-plane revoke-enroll-token --token enr-...

Machine-readable output is available:

wakey-control-plane list-enroll-tokens --include-expired --json
wakey-control-plane state-stats --json

Example:

data_dir = "/var/lib/wakey-control-plane"
bind = "0.0.0.0:8080"
public_url = "https://cp.example.com"
state_file = "state.db"
pid_file = "wakey-control-plane.pid"
command_timeout_ms = 30000
enroll_token_ttl_seconds = 86400

[telemetry]
otlp_endpoint = "http://127.0.0.1:4317"
service_name = "wakey-control-plane"
json_logs = false

If telemetry.otlp_endpoint is omitted, logs still work normally and only local structured logs are emitted.

State is persisted in an embedded sled database (default /var/lib/wakey-control-plane/state.db). Relative paths in config are resolved under data_dir.

Enroll tokens are now expiring and revocable. Issuance returns expires_at_unix. Expired tokens are rejected on enroll and can be garbage-collected periodically or on demand.

Quick start

Control-plane:

wakey-control-plane -v serve --bind 0.0.0.0:8787 --public-url https://cp.example.com

Agent:

wakey-agent -v serve --config /etc/wakey-agent/config.toml

Fine-grained log filters

Use RUST_LOG when you want to focus on websocket/API internals.

RUST_LOG=wakey_control_plane=debug,wakey_agent=debug wakey-control-plane serve
RUST_LOG=wakey_agent=debug wakey-agent serve

What you should see

During registration/enroll:

  • control-plane: issued enroll token, then agent enrollment accepted
  • agent: starting agent enrollment, then agent enrollment succeeded and config was written

During live connectivity:

  • control-plane: agent websocket upgraded, agent authenticated, agent disconnected
  • agent: connecting agent websocket, agent websocket dns resolved, agent websocket connected, agent websocket session authenticated, heartbeat sent (debug)

During command relay:

  • control-plane: dispatching command to agent
  • agent: received command from control-plane, then command execution completed (or command dispatch failed)
  • control-plane: agent command completed (or timeout/error warnings)

During daemon control/state operations:

  • control-plane: wrote control-plane pid file, saved control-plane store, reloaded control-plane store from disk
  • agent: wrote wakey-agent pid file, sending wakey-agent reload signal

Control-plane admin API includes token management endpoints:

  • POST /api/v1/control/enroll-token?ttl_seconds=<n>
  • GET /api/v1/control/enroll-tokens?include_expired=true|false
  • DELETE /api/v1/control/enroll-tokens/{token}
  • GET /api/v1/control/audit/events?agent_id=<id>&event_type=<type>&limit=<n>
  • GET /api/v1/control/alerts?lookback_seconds=900
  • GET /api/v1/control/alerts/history?since_unix=<ts>&limit=<n>
  • GET /api/v1/control/alerts/ws (websocket snapshots + recent transitions)

If commands still appear silent, verify both processes are running with -v and that RUST_LOG is not overriding to a stricter level.

If websocket connect feels delayed, compare dns_resolve_ms and ws_connect_ms from agent logs. Slow DNS is a common source of multi-second connection stalls when using hostnames; using a stable IP or local host mapping can avoid this.

Edge Exposure (Caddy + Cloudflare Access)

Control-plane is intended to run behind a reverse proxy with TLS termination. Use Cloudflare Access to protect /ui/* and /api/v1/control/*, while keeping agent enrollment and websocket endpoints reachable.

An example Caddy config is provided at:

  • deploy/Caddyfile.control-plane.example

Expected exposure model:

  • Public: /healthz, /api/v1/agents/enroll, /api/v1/agent/ws
  • Private (Cloudflare Access): /ui/*, /api/v1/control/*

Control-plane routing is organized with the same boundary in code:

  • public router: health, enroll, agent websocket
  • control router: all /api/v1/control/* admin endpoints

This keeps edge policy and app routing aligned as features grow.

UI (Initial Shell)

Control-plane now serves a minimal operator shell at /ui/ for immediate workflow testing (agents, command runner, alerts, and recent audits).

This UI is intentionally lightweight and is the starting point for the richer Operator UI v1 plan.

CLI

wakey is usable as a local/operator CLI.

Status

Show device status rows using a free-form selector:

wakey status bedroom-pc

Or use explicit filters:

wakey status --dev br-lan --nud reachable
wakey status --mac aa:bb:cc:dd:ee:ff
wakey status --json

Leases

Show DHCP leases:

wakey leases
wakey leases --include-state
wakey leases --include-state --json

Wake

Query mode:

wakey wake bedroom-pc

Explicit/manual mode:

wakey wake --mac aa:bb:cc:dd:ee:ff
wakey wake --mac aa:bb:cc:dd:ee:ff --ip 192.168.1.255
wakey wake --mac aa:bb:cc:dd:ee:ff --json

Rules:

  • query mode and explicit --mac/--ip mode are mutually exclusive
  • --ip requires --mac
  • --mac without --ip fans out to interface broadcast targets

Interfaces

Show condensed interface summaries:

wakey devs
wakey devs br-lan
wakey devs --up
wakey devs --json

Tests

This repo has two useful testing modes:

  • local compile checks
  • live on-device tests against the real router/runtime environment

Local

cargo check
cargo test --no-run
cargo clippy --all-targets --all-features -- -D warnings

Focused control-plane state tests:

cargo test -p wakey-control-plane state::store::tests::gc_removes_expired_tokens
cargo test -p wakey-control-plane state::store::tests::enroll_rejects_expired_token
cargo test -p wakey-control-plane state::store::tests::stats_counts_agents_and_expired_tokens

On-device

Some integration tests are intentionally #[ignore] because they use real router state. Use the PowerShell helper:

./scripts/test_remote.ps1 -Package wakey -BinaryFilter integration_live_services -Ignored -NoCapture
./scripts/test_remote.ps1 -Package wakey -BinaryFilter integration_inventory -Ignored -NoCapture

You can further narrow execution with -Filter to select individual Rust test functions inside a test binary.

Build target

This project is primarily aimed at an OpenWrt/Linux ARM router target. The workspace is commonly built for:

armv7-unknown-linux-musleabihf

Some crates and tests are Linux-specific by design.

Notes

  • ipjs is JSON-first by default; experimental netlink paths exist where they are worth keeping.
  • the current web client is temporary and kept alive through explicit compatibility mapping
  • the service layer is the part intended to survive the migration
S
Description
router shit. TS GOT CARRIED BY codex and copilot. With too many features and too many bugs, how am I controlling ts things quality?
https://wakey.ldlda.com
Readme
3.8 MiB
0 Stars 1 Watchers 0 Forks
v0.3.7
Latest
2026-10-13 03:15:54 +07:00
Languages
Rust 71.2%
TypeScript 18.5%
PowerShell 4.6%
Shell 3.1%
CSS 1.5%
Other 1%