From 27be2618fa0c8954fc38be18dd658a780dbfa11f Mon Sep 17 00:00:00 2001 From: agatha197 Date: Tue, 14 Jan 2025 15:31:51 +0900 Subject: [PATCH] feat(FR-360): add `max_pending_session_count`, `max_concurrent_sftp_sessions` to keypair resource policy. --- .../src/components/FormItemWithUnlimited.tsx | 24 +- .../components/KeypairResourcePolicyList.tsx | 56 ++-- .../KeypairResourcePolicySettingModal.tsx | 265 +++++++++++------- react/src/helper/const-vars.ts | 4 +- react/src/hooks/hooksUsingRelay.tsx | 4 +- resources/i18n/de.json | 4 +- resources/i18n/el.json | 4 +- resources/i18n/en.json | 4 +- resources/i18n/es.json | 4 +- resources/i18n/fr.json | 4 +- resources/i18n/id.json | 4 +- resources/i18n/it.json | 4 +- resources/i18n/ja.json | 4 +- resources/i18n/ko.json | 4 +- resources/i18n/mn.json | 4 +- resources/i18n/ms.json | 4 +- resources/i18n/pl.json | 4 +- resources/i18n/pt-BR.json | 4 +- resources/i18n/pt.json | 4 +- resources/i18n/ru.json | 4 +- resources/i18n/th.json | 4 +- resources/i18n/tr.json | 4 +- resources/i18n/vi.json | 4 +- resources/i18n/zh-CN.json | 4 +- resources/i18n/zh-TW.json | 4 +- src/lib/backend.ai-client-esm.ts | 2 + 26 files changed, 286 insertions(+), 149 deletions(-) diff --git a/react/src/components/FormItemWithUnlimited.tsx b/react/src/components/FormItemWithUnlimited.tsx index dd833bf250..92a019a258 100644 --- a/react/src/components/FormItemWithUnlimited.tsx +++ b/react/src/components/FormItemWithUnlimited.tsx @@ -1,21 +1,18 @@ import Flex from './Flex'; import { Form, Checkbox, FormItemProps } from 'antd'; import { CheckboxChangeEvent } from 'antd/es/checkbox'; -import React, { - cloneElement, - isValidElement, - useEffect, - useState, -} from 'react'; +import React, { cloneElement, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; interface FormItemWithUnlimitedProps extends FormItemProps { - unlimitedValue?: number | string; + unlimitedValue?: number | string | null; + disableUnlimited?: boolean; } const FormItemWithUnlimited: React.FC = ({ name, unlimitedValue, + disableUnlimited, children, ...formItemPropsWithoutNameAndChildren }) => { @@ -30,19 +27,19 @@ const FormItemWithUnlimited: React.FC = ({ }, [form, name, unlimitedValue]); // Disable children when isUnlimited is true. - const childrenWithProps = isValidElement(children) + const childrenWithProps = React.isValidElement(children) ? cloneElement(children, { disabled: isUnlimited, } as React.Attributes & { disabled?: boolean }) : children; - const childrenWithNullValue = - isUnlimited && isValidElement(children) + const childrenWithUndefinedValue = + isUnlimited && React.isValidElement(children) ? cloneElement(children, { - value: null, + value: undefined, disabled: isUnlimited, } as React.Attributes & { value?: any }) - : null; + : undefined; return ( @@ -59,11 +56,12 @@ const FormItemWithUnlimited: React.FC = ({ style={{ margin: 0 }} {...formItemPropsWithoutNameAndChildren} > - {childrenWithNullValue} + {childrenWithUndefinedValue} ) : null} { const checked = e.target.checked; setIsUnlimited(checked); diff --git a/react/src/components/KeypairResourcePolicyList.tsx b/react/src/components/KeypairResourcePolicyList.tsx index b1c09ef4f7..727e585f7c 100644 --- a/react/src/components/KeypairResourcePolicyList.tsx +++ b/react/src/components/KeypairResourcePolicyList.tsx @@ -1,8 +1,9 @@ -import { localeCompare, numberSorterWithInfinityValue } from '../helper'; import { - UNLIMITED_MAX_CONCURRENT_SESSIONS, - UNLIMITED_MAX_CONTAINERS_PER_SESSIONS, -} from '../helper/const-vars'; + localeCompare, + numberSorterWithInfinityValue, + filterEmptyItem, +} from '../helper'; +import { SIGNED_32BIT_MAX_INT } from '../helper/const-vars'; import { exportCSVWithFormattingRules } from '../helper/csv-util'; import { useSuspendedBackendaiClient, useUpdatableState } from '../hooks'; import { useHiddenColumnKeysSetting } from '../hooks/useHiddenColumnKeysSetting'; @@ -67,8 +68,6 @@ const KeypairResourcePolicyList: React.FC = ( useState(); const baiClient = useSuspendedBackendaiClient(); - const enableParsingStoragePermission = - baiClient?.supports('fine-grained-storage-permissions') ?? false; const { keypair_resource_policies } = useLazyLoadQuery( @@ -82,6 +81,8 @@ const KeypairResourcePolicyList: React.FC = ( max_containers_per_session idle_timeout allowed_vfolder_hosts + max_pending_session_count @since(version: "24.03.4") + max_concurrent_sftp_sessions @since(version: "24.03.4") ...KeypairResourcePolicySettingModalFragment } } @@ -106,7 +107,7 @@ const KeypairResourcePolicyList: React.FC = ( } `); - const columns: ColumnsType = [ + const columns: ColumnsType = filterEmptyItem([ { title: t('resourcePolicy.Name'), dataIndex: 'name', @@ -146,8 +147,7 @@ const KeypairResourcePolicyList: React.FC = ( a?.max_concurrent_sessions && b?.max_concurrent_sessions ? a.max_concurrent_sessions - b.max_concurrent_sessions : 1, - render: (text) => - text === UNLIMITED_MAX_CONCURRENT_SESSIONS ? '∞' : text, + render: (text) => (text ? text : '∞'), }, { title: t('resourcePolicy.ClusterSize'), @@ -157,8 +157,7 @@ const KeypairResourcePolicyList: React.FC = ( a?.max_containers_per_session && b?.max_containers_per_session ? a.max_containers_per_session - b.max_containers_per_session : 1, - render: (text) => - text === UNLIMITED_MAX_CONTAINERS_PER_SESSIONS ? '∞' : text, + render: (text) => (text === SIGNED_32BIT_MAX_INT ? '∞' : text), }, { title: t('resourcePolicy.IdleTimeout'), @@ -187,7 +186,9 @@ const KeypairResourcePolicyList: React.FC = ( dataIndex: 'allowed_vfolder_hosts', key: 'allowed_vfolder_hosts', render: (text, row) => { - const allowedVFolderHosts = enableParsingStoragePermission + const allowedVFolderHosts = baiClient?.supports( + 'fine-grained-storage-permissions', + ) ? _.keys(JSON.parse(row?.allowed_vfolder_hosts || '{}')) : JSON.parse(row?.allowed_vfolder_hosts || '{}'); return ( @@ -199,6 +200,30 @@ const KeypairResourcePolicyList: React.FC = ( ); }, }, + baiClient?.supports('max-pending-session-count') && { + title: t('resourcePolicy.MaxPendingSessionCount'), + dataIndex: 'max_pending_session_count', + key: 'max_pending_session_count', + sorter: (a, b) => + numberSorterWithInfinityValue( + a?.max_pending_session_count, + b?.max_pending_session_count, + 0, + ), + render: (text) => (text ? text : '∞'), + }, + baiClient?.supports('max-concurrent-sftp-sessions') && { + title: t('resourcePolicy.MaxConcurrentSFTPSessions'), + dataIndex: 'max_concurrent_sftp_sessions', + key: 'max_concurrent_sftp_sessions', + sorter: (a, b) => + numberSorterWithInfinityValue( + a?.max_concurrent_sftp_sessions, + b?.max_concurrent_sftp_sessions, + 0, + ), + render: (text) => (text ? text : '∞'), + }, { title: t('general.Control'), key: 'control', @@ -282,7 +307,7 @@ const KeypairResourcePolicyList: React.FC = ( ), }, - ]; + ]); const [hiddenColumnKeys, setHiddenColumnKeys] = useHiddenColumnKeysSetting( 'KeypairResourcePolicyList', @@ -311,10 +336,9 @@ const KeypairResourcePolicyList: React.FC = ( { total_resource_slots: (text) => _.isEmpty(text) ? '-' : JSON.stringify(text), - max_concurrent_sessions: (text) => - text === UNLIMITED_MAX_CONCURRENT_SESSIONS ? '-' : text, + max_concurrent_sessions: (text) => (text ? text : '-'), max_containers_per_session: (text) => - text === UNLIMITED_MAX_CONTAINERS_PER_SESSIONS ? '-' : text, + text === SIGNED_32BIT_MAX_INT ? '-' : text, idle_timeout: (text) => (text ? text : '-'), max_session_lifetime: (text) => (text ? text : '-'), allowed_vfolder_hosts: (text) => diff --git a/react/src/components/KeypairResourcePolicySettingModal.tsx b/react/src/components/KeypairResourcePolicySettingModal.tsx index 2c2a36edfd..51466ed9b7 100644 --- a/react/src/components/KeypairResourcePolicySettingModal.tsx +++ b/react/src/components/KeypairResourcePolicySettingModal.tsx @@ -1,8 +1,5 @@ import { convertBinarySizeUnit } from '../helper'; -import { - UNLIMITED_MAX_CONCURRENT_SESSIONS, - UNLIMITED_MAX_CONTAINERS_PER_SESSIONS, -} from '../helper/const-vars'; +import { SIGNED_32BIT_MAX_INT } from '../helper/const-vars'; import { useSuspendedBackendaiClient } from '../hooks'; import { useResourceSlots, useResourceSlotsDetails } from '../hooks/backendai'; import AllowedHostNamesSelect from './AllowedHostNamesSelect'; @@ -28,8 +25,8 @@ import { Input, InputNumber, Row, - theme, } from 'antd'; +import { createStyles } from 'antd-style'; import graphql from 'babel-plugin-relay/macro'; import _ from 'lodash'; import React, { useMemo, useRef } from 'react'; @@ -39,6 +36,18 @@ import { useMutation, } from 'react-relay'; +const useStyles = createStyles(({ css }) => ({ + label: css` + .ant-form-item + .ant-form-item-label + > label.ant-form-item-required:not( + .ant-form-item-required-mark-optional + )::before { + display: none; + } + `, +})); + interface KeypairResourcePolicySettingModalProps extends BAIModalProps { existingPolicyNames?: string[]; keypairResourcePolicyFrgmt?: KeypairResourcePolicySettingModalFragment$key | null; @@ -54,7 +63,7 @@ const KeypairResourcePolicySettingModal: React.FC< ...props }) => { const { t } = useTranslation(); - const { token } = theme.useToken(); + const { styles } = useStyles(); const { message } = App.useApp(); const formRef = useRef(null); const [resourceSlots] = useResourceSlots(); @@ -76,6 +85,8 @@ const KeypairResourcePolicySettingModal: React.FC< idle_timeout allowed_vfolder_hosts max_vfolder_count @deprecatedSince(version: "23.09.4") + max_pending_session_count @since(version: "24.03.4") + max_concurrent_sftp_sessions @since(version: "24.03.4") } `, keypairResourcePolicyFrgmt, @@ -120,51 +131,57 @@ const KeypairResourcePolicySettingModal: React.FC< `); const initialValues = useMemo(() => { + const parsedVfolderHosts = JSON.parse( + keypairResourcePolicy?.allowed_vfolder_hosts ?? '{}', + ); const parsedTotalResourceSlots = JSON.parse( - keypairResourcePolicy?.total_resource_slots || '{}', + keypairResourcePolicy?.total_resource_slots ?? '{}', ); - if (parsedTotalResourceSlots?.mem) { - parsedTotalResourceSlots.mem = convertBinarySizeUnit( + let autoUniResult = convertBinarySizeUnit( parsedTotalResourceSlots?.mem + 'b', - 'g', + 'auto', 2, true, - )?.numberUnit; - } + ); - let unlimitedValues = {}; - if (keypairResourcePolicy === null) { - // Initialize unlimited values as a default - unlimitedValues = { - max_session_lifetime: 0, - max_concurrent_sessions: UNLIMITED_MAX_CONCURRENT_SESSIONS, - max_containers_per_session: UNLIMITED_MAX_CONTAINERS_PER_SESSIONS, - idle_timeout: 0, - }; + if (autoUniResult?.unit === 'B' || autoUniResult?.unit === 'K') { + autoUniResult = convertBinarySizeUnit( + parsedTotalResourceSlots?.mem + 'b', + 'M', + 3, + true, + ); + } + parsedTotalResourceSlots.mem = autoUniResult?.numberUnit || '0G'; } return { - parsedTotalResourceSlots, - allowedVfolderHostNames: _.keys( - JSON.parse(keypairResourcePolicy?.allowed_vfolder_hosts || '{}'), - ), - ...unlimitedValues, - ...keypairResourcePolicy, + name: keypairResourcePolicy?.name ?? '', + total_resource_slots: parsedTotalResourceSlots ?? {}, + max_session_lifetime: keypairResourcePolicy?.max_session_lifetime ?? 0, + max_concurrent_sessions: + keypairResourcePolicy?.max_concurrent_sessions ?? 0, + max_containers_per_session: + keypairResourcePolicy?.max_containers_per_session ?? 1, + idle_timeout: keypairResourcePolicy?.idle_timeout ?? 0, + allowed_vfolder_hosts: _.keys(parsedVfolderHosts) ?? [], + max_pending_session_count: + keypairResourcePolicy?.max_pending_session_count ?? null, + max_concurrent_sftp_sessions: + keypairResourcePolicy?.max_concurrent_sftp_sessions ?? 0, }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ - keypairResourcePolicy, - keypairResourcePolicy?.total_resource_slots, - keypairResourcePolicy?.allowed_vfolder_hosts, - ]); + }, [keypairResourcePolicy]); const handleOk = () => { return formRef?.current ?.validateFields() .then((values) => { - let totalResourceSlots = _.mapValues( - values?.parsedTotalResourceSlots, + const total_resource_slots = _.mapValues( + _.pickBy( + values.total_resource_slots, + (value) => !_.isUndefined(value), + ), (value, key) => { if (_.includes(key, 'mem')) { return convertBinarySizeUnit(value, 'b', 0)?.numberFixed; @@ -172,44 +189,52 @@ const KeypairResourcePolicySettingModal: React.FC< return value; }, ); - // Remove undefined values - totalResourceSlots = _.pickBy( - totalResourceSlots, - _.negate(_.isUndefined), - ); - const parsedAllowedVfolderHosts: Record = - keypairResourcePolicy - ? JSON.parse(keypairResourcePolicy.allowed_vfolder_hosts || '{}') - : {}; - const allowedVfolderHosts: Record = + const allowed_vfolder_hosts: Record = _.fromPairs( - _.map(values.allowedVfolderHostNames, (hostName) => { - const permissions = _.get( - parsedAllowedVfolderHosts, + _.map(values.allowed_vfolder_hosts, (hostName) => { + if (initialValues?.allowed_vfolder_hosts?.includes(hostName)) { + const initialPermissions = JSON.parse( + keypairResourcePolicy?.allowed_vfolder_hosts || '{}', + ); + return [hostName, initialPermissions[hostName]]; + } + const defaultPermissions = _.get( + values, hostName, - // TODO: Comment out if allow all permissions by default - // vfolder_host_permissions?.vfolder_host_permission_list, - [], // Default value if undefined + [ + 'create-vfolder', + 'modify-vfolder', + 'delete-vfolder', + 'mount-in-session', + 'upload-file', + 'download-file', + 'invite-others', + 'set-user-specific-permission', + ], // Default permissions ); - return [hostName, permissions]; + return [hostName, defaultPermissions]; }), ); + const { name, ...restValues } = values; const props: | CreateKeyPairResourcePolicyInput | ModifyKeyPairResourcePolicyInput = { + ..._.omit(restValues, 'parsedTotalResourceSlots'), + total_resource_slots: JSON.stringify(total_resource_slots), + allowed_vfolder_hosts: JSON.stringify(allowed_vfolder_hosts), default_for_unspecified: 'UNLIMITED', - total_resource_slots: JSON.stringify(totalResourceSlots || '{}'), - max_session_lifetime: values?.max_session_lifetime, - max_concurrent_sessions: values?.max_concurrent_sessions, - max_containers_per_session: values?.max_containers_per_session, - idle_timeout: values?.idle_timeout, - allowed_vfolder_hosts: JSON.stringify(allowedVfolderHosts || '{}'), }; if (!isDeprecatedMaxVfolderCountInKeypairResourcePolicy) { props.max_vfolder_count = values?.max_vfolder_count; } + if (!baiClient.supports('max-pending-session-count')) { + delete props?.max_pending_session_count; + } + if (!baiClient.supports('max-concurrent-sftp-sessions')) { + delete props?.max_concurrent_sftp_sessions; + } if (keypairResourcePolicy === null) { commitCreateKeypairResourcePolicy({ @@ -272,6 +297,7 @@ const KeypairResourcePolicySettingModal: React.FC< return (
@@ -322,22 +350,17 @@ const KeypairResourcePolicySettingModal: React.FC< - + {_.map( _.chunk(_.keys(resourceSlots), 2), (resourceSlotKeys, index) => ( - + {_.map(resourceSlotKeys, (resourceSlotKey) => ( {_.includes(resourceSlotKey, 'mem') ? ( - + ) : ( )} @@ -391,68 +416,116 @@ const KeypairResourcePolicySettingModal: React.FC< - - + + - + - - + {baiClient.supports('max-pending-session-count') ? ( + + + + + + ) : null} - + + {baiClient.supports('max-concurrent-sftp-sessions') ? ( + + + + + + ) : null} @@ -460,7 +533,7 @@ const KeypairResourcePolicySettingModal: React.FC< diff --git a/react/src/helper/const-vars.ts b/react/src/helper/const-vars.ts index 23d833ebb7..5237797f98 100644 --- a/react/src/helper/const-vars.ts +++ b/react/src/helper/const-vars.ts @@ -1,2 +1,2 @@ -export const UNLIMITED_MAX_CONTAINERS_PER_SESSIONS = 1000000; -export const UNLIMITED_MAX_CONCURRENT_SESSIONS = 1000000; +export const SIGNED_32BIT_MAX_INT = 2147483647; +export const SIGNED_32BIT_MIN_INT = -2147483648; diff --git a/react/src/hooks/hooksUsingRelay.tsx b/react/src/hooks/hooksUsingRelay.tsx index 9e659d280f..de051ababa 100644 --- a/react/src/hooks/hooksUsingRelay.tsx +++ b/react/src/hooks/hooksUsingRelay.tsx @@ -1,5 +1,5 @@ import { useSuspendedBackendaiClient, useUpdatableState } from '.'; -import { UNLIMITED_MAX_CONCURRENT_SESSIONS } from '../helper/const-vars'; +import { SIGNED_32BIT_MAX_INT } from '../helper/const-vars'; import { hooksUsingRelay_KeyPairQuery } from './__generated__/hooksUsingRelay_KeyPairQuery.graphql'; import { hooksUsingRelay_KeyPairResourcePolicyQuery } from './__generated__/hooksUsingRelay_KeyPairResourcePolicyQuery.graphql'; import graphql from 'babel-plugin-relay/macro'; @@ -85,7 +85,7 @@ export const useCurrentKeyPairResourcePolicyLazyLoadQuery = ( sessionLimitAndRemaining: { max: _.min([ (keypair_resource_policy || {}).max_concurrent_sessions || - UNLIMITED_MAX_CONCURRENT_SESSIONS, + SIGNED_32BIT_MAX_INT, 3, //BackendAiResourceBroker.DEFAULT_CONCURRENT_SESSION_COUNT ]) as number, remaining: diff --git a/resources/i18n/de.json b/resources/i18n/de.json index b74e5f040d..0318a2466f 100644 --- a/resources/i18n/de.json +++ b/resources/i18n/de.json @@ -1085,7 +1085,9 @@ "ExportCSV": "CSV exportieren", "Tools": "Werkzeuge", "MemorySizeExceedsLimit": "Die Speichergröße sollte weniger als 300 PiB betragen", - "MaxNetworkCount": "Maximale Netzwerkanzahl" + "MaxNetworkCount": "Maximale Netzwerkanzahl", + "MaxPendingSessionCount": "Maximale Anzahl ausstehender Sitzungen", + "MaxConcurrentSFTPSessions": "Max. gleichzeitige SFTP-Sitzungen" }, "registry": { "Hostname": "Hostname", diff --git a/resources/i18n/el.json b/resources/i18n/el.json index 9778b2aa0a..c363305fbb 100644 --- a/resources/i18n/el.json +++ b/resources/i18n/el.json @@ -1085,7 +1085,9 @@ "ExportCSV": "εξαγωγή CSV", "Tools": "Εργαλεία", "MemorySizeExceedsLimit": "Το μέγεθος της μνήμης πρέπει να είναι μικρότερο από 300 PiB", - "MaxNetworkCount": "Μέγιστος αριθμός δικτύου" + "MaxNetworkCount": "Μέγιστος αριθμός δικτύου", + "MaxPendingSessionCount": "Μέγιστος αριθμός συνεδριών σε εκκρεμότητα", + "MaxConcurrentSFTPSessions": "Μέγιστες ταυτόχρονες συνεδρίες SFTP" }, "registry": { "Hostname": "Όνομα κεντρικού υπολογιστή", diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 2cd0cedaed..1270934030 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -1212,7 +1212,9 @@ "ExportCSV": "export CSV", "Tools": "Tools", "MemorySizeExceedsLimit": "Memory size should be less than 300 PiB", - "MaxNetworkCount": "Max Network Count" + "MaxNetworkCount": "Max Network Count", + "MaxPendingSessionCount": "Max Pending Session Count", + "MaxConcurrentSFTPSessions": "Max Concurrent SFTP Sessions" }, "registry": { "Hostname": "Hostname", diff --git a/resources/i18n/es.json b/resources/i18n/es.json index 5f1668f186..cc18cb163b 100644 --- a/resources/i18n/es.json +++ b/resources/i18n/es.json @@ -985,7 +985,9 @@ "ExportCSV": "exportar CSV", "Tools": "Herramientas", "MemorySizeExceedsLimit": "El tamaño de la memoria debe ser inferior a 300 PiB", - "MaxNetworkCount": "Recuento máximo de red" + "MaxNetworkCount": "Recuento máximo de red", + "MaxPendingSessionCount": "Recuento máximo de sesiones pendientes", + "MaxConcurrentSFTPSessions": "Sesiones SFTP simultáneas máximas" }, "resourcePreset": { "AboutToDeletePreset": "Está a punto de borrar este preajuste:", diff --git a/resources/i18n/fr.json b/resources/i18n/fr.json index c08204eddc..b3cc89d9f9 100644 --- a/resources/i18n/fr.json +++ b/resources/i18n/fr.json @@ -1085,7 +1085,9 @@ "ExportCSV": "exporter au format CSV", "Tools": "Outils", "MemorySizeExceedsLimit": "La taille de la mémoire doit être inférieure à 300 PiB", - "MaxNetworkCount": "Nombre maximum de réseaux" + "MaxNetworkCount": "Nombre maximum de réseaux", + "MaxPendingSessionCount": "Nombre maximum de sessions en attente", + "MaxConcurrentSFTPSessions": "Nombre maximal de sessions SFTP simultanées" }, "registry": { "Hostname": "Nom d'hôte", diff --git a/resources/i18n/id.json b/resources/i18n/id.json index 9a30155548..afa06f0fcf 100644 --- a/resources/i18n/id.json +++ b/resources/i18n/id.json @@ -1086,7 +1086,9 @@ "ExportCSV": "ekspor CSV", "Tools": "Peralatan", "MemorySizeExceedsLimit": "Ukuran memori harus kurang dari 300 PiB", - "MaxNetworkCount": "Jumlah Jaringan Maks" + "MaxNetworkCount": "Jumlah Jaringan Maks", + "MaxPendingSessionCount": "Jumlah Sesi Tertunda Maks", + "MaxConcurrentSFTPSessions": "Sesi SFTP Serentak Maks" }, "registry": { "Hostname": "Nama host", diff --git a/resources/i18n/it.json b/resources/i18n/it.json index 2d68ec2282..9e71ca2ddc 100644 --- a/resources/i18n/it.json +++ b/resources/i18n/it.json @@ -1084,7 +1084,9 @@ "ExportCSV": "esportare CSV", "Tools": "Utensili", "MemorySizeExceedsLimit": "La dimensione della memoria deve essere inferiore a 300 PiB", - "MaxNetworkCount": "Conteggio massimo della rete" + "MaxNetworkCount": "Conteggio massimo della rete", + "MaxPendingSessionCount": "Conteggio massimo delle sessioni in sospeso", + "MaxConcurrentSFTPSessions": "Numero massimo di sessioni SFTP simultanee" }, "registry": { "Hostname": "Nome host", diff --git a/resources/i18n/ja.json b/resources/i18n/ja.json index 4889edbc6b..a43c40c812 100644 --- a/resources/i18n/ja.json +++ b/resources/i18n/ja.json @@ -1085,7 +1085,9 @@ "ExportCSV": "CSVエクスポート", "Tools": "ツール", "MemorySizeExceedsLimit": "メモリ サイズは 300 PiB 未満である必要があります", - "MaxNetworkCount": "最大ネットワーク数" + "MaxNetworkCount": "最大ネットワーク数", + "MaxPendingSessionCount": "最大保留セッション数", + "MaxConcurrentSFTPSessions": "最大同時SFTPセッション数" }, "registry": { "Hostname": "ホスト名", diff --git a/resources/i18n/ko.json b/resources/i18n/ko.json index 3d882ac61d..74bbafaa5e 100644 --- a/resources/i18n/ko.json +++ b/resources/i18n/ko.json @@ -1200,7 +1200,9 @@ "ExportCSV": "CSV로 내보내기", "Tools": "도구", "MemorySizeExceedsLimit": "메모리 크기는 300PiB 미만이어야 합니다.", - "MaxNetworkCount": "최대 네트워크 수" + "MaxNetworkCount": "최대 네트워크 수", + "MaxPendingSessionCount": "최대 대기 세션 수", + "MaxConcurrentSFTPSessions": "최대 동시 SFTP 세션" }, "registry": { "Hostname": "호스트명", diff --git a/resources/i18n/mn.json b/resources/i18n/mn.json index a5bf8a5395..950faefe33 100644 --- a/resources/i18n/mn.json +++ b/resources/i18n/mn.json @@ -1084,7 +1084,9 @@ "ExportCSV": "CSV экспортлох", "Tools": "Багаж хэрэгсэл", "MemorySizeExceedsLimit": "Санах ойн хэмжээ 300 PiB-ээс бага байх ёстой", - "MaxNetworkCount": "Хамгийн их сүлжээний тоо" + "MaxNetworkCount": "Хамгийн их сүлжээний тоо", + "MaxPendingSessionCount": "Хамгийн их хүлээгдэж буй сессийн тоо", + "MaxConcurrentSFTPSessions": "Хамгийн их зэрэгцсэн SFTP сессүүд" }, "registry": { "Hostname": "Хостын нэр", diff --git a/resources/i18n/ms.json b/resources/i18n/ms.json index 53b784133a..0097ea020c 100644 --- a/resources/i18n/ms.json +++ b/resources/i18n/ms.json @@ -1085,7 +1085,9 @@ "ExportCSV": "eksport CSV", "Tools": "Alatan", "MemorySizeExceedsLimit": "Saiz memori hendaklah kurang daripada 300 PiB", - "MaxNetworkCount": "Kiraan Rangkaian Maks" + "MaxNetworkCount": "Kiraan Rangkaian Maks", + "MaxPendingSessionCount": "Kiraan Sesi Menunggu Maks", + "MaxConcurrentSFTPSessions": "Sesi SFTP Serentak Maks" }, "registry": { "Hostname": "Nama Hos", diff --git a/resources/i18n/pl.json b/resources/i18n/pl.json index 30776fca4d..ce28cbd807 100644 --- a/resources/i18n/pl.json +++ b/resources/i18n/pl.json @@ -1085,7 +1085,9 @@ "ExportCSV": "eksportuj plik CSV", "Tools": "Narzędzia", "MemorySizeExceedsLimit": "Rozmiar pamięci powinien być mniejszy niż 300 PiB", - "MaxNetworkCount": "Maksymalna liczba sieci" + "MaxNetworkCount": "Maksymalna liczba sieci", + "MaxPendingSessionCount": "Maksymalna liczba oczekujących sesji", + "MaxConcurrentSFTPSessions": "Maksymalna liczba jednoczesnych sesji SFTP" }, "registry": { "Hostname": "Nazwa hosta", diff --git a/resources/i18n/pt-BR.json b/resources/i18n/pt-BR.json index ca09bab311..d7637c5e9a 100644 --- a/resources/i18n/pt-BR.json +++ b/resources/i18n/pt-BR.json @@ -1085,7 +1085,9 @@ "ExportCSV": "exportar CSV", "Tools": "Ferramentas", "MemorySizeExceedsLimit": "O tamanho da memória deve ser inferior a 300 PiB", - "MaxNetworkCount": "Contagem máxima de rede" + "MaxNetworkCount": "Contagem máxima de rede", + "MaxPendingSessionCount": "Contagem máxima de sessões pendentes", + "MaxConcurrentSFTPSessions": "Máximo de sessões SFTP simultâneas" }, "registry": { "Hostname": "nome de anfitrião", diff --git a/resources/i18n/pt.json b/resources/i18n/pt.json index 12910659e1..d5b7c1006e 100644 --- a/resources/i18n/pt.json +++ b/resources/i18n/pt.json @@ -1085,7 +1085,9 @@ "ExportCSV": "exportar CSV", "Tools": "Ferramentas", "MemorySizeExceedsLimit": "O tamanho da memória deve ser inferior a 300 PiB", - "MaxNetworkCount": "Contagem máxima de rede" + "MaxNetworkCount": "Contagem máxima de rede", + "MaxPendingSessionCount": "Contagem máxima de sessões pendentes", + "MaxConcurrentSFTPSessions": "Máximo de sessões SFTP simultâneas" }, "registry": { "Hostname": "nome de anfitrião", diff --git a/resources/i18n/ru.json b/resources/i18n/ru.json index 182f51dcd0..63d3731957 100644 --- a/resources/i18n/ru.json +++ b/resources/i18n/ru.json @@ -1085,7 +1085,9 @@ "ExportCSV": "экспортировать CSV", "Tools": "Инструменты", "MemorySizeExceedsLimit": "Размер памяти должен быть менее 300 ПиБ.", - "MaxNetworkCount": "Максимальное количество сетей" + "MaxNetworkCount": "Максимальное количество сетей", + "MaxPendingSessionCount": "Максимальное количество ожидающих сеансов", + "MaxConcurrentSFTPSessions": "Максимальное количество одновременных SFTP-сессий" }, "registry": { "Hostname": "Имя хоста", diff --git a/resources/i18n/th.json b/resources/i18n/th.json index 168fe19a8f..7b2bec102a 100644 --- a/resources/i18n/th.json +++ b/resources/i18n/th.json @@ -1197,7 +1197,9 @@ "ExportCSV": "ส่งออก CSV", "Tools": "เครื่องมือ", "MemorySizeExceedsLimit": "ขนาดหน่วยความจำควรน้อยกว่า 300 PiB", - "MaxNetworkCount": "จำนวนเครือข่ายสูงสุด" + "MaxNetworkCount": "จำนวนเครือข่ายสูงสุด", + "MaxPendingSessionCount": "จำนวนเซสชันที่รอดำเนินการสูงสุด", + "MaxConcurrentSFTPSessions": "เซสชัน SFTP พร้อมกันสูงสุด" }, "registry": { "Hostname": "ชื่อโฮสต์", diff --git a/resources/i18n/tr.json b/resources/i18n/tr.json index 36cbb69e52..221c120be6 100644 --- a/resources/i18n/tr.json +++ b/resources/i18n/tr.json @@ -1084,7 +1084,9 @@ "ExportCSV": "CSV'yi dışa aktar", "Tools": "Aletler", "MemorySizeExceedsLimit": "Bellek boyutu 300 PiB'den az olmalıdır", - "MaxNetworkCount": "Maksimum Ağ Sayısı" + "MaxNetworkCount": "Maksimum Ağ Sayısı", + "MaxPendingSessionCount": "Maksimum Bekleyen Oturum Sayısı", + "MaxConcurrentSFTPSessions": "Maksimum Eşzamanlı SFTP Oturumu Sayısı" }, "registry": { "Hostname": "ana bilgisayar adı", diff --git a/resources/i18n/vi.json b/resources/i18n/vi.json index e9f935568f..368bce2298 100644 --- a/resources/i18n/vi.json +++ b/resources/i18n/vi.json @@ -1085,7 +1085,9 @@ "ExportCSV": "xuất CSV", "Tools": "Công cụ", "MemorySizeExceedsLimit": "Kích thước bộ nhớ phải nhỏ hơn 300 PiB", - "MaxNetworkCount": "Số lượng mạng tối đa" + "MaxNetworkCount": "Số lượng mạng tối đa", + "MaxPendingSessionCount": "Số phiên chờ xử lý tối đa", + "MaxConcurrentSFTPSessions": "Phiên SFTP đồng thời tối đa" }, "registry": { "Hostname": "Tên máy chủ", diff --git a/resources/i18n/zh-CN.json b/resources/i18n/zh-CN.json index ea5e2020f1..48c2a90888 100644 --- a/resources/i18n/zh-CN.json +++ b/resources/i18n/zh-CN.json @@ -1085,7 +1085,9 @@ "ExportCSV": "导出 CSV", "Tools": "工具", "MemorySizeExceedsLimit": "内存大小应小于 300 PiB", - "MaxNetworkCount": "最大网络数" + "MaxNetworkCount": "最大网络数", + "MaxPendingSessionCount": "最大待处理会话数", + "MaxConcurrentSFTPSessions": "最大并发 SFTP 会话数" }, "registry": { "Hostname": "主机名", diff --git a/resources/i18n/zh-TW.json b/resources/i18n/zh-TW.json index 63d7b07cf3..96d8c703a5 100644 --- a/resources/i18n/zh-TW.json +++ b/resources/i18n/zh-TW.json @@ -1084,7 +1084,9 @@ "ExportCSV": "匯出 CSV", "Tools": "工具", "MemorySizeExceedsLimit": "記憶體大小應小於 300 PiB", - "MaxNetworkCount": "最大網路數" + "MaxNetworkCount": "最大網路數", + "MaxPendingSessionCount": "最大待處理會話數", + "MaxConcurrentSFTPSessions": "最大並發 SFTP 會話數" }, "registry": { "Hostname": "主機名", diff --git a/src/lib/backend.ai-client-esm.ts b/src/lib/backend.ai-client-esm.ts index ab1dfd4738..17ab736394 100644 --- a/src/lib/backend.ai-client-esm.ts +++ b/src/lib/backend.ai-client-esm.ts @@ -702,6 +702,8 @@ class Client { } if (this.isManagerVersionCompatibleWith('24.03.4')) { this._features['endpoint-extra-mounts'] = true; + this._features['max-pending-session-count'] = true; + this._features['max-concurrent-sftp-sessions'] = true; } if (this.isManagerVersionCompatibleWith('24.03.5')) { this._features['modify-endpoint-environ'] = true;