3 Commits

Author SHA1 Message Date
Adam Shiervani 5b143578d6 refactor: move tailscale logic into internal/tailscale package (#1318)
Move types, parsing, exec, and control-URL logic from the root kvm
package into internal/tailscale/ so go test ./... no longer tries to
link ARM-only CGO libraries on x86_64 hosts.
2026-03-24 15:41:44 +01:00
Lukas Wolfsteiner 519e391595 feat(remote): add support for custom tailscale control servers (#1312)
* feat(tailscale): add custom control URL configuration & handling w/ tests
- Introduced TailscaleControlURL in the Config struct to allow configuration of the Tailscale control server.
- Added RPC handlers for getting and setting the Tailscale control URL.
- Updated TailscaleStatus to include controlURL, ensuring it reflects the configured or default value.
- Enhanced parsing and normalization of the control URL to enforce valid formats.
- Updated TailscaleCard component to manage and display the control server URL, allowing users to save changes.

* docs: update README to include optional Tailscale networking feature
Added a new section highlighting the built-in Tailscale status and control-server configuration, including support for custom Headscale-compatible endpoints.

* docs: Extend DEVELOPMENT.md with Tailscale control server details

* fix(tailscale): enhance error handling in rpcSetTailscaleControlURL

- Updated the rpcSetTailscaleControlURL function to revert the TailscaleControlURL to its previous value if saving or applying the new URL fails.
- Added a new test to ensure that the configuration is not saved when the apply command fails, verifying that the previous URL remains intact.
- Adjusted existing tests to validate the order of operations during the URL setting process.

Related to Review: https://github.com/jetkvm/kvm/pull/1312#pullrequestreview-3984856379

* refactor(tailscale): simplify control URL application logic and enhance error handling

- Renamed the test function to better reflect its purpose and updated the test cases to ensure correct command execution.
- Removed fallback logic for applying the Tailscale control URL, streamlining the error handling to return a clear error message when the "set" command fails.
- Added a new test to verify behavior when the "set" command fails, ensuring proper error reporting.

Related to Review https://github.com/jetkvm/kvm/pull/1312#pullrequestreview-3984856379

* refactor(tailscale): update control server configuration in UI & documentation

- Updated the TailscaleCard component to allow users to select between default and custom control server URLs.
- Improved state management for control server URL input based on the selected mode.
- Revised DEVELOPMENT.md to clarify control server application logic and error handling.
- Removed outdated example JSON-RPC payloads for clarity.

Related to Review: https://github.com/jetkvm/kvm/pull/1312#discussion_r2980284611

* refactor(ui): use built-in components and i18n for TailscaleCard

- Replace raw <select> with SelectMenuBasic component
- Use SettingsItem with new SM size for control server setting
- Use NestedSettingsGroup for indented custom URL input
- Add tailscale_* i18n keys to all 14 locale files with translations
- Add size prop (SM/MD) to SettingsItem for compact contexts

---------

Co-authored-by: Adam Shiervani <adam.shiervani@gmail.com>
2026-03-24 15:20:15 +01:00
Alex Howells 032457c9e5 feat(network): add Tailscale status to Settings > Network (#1276)
* feat(network): add Tailscale status to Settings > Network

Tailscale runs on JetKVM devices but has no visibility in the web UI.
This adds a read-only status card to the network settings page that
surfaces the output of `tailscale status --json` over the existing
JSON-RPC transport.

Backend (Go):

  tailscale.go -- TailscaleStatus/TailscalePeer structs returned by a
  single RPC handler (getTailscaleStatus). isTailscaleInstalled uses
  exec.LookPath; getTailscaleStatus shells out via exec.CommandContext
  with a 10s timeout and parses the JSON response. When the binary is
  absent the handler returns {installed: false} without error. When the
  daemon is unreachable it returns {installed: true, running: false}.

  tailscale_test.go -- table-driven tests for parseTailscaleStatus
  covering Running, NeedsLogin, Stopped, Starting, malformed JSON, and
  empty object inputs. Integration-level tests for getTailscaleStatus
  verify the exec mock path and confirm the function never returns an
  error regardless of environment state.

  jsonrpc.go -- getTailscaleStatus registered in rpcHandlers.
  log.go -- tailscaleLogger subsystem added.

Frontend (TypeScript/React):

  TailscaleCard.tsx -- GridCard component that calls getTailscaleStatus
  on mount. Renders nothing when installed=false. Shows a status badge
  (Connected/Needs Login/Stopped), Tailscale IPv4/IPv6, hostname, DNS
  name, auth URL when NeedsLogin, and health warnings when present.

  stores.ts -- TailscaleStatus and TailscalePeer interfaces.

  devices.$id.settings.network.tsx -- TailscaleCard rendered after
  PublicIPCard.

* fix(ui): address review feedback on TailscaleCard

Remove the health warnings section from TailscaleCard.tsx — these
surface raw Tailscale internal diagnostics (nftables errors, routing
warnings) that are not actionable for end users and clutter the
status card.

Reduce monospace font size on IPv4 and IPv6 address spans from
text-sm (14px) to text-[13px] so the mono typeface visually matches
the surrounding 14px proportional text.

Signed-off-by: Alex Howells <alex@howells.me>

---------

Signed-off-by: Alex Howells <alex@howells.me>
2026-03-17 18:37:03 +01:00