Motty
原生桌面 SSH 工作台:终端、SFTP/SCP、端口转发、VNC 与 RDP 远程桌面、AI 助手都在一个窗口里。Go 编写,没有 Electron,空闲时保持安静。免费开源,支持 macOS、Windows 和 Linux。
翻譯準備中
A hawkBit compatible OTA update server in Rust
翻譯準備中
正在載入完整 README。
檢視完整 README ↗A hawkBit-compatible OTA update server in Rust. One binary, one config file. Speaks hawkBit's DDI v1 API (SWUpdate, RAUC hawkbit-updater and other hawkBit clients work unchanged — see the Zephyr guide for a worked example and a per-feature compatibility matrix) and the core Management API workflow.
Full documentation lives in docs/ as an mdbook — overview, getting
started, per-feature guides, concepts, and API/config/CLI reference. Build it
locally with mdbook build docs (or mdbook serve docs), or read the published
site once GitHub Pages is enabled.
CHANGELOG.md indexes what changed in each release; the
GitHub releases carry the full
notes and upgrade guidance.
cargo build --release
printf 'yourpassword\n' | ./target/release/raptor hash-password
# put the hash in raptor.toml, then:
./target/release/raptor serve --config raptor.toml
Minimal raptor.toml:
bind = "0.0.0.0:8088"
database_url = "sqlite://raptor.db?mode=rwc" # or postgres://user:pass@host/db
artifact_dir = "./artifacts"
[ddi]
gateway_token = "change-me" # or anonymous = true for dev
# confirmation_flow = true # assignments wait for device/operator confirmation
[mgmt]
username = "admin"
password_hash = "$argon2id$..."
Deploy an update:
# module + artifact + distribution set
curl -u admin:pw -X POST localhost:8088/rest/v1/softwaremodules \
-H 'Content-Type: application/json' \
-d '[{"name":"rootfs","version":"1.0","type":"os"}]'
curl -u admin:pw -X POST localhost:8088/rest/v1/softwaremodules/1/artifacts \
-F '[email protected]'
curl -u admin:pw -X POST localhost:8088/rest/v1/distributionsets \
-H 'Content-Type: application/json' \
-d '[{"name":"release","version":"1.0","type":"os","modules":[{"id":1}]}]'
# assign to a device (auto-registered on first poll)
curl -u admin:pw -X POST localhost:8088/rest/v1/targets/my-device/assignedDS \
-H 'Content-Type: application/json' -d '{"id":1,"type":"forced"}'
Prebuilt .deb packages are attached to each GitHub Release:
sudo dpkg -i raptor_*.deb
The package installs:
/usr/bin/raptor — the server (with the web console embedded)/usr/bin/raptorctl — the CLI & TUI client/etc/raptor/config.toml — default config (a dpkg conffile; your edits
survive upgrades)raptor.service systemd unit running as a locked-down DynamicUser, with
state (SQLite DB + artifacts) under /var/lib/raptorThe service is enabled but not started on install, because you must set an admin password first:
raptor hash-password # type a password, paste the hash into config
sudoedit /etc/raptor/config.toml # set password_hash, pick a DDI auth mode
sudo systemctl start raptor
Keep plaintext secrets (e.g. a DDI gateway token) out of the world-readable
config — put them in a root-only /etc/raptor/raptor.env as RAPTOR_*
environment overrides, which the unit loads before dropping privileges.
To build a package yourself: mise run deb (tools pinned in mise.toml;
install mise first). It clears stale console assets
before dx build — see Web UI for why that matters.
raptor ships an optional web console (Dioxus/WASM) embedded in the binary.
One-time setup, then the build:
rustup target add wasm32-unknown-unknown
mise install # dx pinned in mise.toml to match `dioxus = "=0.7.10"`
mise run ui # rm -rf target/dx/raptor-ui/release + dx build --release
cargo build --release --features embed-ui
dx writes content-hashed asset filenames and never prunes superseded ones, so
target/dx/raptor-ui/release/web/public/assets/ accumulates one wasm bundle and
one stylesheet per build. embed-ui embeds that whole directory, so on a target
dir that has seen a few builds the binary carries several megabytes of assets
nothing can reach. Clearing the release output first keeps the .deb honest;
CI builds from a fresh checkout and is unaffected.
Then browse to http://<server>/ui and log in with the [mgmt] credentials.
The UI authenticates with an httpOnly session cookie (POST /rest/v1/login);
basic auth for curl/CI keeps working unchanged. CSRF note: the cookie is
SameSite=Strict, which blocks cross-site browser POSTs; there is no separate
CSRF token. Sessions live in memory — a server restart logs everyone out.
Without --features embed-ui, raptor builds and runs exactly as before and
/ui returns 404 — the Dioxus toolchain is only needed when embedding the UI.
Development loop (hot reload):
Both commands run from the repo root:
cargo run -- serve --config raptor.toml # terminal 1: API on :8088
dx serve --package raptor-ui # terminal 2: UI on :8080/ui, /rest proxied
dx must be invoked from the workspace root — from inside raptor-ui/ it
panics canonicalizing the workspace default-members paths against the wrong
cwd.
(dx build --release may print a non-fatal wasm-opt/DWARF warning — harmless,
the bundle still builds.)
Release smoke test: login → create module → upload artifact → create distribution set → assign module → deploy to a target → watch the action on the dashboard → cancel or complete → logout.
raptorctl (crate raptor-cli) is a scriptable client and terminal dashboard
for the Management API — build/upload artifacts, manage targets, and watch
deployments from a terminal or CI job, no browser required:
cargo build --release -p raptor-cli # or a prebuilt release archive / the .deb
raptorctl login --url http://localhost:8088 --user admin
raptorctl target list
raptorctl tui
See the CLI & TUI guide for the full command reference and TUI keybindings.
以上為 README 的開頭部分。其餘內容請閱讀原文。 檢視完整 README ↗