feat: 容器创建编辑增加拉取最新镜像选项 (#1597)

This commit is contained in:
ssongliu 2023-07-10 22:45:08 +08:00 committed by GitHub
parent 55ed67eaed
commit b9227caaf8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 47 additions and 15 deletions

View file

@ -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"`
@ -56,6 +57,7 @@ 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 {

View file

@ -317,10 +317,13 @@ 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 {
if !req.ForcePull {
return err 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)
if err != nil { if err != nil {
@ -410,10 +413,13 @@ 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 {
if !req.ForcePull {
return err return err
} }
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
}
} }
config := oldContainer.Config config := oldContainer.Config
hostConf := oldContainer.HostConfig hostConf := oldContainer.HostConfig
@ -448,10 +454,13 @@ 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 {
if !req.ForcePull {
return err return err
} }
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
}
} }
config := oldContainer.Config config := oldContainer.Config
config.Image = req.Image config.Image = req.Image

View file

@ -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
} }

View file

@ -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()

View file

@ -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;

View file

@ -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 });

View file

@ -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',

View file

@ -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',

View file

@ -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',

View file

@ -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

View file

@ -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>

View file

@ -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');