OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Reverse-spec · Services

skyline-console — Scenarios

Scenarios — skyline-console — branch stable/2026.2

Branch stable/2026.2 @ 806d200392ee — repository https://opendev.org/openstack/skyline-console — analysed on 2026-10-29

Participants: the browser running the console, nginx (generated by skyline-apiserver, same origin), skyline-apiserver, Keystone and the OpenStack services. Steps 1 to 4 of scenario 1 were recorded against a stand-in server (_rewrite/smoke-exchanges_stable-2026.2.json); the rest is read from the code.

1. Cold start, login and first page

The user opens a deep link (/compute/instance) without a session.

sequenceDiagram
  autonumber
  actor U as User
  participant B as Browser (console)
  participant N as nginx (same origin)
  participant S as skyline-apiserver
  participant K as Keystone
  participant O as Neutron / Nova (via nginx)
  U->>B: open /compute/instance
  B->>N: GET /compute/instance
  N-->>B: index.html (try_files fallback) + bundles
  B->>N: GET /api/openstack/skyline/api/v1/profile
  N->>S: GET /api/v1/profile (no session cookie)
  S-->>B: 401
  B->>B: redirect /auth/login?referer=/compute/instance
  B->>S: GET sso, GET config (login page)
  U->>B: username + password
  B->>S: POST login {domain, username, password}
  S->>K: POST /v3/auth/tokens (+ catalog, projects)
  S-->>B: 200 profile + Set-Cookie session, time_expired
  B->>B: localStorage.keystone_token = profile.keystone_token
  par
    B->>S: GET profile (X-Auth-Token)
  and
    B->>S: GET policies
  end
  B->>O: GET /api/openstack/regionone/keystone/v3/system/users/{id}/roles
  B->>O: GET /api/openstack/regionone/neutron/v2.0/extensions
  B->>S: GET extension/servers?limit=10&sort_keys=created_at&sort_dirs=desc
  S-->>B: servers joined with images, flavors, ports
  B-->>U: instance table; auto refresh armed (30 s)

Diagnostics:

  • Step 3 returns the HTML of another app or a 404: the ingress does not send unknown paths to the console (SPA fallback missing).
  • Step 7 (login) fails with 401 and a detail text: see the Keystone side in the apiserver reverse-spec. A 401 on every call after a successful login means the session cookie is not sent back (different host or path between the login and the API) or time_expired is in the past (clock skew between server and browser: the console compares it with the browser clock, src/client/client/request.js:56).
  • Menus missing after login: profile.endpoints lacks the key (service type not in service_mapping, or endpoint of another interface/region).
  • Login answers 401 {"detail": "Endpoint not found"} while Keystone logged a successful POST /v3/auth/tokens: the catalog has no network endpoint. skyline-apiserver calls Neutron's extension list to build every profile (skyline-apiserver:skyline_apiserver/client/openstack/system.py:79). Observed in kind.
  • The "Administrator" switch is missing, or an administrator deep link lands on /base/overview: the user has no system-scope admin/reader role (src/stores/root.js:155). If the user does have one, this is the post-login race of 07 § 6.3: reload the deep link.

2. Create an instance and follow its build

sequenceDiagram
  autonumber
  actor U as User
  participant B as Browser (console)
  participant N as nginx proxy /api/openstack/regionone/nova/
  participant NV as Nova API
  participant S as skyline-apiserver
  U->>B: wizard (flavor, image, network, security group)
  B->>N: GET flavors/detail, os-availability-zone, ... (compute 2.79)
  B->>N: POST /v2.1/servers {server{name, flavorRef, networks, security_groups[{name: id}], block_device_mapping_v2...}}
  N->>NV: same request, X-Auth-Token forwarded
  alt accepted
    NV-->>B: 202 {server{id, adminPass?}}
    B-->>U: success, back to the list
    loop every 10 s while status BUILD
      B->>S: GET extension/servers
    end
  else quota
    NV-->>B: 403 {"forbidden": {"message": "Quota exceeded ..."}}
    B-->>U: "Quota exceeded"
  else other error
    NV-->>B: 4xx/5xx body
    B-->>U: error notification with the raw body
  end

Diagnostics: a 400 on hypervisor_hostname or on tags means no microversion header reached Nova (proxy location without nova in the path, § 2 of 03). A server that stays BUILD keeps the list in 10 s polling until the 20-refresh budget is spent (05).

3. Stop an instance (state action with confirmation)

sequenceDiagram
  autonumber
  actor U as User
  participant B as Browser (console)
  participant NV as Nova (via nginx)
  U->>B: click Stop
  B->>B: allowedCheckFunc: status active, not locked (else performErrorMsg)
  B-->>U: confirm dialog
  U->>B: OK
  B->>NV: POST servers/{id}/action {"os-stop": null} (compute 2.79)
  NV-->>B: 202
  B->>B: success notification; refresh after 500 ms
  loop every 10 s while task_state / transition status
    B->>NV: list refresh (skyline extension/servers)
  end

For lock, rebuild, rescue and os-migrateLive the header is compute 2.79, compute <action version> and Nova applies the action version.

4. Extend a volume

sequenceDiagram
  autonumber
  actor U as User
  participant B as Browser (console)
  participant C as Cinder (via nginx)
  U->>B: Extend volume, new size
  B->>C: POST /v3/{project}/volumes/{id}/action {"os-extend": {"new_size": n}}<br/>Openstack-Api-Version: volume 3.59, volume 3.60
  Note over C: Cinder keeps the first "volume" value: 3.59
  alt available or in-use (≥ 3.42)
    C-->>B: 202
    B->>B: refresh every 10 s while "extending"
  else invalid state / quota
    C-->>B: 400 / 413 body
    B-->>U: error notification with the body
  end

5. Switch project

sequenceDiagram
  autonumber
  actor U as User
  participant B as Browser (console)
  participant S as skyline-apiserver
  participant K as Keystone
  U->>B: pick a project in the header
  B->>S: POST switch_project/{project_id}?project_domain_id=... {project_id, project_domain_id}
  S->>K: rescope token
  S-->>B: profile + new cookies
  B->>B: clear every store and localStorage (except lang); store new keystone_token
  B->>S: GET profile + GET policies
  B->>B: re-render menus from endpoints and policies

Diagnostics: if menus stay empty after the switch, GET policies returned an empty list. Every policy check then denies (src/resources/skyline/policy.js:176).

6. Session expiry

sequenceDiagram
  autonumber
  participant B as Browser (console)
  participant O as any API (via nginx)
  Note over B: time_expired (epoch s) < browser clock
  B->>O: GET ... (no X-Auth-Token sent)
  O-->>B: 401
  B->>B: redirect /auth/login?referer=<path>
  B->>B: list: "The session has expired, please log in again."; auto refresh stopped

Source: reverse-spec-skyline-console/04-scenarios_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.