refactor: adapt org-namespace lookup to principal name rename

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.
This commit is contained in:
gitlawr
2026-05-21 12:15:39 +08:00
committed by jialin
parent 15cf4d89b7
commit e7a376db70
9 changed files with 15 additions and 13 deletions
+7 -5
View File
@@ -30,9 +30,11 @@ export const initialPasswordAtom = atomWithStorage<string>(
// Namespace the server creates for an Org's resources on each Kubernetes
// cluster. The format must match the backend's ``get_namespace_name``
// helper — ``gpustack-{slug}`` — because the GPU-instance / storage CRDs
// helper — ``gpustack-{name}`` — because the GPU-instance / storage CRDs
// (worker.gpustack.ai/v1) are namespaced and the server-side admission
// keys off this exact name.
// keys off this exact name. The identifier column on the unified
// Principal table is now ``name`` (post identity-consolidation rename
// of the legacy ``slug``); the namespace prefix is unchanged.
//
// Resolution path:
// 1. The Org the caller is currently acting under — the enterprise
@@ -75,7 +77,7 @@ const getStoredCurrentOrgId = (): number | null => {
// the caller's member orgs; ``allOrganizations`` is admin-only (every
// Org on the platform) so admin sessions can resolve any owner Org id.
// Both are checked because ``currentOrganizationId`` is null in the
// admin "All" view but a member org's slug might still cover the
// admin "All" view but a member org's ``name`` might still cover the
// cluster-owner fallback.
const ORG_CACHE_KEYS = ['organizationList', 'allOrganizations'] as const;
@@ -89,10 +91,10 @@ const lookupOrgNamespace = (id: number | null): string | null => {
try {
const raw = localStorage.getItem(key);
if (!raw) continue;
const list = JSON.parse(raw) as Array<{ id: number; slug?: string }>;
const list = JSON.parse(raw) as Array<{ id: number; name?: string }>;
if (!Array.isArray(list)) continue;
const match = list.find((item) => String(item?.id) === target);
if (match?.slug) return `gpustack-${match.slug}`;
if (match?.name) return `gpustack-${match.name}`;
} catch {
// ignore malformed cache; continue checking other keys
}
+1 -1
View File
@@ -89,7 +89,7 @@ export interface ClusterListItem {
worker_pools: NodePoolListItem[];
k8s_volume_mounts?: VolumeMount[];
// Backend ClusterPublic carries this; admin-"All" namespace
// resolution falls back to the cluster's owner Org slug.
// resolution falls back to the cluster's owner Org name.
owner_principal_id?: number;
}
+1 -1
View File
@@ -41,7 +41,7 @@ const GPUService: React.FC = () => {
const [currentCluster, setCurrentCluster] = useAtom(currentClusterAtom);
const clusterID = currentCluster?.id;
// In admin "All" view there's no Org context, so the helper falls
// back to the selected cluster's owner Org slug.
// back to the selected cluster's owner Org name.
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
const deleteInstance = useCallback(
@@ -15,7 +15,7 @@ export default function useCreateInstance() {
const currentCluster = useAtomValue(currentClusterAtom);
const clusterID = currentCluster?.id;
// Admin "All" view has no Org context — fall back to the
// selected cluster's owner Org slug for the K8s namespace.
// selected cluster's owner Org name for the K8s namespace.
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
const fetchDetail = useCallback(
@@ -16,7 +16,7 @@ export default function useUpdateInstance() {
const currentCluster = useAtomValue(currentClusterAtom);
const clusterID = currentCluster?.id;
// Admin "All" view has no Org context — fall back to the
// selected cluster's owner Org slug for the K8s namespace.
// selected cluster's owner Org name for the K8s namespace.
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
const fetchDetail = useCallback(
+1 -1
View File
@@ -36,7 +36,7 @@ const GPUServiceStorage: React.FC = () => {
const intl = useIntl();
const [currentCluster, setCurrentCluster] = useAtom(currentClusterAtom);
const clusterID = currentCluster?.id;
// Admin "All" view falls back to the cluster's owner Org slug
// Admin "All" view falls back to the cluster's owner Org name
// see :func:`getCurrentOrgNamespace`.
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
@@ -15,7 +15,7 @@ export default function useCreateStorage() {
const currentCluster = useAtomValue(currentClusterAtom);
const clusterID = currentCluster?.id;
// Admin "All" view has no Org context — fall back to the
// selected cluster's owner Org slug for the K8s namespace.
// selected cluster's owner Org name for the K8s namespace.
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
const fetchDetail = useCallback(
@@ -10,7 +10,7 @@ export default function useQueryStorage() {
const currentCluster = useAtomValue(currentClusterAtom);
const clusterID = currentCluster?.id;
// Admin "All" view has no Org context — fall back to the
// selected cluster's owner Org slug for the K8s namespace.
// selected cluster's owner Org name for the K8s namespace.
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
const fetchDetail = useCallback(
@@ -16,7 +16,7 @@ export default function useUpdateStorage() {
const currentCluster = useAtomValue(currentClusterAtom);
const clusterID = currentCluster?.id;
// Admin "All" view has no Org context — fall back to the
// selected cluster's owner Org slug for the K8s namespace.
// selected cluster's owner Org name for the K8s namespace.
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
const fetchDetail = useCallback(