mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 13:29:03 +08:00
feat: 容器创建编辑增加拉取最新镜像选项 (#1597)
This commit is contained in:
parent
55ed67eaed
commit
b9227caaf8
12 changed files with 47 additions and 15 deletions
|
|
@ -37,6 +37,7 @@ type ResourceLimit struct {
|
||||||
|
|
||||||
type ContainerOperate struct {
|
type ContainerOperate struct {
|
||||||
ContainerID string `json:"containerID"`
|
ContainerID string `json:"containerID"`
|
||||||
|
ForcePull bool `json:"forcePull"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Image string `json:"image"`
|
Image string `json:"image"`
|
||||||
Network string `json:"network"`
|
Network string `json:"network"`
|
||||||
|
|
@ -54,8 +55,9 @@ type ContainerOperate struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContainerUpgrade struct {
|
type ContainerUpgrade struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Image string `json:"image" validate:"required"`
|
Image string `json:"image" validate:"required"`
|
||||||
|
ForcePull bool `json:"forcePull"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContainerListStats struct {
|
type ContainerListStats struct {
|
||||||
|
|
|
||||||
|
|
@ -317,9 +317,12 @@ func (u *ContainerService) ContainerCreate(req dto.ContainerOperate) error {
|
||||||
|
|
||||||
global.LOG.Infof("new container info %s has been made, now start to create", req.Name)
|
global.LOG.Infof("new container info %s has been made, now start to create", req.Name)
|
||||||
|
|
||||||
if !checkImageExist(client, req.Image) {
|
if !checkImageExist(client, req.Image) || req.ForcePull {
|
||||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||||
return err
|
if !req.ForcePull {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
container, err := client.ContainerCreate(ctx, &config, &hostConf, &networkConf, &v1.Platform{}, req.Name)
|
container, err := client.ContainerCreate(ctx, &config, &hostConf, &networkConf, &v1.Platform{}, req.Name)
|
||||||
|
|
@ -410,9 +413,12 @@ func (u *ContainerService) ContainerUpdate(req dto.ContainerOperate) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !checkImageExist(client, req.Image) {
|
if !checkImageExist(client, req.Image) || req.ForcePull {
|
||||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||||
return err
|
if !req.ForcePull {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config := oldContainer.Config
|
config := oldContainer.Config
|
||||||
|
|
@ -448,9 +454,12 @@ func (u *ContainerService) ContainerUpgrade(req dto.ContainerUpgrade) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !checkImageExist(client, req.Image) {
|
if !checkImageExist(client, req.Image) || req.ForcePull {
|
||||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||||
return err
|
if !req.ForcePull {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config := oldContainer.Config
|
config := oldContainer.Config
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,9 @@ func (u *ContainerService) ListNetwork() ([]dto.Options, error) {
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
datas = append(datas, dto.Options{Option: item.Name})
|
datas = append(datas, dto.Options{Option: item.Name})
|
||||||
}
|
}
|
||||||
|
sort.Slice(datas, func(i, j int) bool {
|
||||||
|
return datas[i].Option < datas[j].Option
|
||||||
|
})
|
||||||
return datas, nil
|
return datas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,13 +80,16 @@ func (u *ContainerService) ListVolume() ([]dto.Options, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var data []dto.Options
|
var datas []dto.Options
|
||||||
for _, item := range list.Volumes {
|
for _, item := range list.Volumes {
|
||||||
data = append(data, dto.Options{
|
datas = append(datas, dto.Options{
|
||||||
Option: item.Name,
|
Option: item.Name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return data, nil
|
sort.Slice(datas, func(i, j int) bool {
|
||||||
|
return datas[i].Option < datas[j].Option
|
||||||
|
})
|
||||||
|
return datas, nil
|
||||||
}
|
}
|
||||||
func (u *ContainerService) DeleteVolume(req dto.BatchDelete) error {
|
func (u *ContainerService) DeleteVolume(req dto.BatchDelete) error {
|
||||||
client, err := docker.NewDockerClient()
|
client, err := docker.NewDockerClient()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ export namespace Container {
|
||||||
containerID: string;
|
containerID: string;
|
||||||
name: string;
|
name: string;
|
||||||
image: string;
|
image: string;
|
||||||
|
forcePull: boolean;
|
||||||
network: string;
|
network: string;
|
||||||
cmdStr: string;
|
cmdStr: string;
|
||||||
memoryItem: number;
|
memoryItem: number;
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ export const createContainer = (params: Container.ContainerHelper) => {
|
||||||
export const updateContainer = (params: Container.ContainerHelper) => {
|
export const updateContainer = (params: Container.ContainerHelper) => {
|
||||||
return http.post(`/containers/update`, params, 3000000);
|
return http.post(`/containers/update`, params, 3000000);
|
||||||
};
|
};
|
||||||
export const upgradeContainer = (name: string, image: string) => {
|
export const upgradeContainer = (name: string, image: string, forcePull: boolean) => {
|
||||||
return http.post(`/containers/upgrade`, { name: name, image: image }, 3000000);
|
return http.post(`/containers/upgrade`, { name: name, image: image, forcePull: forcePull }, 3000000);
|
||||||
};
|
};
|
||||||
export const loadContainerInfo = (name: string) => {
|
export const loadContainerInfo = (name: string) => {
|
||||||
return http.post<Container.ContainerHelper>(`/containers/info`, { name: name });
|
return http.post<Container.ContainerHelper>(`/containers/info`, { name: name });
|
||||||
|
|
|
||||||
|
|
@ -504,6 +504,7 @@ const message = {
|
||||||
appHelper:
|
appHelper:
|
||||||
'This container is sourced from the application store. Upgrading it may cause the service to be unavailable. Do you want to continue?',
|
'This container is sourced from the application store. Upgrading it may cause the service to be unavailable. Do you want to continue?',
|
||||||
|
|
||||||
|
forcePull: 'Pull the latest image',
|
||||||
server: 'Host',
|
server: 'Host',
|
||||||
serverExample: 'e.g. 80, 80-88, ip:80 or ip:80-88',
|
serverExample: 'e.g. 80, 80-88, ip:80 or ip:80-88',
|
||||||
containerExample: 'e.g. 80 or 80-88',
|
containerExample: 'e.g. 80 or 80-88',
|
||||||
|
|
|
||||||
|
|
@ -493,6 +493,7 @@ const message = {
|
||||||
targetImageHelper: '請輸入目標鏡像版本',
|
targetImageHelper: '請輸入目標鏡像版本',
|
||||||
appHelper: '該容器來源於應用商店,升級可能導致該服務不可用,是否繼續?',
|
appHelper: '該容器來源於應用商店,升級可能導致該服務不可用,是否繼續?',
|
||||||
|
|
||||||
|
forcePull: '拉取最新鏡像',
|
||||||
server: '服務器',
|
server: '服務器',
|
||||||
serverExample: '例: 80, 80-88, ip:80 或者 ip:80-88',
|
serverExample: '例: 80, 80-88, ip:80 或者 ip:80-88',
|
||||||
containerExample: '例: 80 或者 80-88',
|
containerExample: '例: 80 或者 80-88',
|
||||||
|
|
|
||||||
|
|
@ -493,6 +493,7 @@ const message = {
|
||||||
targetImageHelper: '请输入目标镜像版本',
|
targetImageHelper: '请输入目标镜像版本',
|
||||||
appHelper: '该容器来源于应用商店,升级可能导致该服务不可用,是否继续?',
|
appHelper: '该容器来源于应用商店,升级可能导致该服务不可用,是否继续?',
|
||||||
|
|
||||||
|
forcePull: '拉取最新镜像',
|
||||||
server: '服务器',
|
server: '服务器',
|
||||||
serverExample: '例: 80, 80-88, ip:80 或者 ip:80-88',
|
serverExample: '例: 80, 80-88, ip:80 或者 ip:80-88',
|
||||||
containerExample: '例: 80 或者 80-88',
|
containerExample: '例: 80 或者 80-88',
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@
|
||||||
/>
|
/>
|
||||||
<fu-table-operations
|
<fu-table-operations
|
||||||
width="300px"
|
width="300px"
|
||||||
:ellipsis="3"
|
:ellipsis="4"
|
||||||
:buttons="buttons"
|
:buttons="buttons"
|
||||||
:label="$t('commons.table.operate')"
|
:label="$t('commons.table.operate')"
|
||||||
fix
|
fix
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,11 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item prop="forcePull">
|
||||||
|
<el-checkbox v-model="dialogData.rowData!.forcePull">
|
||||||
|
{{ $t('container.forcePull') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item :label="$t('commons.table.port')">
|
<el-form-item :label="$t('commons.table.port')">
|
||||||
<el-radio-group v-model="dialogData.rowData!.publishAllPorts" class="ml-4">
|
<el-radio-group v-model="dialogData.rowData!.publishAllPorts" class="ml-4">
|
||||||
<el-radio :label="false">{{ $t('container.exposePort') }}</el-radio>
|
<el-radio :label="false">{{ $t('container.exposePort') }}</el-radio>
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,11 @@
|
||||||
<el-input v-model="form.newTag" :placeholder="$t('container.targetImageHelper')" />
|
<el-input v-model="form.newTag" :placeholder="$t('container.targetImageHelper')" />
|
||||||
<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="forcePull">
|
||||||
|
<el-checkbox v-model="form.forcePull">
|
||||||
|
{{ $t('container.forcePull') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
@ -71,6 +76,7 @@ const form = reactive({
|
||||||
oldTag: '',
|
oldTag: '',
|
||||||
newTag: '',
|
newTag: '',
|
||||||
fromApp: false,
|
fromApp: false,
|
||||||
|
forcePull: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
|
|
@ -106,7 +112,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)
|
await upgradeContainer(form.name, form.imageName + ':' + form.newTag, form.forcePull)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
emit('search');
|
emit('search');
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue