mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 21:38:57 +08:00
parent
168b6b8667
commit
ed6735e610
9 changed files with 60 additions and 45 deletions
|
|
@ -407,6 +407,7 @@ func (u *ContainerService) ContainerInfo(req dto.OperationWithName) (*dto.Contai
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.AutoRemove = oldContainer.HostConfig.AutoRemove
|
data.AutoRemove = oldContainer.HostConfig.AutoRemove
|
||||||
|
data.Privileged = oldContainer.HostConfig.Privileged
|
||||||
data.PublishAllPorts = oldContainer.HostConfig.PublishAllPorts
|
data.PublishAllPorts = oldContainer.HostConfig.PublishAllPorts
|
||||||
data.RestartPolicy = oldContainer.HostConfig.RestartPolicy.Name
|
data.RestartPolicy = oldContainer.HostConfig.RestartPolicy.Name
|
||||||
if oldContainer.HostConfig.NanoCPUs != 0 {
|
if oldContainer.HostConfig.NanoCPUs != 0 {
|
||||||
|
|
@ -440,7 +441,7 @@ func (u *ContainerService) ContainerUpdate(req dto.ContainerOperate) error {
|
||||||
if !req.ForcePull {
|
if !req.ForcePull {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
return fmt.Errorf("pull image %s failed, err: %v", req.Image, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,7 +484,7 @@ func (u *ContainerService) ContainerUpgrade(req dto.ContainerUpgrade) error {
|
||||||
if !req.ForcePull {
|
if !req.ForcePull {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
return fmt.Errorf("pull image %s failed, err: %v", req.Image, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config := oldContainer.Config
|
config := oldContainer.Config
|
||||||
|
|
|
||||||
|
|
@ -485,31 +485,20 @@ func (u *FirewallService) updatePingStatus(enable string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
hasV4Line, hasV6Line := false, false
|
|
||||||
if _, err := os.Stat("/proc/sys/net/ipv6/icmp_echo_ignore_all"); err != nil {
|
|
||||||
hasV6Line = true
|
|
||||||
}
|
|
||||||
files := strings.Split(string(lineBytes), "\n")
|
files := strings.Split(string(lineBytes), "\n")
|
||||||
var newFiles []string
|
var newFiles []string
|
||||||
|
hasLine := false
|
||||||
for _, line := range files {
|
for _, line := range files {
|
||||||
if strings.HasPrefix(strings.ReplaceAll(line, " ", ""), "net/ipv4/icmp_echo_ignore_all") && !hasV4Line {
|
if strings.Contains(line, "net/ipv4/icmp_echo_ignore_all") || strings.HasPrefix(line, "net/ipv4/icmp_echo_ignore_all") {
|
||||||
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enable)
|
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enable)
|
||||||
hasV4Line = true
|
hasLine = true
|
||||||
continue
|
} else {
|
||||||
|
newFiles = append(newFiles, line)
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(strings.ReplaceAll(line, " ", ""), "net/ipv6/icmp_echo_ignore_all") && !hasV6Line {
|
|
||||||
newFiles = append(newFiles, "net/ipv6/icmp_echo_ignore_all="+enable)
|
|
||||||
hasV6Line = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
newFiles = append(newFiles, line)
|
|
||||||
}
|
}
|
||||||
if !hasV4Line {
|
if !hasLine {
|
||||||
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enable)
|
newFiles = append(newFiles, "net/ipv4/icmp_echo_ignore_all="+enable)
|
||||||
}
|
}
|
||||||
if !hasV6Line {
|
|
||||||
newFiles = append(newFiles, "net/ipv6/icmp_echo_ignore_all="+enable)
|
|
||||||
}
|
|
||||||
file, err := os.OpenFile(confPath, os.O_WRONLY|os.O_TRUNC, 0666)
|
file, err := os.OpenFile(confPath, os.O_WRONLY|os.O_TRUNC, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -526,6 +515,11 @@ func (u *FirewallService) updatePingStatus(enable string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("update ping status failed, err: %v", stdout)
|
return fmt.Errorf("update ping status failed, err: %v", stdout)
|
||||||
}
|
}
|
||||||
|
handle := "-A"
|
||||||
|
if enable == "1" {
|
||||||
|
handle = "-D"
|
||||||
|
}
|
||||||
|
_, _ = cmd.Execf("%s ip6tables %s INPUT -p icmpv6 --icmpv6-type echo-request -j DROP", cmd.SudoHandleCmd(), handle)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -597,7 +597,7 @@ const message = {
|
||||||
'The upgrade operation requires rebuilding the container, and any non-persistent data will be lost. Do you want to continue?',
|
'The upgrade operation requires rebuilding the container, and any non-persistent data will be lost. Do you want to continue?',
|
||||||
oldImage: 'Current image',
|
oldImage: 'Current image',
|
||||||
targetImage: 'Target image',
|
targetImage: 'Target image',
|
||||||
targetImageHelper: 'Please enter the target image version',
|
imageLoadErr: 'System did not detect the container image name, please manually enter the full image name:tag ',
|
||||||
appHelper:
|
appHelper:
|
||||||
'This container is sourced from the application store. Upgrading it may cause the service to be unavailable.',
|
'This container is sourced from the application store. Upgrading it may cause the service to be unavailable.',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -578,7 +578,7 @@ const message = {
|
||||||
upgradeWarning2: '升級操作需要重建容器,任何未持久化的數據將會丟失,是否繼續?',
|
upgradeWarning2: '升級操作需要重建容器,任何未持久化的數據將會丟失,是否繼續?',
|
||||||
oldImage: '當前鏡像',
|
oldImage: '當前鏡像',
|
||||||
targetImage: '目標鏡像',
|
targetImage: '目標鏡像',
|
||||||
targetImageHelper: '請輸入目標鏡像版本',
|
imageLoadErr: '系統未檢測到容器的鏡像名稱,請手動輸入完整的鏡像名稱:標籤',
|
||||||
appHelper: '該容器來源於應用商店,升級可能導致該服務不可用',
|
appHelper: '該容器來源於應用商店,升級可能導致該服務不可用',
|
||||||
|
|
||||||
input: '手動輸入',
|
input: '手動輸入',
|
||||||
|
|
|
||||||
|
|
@ -579,7 +579,7 @@ const message = {
|
||||||
upgradeWarning2: '升级操作需要重建容器,任何未持久化的数据将会丢失,是否继续?',
|
upgradeWarning2: '升级操作需要重建容器,任何未持久化的数据将会丢失,是否继续?',
|
||||||
oldImage: '当前镜像',
|
oldImage: '当前镜像',
|
||||||
targetImage: '目标镜像',
|
targetImage: '目标镜像',
|
||||||
targetImageHelper: '请输入目标镜像版本',
|
imageLoadErr: '系统未检测到容器的镜像名称,请手动输入完整的镜像名称:标签',
|
||||||
appHelper: '该容器来源于应用商店,升级可能导致该服务不可用',
|
appHelper: '该容器来源于应用商店,升级可能导致该服务不可用',
|
||||||
|
|
||||||
input: '手动输入',
|
input: '手动输入',
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ const acceptParams = (): void => {
|
||||||
form.path = '';
|
form.path = '';
|
||||||
form.file = '';
|
form.file = '';
|
||||||
form.template = null;
|
form.template = null;
|
||||||
|
onCreating.value = false;
|
||||||
loadTemplates();
|
loadTemplates();
|
||||||
loadPath();
|
loadPath();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,27 +15,33 @@
|
||||||
/>
|
/>
|
||||||
<el-form @submit.prevent ref="formRef" :model="form" label-position="top">
|
<el-form @submit.prevent ref="formRef" :model="form" label-position="top">
|
||||||
<el-form-item :label="$t('container.oldImage')" prop="oldImage">
|
<el-form-item :label="$t('container.oldImage')" prop="oldImage">
|
||||||
<el-tooltip placement="top-start" :content="form.imageName" v-if="form.imageName.length > 50">
|
<el-tooltip
|
||||||
<el-tag>{{ form.imageName.substring(0, 50) }}...:{{ form.oldTag }}</el-tag>
|
placement="top-start"
|
||||||
|
:content="form.oldImageName"
|
||||||
|
v-if="form.oldImageName.length > 50"
|
||||||
|
>
|
||||||
|
<el-tag>{{ form.oldImageName.substring(0, 50) }}...</el-tag>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tag v-else>{{ form.imageName }}:{{ form.oldTag }}</el-tag>
|
<el-tag v-else>{{ form.oldImageName }}</el-tag>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="newTag" :rules="Rules.imageName">
|
<el-form-item prop="newImageName" :rules="Rules.imageName">
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
placement="top-start"
|
placement="top-start"
|
||||||
:content="form.imageName"
|
:content="form.imageHelper"
|
||||||
v-if="form.imageName.length > 40"
|
v-if="form.imageHelper.length > 40"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
{{ $t('container.targetImage') + ' (' + form.imageName.substring(0, 40) + '...)' }}
|
{{
|
||||||
|
$t('container.targetImage') + ' (' + form.imageHelper.substring(0, 40) + '...)'
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
{{ $t('container.targetImage') + ' (' + form.imageName + ')' }}
|
{{ $t('container.targetImage') + ' (' + form.imageHelper + ')' }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<el-input v-model="form.newTag" :placeholder="$t('container.targetImageHelper')" />
|
<el-input v-model="form.newImageName" :placeholder="$t('container.imageNameHelper')" />
|
||||||
<span class="input-help">{{ $t('container.upgradeHelper') }}</span>
|
<span class="input-help">{{ $t('container.upgradeHelper') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="ignoreCompare">
|
<el-form-item prop="ignoreCompare">
|
||||||
|
|
@ -79,9 +85,9 @@ const loading = ref(false);
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
imageName: '',
|
oldImageName: '',
|
||||||
oldTag: '',
|
newImageName: '',
|
||||||
newTag: '',
|
imageHelper: '',
|
||||||
fromApp: false,
|
fromApp: false,
|
||||||
forcePull: false,
|
forcePull: false,
|
||||||
|
|
||||||
|
|
@ -100,11 +106,16 @@ interface DialogProps {
|
||||||
}
|
}
|
||||||
const acceptParams = (props: DialogProps): void => {
|
const acceptParams = (props: DialogProps): void => {
|
||||||
form.name = props.container;
|
form.name = props.container;
|
||||||
form.imageName = props.image.indexOf(':') !== -1 ? props.image.split(':')[0] : props.image;
|
form.oldImageName = props.image;
|
||||||
form.oldTag = props.image.indexOf(':') !== -1 ? props.image.split(':')[1] : 'latest';
|
|
||||||
form.newTag = form.oldTag;
|
|
||||||
form.fromApp = props.fromApp;
|
form.fromApp = props.fromApp;
|
||||||
form.ignoreCompare = false;
|
form.ignoreCompare = false;
|
||||||
|
|
||||||
|
if (props.image.indexOf('sha256:') !== -1) {
|
||||||
|
form.imageHelper = i18n.global.t('container.imageLoadErr');
|
||||||
|
drawerVisible.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
form.imageHelper = props.image.indexOf(':') !== -1 ? props.image.split(':')[0] : props.image;
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
};
|
};
|
||||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||||
|
|
@ -113,7 +124,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
formEl.validate(async (valid) => {
|
formEl.validate(async (valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (!form.ignoreCompare && !compareVersion(form.newTag, form.oldTag)) {
|
if (!form.ignoreCompare && !compareVersion(form.newImageName, form.oldImageName)) {
|
||||||
MsgWarning(i18n.global.t('container.upgradeWarning'));
|
MsgWarning(i18n.global.t('container.upgradeWarning'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +133,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||||
}).then(async () => {
|
}).then(async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await upgradeContainer(form.name, form.imageName + ':' + form.newTag, form.forcePull)
|
await upgradeContainer(form.name, form.newImageName, form.forcePull)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
emit('search');
|
emit('search');
|
||||||
|
|
@ -141,14 +152,22 @@ const handleClose = async () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
function compareVersion(vNew, vOld) {
|
function compareVersion(vNew, vOld) {
|
||||||
if (vNew === 'latest') {
|
let newImageName = vNew.indexOf(':') !== -1 ? vNew.split(':')[0] : vNew;
|
||||||
|
let oldImageName = vOld.indexOf(':') !== -1 ? vOld.split(':')[0] : vOld;
|
||||||
|
if (newImageName !== oldImageName) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let v1 = vNew
|
let newTag = vNew.indexOf(':') !== -1 ? vNew.split(':')[1] : 'latest';
|
||||||
|
|
||||||
|
if (newTag === 'latest') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let oldTag = vOld.indexOf(':') !== -1 ? vOld.split(':')[1] : 'latest';
|
||||||
|
let v1 = newTag
|
||||||
.replace('-', '.')
|
.replace('-', '.')
|
||||||
.replace(/[^\d.]/g, '')
|
.replace(/[^\d.]/g, '')
|
||||||
.split('.');
|
.split('.');
|
||||||
let v2 = vOld
|
let v2 = oldTag
|
||||||
.replace('-', '.')
|
.replace('-', '.')
|
||||||
.replace(/[^\d.]/g, '')
|
.replace(/[^\d.]/g, '')
|
||||||
.split('.');
|
.split('.');
|
||||||
|
|
|
||||||
|
|
@ -202,10 +202,10 @@ const handleClose = () => {
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
name: [Rules.requiredInput],
|
name: [Rules.requiredInput],
|
||||||
driver: [Rules.requiredSelect],
|
driver: [Rules.requiredSelect],
|
||||||
subnet: [{ validator: checkCidr, trigger: 'blur' }],
|
subnet: [{ validator: checkCidr, trigger: 'blur' }, Rules.requiredInput],
|
||||||
gateway: [{ validator: checkGateway, trigger: 'blur' }],
|
gateway: [{ validator: checkGateway, trigger: 'blur' }],
|
||||||
scope: [{ validator: checkCidr, trigger: 'blur' }],
|
scope: [{ validator: checkCidr, trigger: 'blur' }],
|
||||||
subnetV6: [{ validator: checkFixedCidrV6, trigger: 'blur' }],
|
subnetV6: [{ validator: checkFixedCidrV6, trigger: 'blur' }, Rules.requiredInput],
|
||||||
gatewayV6: [{ validator: checkGatewayV6, trigger: 'blur' }],
|
gatewayV6: [{ validator: checkGatewayV6, trigger: 'blur' }],
|
||||||
scopeV6: [{ validator: checkFixedCidrV6, trigger: 'blur' }],
|
scopeV6: [{ validator: checkFixedCidrV6, trigger: 'blur' }],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-drawer :close-on-click-modal="false" v-model="drawerVisible" size="30%">
|
<el-drawer :close-on-click-modal="false" :destroy-on-close="true" v-model="drawerVisible" size="30%">
|
||||||
<template #header>
|
<template #header>
|
||||||
<Header :header="$t('toolbox.fail2ban.' + form.operate + 'IP')" :back="handleClose"></Header>
|
<Header :header="$t('toolbox.fail2ban.' + form.operate + 'IP')" :back="handleClose"></Header>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue