prepare for release!
This commit was merged in pull request #8.
This commit is contained in:
@@ -21,7 +21,8 @@ jobs:
|
|||||||
rustc -V
|
rustc -V
|
||||||
cargo -V
|
cargo -V
|
||||||
rustup target add armv7-unknown-linux-musleabihf
|
rustup target add armv7-unknown-linux-musleabihf
|
||||||
# x86_64-unknown-linux-gnu86_64-pc-windows-msvc aarch64-unknown-linux-gnu
|
rustup target add x86_64-unknown-linux-gnu
|
||||||
|
rustup target add aarch64-unknown-linux-gnu
|
||||||
|
|
||||||
- name: Cache cargo
|
- name: Cache cargo
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -37,17 +38,49 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cargo build --release --target armv7-unknown-linux-musleabihf -p wakey -p wakey-agent
|
cargo build --release --target armv7-unknown-linux-musleabihf -p wakey -p wakey-agent
|
||||||
|
|
||||||
|
- name: Build UI dist
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
cd ui
|
||||||
|
corepack enable
|
||||||
|
pnpm install --frozen-lockfile
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
- name: Build control-plane (linux gnu)
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
for target in x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
|
||||||
|
cargo build --release --target "$target" -p wakey-control-plane
|
||||||
|
done
|
||||||
|
|
||||||
- name: Package rootfs tarball
|
- name: Package rootfs tarball
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
./scripts/package_rootfs.ps1 -Version "${{ github.ref_name }}" -Target armv7-unknown-linux-musleabihf
|
./scripts/package_rootfs.ps1 -Version "${{ github.ref_name }}" -Target armv7-unknown-linux-musleabihf
|
||||||
|
|
||||||
|
- name: Package control-plane bundles
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
chmod +x scripts/update_wakey_cc.sh scripts/package_wakey_cc_bundle.sh
|
||||||
|
for target in x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
|
||||||
|
./scripts/package_wakey_cc_bundle.sh --version "${{ github.ref_name }}" --target "$target"
|
||||||
|
done
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: wakey-rootfs
|
name: wakey-rootfs
|
||||||
path: dist/wakey-rootfs-*armv7-unknown-linux-musleabihf.tgz
|
path: dist/wakey-rootfs-*armv7-unknown-linux-musleabihf.tgz
|
||||||
|
|
||||||
|
- name: Upload control-plane bundles
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: wakey-cc-bundles
|
||||||
|
path: dist/wakey-cc-*unknown-linux-gnu.tgz
|
||||||
|
|
||||||
- name: Publish Release to Gitea
|
- name: Publish Release to Gitea
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
uses: actions/gitea-release-action@v1
|
uses: actions/gitea-release-action@v1
|
||||||
@@ -55,4 +88,5 @@ jobs:
|
|||||||
token: ${{ secrets.GITEA_TOKEN }}
|
token: ${{ secrets.GITEA_TOKEN }}
|
||||||
files: |
|
files: |
|
||||||
dist/wakey-rootfs-*armv7-unknown-linux-musleabihf.tgz
|
dist/wakey-rootfs-*armv7-unknown-linux-musleabihf.tgz
|
||||||
|
dist/wakey-cc-*unknown-linux-gnu.tgz
|
||||||
tag_name: ${{ github.ref_name }}
|
tag_name: ${{ github.ref_name }}
|
||||||
|
|||||||
Generated
+2
-2
@@ -3106,7 +3106,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wakey-core"
|
name = "wakey-core"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"macaddr",
|
"macaddr",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -3117,7 +3117,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wakey-linux"
|
name = "wakey-linux"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"futures",
|
"futures",
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ bind = "0.0.0.0:8080"
|
|||||||
public_url = "https://cp.example.com"
|
public_url = "https://cp.example.com"
|
||||||
state_file = "state.db"
|
state_file = "state.db"
|
||||||
pid_file = "wakey-control-plane.pid"
|
pid_file = "wakey-control-plane.pid"
|
||||||
|
ui_dist_dir = "/opt/wakey/ui/dist"
|
||||||
command_timeout_ms = 30000
|
command_timeout_ms = 30000
|
||||||
enroll_token_ttl_seconds = 86400
|
enroll_token_ttl_seconds = 86400
|
||||||
|
|
||||||
@@ -229,7 +230,9 @@ This keeps edge policy and app routing aligned as features grow.
|
|||||||
|
|
||||||
## UI (Initial Shell)
|
## UI (Initial Shell)
|
||||||
|
|
||||||
Control-plane serves the built Operator UI at `/ui/` from `ui/dist`.
|
Control-plane serves the built Operator UI at `/ui/` from `ui_dist_dir`
|
||||||
|
(defaults to `ui/dist`). Configure this in
|
||||||
|
`/etc/wakey-control-plane/config.toml` or pass `--ui-dist-dir` to `serve`.
|
||||||
|
|
||||||
Build UI assets before starting control-plane:
|
Build UI assets before starting control-plane:
|
||||||
|
|
||||||
@@ -241,6 +244,40 @@ pnpm build
|
|||||||
|
|
||||||
Then start control-plane and open `/ui/` on the same host/port.
|
Then start control-plane and open `/ui/` on the same host/port.
|
||||||
|
|
||||||
|
## VPS Deploy (Manual Updates)
|
||||||
|
|
||||||
|
Suggested layout on VPS:
|
||||||
|
|
||||||
|
- `/opt/wakey/bin/wakey-control-plane`
|
||||||
|
- `/opt/wakey/ui/dist/*`
|
||||||
|
- `/etc/wakey-control-plane/config.toml` with `ui_dist_dir = "/opt/wakey/ui/dist"`
|
||||||
|
|
||||||
|
Use the provided unit template:
|
||||||
|
|
||||||
|
- `deploy/systemd/wakey-cc.service`
|
||||||
|
|
||||||
|
Install on VPS:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo install -m 0644 deploy/systemd/wakey-cc.service /etc/systemd/system/wakey-cc.service
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now wakey-cc.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Manual update helper for VPS:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
chmod +x scripts/update_wakey_cc.sh
|
||||||
|
cd /opt/wakey
|
||||||
|
WAKEY_CC_VERSION=v0.1.0 WAKEY_CC_TARGET=x86_64-unknown-linux-gnu \
|
||||||
|
sudo -E ./scripts/update_wakey_cc.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The update tarball is expected to contain:
|
||||||
|
|
||||||
|
- `bin/wakey-control-plane`
|
||||||
|
- `ui/dist/index.html` (plus `ui/dist/assets/*`)
|
||||||
|
|
||||||
## CLI
|
## CLI
|
||||||
|
|
||||||
`wakey` is usable as a local/operator CLI.
|
`wakey` is usable as a local/operator CLI.
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Wakey Control Plane
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=wakey
|
||||||
|
Group=wakey
|
||||||
|
WorkingDirectory=/opt/wakey
|
||||||
|
ExecStart=/opt/wakey/bin/wakey-control-plane serve --config-file /etc/wakey-control-plane/config.toml
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=2
|
||||||
|
Environment=RUST_LOG=info
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -44,9 +44,28 @@ This folder has small helpers for build, CI, and router install. Keep it simple;
|
|||||||
- `./scripts/dev_push.ps1 -Pass <password> [-HostName <ip>] [-RemotePath </root/.bin/wakey>] [-Restart] [-Quiet]`
|
- `./scripts/dev_push.ps1 -Pass <password> [-HostName <ip>] [-RemotePath </root/.bin/wakey>] [-Restart] [-Quiet]`
|
||||||
- Uploads to `<RemotePath>.tmp` then atomically moves into place; `-Restart` restarts the service; `-Quiet` silences MOTD.
|
- Uploads to `<RemotePath>.tmp` then atomically moves into place; `-Restart` restarts the service; `-Quiet` silences MOTD.
|
||||||
- `package_rootfs.ps1` — Produces `dist/wakey-rootfs-<version>-<target>.tgz` with `/root/.bin/wakey` and `/etc/init.d/*`.
|
- `package_rootfs.ps1` — Produces `dist/wakey-rootfs-<version>-<target>.tgz` with `/root/.bin/wakey` and `/etc/init.d/*`.
|
||||||
|
- `update_wakey_cc.sh` — Linux VPS updater for control-plane bundles; extracts into the selected directory (default: current directory) and restarts `wakey-cc.service`.
|
||||||
|
- `package_wakey_cc_bundle.sh` — Produces `dist/wakey-cc-<version>-<target>.tgz` with `bin/wakey-control-plane`, `ui/dist/*`, updater script, and systemd template.
|
||||||
- `publish.ps1` — Optional version bump + build + tag (and `cargo publish` only if you pass `-Publish`).
|
- `publish.ps1` — Optional version bump + build + tag (and `cargo publish` only if you pass `-Publish`).
|
||||||
- `test_remote.ps1` — Build ARM Linux test binaries locally, upload them to the router, and run them there.
|
- `test_remote.ps1` — Build ARM Linux test binaries locally, upload them to the router, and run them there.
|
||||||
|
|
||||||
|
## VPS updater (control-plane)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
chmod +x ./scripts/update_wakey_cc.sh
|
||||||
|
cd /opt/wakey
|
||||||
|
WAKEY_CC_VERSION=v0.1.0 WAKEY_CC_TARGET=x86_64-unknown-linux-gnu \
|
||||||
|
sudo -E ./scripts/update_wakey_cc.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected tarball layout:
|
||||||
|
|
||||||
|
- `bin/wakey-control-plane`
|
||||||
|
- `ui/dist/index.html`
|
||||||
|
- `ui/dist/assets/*`
|
||||||
|
- `scripts/update_wakey_cc.sh`
|
||||||
|
- `deploy/systemd/wakey-cc.service`
|
||||||
|
|
||||||
## Remote test runner
|
## Remote test runner
|
||||||
|
|
||||||
`test_remote.ps1` is the main way to run Linux/router-specific tests that do not
|
`test_remote.ps1` is the main way to run Linux/router-specific tests that do not
|
||||||
|
|||||||
Executable
+87
@@ -0,0 +1,87 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# Package wakey-control-plane bundle (binary + UI dist + updater + systemd template).
|
||||||
|
# Archive paths are relative so extraction can target any install directory.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./scripts/package_wakey_cc_bundle.sh --version v0.1.0 --target x86_64-unknown-linux-gnu
|
||||||
|
#
|
||||||
|
# Optional:
|
||||||
|
# --out-dir dist
|
||||||
|
# --binary target/<target>/release/wakey-control-plane
|
||||||
|
# --ui-dist ui/dist
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
VERSION=""
|
||||||
|
TARGET=""
|
||||||
|
OUT_DIR="dist"
|
||||||
|
BINARY=""
|
||||||
|
UI_DIST="ui/dist"
|
||||||
|
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--version)
|
||||||
|
VERSION="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--target)
|
||||||
|
TARGET="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--out-dir)
|
||||||
|
OUT_DIR="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--binary)
|
||||||
|
BINARY="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--ui-dist)
|
||||||
|
UI_DIST="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "unknown arg: $1" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -n "$VERSION" ] || { echo "--version is required" >&2; exit 1; }
|
||||||
|
[ -n "$TARGET" ] || { echo "--target is required" >&2; exit 1; }
|
||||||
|
|
||||||
|
ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||||
|
cd "$ROOT_DIR"
|
||||||
|
|
||||||
|
if [ -z "$BINARY" ]; then
|
||||||
|
BINARY="target/$TARGET/release/wakey-control-plane"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -f "$BINARY" ] || { echo "missing binary: $BINARY" >&2; exit 1; }
|
||||||
|
[ -f "$UI_DIST/index.html" ] || { echo "missing UI dist index: $UI_DIST/index.html" >&2; exit 1; }
|
||||||
|
[ -f "scripts/update_wakey_cc.sh" ] || { echo "missing updater script" >&2; exit 1; }
|
||||||
|
[ -f "deploy/systemd/wakey-cc.service" ] || { echo "missing systemd template" >&2; exit 1; }
|
||||||
|
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
STAGING="$OUT_DIR/wakey-cc-stage.$$"
|
||||||
|
PKG="wakey-cc-$VERSION-$TARGET.tgz"
|
||||||
|
|
||||||
|
rm -rf "$STAGING"
|
||||||
|
mkdir -p "$STAGING/bin" "$STAGING/ui" "$STAGING/scripts" "$STAGING/deploy/systemd"
|
||||||
|
|
||||||
|
cp "$BINARY" "$STAGING/bin/wakey-control-plane"
|
||||||
|
cp -a "$UI_DIST" "$STAGING/ui/dist"
|
||||||
|
cp "scripts/update_wakey_cc.sh" "$STAGING/scripts/update_wakey_cc.sh"
|
||||||
|
cp "deploy/systemd/wakey-cc.service" "$STAGING/deploy/systemd/wakey-cc.service"
|
||||||
|
|
||||||
|
chmod +x "$STAGING/bin/wakey-control-plane" "$STAGING/scripts/update_wakey_cc.sh"
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$STAGING"
|
||||||
|
tar -czf "$ROOT_DIR/$OUT_DIR/$PKG" .
|
||||||
|
)
|
||||||
|
|
||||||
|
rm -rf "$STAGING"
|
||||||
|
|
||||||
|
echo "Bundle package: $OUT_DIR/$PKG"
|
||||||
|
echo "Contains: bin/wakey-control-plane, ui/dist, scripts/update_wakey_cc.sh, deploy/systemd/wakey-cc.service"
|
||||||
Executable
+115
@@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# Update/install wakey-control-plane bundle on Linux VPS and optionally restart systemd unit.
|
||||||
|
#
|
||||||
|
# Expected tarball layout:
|
||||||
|
# bin/wakey-control-plane
|
||||||
|
# ui/dist/index.html
|
||||||
|
# ui/dist/assets/*
|
||||||
|
#
|
||||||
|
# Env options:
|
||||||
|
# WAKEY_CC_TGZ_URL Direct URL to bundle tarball (preferred)
|
||||||
|
# WAKEY_HOST Release host (default: git.ldlda.com)
|
||||||
|
# WAKEY_OWNER Repo owner (default: lda)
|
||||||
|
# WAKEY_REPO Repo name (default: wakey)
|
||||||
|
# WAKEY_CC_VERSION Tag, e.g. v0.1.0 (required unless WAKEY_CC_TGZ_URL set)
|
||||||
|
# WAKEY_CC_TARGET Target triple (default from uname: x86_64-unknown-linux-gnu or aarch64-unknown-linux-gnu)
|
||||||
|
# WAKEY_CC_FILE Asset filename (default: wakey-cc-${WAKEY_CC_VERSION}-${WAKEY_CC_TARGET}.tgz)
|
||||||
|
# WAKEY_CC_ROOT Install root (default: current directory)
|
||||||
|
# WAKEY_CC_SERVICE systemd unit name (default: wakey-cc.service)
|
||||||
|
# WAKEY_CC_NO_RESTART If set, skip systemd restart
|
||||||
|
# WAKEY_INSECURE If set, disable TLS verification
|
||||||
|
#
|
||||||
|
# Requires: tar, systemctl, curl or wget
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
log() { printf '[update_wakey_cc] %s\n' "$*"; }
|
||||||
|
fail() {
|
||||||
|
printf '[update_wakey_cc] ERROR: %s\n' "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
# fetch <url> <out>
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
if [ -n "${WAKEY_INSECURE:-}" ]; then
|
||||||
|
curl -fSL -k -o "$2" "$1"
|
||||||
|
else
|
||||||
|
curl -fSL -o "$2" "$1"
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v wget >/dev/null 2>&1; then
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
wget ${WAKEY_INSECURE:+--no-check-certificate} -O "$2" "$1"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
fail 'curl or wget is required'
|
||||||
|
}
|
||||||
|
|
||||||
|
default_target() {
|
||||||
|
arch=$(uname -m)
|
||||||
|
case "$arch" in
|
||||||
|
x86_64)
|
||||||
|
printf '%s' 'x86_64-unknown-linux-gnu'
|
||||||
|
;;
|
||||||
|
aarch64|arm64)
|
||||||
|
printf '%s' 'aarch64-unknown-linux-gnu'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf '%s' "$arch"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
ROOT="${WAKEY_CC_ROOT:-$PWD}"
|
||||||
|
SERVICE="${WAKEY_CC_SERVICE:-wakey-cc.service}"
|
||||||
|
TMPDIR="${TMPDIR:-/tmp}"
|
||||||
|
ARCHIVE="$TMPDIR/wakey-cc.$$.tgz"
|
||||||
|
STAGING="$TMPDIR/wakey-cc-stage.$$"
|
||||||
|
|
||||||
|
URL="${WAKEY_CC_TGZ_URL:-}"
|
||||||
|
if [ -z "$URL" ]; then
|
||||||
|
HOST="${WAKEY_HOST:-git.ldlda.com}"
|
||||||
|
OWNER="${WAKEY_OWNER:-lda}"
|
||||||
|
REPO="${WAKEY_REPO:-wakey}"
|
||||||
|
VERSION="${WAKEY_CC_VERSION:-}"
|
||||||
|
[ -n "$VERSION" ] || fail 'set WAKEY_CC_TGZ_URL or WAKEY_CC_VERSION'
|
||||||
|
TARGET="${WAKEY_CC_TARGET:-$(default_target)}"
|
||||||
|
FILE="${WAKEY_CC_FILE:-wakey-cc-${VERSION}-${TARGET}.tgz}"
|
||||||
|
URL="https://$HOST/$OWNER/$REPO/releases/download/$VERSION/$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap 'rm -f "$ARCHIVE"; rm -rf "$STAGING"' EXIT INT TERM
|
||||||
|
|
||||||
|
log "fetching $URL"
|
||||||
|
fetch "$URL" "$ARCHIVE" || fail 'download failed'
|
||||||
|
|
||||||
|
rm -rf "$STAGING"
|
||||||
|
mkdir -p "$STAGING"
|
||||||
|
tar -xzf "$ARCHIVE" -C "$STAGING" || fail 'extract failed'
|
||||||
|
|
||||||
|
[ -f "$STAGING/bin/wakey-control-plane" ] || fail 'bundle missing bin/wakey-control-plane'
|
||||||
|
[ -f "$STAGING/ui/dist/index.html" ] || fail 'bundle missing ui/dist/index.html'
|
||||||
|
|
||||||
|
mkdir -p "$ROOT"
|
||||||
|
cp -a "$STAGING/." "$ROOT/"
|
||||||
|
|
||||||
|
if [ -z "${WAKEY_CC_NO_RESTART:-}" ] && command -v systemctl >/dev/null 2>&1; then
|
||||||
|
if systemctl list-unit-files "$SERVICE" >/dev/null 2>&1; then
|
||||||
|
log "restarting $SERVICE"
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart "$SERVICE"
|
||||||
|
systemctl --no-pager --full status "$SERVICE" | sed -n '1,16p'
|
||||||
|
else
|
||||||
|
log "service $SERVICE not installed; skipped restart"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "done: installed into $ROOT"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@@ -73,6 +73,9 @@ pub struct ServeArgs {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub pid_file: Option<PathBuf>,
|
pub pid_file: Option<PathBuf>,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
pub ui_dist_dir: Option<PathBuf>,
|
||||||
|
|
||||||
#[arg(long, visible_alias="config", default_value = DEFAULT_CONFIG_FILE)]
|
#[arg(long, visible_alias="config", default_value = DEFAULT_CONFIG_FILE)]
|
||||||
pub config_file: PathBuf,
|
pub config_file: PathBuf,
|
||||||
|
|
||||||
@@ -103,6 +106,9 @@ pub struct InitConfigArgs {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub pid_file: Option<PathBuf>,
|
pub pid_file: Option<PathBuf>,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
pub ui_dist_dir: Option<PathBuf>,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub command_timeout_ms: Option<u64>,
|
pub command_timeout_ms: Option<u64>,
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ pub fn write_init_config(args: &InitConfigArgs) -> Result<Option<PathBuf>> {
|
|||||||
.unwrap_or_else(|| PathBuf::from("wakey-control-plane.pid"));
|
.unwrap_or_else(|| PathBuf::from("wakey-control-plane.pid"));
|
||||||
let pid_file = resolve_path(&data_dir, pid_file_raw);
|
let pid_file = resolve_path(&data_dir, pid_file_raw);
|
||||||
|
|
||||||
|
let ui_dist_dir = args
|
||||||
|
.ui_dist_dir
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| PathBuf::from("ui/dist"));
|
||||||
|
|
||||||
let body = WritableConfig {
|
let body = WritableConfig {
|
||||||
data_dir,
|
data_dir,
|
||||||
bind: bind.to_string(),
|
bind: bind.to_string(),
|
||||||
@@ -57,6 +62,7 @@ pub fn write_init_config(args: &InitConfigArgs) -> Result<Option<PathBuf>> {
|
|||||||
command_timeout_ms: args.command_timeout_ms.unwrap_or(30_000).max(1),
|
command_timeout_ms: args.command_timeout_ms.unwrap_or(30_000).max(1),
|
||||||
enroll_token_ttl_seconds: args.enroll_token_ttl_seconds.unwrap_or(86_400).max(1),
|
enroll_token_ttl_seconds: args.enroll_token_ttl_seconds.unwrap_or(86_400).max(1),
|
||||||
pid_file,
|
pid_file,
|
||||||
|
ui_dist_dir,
|
||||||
bootstrap_enroll_tokens: args.bootstrap_enroll_tokens.clone(),
|
bootstrap_enroll_tokens: args.bootstrap_enroll_tokens.clone(),
|
||||||
telemetry: WritableTelemetry {
|
telemetry: WritableTelemetry {
|
||||||
otlp_endpoint: args.telemetry_otlp_endpoint.clone(),
|
otlp_endpoint: args.telemetry_otlp_endpoint.clone(),
|
||||||
@@ -98,6 +104,7 @@ pub fn bootstrap_config_if_missing(args: &ServeArgs) -> Result<bool> {
|
|||||||
public_url: args.public_url.clone(),
|
public_url: args.public_url.clone(),
|
||||||
state_file: args.state_file.clone(),
|
state_file: args.state_file.clone(),
|
||||||
pid_file: args.pid_file.clone(),
|
pid_file: args.pid_file.clone(),
|
||||||
|
ui_dist_dir: args.ui_dist_dir.clone(),
|
||||||
command_timeout_ms: args.command_timeout_ms,
|
command_timeout_ms: args.command_timeout_ms,
|
||||||
enroll_token_ttl_seconds: args.enroll_token_ttl_seconds,
|
enroll_token_ttl_seconds: args.enroll_token_ttl_seconds,
|
||||||
bootstrap_enroll_tokens: args.bootstrap_enroll_tokens.clone(),
|
bootstrap_enroll_tokens: args.bootstrap_enroll_tokens.clone(),
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ impl DaemonConfig {
|
|||||||
.unwrap_or_else(|| PathBuf::from("wakey-control-plane.pid"));
|
.unwrap_or_else(|| PathBuf::from("wakey-control-plane.pid"));
|
||||||
let pid_file = resolve_path(&data_dir, pid_file_raw);
|
let pid_file = resolve_path(&data_dir, pid_file_raw);
|
||||||
|
|
||||||
|
let ui_dist_dir = args
|
||||||
|
.ui_dist_dir
|
||||||
|
.clone()
|
||||||
|
.or(file.ui_dist_dir)
|
||||||
|
.unwrap_or_else(|| PathBuf::from("ui/dist"));
|
||||||
|
|
||||||
let bootstrap_enroll_tokens = if args.bootstrap_enroll_tokens.is_empty() {
|
let bootstrap_enroll_tokens = if args.bootstrap_enroll_tokens.is_empty() {
|
||||||
file.bootstrap_enroll_tokens.unwrap_or_default()
|
file.bootstrap_enroll_tokens.unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
@@ -89,6 +95,7 @@ impl DaemonConfig {
|
|||||||
command_timeout,
|
command_timeout,
|
||||||
enroll_token_ttl,
|
enroll_token_ttl,
|
||||||
pid_file,
|
pid_file,
|
||||||
|
ui_dist_dir,
|
||||||
bootstrap_enroll_tokens,
|
bootstrap_enroll_tokens,
|
||||||
telemetry,
|
telemetry,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ pub struct DaemonConfig {
|
|||||||
pub command_timeout: Duration,
|
pub command_timeout: Duration,
|
||||||
pub enroll_token_ttl: Duration,
|
pub enroll_token_ttl: Duration,
|
||||||
pub pid_file: PathBuf,
|
pub pid_file: PathBuf,
|
||||||
|
pub ui_dist_dir: PathBuf,
|
||||||
pub bootstrap_enroll_tokens: Vec<String>,
|
pub bootstrap_enroll_tokens: Vec<String>,
|
||||||
pub telemetry: TelemetryConfig,
|
pub telemetry: TelemetryConfig,
|
||||||
}
|
}
|
||||||
@@ -43,6 +44,7 @@ pub(crate) struct FileConfig {
|
|||||||
pub(crate) command_timeout_ms: Option<u64>,
|
pub(crate) command_timeout_ms: Option<u64>,
|
||||||
pub(crate) enroll_token_ttl_seconds: Option<u64>,
|
pub(crate) enroll_token_ttl_seconds: Option<u64>,
|
||||||
pub(crate) pid_file: Option<PathBuf>,
|
pub(crate) pid_file: Option<PathBuf>,
|
||||||
|
pub(crate) ui_dist_dir: Option<PathBuf>,
|
||||||
#[serde(alias = "enroll_tokens")]
|
#[serde(alias = "enroll_tokens")]
|
||||||
pub(crate) bootstrap_enroll_tokens: Option<Vec<String>>,
|
pub(crate) bootstrap_enroll_tokens: Option<Vec<String>>,
|
||||||
pub(crate) telemetry: Option<FileTelemetryConfig>,
|
pub(crate) telemetry: Option<FileTelemetryConfig>,
|
||||||
@@ -64,6 +66,7 @@ pub(crate) struct WritableConfig {
|
|||||||
pub(crate) command_timeout_ms: u64,
|
pub(crate) command_timeout_ms: u64,
|
||||||
pub(crate) enroll_token_ttl_seconds: u64,
|
pub(crate) enroll_token_ttl_seconds: u64,
|
||||||
pub(crate) pid_file: PathBuf,
|
pub(crate) pid_file: PathBuf,
|
||||||
|
pub(crate) ui_dist_dir: PathBuf,
|
||||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
pub(crate) bootstrap_enroll_tokens: Vec<String>,
|
pub(crate) bootstrap_enroll_tokens: Vec<String>,
|
||||||
pub(crate) telemetry: WritableTelemetry,
|
pub(crate) telemetry: WritableTelemetry,
|
||||||
|
|||||||
@@ -57,14 +57,14 @@ pub enum AgentReply {
|
|||||||
Error(ErrorPayload),
|
Error(ErrorPayload),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn public_api_routes() -> Router<AppState> {
|
fn public_api_routes(ui_dist_dir: std::path::PathBuf) -> Router<AppState> {
|
||||||
|
let index_file = ui_dist_dir.join("index.html");
|
||||||
|
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/ui", get(|| async { Redirect::temporary("/ui/") }))
|
.route("/ui", get(|| async { Redirect::temporary("/ui/") }))
|
||||||
.nest_service(
|
.nest_service(
|
||||||
"/ui/",
|
"/ui/",
|
||||||
get_service(
|
get_service(ServeDir::new(ui_dist_dir).not_found_service(ServeFile::new(index_file))),
|
||||||
ServeDir::new("ui/dist").not_found_service(ServeFile::new("ui/dist/index.html")),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.route("/healthz", get(api::healthz))
|
.route("/healthz", get(api::healthz))
|
||||||
.route("/api/v1/agents/enroll", post(api::enroll))
|
.route("/api/v1/agents/enroll", post(api::enroll))
|
||||||
@@ -131,11 +131,11 @@ pub async fn serve(daemon: config::DaemonConfig) -> Result<()> {
|
|||||||
// - public_api_routes: intended internet-facing agent endpoints
|
// - public_api_routes: intended internet-facing agent endpoints
|
||||||
// - control_api_routes: intended admin-only endpoints behind Access
|
// - control_api_routes: intended admin-only endpoints behind Access
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.merge(public_api_routes())
|
.merge(public_api_routes(daemon.ui_dist_dir.clone()))
|
||||||
.merge(control_api_routes())
|
.merge(control_api_routes())
|
||||||
.with_state(app_state.clone());
|
.with_state(app_state.clone());
|
||||||
|
|
||||||
info!(bind = %daemon.bind, data_dir = %daemon.data_dir.display(), pid_file = %daemon.pid_file.display(), state_file = %daemon.state_file.display(), "starting control-plane server");
|
info!(bind = %daemon.bind, data_dir = %daemon.data_dir.display(), pid_file = %daemon.pid_file.display(), state_file = %daemon.state_file.display(), ui_dist_dir = %daemon.ui_dist_dir.display(), "starting control-plane server");
|
||||||
let listener = TcpListener::bind(daemon.bind).await?;
|
let listener = TcpListener::bind(daemon.bind).await?;
|
||||||
let server = tokio::spawn(async move {
|
let server = tokio::spawn(async move {
|
||||||
axum::serve(listener, app)
|
axum::serve(listener, app)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wakey-core"
|
name = "wakey-core"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wakey-linux"
|
name = "wakey-linux"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
Reference in New Issue
Block a user