1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 00:09:16 +08:00

fix: 解决容器参数修改失败的问题 (#1590)

This commit is contained in:
ssongliu 2023-07-10 14:45:08 +08:00 committed by GitHub
parent f22980f4ce
commit c0c1d519bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 67 additions and 284 deletions

View File

@ -44,8 +44,8 @@ type ContainerOperate struct {
ExposedPorts []PortHelper `json:"exposedPorts"`
Cmd []string `json:"cmd"`
CPUShares int64 `json:"cpuShares"`
NanoCPUs int64 `json:"nanoCPUs"`
Memory int64 `json:"memory"`
NanoCPUs float64 `json:"nanoCPUs"`
Memory float64 `json:"memory"`
AutoRemove bool `json:"autoRemove"`
Volumes []VolumeHelper `json:"volumes"`
Labels []string `json:"labels"`

View File

@ -379,10 +379,10 @@ func (u *ContainerService) ContainerInfo(req dto.OperationWithName) (*dto.Contai
data.PublishAllPorts = oldContainer.HostConfig.PublishAllPorts
data.RestartPolicy = oldContainer.HostConfig.RestartPolicy.Name
if oldContainer.HostConfig.NanoCPUs != 0 {
data.NanoCPUs = oldContainer.HostConfig.NanoCPUs / 1000000000
data.NanoCPUs = float64(oldContainer.HostConfig.NanoCPUs) / 1000000000
}
if oldContainer.HostConfig.Memory != 0 {
data.Memory = oldContainer.HostConfig.Memory
data.Memory = float64(oldContainer.HostConfig.Memory) / 1024 / 1024
}
for _, bind := range oldContainer.HostConfig.Binds {
parts := strings.Split(bind, ":")
@ -783,22 +783,14 @@ func loadConfigInfo(req dto.ContainerOperate, config *container.Config, hostConf
if req.RestartPolicy == "on-failure" {
hostConf.RestartPolicy.MaximumRetryCount = 5
}
if req.NanoCPUs != 0 {
hostConf.NanoCPUs = req.NanoCPUs * 1000000000
}
if req.Memory != 0 {
hostConf.Memory = req.Memory
}
if len(req.ExposedPorts) != 0 {
hostConf.PortBindings = portMap
}
hostConf.NanoCPUs = int64(req.NanoCPUs * 1000000000)
hostConf.Memory = int64(req.Memory * 1024 * 1024)
hostConf.PortBindings = portMap
hostConf.Binds = []string{}
if len(req.Volumes) != 0 {
config.Volumes = make(map[string]struct{})
for _, volume := range req.Volumes {
config.Volumes[volume.ContainerDir] = struct{}{}
hostConf.Binds = append(hostConf.Binds, fmt.Sprintf("%s:%s:%s", volume.SourceDir, volume.ContainerDir, volume.Mode))
}
config.Volumes = make(map[string]struct{})
for _, volume := range req.Volumes {
config.Volumes[volume.ContainerDir] = struct{}{}
hostConf.Binds = append(hostConf.Binds, fmt.Sprintf("%s:%s:%s", volume.SourceDir, volume.ContainerDir, volume.Mode))
}
return nil
}

View File

@ -65,13 +65,6 @@
"sass": "^1.49.7",
"standard-version": "^9.5.0",
"stylelint": "^15.10.1",
"stylelint-config-html": "^1.0.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recess-order": "^3.0.0",
"stylelint-config-recommended-scss": "^6.0.0",
"stylelint-config-recommended-vue": "^1.4.0",
"stylelint-config-standard": "^25.0.0",
"stylelint-config-standard-scss": "^3.0.0",
"tailwindcss": "^3.3.2",
"typescript": "^4.5.4",
"unplugin-auto-import": "^0.16.4",
@ -7918,12 +7911,6 @@
"node": ">= 14"
}
},
"node_modules/postcss-media-query-parser": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
"integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
"dev": true
},
"node_modules/postcss-nested": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
@ -7965,28 +7952,6 @@
"postcss": "^8.3.3"
}
},
"node_modules/postcss-scss": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.6.tgz",
"integrity": "sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss-scss"
}
],
"engines": {
"node": ">=12.0"
},
"peerDependencies": {
"postcss": "^8.4.19"
}
},
"node_modules/postcss-selector-parser": {
"version": "6.0.13",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
@ -8000,15 +7965,6 @@
"node": ">=4"
}
},
"node_modules/postcss-sorting": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz",
"integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==",
"dev": true,
"peerDependencies": {
"postcss": "^8.3.9"
}
},
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@ -9385,203 +9341,6 @@
"url": "https://opencollective.com/stylelint"
}
},
"node_modules/stylelint-config-html": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/stylelint-config-html/-/stylelint-config-html-1.1.0.tgz",
"integrity": "sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==",
"dev": true,
"engines": {
"node": "^12 || >=14"
},
"funding": {
"url": "https://github.com/sponsors/ota-meshi"
},
"peerDependencies": {
"postcss-html": "^1.0.0",
"stylelint": ">=14.0.0"
}
},
"node_modules/stylelint-config-prettier": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.5.tgz",
"integrity": "sha512-U44lELgLZhbAD/xy/vncZ2Pq8sh2TnpiPvo38Ifg9+zeioR+LAkHu0i6YORIOxFafZoVg0xqQwex6e6F25S5XA==",
"dev": true,
"bin": {
"stylelint-config-prettier": "bin/check.js",
"stylelint-config-prettier-check": "bin/check.js"
},
"engines": {
"node": ">= 12"
},
"peerDependencies": {
"stylelint": ">= 11.x < 15"
}
},
"node_modules/stylelint-config-recess-order": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-3.1.0.tgz",
"integrity": "sha512-LXR6zD5O9cS1a9gbLbuKvWLs7qmHj4xm5MQ5KhhwZPMhtQP9da3F6Jsp/NAUdsAwDQEnT1ShU16YVdgN6p4a/w==",
"dev": true,
"dependencies": {
"stylelint-order": "5.x"
},
"peerDependencies": {
"stylelint": ">=14"
}
},
"node_modules/stylelint-config-recess-order/node_modules/stylelint-order": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz",
"integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==",
"dev": true,
"dependencies": {
"postcss": "^8.3.11",
"postcss-sorting": "^7.0.1"
},
"peerDependencies": {
"stylelint": "^14.0.0"
}
},
"node_modules/stylelint-config-recommended": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz",
"integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==",
"dev": true,
"engines": {
"node": "^14.13.1 || >=16.0.0"
},
"peerDependencies": {
"stylelint": "^15.10.0"
}
},
"node_modules/stylelint-config-recommended-scss": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-6.0.0.tgz",
"integrity": "sha512-6QOe2/OzXV2AP5FE12A7+qtKdZik7Saf42SMMl84ksVBBPpTdrV+9HaCbPYiRMiwELY9hXCVdH4wlJ+YJb5eig==",
"dev": true,
"dependencies": {
"postcss-scss": "^4.0.2",
"stylelint-config-recommended": "^7.0.0",
"stylelint-scss": "^4.0.0"
},
"peerDependencies": {
"stylelint": "^14.4.0"
}
},
"node_modules/stylelint-config-recommended-scss/node_modules/stylelint-config-recommended": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz",
"integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==",
"dev": true,
"peerDependencies": {
"stylelint": "^14.4.0"
}
},
"node_modules/stylelint-config-recommended-vue": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended-vue/-/stylelint-config-recommended-vue-1.4.0.tgz",
"integrity": "sha512-DVJqyX2KvMCn9U0+keL12r7xlsH26K4Vg8NrIZuq5MoF7g82DpMp326Om4E0Q+Il1o+bTHuUyejf2XAI0iD04Q==",
"dev": true,
"dependencies": {
"semver": "^7.3.5",
"stylelint-config-html": ">=1.0.0",
"stylelint-config-recommended": ">=6.0.0"
},
"engines": {
"node": "^12 || >=14"
},
"funding": {
"url": "https://github.com/sponsors/ota-meshi"
},
"peerDependencies": {
"postcss-html": "^1.0.0",
"stylelint": ">=14.0.0"
}
},
"node_modules/stylelint-config-standard": {
"version": "25.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz",
"integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==",
"dev": true,
"dependencies": {
"stylelint-config-recommended": "^7.0.0"
},
"peerDependencies": {
"stylelint": "^14.4.0"
}
},
"node_modules/stylelint-config-standard-scss": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-3.0.0.tgz",
"integrity": "sha512-zt3ZbzIbllN1iCmc94e4pDxqpkzeR6CJo5DDXzltshuXr+82B8ylHyMMARNnUYrZH80B7wgY7UkKTYCFM0UUyw==",
"dev": true,
"dependencies": {
"stylelint-config-recommended-scss": "^5.0.2",
"stylelint-config-standard": "^24.0.0"
},
"peerDependencies": {
"stylelint": "^14.0.0"
}
},
"node_modules/stylelint-config-standard-scss/node_modules/stylelint-config-recommended": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz",
"integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==",
"dev": true,
"peerDependencies": {
"stylelint": "^14.0.0"
}
},
"node_modules/stylelint-config-standard-scss/node_modules/stylelint-config-recommended-scss": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-5.0.2.tgz",
"integrity": "sha512-b14BSZjcwW0hqbzm9b0S/ScN2+3CO3O4vcMNOw2KGf8lfVSwJ4p5TbNEXKwKl1+0FMtgRXZj6DqVUe/7nGnuBg==",
"dev": true,
"dependencies": {
"postcss-scss": "^4.0.2",
"stylelint-config-recommended": "^6.0.0",
"stylelint-scss": "^4.0.0"
},
"peerDependencies": {
"stylelint": "^14.0.0"
}
},
"node_modules/stylelint-config-standard-scss/node_modules/stylelint-config-standard": {
"version": "24.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-24.0.0.tgz",
"integrity": "sha512-+RtU7fbNT+VlNbdXJvnjc3USNPZRiRVp/d2DxOF/vBDDTi0kH5RX2Ny6errdtZJH3boO+bmqIYEllEmok4jiuw==",
"dev": true,
"dependencies": {
"stylelint-config-recommended": "^6.0.0"
},
"peerDependencies": {
"stylelint": "^14.0.0"
}
},
"node_modules/stylelint-config-standard/node_modules/stylelint-config-recommended": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz",
"integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==",
"dev": true,
"peerDependencies": {
"stylelint": "^14.4.0"
}
},
"node_modules/stylelint-scss": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.7.0.tgz",
"integrity": "sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==",
"dev": true,
"dependencies": {
"postcss-media-query-parser": "^0.2.3",
"postcss-resolve-nested-selector": "^0.1.1",
"postcss-selector-parser": "^6.0.11",
"postcss-value-parser": "^4.2.0"
},
"peerDependencies": {
"stylelint": "^14.5.1 || ^15.0.0"
}
},
"node_modules/stylelint/node_modules/balanced-match": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz",

View File

@ -77,13 +77,6 @@
"sass": "^1.49.7",
"standard-version": "^9.5.0",
"stylelint": "^15.10.1",
"stylelint-config-html": "^1.0.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recess-order": "^3.0.0",
"stylelint-config-recommended-scss": "^6.0.0",
"stylelint-config-recommended-vue": "^1.4.0",
"stylelint-config-standard": "^25.0.0",
"stylelint-config-standard-scss": "^3.0.0",
"tailwindcss": "^3.3.2",
"typescript": "^4.5.4",
"unplugin-auto-import": "^0.16.4",

View File

@ -161,7 +161,7 @@ const checkVolumeName = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.volumeName')));
} else {
const reg = /^[a-zA-Z0-9]{1}[a-z:A-Z0-9_.-]{1,30}$/;
const reg = /^[a-zA-Z0-9]{1}[a-zA-Z0-9_.-]{1,30}$/;
if (!reg.test(value) && value !== '') {
callback(new Error(i18n.global.t('commons.rule.volumeName')));
} else {
@ -236,6 +236,19 @@ const checkIntegerNumber = (rule: any, value: any, callback: any) => {
}
};
const checkFloatNumber = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.integer')));
} else {
const reg = /^\d+(\.\d+)?$/;
if (!reg.test(value) && value !== '') {
callback(new Error(i18n.global.t('commons.rule.number')));
} else {
callback();
}
}
};
const checkParamCommon = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.paramName')));
@ -313,6 +326,26 @@ export function checkNumberRange(min: number, max: number): FormItemRule {
};
}
export function checkFloatNumberRange(min: number, max: number): FormItemRule {
let validatorFunc = function (rule: any, value: any, callback: any) {
if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.disableFunction')));
} else {
if ((Number(value) < min || Number(value) > max) && value !== '') {
callback(new Error(i18n.global.t('commons.rule.disableFunction')));
} else {
callback();
}
}
};
return {
required: false,
trigger: 'blur',
validator: validatorFunc,
message: i18n.global.t('commons.rule.numberRange', [min, max]),
};
}
const checkContainerName = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) {
callback();
@ -380,6 +413,7 @@ interface CommonRule {
email: FormItemRule;
number: FormItemRule;
integerNumber: FormItemRule;
floatNumber: FormItemRule;
ip: FormItemRule;
ipV4V6: FormItemRule;
host: FormItemRule;
@ -481,6 +515,13 @@ export const Rules: CommonRule = {
validator: checkIntegerNumber,
trigger: 'blur',
},
floatNumber: {
required: true,
validator: checkFloatNumber,
trigger: 'blur',
min: 0,
message: i18n.global.t('commons.rule.number'),
},
ip: {
validator: checkIp,
required: true,

View File

@ -107,9 +107,9 @@
<el-form-item
:label="$t('container.cpuQuota')"
prop="nanoCPUs"
:rules="checkNumberRange(0, limits.cpu)"
:rules="checkFloatNumberRange(0, Number(limits.cpu))"
>
<el-input class="mini-form-item" v-model.number="dialogData.rowData!.nanoCPUs">
<el-input class="mini-form-item" v-model="dialogData.rowData!.nanoCPUs">
<template #append>
<div style="width: 35px">{{ $t('commons.units.core') }}</div>
</template>
@ -118,12 +118,8 @@
{{ $t('container.limitHelper', [limits.cpu]) }}{{ $t('commons.units.core') }}
</span>
</el-form-item>
<el-form-item
:label="$t('container.memoryLimit')"
prop="memoryItem"
:rules="checkNumberRange(0, limits.memory)"
>
<el-input class="mini-form-item" v-model.number="dialogData.rowData!.memoryItem">
<el-form-item :label="$t('container.memoryLimit')" prop="memory">
<el-input class="mini-form-item" v-model="dialogData.rowData!.memory">
<template #append><div style="width: 35px">MB</div></template>
</el-input>
<span class="input-help">{{ $t('container.limitHelper', [limits.memory]) }}MB</span>
@ -228,7 +224,7 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { Rules, checkNumberRange } from '@/global/form-rules';
import { Rules, checkFloatNumberRange, checkNumberRange } from '@/global/form-rules';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
@ -261,7 +257,7 @@ const acceptParams = (params: DialogProps): void => {
dialogData.value = params;
title.value = i18n.global.t('container.' + dialogData.value.title);
if (params.title === 'edit') {
dialogData.value.rowData.memoryItem = Number((dialogData.value.rowData.memory / 1024 / 1024).toFixed(2));
dialogData.value.rowData.memory = Number(dialogData.value.rowData.memory.toFixed(2));
let itemCmd = '';
for (const item of dialogData.value.rowData.cmd) {
itemCmd += `'${item}' `;
@ -298,12 +294,12 @@ const handleClose = () => {
};
const rules = reactive({
network: [Rules.requiredSelect],
cpuShares: [Rules.number, checkNumberRange(0, 262144)],
name: [Rules.requiredInput, Rules.name],
name: [Rules.requiredInput, Rules.volumeName],
image: [Rules.requiredSelect],
nanoCPUs: [Rules.number],
memoryItem: [Rules.number],
network: [Rules.requiredSelect],
cpuShares: [Rules.floatNumber, checkNumberRange(0, 262144)],
nanoCPUs: [Rules.floatNumber],
memory: [Rules.floatNumber],
});
type FormInstance = InstanceType<typeof ElForm>;
@ -383,7 +379,9 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
if (!checkPortValid()) {
return;
}
dialogData.value.rowData!.memory = dialogData.value.rowData!.memoryItem * 1024 * 1024;
dialogData.value.rowData!.memory = Number(dialogData.value.rowData!.memory);
dialogData.value.rowData!.cpuShares = Number(dialogData.value.rowData!.cpuShares);
dialogData.value.rowData!.nanoCPUs = Number(dialogData.value.rowData!.nanoCPUs);
loading.value = true;
if (dialogData.value.title === 'create') {