`sunbeam connect` now fork-execs itself with a hidden `__vpn-daemon`
subcommand instead of running the daemon in-process. The user-facing
command spawns the child detached (stdio → log file, setsid for no
controlling TTY), polls the IPC socket until the daemon reaches
Running, prints a one-line status, and exits. The user gets back to
their shell immediately.
- src/cli.rs: `Connect { foreground }` instead of unit. Add hidden
`__vpn-daemon` Verb that the spawned child runs.
- src/vpn_cmds.rs: split into spawn_background_daemon (default path)
and run_daemon_foreground (used by both `connect --foreground` and
`__vpn-daemon`). Detached child uses pre_exec(setsid) and inherits
--context from the parent so it resolves the same VPN config.
Refuses to start if a daemon is already running on the control
socket; cleans up stale socket files. Switches the proxy bind from
16443 (sienna's existing SSH tunnel uses it) to 16579.
- sunbeam-net/src/daemon/lifecycle: add a SocketGuard RAII type so the
IPC control socket is unlinked when the daemon exits, regardless of
shutdown path. Otherwise `vpn status` after a clean disconnect would
see a stale socket and report an error.
End-to-end smoke test against the docker stack:
$ sunbeam connect
==> VPN daemon spawned (pid 90072, ...)
Connected (100.64.0.154, fd7a:115c:a1e0::9a) — 2 peers visible
$ sunbeam vpn status
VPN: running
addresses: 100.64.0.154, fd7a:115c:a1e0::9a
peers: 2
derp home: region 0
$ sunbeam disconnect
==> Asking VPN daemon to stop...
Daemon acknowledged shutdown.
$ sunbeam vpn status
VPN: not running
98 lines
2.2 KiB
TOML
98 lines
2.2 KiB
TOML
[package]
|
|
name = "sunbeam"
|
|
version = "1.1.2"
|
|
edition = "2024"
|
|
description = "Sunbeam Studios CLI"
|
|
repository = "https://src.sunbeam.pt/studio/cli"
|
|
license = "MIT"
|
|
|
|
[[bin]]
|
|
name = "sunbeam"
|
|
path = "src/main.rs"
|
|
|
|
[workspace]
|
|
members = ["sunbeam-sdk", "sunbeam-net"]
|
|
resolver = "3"
|
|
|
|
[dependencies]
|
|
# Workspace
|
|
sunbeam-sdk = { path = "sunbeam-sdk" }
|
|
sunbeam-net = { path = "sunbeam-net" }
|
|
|
|
# Core
|
|
thiserror = "2"
|
|
tokio = { version = "1", features = ["full"] }
|
|
clap = { version = "4", features = ["derive"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
serde_yaml = "0.9"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
rustls = { version = "0.23", features = ["ring"] }
|
|
|
|
# Kubernetes
|
|
kube = { version = "0.99", features = ["client", "runtime", "derive", "ws"] }
|
|
k8s-openapi = { version = "0.24", features = ["v1_32"] }
|
|
|
|
# HTTP + TLS
|
|
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
|
bytes = "1"
|
|
|
|
# SSH
|
|
russh = "0.46"
|
|
russh-keys = "0.46"
|
|
|
|
# Crypto
|
|
rsa = "0.9"
|
|
pkcs8 = { version = "0.10", features = ["pem"] }
|
|
pkcs1 = { version = "0.7", features = ["pem"] }
|
|
sha2 = "0.10"
|
|
hmac = "0.12"
|
|
base64 = "0.22"
|
|
rand = "0.8"
|
|
aes-gcm = "0.10"
|
|
argon2 = "0.5"
|
|
indicatif = { version = "0.17", features = ["tokio"] }
|
|
|
|
# Certificate generation
|
|
rcgen = "0.14"
|
|
|
|
# SMTP
|
|
lettre = { version = "0.11", default-features = false, features = ["smtp-transport", "tokio1-rustls-tls", "builder", "hostname"] }
|
|
|
|
# Archive handling
|
|
flate2 = "1"
|
|
tar = "0.4"
|
|
|
|
# Async
|
|
futures = "0.3"
|
|
tokio-stream = "0.1"
|
|
|
|
# Utility
|
|
tempfile = "3"
|
|
dirs = "5"
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
|
|
# OpenBao/Vault client
|
|
vaultrs = "0.8"
|
|
|
|
# Workflow engine
|
|
wfe = { version = "1.6.3", registry = "sunbeam" }
|
|
wfe-core = { version = "1.6.3", registry = "sunbeam", features = ["test-support"] }
|
|
wfe-sqlite = { version = "1.6.3", registry = "sunbeam" }
|
|
wfe-yaml = { version = "1.6.3", registry = "sunbeam" }
|
|
async-trait = "0.1"
|
|
hostname = "0.4.2"
|
|
whoami = "2.1.1"
|
|
libc = "0.2.184"
|
|
|
|
[dev-dependencies]
|
|
wiremock = "0.6"
|
|
|
|
[build-dependencies]
|
|
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] }
|
|
sha2 = "0.10"
|
|
flate2 = "1"
|
|
tar = "0.4"
|
|
chrono = "0.4"
|