mirror of
				https://github.com/1Panel-dev/1Panel.git
				synced 2025-10-31 19:26:02 +08:00 
			
		
		
		
	fix: 解决容器端口冲突导致创建失败的问题 (#1770)
This commit is contained in:
		
							parent
							
								
									2a20ff0b79
								
							
						
					
					
						commit
						87a7cf3aca
					
				
					 4 changed files with 46 additions and 12 deletions
				
			
		|  | @ -432,13 +432,15 @@ func (u *ContainerService) ContainerUpdate(req dto.ContainerOperate) error { | |||
| 	hostConf := oldContainer.HostConfig | ||||
| 	var networkConf network.NetworkingConfig | ||||
| 	if err := loadConfigInfo(req, config, hostConf, &networkConf); err != nil { | ||||
| 		reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings) | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	global.LOG.Infof("new container info %s has been update, now start to recreate", req.Name) | ||||
| 	container, err := client.ContainerCreate(ctx, config, hostConf, &networkConf, &v1.Platform{}, req.Name) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("recreate contianer failed, err: %v", err) | ||||
| 		reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings) | ||||
| 		return fmt.Errorf("update contianer failed, err: %v", err) | ||||
| 	} | ||||
| 	global.LOG.Infof("update container %s successful! now check if the container is started.", req.Name) | ||||
| 	if err := client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}); err != nil { | ||||
|  | @ -481,13 +483,14 @@ func (u *ContainerService) ContainerUpgrade(req dto.ContainerUpgrade) error { | |||
| 	} | ||||
| 
 | ||||
| 	global.LOG.Infof("new container info %s has been update, now start to recreate", req.Name) | ||||
| 	container, err := client.ContainerCreate(ctx, config, hostConf, &network.NetworkingConfig{}, &v1.Platform{}, req.Name) | ||||
| 	container, err := client.ContainerCreate(ctx, config, hostConf, &networkConf, &v1.Platform{}, req.Name) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("recreate contianer failed, err: %v", err) | ||||
| 		reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings) | ||||
| 		return fmt.Errorf("upgrade contianer failed, err: %v", err) | ||||
| 	} | ||||
| 	global.LOG.Infof("update container %s successful! now check if the container is started.", req.Name) | ||||
| 	global.LOG.Infof("upgrade container %s successful! now check if the container is started.", req.Name) | ||||
| 	if err := client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}); err != nil { | ||||
| 		return fmt.Errorf("update successful but start failed, err: %v", err) | ||||
| 		return fmt.Errorf("upgrade successful but start failed, err: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
|  | @ -795,7 +798,11 @@ func loadConfigInfo(req dto.ContainerOperate, config *container.Config, hostConf | |||
| 	config.Labels = stringsToMap(req.Labels) | ||||
| 	config.ExposedPorts = exposeds | ||||
| 
 | ||||
| 	networkConf.EndpointsConfig = map[string]*network.EndpointSettings{req.Network: {}} | ||||
| 	if len(req.Network) != 0 { | ||||
| 		networkConf.EndpointsConfig = map[string]*network.EndpointSettings{req.Network: {}} | ||||
| 	} else { | ||||
| 		networkConf = &network.NetworkingConfig{} | ||||
| 	} | ||||
| 
 | ||||
| 	hostConf.AutoRemove = req.AutoRemove | ||||
| 	hostConf.CPUShares = req.CPUShares | ||||
|  | @ -815,3 +822,24 @@ func loadConfigInfo(req dto.ContainerOperate, config *container.Config, hostConf | |||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func reCreateAfterUpdate(name string, client *client.Client, config *container.Config, hostConf *container.HostConfig, networkConf *types.NetworkSettings) { | ||||
| 	ctx := context.Background() | ||||
| 
 | ||||
| 	var oldNetworkConf network.NetworkingConfig | ||||
| 	if networkConf != nil { | ||||
| 		for networkKey := range networkConf.Networks { | ||||
| 			oldNetworkConf.EndpointsConfig = map[string]*network.EndpointSettings{networkKey: {}} | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	oldContainer, err := client.ContainerCreate(ctx, config, hostConf, &oldNetworkConf, &v1.Platform{}, name) | ||||
| 	if err != nil { | ||||
| 		global.LOG.Errorf("recreate after container update failed, err: %v", err) | ||||
| 		return | ||||
| 	} | ||||
| 	if err := client.ContainerStart(ctx, oldContainer.ID, types.ContainerStartOptions{}); err != nil { | ||||
| 		global.LOG.Errorf("restart after container update failed, err: %v", err) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -297,6 +297,7 @@ const onOpenDialog = async ( | |||
|     rowData: Partial<Container.ContainerHelper> = { | ||||
|         cmd: [], | ||||
|         cmdStr: '', | ||||
|         publishAllPorts: false, | ||||
|         exposedPorts: [], | ||||
|         cpuShares: 1024, | ||||
|         nanoCPUs: 0, | ||||
|  |  | |||
|  | @ -17,7 +17,13 @@ | |||
|                         <el-input clearable v-model.trim="dialogData.rowData!.name" /> | ||||
|                     </el-form-item> | ||||
|                     <el-form-item :label="$t('container.image')" prop="image"> | ||||
|                         <el-select class="widthClass" allow-create filterable v-model="dialogData.rowData!.image"> | ||||
|                         <el-select | ||||
|                             class="widthClass" | ||||
|                             :placeholder="$t('commons.msg.inputOrSelect')" | ||||
|                             allow-create | ||||
|                             filterable | ||||
|                             v-model="dialogData.rowData!.image" | ||||
|                         > | ||||
|                             <el-option | ||||
|                                 v-for="(item, index) of images" | ||||
|                                 :key="index" | ||||
|  | @ -159,7 +165,7 @@ | |||
|                                                 v-for="(item, indexV) of volumes" | ||||
|                                                 :key="indexV" | ||||
|                                                 :value="item.option" | ||||
|                                                 :label="item.option" | ||||
|                                                 :label="item.option.substring(0, 12)" | ||||
|                                             /> | ||||
|                                         </el-select> | ||||
|                                     </td> | ||||
|  | @ -301,13 +307,13 @@ const limits = ref<Container.ResourceLimit>({ | |||
| }); | ||||
| 
 | ||||
| const handleClose = () => { | ||||
|     emit('search'); | ||||
|     drawerVisiable.value = false; | ||||
| }; | ||||
| 
 | ||||
| const rules = reactive({ | ||||
|     name: [Rules.requiredInput, Rules.volumeName], | ||||
|     image: [Rules.requiredSelect], | ||||
|     network: [Rules.requiredSelect], | ||||
|     cpuShares: [Rules.integerNumberWith0, checkNumberRange(0, 262144)], | ||||
|     nanoCPUs: [Rules.floatNumber], | ||||
|     memory: [Rules.floatNumber], | ||||
|  |  | |||
|  | @ -41,9 +41,9 @@ | |||
|             </template> | ||||
|             <template #main> | ||||
|                 <ComplexTable :pagination-config="paginationConfig" :data="data" @search="search"> | ||||
|                     <el-table-column label="ID" prop="id" min-width="60"> | ||||
|                     <el-table-column label="ID" prop="id" min-width="50"> | ||||
|                         <template #default="{ row }"> | ||||
|                             <Tooltip :islink="false" :text="row.id" /> | ||||
|                             <span>{{ row.id.replaceAll('sha256:', '').substring(0, 12) }}</span> | ||||
|                         </template> | ||||
|                     </el-table-column> | ||||
|                     <el-table-column :label="$t('container.tag')" prop="tags" min-width="160" fix> | ||||
|  | @ -82,7 +82,6 @@ | |||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import Tooltip from '@/components/tooltip/index.vue'; | ||||
| import TableSetting from '@/components/table-setting/index.vue'; | ||||
| import { reactive, onMounted, ref } from 'vue'; | ||||
| import { dateFormat } from '@/utils/util'; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue