feat(node): package Ubuntu desktop setup and trusted access
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
# Mission Core Node — Ubuntu system configuration candidate
|
||||
|
||||
0.3.0 adopts the canonical Mission Core shell, navigation, system views and a
|
||||
GUI list of trusted SSH devices. ResourceRow is shared from Design Guideline;
|
||||
see `docs/node/02_NODE_DESKTOP_SURFACE.md` for composition and acceptance.
|
||||
The Debian package still contains the GTK/WebKit desktop launcher and bundled
|
||||
React UI. Real Mini installation and read-only UI checks passed; physical
|
||||
reboot, bare-Ubuntu installation and full GUI upgrade/removal remain open.
|
||||
|
||||
**Qualification in progress (2026-09-05):** the owner installed 0.2.0 through
|
||||
App Center after closing Synaptic, which had blocked package installation.
|
||||
PackageKit completed successfully and the packaged service is active.
|
||||
The owner subsequently confirmed the corrected icon and Tailscale “online” with
|
||||
the board address under 0.2.2. 0.2.2 corrects the desktop icon's
|
||||
canvas and configures the pinned provider's HTTPS control transport. The earlier
|
||||
0.2.1 icon-only candidate was superseded before installation.
|
||||
Manual SSH bootstrap is authorized for engineering access only.
|
||||
|
||||
0.2.3 also routes expired-session errors from Tailscale polling to the existing
|
||||
application login surface. Browser acceptance confirmed that restarting the
|
||||
temporary test service now shows login instead of a misleading unavailable
|
||||
provider. This does not preserve authentication across a service restart.
|
||||
|
||||
Source of truth: MISSIONCOR-76 and its UI-FIRST / BRIDGE-ONLY / system
|
||||
configuration comments. Product surface and physical acceptance procedure:
|
||||
`docs/node/01_BOOTSTRAP_SURFACE_AND_ACCEPTANCE.md` at the repository root.
|
||||
|
||||
This is an independently built application in the Mission Core monorepo.
|
||||
Version 0.2.0 contains local host/USB/network inventory, persistent Ed25519
|
||||
identity, GUI naming, OS-authenticated local launch, redacted report export,
|
||||
OpenSSH installation/autostart, and GUI enrollment/revocation of Ed25519 public
|
||||
keys for local Ubuntu administrators. The agent and desktop window run
|
||||
unprivileged; the polkit helper can only issue a temporary local login. SSH configuration is
|
||||
owned by the installer, with conflict detection and cleanup on removal.
|
||||
|
||||
Core pairing/mTLS, sensor plugins, capture, media and
|
||||
recovery are subsequent vertical increments, not implemented capabilities of
|
||||
this package. This is not a completed Node v1 or a hardware-qualified release.
|
||||
|
||||
## Operator workflow
|
||||
|
||||
Open the `.deb` in Ubuntu's graphical package installer, install it, then launch
|
||||
Mission Core Node from the applications menu and approve the normal OS dialog.
|
||||
The application opens in its own GTK window with embedded WebKit rendering and
|
||||
native system dialogs for authorization and report saving. No external browser
|
||||
is opened. Closing the window leaves the independent board service running.
|
||||
The system installer resolves dependencies from Ubuntu repositories; internet
|
||||
access is needed when those dependencies are absent. There are no shared
|
||||
credentials in the package. SSH public keys are enrolled explicitly in the UI.
|
||||
No shell, Go, Python environment setup, npm, or source checkout is required from
|
||||
the operator. The included Python launcher uses the system Python dependency.
|
||||
|
||||
The desktop icon contains the unchanged canonical NODE.DC mark from the admitted
|
||||
Design Guideline revision inside a transparent square SVG canvas. This gives
|
||||
desktop loaders square intrinsic dimensions without stretching the mark. After
|
||||
upgrading the package, close and reopen the
|
||||
application window so its native helpers and embedded UI have matching features.
|
||||
|
||||
**Observed installer limitation (2026-09-05):** App Center revision 1270 on the
|
||||
qualification board showed “installed” instead of offering the 0.1.1 → 0.2.0
|
||||
local-file upgrade. Do not claim that update path is accepted. The owner's
|
||||
subsequent GUI removal succeeded; reinstall attempts then failed before dpkg
|
||||
because Synaptic remained open and held `/var/lib/dpkg/lock-frontend`.
|
||||
Exit Synaptic through File → Quit before retrying the `.deb` in App Center.
|
||||
Do not delete package-manager locks or terminate a running transaction. The
|
||||
0.2.0 SHA-256 still matches, and APT simulation resolves its dependencies;
|
||||
neither check alone establishes actual installation. The following GUI retry
|
||||
completed successfully and the installed package is 0.2.0. A complete product installer
|
||||
must still qualify GUI upgrade, removal and actionable lock/error handling.
|
||||
|
||||
## Private network setup
|
||||
|
||||
The optional Tailscale panel has real install, login, waiting-for-approval,
|
||||
stopped, starting, unavailable and connected states. Installation and connection
|
||||
use two fixed root-owned polkit helpers from the desktop window. The web API
|
||||
can only read a reduced local status; it cannot run commands or change network
|
||||
settings. The generic Node identity and capture lifecycle do not depend on
|
||||
Tailscale. Pairing to Mission Core is still a separate, unimplemented operation.
|
||||
|
||||
On a new machine, the helper downloads the official amd64 `.deb` pinned in
|
||||
`packaging/tailscale-release.json`, verifies SHA-256 before invoking APT, installs
|
||||
without removing other packages, and enables `tailscaled`. It does not add an
|
||||
APT repository or upgrade an existing Tailscale installation. An existing
|
||||
stopped authenticated configuration is resumed with a bare `tailscale up`;
|
||||
fresh login explicitly disables accepting remote DNS and subnet routes. No
|
||||
exit node, advertised subnet, Tailscale SSH, forced reauthentication or reset
|
||||
is configured. Incompatible existing preferences fail instead of being reset.
|
||||
|
||||
For a new provider install, and when explicitly reconnecting a disconnected
|
||||
provider, a root-owned systemd drop-in selects `TS_FORCE_NOISE_443=true`.
|
||||
The board's port-80 control connection stalled after registration with queued
|
||||
unacknowledged data; the upstream `debug ts2021` handshake succeeded over 443.
|
||||
The helper checks the daemon's effective flag and restarts it only when needed.
|
||||
An already Running/NeedsMachineAuth provider is left untouched. Conflicting
|
||||
custom drop-ins are preserved and reported. Keys, DNS and route preferences
|
||||
are not changed. This drop-in remains with the independent provider on Node
|
||||
removal. The transport setting is specific to pinned Tailscale, not Node identity.
|
||||
|
||||
The provider's validated `https://login.tailscale.com/a/...` URL opens in the
|
||||
user's normal browser only after the explicit login action. Node never collects
|
||||
the account password or exports the login URL to JS, its status API or reports.
|
||||
The status probe requests no peers and returns only installation/state, local
|
||||
Tailscale addresses and the provider's online flag. Closing Node or uninstalling
|
||||
it does not disconnect or remove the independently installed Tailscale service.
|
||||
|
||||
Source contracts: [Tailscale stable packages](https://pkgs.tailscale.com/stable/),
|
||||
[pinned up implementation](https://github.com/tailscale/tailscale/blob/v1.102.3/cmd/tailscale/cli/up.go),
|
||||
[pinned status implementation](https://github.com/tailscale/tailscale/blob/v1.102.3/cmd/tailscale/cli/status.go).
|
||||
HTTPS underlay: [pinned control dialer](https://github.com/tailscale/tailscale/blob/v1.102.3/control/controlhttp/client.go).
|
||||
JSON contracts are version-sensitive; review the adapter when updating the pin.
|
||||
|
||||
Only Ubuntu 24.04 LTS Desktop amd64 is admitted by this first package. No blind
|
||||
upgrade of OS, firmware, network profiles, router settings or camera SDK occurs.
|
||||
Existing Ubuntu SSH authentication is retained. Keys enrolled in Node are
|
||||
limited to private source addresses. Removing Node removes its SSH integration,
|
||||
but leaves the SSH server and persistent Node state available for reinstall.
|
||||
|
||||
## Engineering build (not the operator installation procedure)
|
||||
|
||||
Install UI dependencies with `npm ci --ignore-scripts` in `ui/`. The build
|
||||
requires the sibling Design Guideline repository used by the monorepo, at
|
||||
`8a79dfe84d895c9f1d42b8d285bc6670114f939f`. In that checkout, run
|
||||
`npm ci --ignore-scripts` and `npm run build:packages` before building Node.
|
||||
Its dependencies are bundled into the binary; the board never references that
|
||||
sibling path. The pinned commit includes ResourceRow and the shared shell fixes;
|
||||
source and generated export hashes are also retained in package provenance.
|
||||
|
||||
Use the Go release pinned in `toolchain.json`; download it from the official
|
||||
Go distribution and verify its SHA-256. No global Go install is needed.
|
||||
|
||||
```sh
|
||||
python3 packaging/build.py --go /path/to/verified/go/bin/go
|
||||
```
|
||||
|
||||
This runs the production UI build, replaces generated embedded assets, builds
|
||||
a static Linux amd64 Go binary, records source/build provenance, and packages
|
||||
the `.deb` without executing any installer scripts. `build/` is ignored.
|
||||
|
||||
Validation is sequential: `go test -race ./...`, the Control Station application
|
||||
architecture boundary test, Node UI typecheck/unit tests/build, then desktop GUI QA.
|
||||
Package script syntax/archive checks and a macOS browser run cannot establish
|
||||
Ubuntu systemd/polkit/SSH or clean-install acceptance. Those require the GUI
|
||||
procedure on the actual board. The temporary native QA build must be stopped
|
||||
after inspection; the canonical Mission Core on port 8000 stays running.
|
||||
|
||||
For this board, the owner's engineering checkout is under
|
||||
`Загрузки/NDC/MISSION_CORE` in the operator's home directory. Keep complete Git history separately
|
||||
from generated artifacts; do not copy another worktree's `.git` pointer. The
|
||||
launcher accepts `--development-socket` for an unprivileged development service
|
||||
on the board. This does not grant OS privileges and is not installer acceptance.
|
||||
|
||||
K1 uses wireless Bridge in the common LAN only. D455 is attached by USB; check
|
||||
its actual negotiated speed and SDK operation separately from enumeration.
|
||||
|
||||
## Local authority
|
||||
|
||||
The node service binds only `127.0.0.1:8780`. This is not the remote Node/Core
|
||||
control plane. Its private Unix socket is `0600` in a `0700` directory. The
|
||||
root-owned launcher helper has a fixed executable and socket; no user command,
|
||||
path, URL or environment is executed with elevated privileges. One-use login
|
||||
tokens expire after one minute, authenticated cookies after eight hours, and
|
||||
all sessions expire on service restart. Identity corruption fails closed.
|
||||
|
||||
Raw device serials and MAC addresses are not collected. The report omits node
|
||||
ID, hostname and network addresses; credentials and private keys never enter
|
||||
the public status or report. Real evidence and credentials stay outside Git.
|
||||
Reference in New Issue
Block a user