fix(gpu-service): use gpustack-{slug} namespace for org resources
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.
This commit is contained in:
@@ -88,6 +88,9 @@ export interface ClusterListItem {
|
||||
state_message: string;
|
||||
worker_pools: NodePoolListItem[];
|
||||
k8s_volume_mounts?: VolumeMount[];
|
||||
// Backend ClusterPublic carries this; admin-"All" namespace
|
||||
// resolution falls back to the cluster's owner Org slug.
|
||||
owner_principal_id?: number;
|
||||
}
|
||||
|
||||
export interface ClusterFormData {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { InputNumber as CInputNumber, Select } from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Flex, Form, Radio } from 'antd';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { FormData as StorageFormData } from '../../storage/config/types';
|
||||
@@ -29,7 +31,8 @@ const StorageVolume = () => {
|
||||
|
||||
const form = Form.useFormInstance<FormData>();
|
||||
|
||||
const namespace = getCurrentOrganizationId();
|
||||
const currentCluster = useAtomValue(currentClusterAtom);
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
useEffect(() => {
|
||||
fetchStorage({});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { PageAction } from '@/config';
|
||||
import { PaginationKey, TABLE_SORT_DIRECTIONS } from '@/config/settings';
|
||||
import type { PageActionType } from '@/config/types';
|
||||
@@ -33,9 +33,11 @@ import useUpdateInstance from './services/use-update-instance';
|
||||
|
||||
const GPUService: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const namespace = getCurrentOrganizationId();
|
||||
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.
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
const deleteInstance = useCallback(
|
||||
(id: number) => deleteGPUServiceInstance({ namespace, clusterID, id }),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { useQueryData } from '@gpustack/core-ui';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
@@ -12,9 +12,11 @@ interface CreateInstanceParams {
|
||||
}
|
||||
|
||||
export default function useCreateInstance() {
|
||||
const namespace = getCurrentOrganizationId();
|
||||
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.
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
const fetchDetail = useCallback(
|
||||
(params: CreateInstanceParams, option?: any) =>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { useQueryData } from '@gpustack/core-ui';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
@@ -13,9 +13,11 @@ interface UpdateInstanceParams {
|
||||
}
|
||||
|
||||
export default function useUpdateInstance() {
|
||||
const namespace = getCurrentOrganizationId();
|
||||
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.
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
const fetchDetail = useCallback(
|
||||
(params: UpdateInstanceParams, option?: any) =>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { PageAction } from '@/config';
|
||||
import { PaginationKey, TABLE_SORT_DIRECTIONS } from '@/config/settings';
|
||||
import type { PageActionType } from '@/config/types';
|
||||
@@ -34,9 +34,11 @@ import useUpdateStorage from './services/use-update-storage';
|
||||
|
||||
const GPUServiceStorage: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const namespace = getCurrentOrganizationId();
|
||||
const [currentCluster, setCurrentCluster] = useAtom(currentClusterAtom);
|
||||
const clusterID = currentCluster?.id;
|
||||
// Admin "All" view falls back to the cluster's owner Org slug —
|
||||
// see :func:`getCurrentOrgNamespace`.
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
const deleteStorage = useCallback(
|
||||
(id: number) => deleteGPUServiceStorage({ namespace, clusterID, id }),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { useQueryData } from '@gpustack/core-ui';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
@@ -12,9 +12,11 @@ interface CreateStorageParams {
|
||||
}
|
||||
|
||||
export default function useCreateStorage() {
|
||||
const namespace = getCurrentOrganizationId();
|
||||
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.
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
const fetchDetail = useCallback(
|
||||
(params: CreateStorageParams, option?: any) =>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { useQueryData } from '@gpustack/core-ui';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
@@ -7,9 +7,11 @@ import { queryGPUServiceStorage } from '../apis';
|
||||
import { ListItem } from '../config/types';
|
||||
|
||||
export default function useQueryStorage() {
|
||||
const namespace = getCurrentOrganizationId();
|
||||
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.
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
const fetchDetail = useCallback(
|
||||
(params: Global.K8sSearchParams = {}, options?: any) =>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { getCurrentOrganizationId } from '@/atoms/user';
|
||||
import { getCurrentOrgNamespace } from '@/atoms/user';
|
||||
import { useQueryData } from '@gpustack/core-ui';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
@@ -13,9 +13,11 @@ interface UpdateStorageParams {
|
||||
}
|
||||
|
||||
export default function useUpdateStorage() {
|
||||
const namespace = getCurrentOrganizationId();
|
||||
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.
|
||||
const namespace = getCurrentOrgNamespace(currentCluster?.owner_principal_id);
|
||||
|
||||
const fetchDetail = useCallback(
|
||||
(params: UpdateStorageParams, option?: any) =>
|
||||
|
||||
Reference in New Issue
Block a user