Feature Specification: Component overview

Created: 2026-10-07

Status: Implemented

Input: Reconstructed from the code at 093e68b6f (core/components/hosting-provider/overview/default.nix, core/components/hosting-provider/overview/page.nix, core/setups/hosts-common.nix, core/setups/overview-uis-test.nix, core/checks/nix-unit-tests.nix).

User Scenarios & Testing (mandatory)

User Story 1 - Find every web UI of a deployment (Priority: P1)

An operator opens one page and sees a tile for each web UI of the deployment. Each tile links to https://<domain>/ and shows the logo, the name and the host of the UI. The setups compute the list of UIs (see 005, FR-008). The component turns the list into a static page and serves it with nginx.

Why this priority: the page is the entry point that an operator opens from the internet.

Independent Test: nix-unit-setups-overview-uis holds that the page lists only the nodes that the deployment deploys.

Acceptance Scenarios:

  1. Given a UI whose artwork gives icon and iconDark, When page.nix builds the tile, Then the logo is a <picture> with a dark srcset for prefers-color-scheme: dark.
  2. Given a UI whose artwork gives only icon, When page.nix builds the tile, Then the logo is an <img>.
  3. Given a UI with artwork = null, When page.nix builds the tile, Then the logo is the first letter of the name in upper case.
  4. Given the list of UIs, When the setups pass it as deploymentUIs, Then the tiles are sorted by the lower-case name, then by domain.

User Story 2 - Serve the page at the apex (Priority: P2)

The operator types only the domain of the deployment. With servedAtApex set, nginx serves the same page at apexDomain and at cfg.domain. The setups give the apex its records (see 005, FR-009).

Why this priority: the apex is the shortest name. The page also works on overview.<domain> alone.

Independent Test: No check of this component covers it.

Acceptance Scenarios:

  1. Given servedAtApex = true, When the component applies, Then the tls request asks ssl for cfg.domain and apexDomain, and nginx has one virtualHosts entry for each name.
  2. Given servedAtApex = false, When the component applies, Then only cfg.domain gets a certificate and a vhost.

Edge Cases

  • page.nix escapes each name and host with escapeXML.
  • page.nix copies the icons to icons/<index>.svg and icons/<index>-dark.svg, so the page closure holds only the icon files.
  • With enable = false, the component emits no request.

Requirements (mandatory)

Functional Requirements

  • FR-001: The component MUST declare components.overview with the name Overview, certAudience = "browser" and the default subdomain overview.
  • FR-002: The component MUST declare servedAtApex (default true) and the hidden option apexDomain (default deploymentDomain).
  • FR-003: The implementation MUST request ssl for cfg.domain and, with servedAtApex, for apexDomain.
  • FR-004: The implementation MUST request spiffe.enable and firewall.publicTCPPorts = [ 80 443 ].
  • FR-005: The code request MUST read the module argument deploymentUIs, build the page with page.nix and serve it as the nginx root of each name.
  • FR-006: page.nix MUST render one <a class="card"> tile per UI, with a link to https://<domain>/.
  • FR-007: On the central group (the one group whose roster provides varsBackend), the setups MUST add the browser UIs of the groups that set centralLogin, such as the hypervisor group (aggregatedHypervisorBrowserUIs), to deploymentUIs.

Key Entities

  • deploymentUIs: the list of browser UIs that the setups give to the module, from supportingRequests.browserUIs of each used node.
  • Browser UI of a node: the UI of its component on the name that uiSubdomain gives, and the UIs that browserUIs of its component gives on names of their own, for example the Swagger UI and AsyncAPI pages of the api node. A UI counts only when the node holds a certificate for its name.
  • Overview page: the overview-page derivation with index.html and the icons.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: nix-unit-setups-overview-uis passes.
  • SC-002: On a live node, https://overview.<domain>/ returns the page with one tile per deployed UI.

Assumptions

  • Each UI that the page links to does its own sign-in. So the page needs no sign-in and can use a public certificate.
  • Public DNS already shows each name on the page.

Known Deviations

None.