diff --git a/src/components/FormItem/MemberAllocator/index.jsx b/src/components/FormItem/MemberAllocator/index.jsx index d48644b7..535c76fa 100644 --- a/src/components/FormItem/MemberAllocator/index.jsx +++ b/src/components/FormItem/MemberAllocator/index.jsx @@ -47,7 +47,7 @@ const MemberAllocator = ({ componentProps, formItemProps }) => { return getLinkRender({ key, params: { id }, value: id }); } - let addOuter = () => { }; + let addOuter = () => {}; return (
@@ -168,15 +168,15 @@ const MemberAllocator = ({ componentProps, formItemProps }) => { name: 'origin_data', options: [ { - label: t('true'), + label: t('True'), key: true, }, ], filterFunc: (record, val) => { return val ? record.fixed_ips.some( - (item) => item.subnet_id === lbSubnetId - ) + (item) => item.subnet_id === lbSubnetId + ) : true; }, }, @@ -250,7 +250,7 @@ const MemberAllocator = ({ componentProps, formItemProps }) => { (it) => it.address === value1.ip_address.ip && it.protocol_port === - value1.ip_address.protocol_port + value1.ip_address.protocol_port ); if (!value1 || !value1.ip_address.ip) { return Promise.reject( diff --git a/src/components/Layout/GlobalHeader/RightContent.jsx b/src/components/Layout/GlobalHeader/RightContent.jsx index d47bc967..908ff628 100644 --- a/src/components/Layout/GlobalHeader/RightContent.jsx +++ b/src/components/Layout/GlobalHeader/RightContent.jsx @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React, { PureComponent } from 'react'; +import React, { Component } from 'react'; import { inject, observer } from 'mobx-react'; import { Button, Col, Row } from 'antd'; import Avatar from './AvatarDropdown'; @@ -20,7 +20,7 @@ import styles from './index.less'; @inject('rootStore') @observer -export class GlobalHeaderRight extends PureComponent { +export class GlobalHeaderRight extends Component { get isAdminPage() { const { isAdminPage = false } = this.props; return isAdminPage; diff --git a/src/locales/en.json b/src/locales/en.json index 67f7301f..6616cddb 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1177,6 +1177,7 @@ "Memory": "Memory", "Memory Optimized": "Memory Optimized", "Memory Page": "Memory Page", + "Memory Page Value": "Memory Page Value", "Memory Usage": "Memory Usage", "Memory usage Num (GB": "Memory usage Num (GB", "Message": "Message", @@ -1300,8 +1301,8 @@ "OSDs": "OSDs", "OSPF": "OSPF", "Object Count": "Object Count", + "Object Count ": "Object Count ", "Object Storage": "Object Storage", - "Objects": "Objects", "Off": "Off", "Offline": "Offline", "Oman": "Oman", @@ -1339,8 +1340,8 @@ "Owner": "Owner", "Ownership of a volume can be transferred from one project to another. The transfer process of the volume needs to perform the transfer operation in the original owner's project, and complete the \"accept\" operation in the receiver's project.": "Ownership of a volume can be transferred from one project to another. The transfer process of the volume needs to perform the transfer operation in the original owner's project, and complete the \"accept\" operation in the receiver's project.", "PFS": "PFS", + "PG Count": "PG Count", "PGM": "PGM", - "PGs": "PGs", "PING": "PING", "PXE": "PXE", "PXE Enabled": "PXE Enabled", @@ -1392,12 +1393,14 @@ "Placement service:": "Placement service:", "Platform Info": "Platform Info", "Please confirm your password!": "Please confirm your password!", + "Please enter a memory page size, such as: 1024, 1024MB": "Please enter a memory page size, such as: 1024, 1024MB", "Please enter a valid ASCII code": "Please enter a valid ASCII code", "Please enter a valid Email Address!": "Please enter a valid Email Address!", "Please enter a valid Phone Number": "Please enter a valid Phone Number", "Please enter complete key value!": "Please enter complete key value!", "Please enter right format custom trait!": "Please enter right format custom trait!", "Please enter right format key value!": "Please enter right format key value!", + "Please enter right format memory page value!": "Please enter right format memory page value!", "Please enter right format trait!": "Please enter right format trait!", "Please fill in the peer network segment and subnet mask of CIDR format, the written subnets should be under the same router, one per line.": "Please fill in the peer network segment and subnet mask of CIDR format, the written subnets should be under the same router, one per line.", "Please input": "Please input", @@ -1917,6 +1920,7 @@ "The total amount of data is { total }, and the interface can support downloading { totalMax } pieces of data. If you need to download all the data, please contact the administrator.": "The total amount of data is { total }, and the interface can support downloading { totalMax } pieces of data. If you need to download all the data, please contact the administrator.", "The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).": "The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).", "The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).": "The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).", + "The unit suffix must be one of the following: Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it), KB, KiB, MB, MiB, GB, GiB, TB, TiB. If the unit suffix is not provided, it is assumed to be KB.": "The unit suffix must be one of the following: Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it), KB, KiB, MB, MiB, GB, GiB, TB, TiB. If the unit suffix is not provided, it is assumed to be KB.", "The user has been disabled, please contact the administrator": "The user has been disabled, please contact the administrator", "The user needs to ensure that the input is a shell script that can run completely and normally.": "The user needs to ensure that the input is a shell script that can run completely and normally.", "The volume associated with the backup is not available, unable to restore.": "The volume associated with the backup is not available, unable to restore.", @@ -1959,6 +1963,7 @@ "Transfer Name": "Transfer Name", "Transform Protocol": "Transform Protocol", "Trinidad and Tobago": "Trinidad and Tobago", + "True": "True", "Tunisia": "Tunisia", "Turkey": "Turkey", "Turkmenistan": "Turkmenistan", diff --git a/src/locales/zh.json b/src/locales/zh.json index 832e3dda..8e6eeac4 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -1177,6 +1177,7 @@ "Memory": "内存", "Memory Optimized": "内存型", "Memory Page": "内存页", + "Memory Page Value": "内存页值", "Memory Usage": "内存使用量", "Memory usage Num (GB": "内存用量 (GB)", "Message": "消息", @@ -1299,8 +1300,8 @@ "OS Version": "系统版本", "OSDs": "", "OSPF": "", - "Objects": "Object数量", "Object Count": "对象数量", + "Object Count ": "Object数量", "Object Storage": "对象存储", "Off": "关", "Offline": "离线", @@ -1339,8 +1340,8 @@ "Owner": "所有者", "Ownership of a volume can be transferred from one project to another. The transfer process of the volume needs to perform the transfer operation in the original owner's project, and complete the \"accept\" operation in the receiver's project.": "卷的拥有权可以从一个项目转给另外一个。卷的转让过程需要在原拥有者的项目中执行转让操作,在接收者项目中完成“接受”操作。", "PFS": "完全向前保密", + "PG Count": "PG数量", "PGM": "", - "PGs": "PG数量", "PING": "", "PXE": "", "PXE Enabled": "PXE启用", @@ -1392,12 +1393,14 @@ "Placement service:": "放置服务(placement):", "Platform Info": "平台概况", "Please confirm your password!": "请确认您的密码", + "Please enter a memory page size, such as: 1024, 1024MB": "请输入内存页大小,如:1024, 1024MB", "Please enter a valid ASCII code": "请输入有效的ASCII码", "Please enter a valid Email Address!": "请输入一个有效的邮箱地址", "Please enter a valid Phone Number": "请输入一个有效的手机号", "Please enter complete key value!": "请输入完整的键值!", "Please enter right format custom trait!": "请输入正确格式的自定义特性!", "Please enter right format key value!": "请输入正确格式的键值", + "Please enter right format memory page value!": "请输入正确格式的内存页值", "Please enter right format trait!": "请输入正确格式的特性!", "Please fill in the peer network segment and subnet mask of CIDR format, the written subnets should be under the same router, one per line.": "请填写CIDR格式的对端网段,且填写的网段需在同一个路由下,每行一个。", "Please input": "请输入", @@ -1802,8 +1805,8 @@ "Storage Cluster Usage": "存储集群使用率", "Storage IOPS": "存储IOPS", "Storage Interface": "Storage接口", - "Storage Pool Capacity Usage": "存储池容量使用情况", "Storage Policy": "存储权限", + "Storage Pool Capacity Usage": "存储池容量使用情况", "Storage Types": "存储类型", "Sub User": "组内用户列表", "Subnet": "子网", @@ -1917,6 +1920,7 @@ "The total amount of data is { total }, and the interface can support downloading { totalMax } pieces of data. If you need to download all the data, please contact the administrator.": "数据总量为{ total },界面可支持下载{ totalMax }条数据,如需下载全部数据,请联系管理员。", "The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).": "云主机类型的特性名称需要与调度节点的特性对应;通过给裸机实例注入必需特性,计算服务将只调度实例到具有所有必需特性的裸金属节点(比如:调度节点的有 HW_CPU_X86_VMX的特性,云主机类型添加HW_CPU_X86_VMX为必需特性,可以调度到此节点)。", "The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).": "被调度节点的特性需要与裸机实例使用的云主机类型的特性对应;通过给裸机实例注入必需特性,计算服务将只调度实例到具有所有必需特性的裸金属节点(比如:调度节点的有 HW_CPU_X86_VMX的特性, 云主机类型添加HW_CPU_X86_VMX为必要特性,可以调度到此节点)。", + "The unit suffix must be one of the following: Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it), KB, KiB, MB, MiB, GB, GiB, TB, TiB. If the unit suffix is not provided, it is assumed to be KB.": "单位后缀必须是以下之一:Kb(it)、Kib(it)、Mb(it)、Mib(it)、Gb(it)、Gib(it)、Tb(it)、Tib(it)、KB、 KiB、MB、MiB、GB、GiB、TB、TiB。如果未提供单位后缀,则假定为千字节。", "The user has been disabled, please contact the administrator": "用户已被禁用,请联系管理员", "The user needs to ensure that the input is a shell script that can run completely and normally.": "请确保输入的是能完整正常运行的 shell 脚本。", "The volume associated with the backup is not available, unable to restore.": "云硬盘不处于可用状态,不支持恢复备份操作。", @@ -1959,6 +1963,7 @@ "Transfer Name": "转让名称", "Transform Protocol": "转换协议", "Trinidad and Tobago": "特立尼达和多巴哥", + "True": "是", "Tunisia": "突尼斯", "Turkey": "土耳其", "Turkmenistan": "土库曼", diff --git a/src/pages/compute/containers/Flavor/actions/StepCreate/ParamSetting.jsx b/src/pages/compute/containers/Flavor/actions/StepCreate/ParamSetting.jsx index 29419a61..855394f2 100644 --- a/src/pages/compute/containers/Flavor/actions/StepCreate/ParamSetting.jsx +++ b/src/pages/compute/containers/Flavor/actions/StepCreate/ParamSetting.jsx @@ -156,6 +156,8 @@ export class ParamSetting extends Base { attachUsb: false, resourceProps: this.getDefaultResourcePropValues(), traitProps: [], + memPageSizeMore: 'any', + memPageSize: 'large', }; return data; } @@ -168,7 +170,14 @@ export class ParamSetting extends Base { } get nameForStateUpdate() { - return ['architecture', 'category', 'attachUsb']; + return [ + 'architecture', + 'category', + 'attachUsb', + 'memPageSizeMore', + 'more', + 'memPageSize', + ]; } allowed = () => Promise.resolve(); @@ -218,6 +227,15 @@ export class ParamSetting extends Base { }, }); + pageSizeValueValidate = (rule, value) => { + const r = + /^[1-9]\d*(Kb\(it\)|Kib\(it\)|Mb\(it\)|Mib\(it\)|Gb\(it\)|Gib\(it\)|Tb\(it\)|Tib\(it\)|KB|KiB|MB|MiB|GB|GiB|TB|TiB)?$/; + if (r.test(value)) { + return Promise.resolve(); + } + return Promise.reject(t('Please enter right format memory page value!')); + }; + checkResourceProps = (values) => { const item = values.find((it, index) => { const { key, value } = it.value || {}; @@ -244,7 +262,14 @@ export class ParamSetting extends Base { }; get formItems() { - const { architecture, category, attachUsb } = this.state; + const { + architecture, + category, + attachUsb, + memPageSizeMore, + more = false, + memPageSize, + } = this.state; const isBareMetal = architecture === 'bare_metal'; const hasIOPS = categoryHasIOPS(category); const hasEphemeral = categoryHasEphemeral(category); @@ -253,6 +278,13 @@ export class ParamSetting extends Base { const isGpuComputeType = isGPUType && !isGpuVisualType; const typeIsComputeOptimized = isComputeOptimized(category); const instanceType = flavorCategoryList[category] || category; + const showNumaInput = !typeIsComputeOptimized && !isBareMetal; + const showMemPageMore = more && showNumaInput; + const showPageSizeInputMore = + showMemPageMore && memPageSizeMore === 'custom'; + const showPageSizeInput = + typeIsComputeOptimized && memPageSize === 'custom'; + const NUMATip = t( 'It is recommended that { instanceType } instance simultaneously set NUMA affinity policy for PCIE device to force or priority matching. This configuration can further improve PCIE computing performance.', { instanceType } @@ -269,6 +301,12 @@ export class ParamSetting extends Base { 'It is recommended that the { instanceType } instance simultaneously set large page memory to large. { instanceType } instances also require faster memory addressing capabilities.', { instanceType } ); + const largePageValueTip = t( + 'The unit suffix must be one of the following: Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it), KB, KiB, MB, MiB, GB, GiB, TB, TiB. If the unit suffix is not provided, it is assumed to be KB.' + ); + const pageSizePlaceholder = t( + 'Please enter a memory page size, such as: 1024, 1024MB' + ); return [ { @@ -357,7 +395,32 @@ export class ParamSetting extends Base { type: 'input-int', min: 1, required: true, - hidden: typeIsComputeOptimized || isBareMetal, + hidden: !showNumaInput, + }, + { + name: 'more', + label: t('Advanced Options'), + type: 'more', + hidden: !showNumaInput, + }, + { + name: 'memPageSizeMore', + label: t('Memory Page'), + type: 'select', + options: pageTypeList, + hidden: !showMemPageMore, + required: showMemPageMore, + tip: largePageTip, + }, + { + name: 'memPageSizeValueMore', + label: t('Memory Page Value'), + type: 'input', + hidden: !showPageSizeInputMore, + required: showPageSizeInputMore, + extra: largePageValueTip, + validator: this.pageSizeValueValidate, + placeholder: pageSizePlaceholder, }, { name: 'gpu-type', @@ -434,6 +497,16 @@ export class ParamSetting extends Base { required: typeIsComputeOptimized, tip: largePageTip, }, + { + name: 'memPageSizeValue', + label: t('Memory Page Value'), + type: 'input', + hidden: !showPageSizeInput, + required: showPageSizeInput, + extra: largePageValueTip, + validator: this.pageSizeValueValidate, + placeholder: pageSizePlaceholder, + }, { name: 'usb-type', label: t('USB Parameters'), diff --git a/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx b/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx index 5611c889..f8838ab0 100644 --- a/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx +++ b/src/pages/compute/containers/Flavor/actions/StepCreate/index.jsx @@ -92,6 +92,10 @@ class StepCreate extends StepAction { return obj; }; + getPageSizeValue(type, value) { + return type === 'custom' ? value : type; + } + onSubmit = (values) => { const { architecture, @@ -105,6 +109,9 @@ class StepCreate extends StepAction { gpuType, gpuNumber, numaNodesNum, + memPageSizeValueMore, + memPageSizeValue, + memPageSizeMore, attachUsb, usbType, usbNumber, @@ -163,9 +170,16 @@ class StepCreate extends StepAction { }); extraSpecs['hw:cpu_policy'] = cpuPolicy; extraSpecs['hw:cpu_thread_policy'] = cpuThreadPolicy; - extraSpecs['hw:mem_page_size'] = memPageSize; + extraSpecs['hw:mem_page_size'] = this.getPageSizeValue( + memPageSize, + memPageSizeValue + ); } else if (architecture !== 'bare_metal') { extraSpecs['hw:numa_nodes'] = numaNodesNum; + extraSpecs['hw:mem_page_size'] = this.getPageSizeValue( + memPageSizeMore, + memPageSizeValueMore + ); extraSpecs['hw:live_resize'] = 'True'; } if (isBareMetal(architecture)) { diff --git a/src/pages/monitor/containers/StorageCluster/RenderTabs.jsx b/src/pages/monitor/containers/StorageCluster/RenderTabs.jsx index c90d9a35..86ed51be 100644 --- a/src/pages/monitor/containers/StorageCluster/RenderTabs.jsx +++ b/src/pages/monitor/containers/StorageCluster/RenderTabs.jsx @@ -216,12 +216,12 @@ const poolsColumns = [ dataIndex: 'name', }, { - title: t('PGs'), + title: t('PG Count'), dataIndex: 'ceph_pg_total', isHideable: true, }, { - title: t('Objects'), + title: t('Object Count '), dataIndex: 'ceph_pool_objects', isHideable: true, }, diff --git a/src/resources/flavor.js b/src/resources/flavor.js index 2b727b04..e9e935e4 100644 --- a/src/resources/flavor.js +++ b/src/resources/flavor.js @@ -53,6 +53,10 @@ export const pageTypeList = [ label: t('Any(Random)'), value: 'any', }, + { + label: t('Custom'), + value: 'custom', + }, ]; export const pageTypeMap = {