- New k8s_pod_spec form sections (image credentials, node selector,
gpu vendor overrides) under k8s_options, replacing the legacy flat
k8s_volume_mounts list. UI keys aligned to the backend wire shape
(snake_case k8s_options + camelCase inside).
- System default container registry is pre-filled into the first image
credential when creating a new cluster; empty username/password are
coerced to null on submit to match the Optional[str] backend schema.
- Register cluster flow supports multi-runtime selection gated by the
cluster's gpuVendorOverrides: non-override vendors stay single-select
with an inline hint; multi-add only opens once an override vendor is
picked, and non-override cards become disabled in that state.
- Manifest URL emits multiple ?runtime= params; check-env step combines
per-vendor commands; downstream steps are disabled when no vendor is
selected.
- Pre-validate gpuVendorOverrides at save time (non-empty selector, no
duplicates across vendors, no key clash with base nodeSelector) so
the user sees the error before hitting the manifest endpoint.
- Misc: dark-mode background of the k8s_pod_spec / volume mount titles
no longer clashes with the drawer; cluster Steps no longer leaks the
internal showModules/showForms props to the DOM.
Tracks the gpustack identity-consolidation effort: the unified
``principals`` table's URL-safe identifier column was renamed
``slug`` → ``name`` (with the legacy display ``name`` → ``display_name``).
The enterprise plugin's persisted org caches (``organizationList``,
``allOrganizations`` in localStorage) now write ``name`` instead of
``slug`` on each Organization row.
``getCurrentOrgNamespace`` reads those caches to compose the k8s
namespace (``gpustack-{name}``) for GPU-instance / storage CRDs.
Updated to read ``item.name`` so namespace resolution stays in sync
with what the enterprise plugin writes — otherwise every gpu-service
write would fall through to ``gpustack-default`` even when the user
has an Org context.
Stale ``slug`` references in surrounding comments also retitled to
``name`` to avoid divergence between code and prose. The namespace
format itself (``gpustack-{...}``) is unchanged — only the column it
sources is.
The legacy ``getCurrentOrganizationId`` helper returned the raw numeric
org id from localStorage, which the GPU-service / storage call sites
then used as the K8s namespace path segment — producing requests like
``/v2/clusters/1/proxy/.../namespaces/5/instances``. The backend
creates a namespace named ``gpustack-{slug}`` (matching
``get_namespace_name``), so the request hit a namespace that doesn't
exist.
Replace the helper with ``getCurrentOrgNamespace`` that:
- prefers the Org the caller is acting under (numeric
``currentOrganizationId`` from localStorage, slug looked up in the
persisted ``organizationList`` or ``allOrganizations`` cache);
- falls back to the selected cluster's owner Org slug for the admin
"All" view, where there is no explicit Org context but the resource
still has to land in some Org's namespace — call sites pass
``currentCluster?.owner_principal_id`` through;
- falls back to ``gpustack-default`` only if neither path resolves a
slug (first load before any cache hydrates, etc.).
``ClusterListItem`` is widened with the optional ``owner_principal_id``
field so TypeScript accepts the fallback argument; the backend has
been returning it via ``ClusterPublic`` all along.