mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-10 09:02:42 +08:00
fix: 删除容器后 compose 记录保存以便后续处理 (#6447)
Refs https://github.com/1Panel-dev/1Panel/issues/5099
This commit is contained in:
parent
1dfbca3d5b
commit
535d4bbe1b
8 changed files with 71 additions and 11 deletions
|
@ -116,7 +116,7 @@ type PortHelper struct {
|
||||||
|
|
||||||
type ContainerOperation struct {
|
type ContainerOperation struct {
|
||||||
Names []string `json:"names" validate:"required"`
|
Names []string `json:"names" validate:"required"`
|
||||||
Operation string `json:"operation" validate:"required,oneof=start stop restart kill pause unpause remove"`
|
Operation string `json:"operation" validate:"required,oneof=up start stop restart kill pause unpause remove"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContainerRename struct {
|
type ContainerRename struct {
|
||||||
|
@ -217,7 +217,7 @@ type ComposeCreate struct {
|
||||||
type ComposeOperation struct {
|
type ComposeOperation struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
Operation string `json:"operation" validate:"required,oneof=start stop down"`
|
Operation string `json:"operation" validate:"required,oneof=up start stop down"`
|
||||||
WithFile bool `json:"withFile"`
|
WithFile bool `json:"withFile"`
|
||||||
}
|
}
|
||||||
type ComposeUpdate struct {
|
type ComposeUpdate struct {
|
||||||
|
|
|
@ -12,4 +12,5 @@ type Compose struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
Name string `gorm:"type:varchar(256)" json:"name"`
|
Name string `gorm:"type:varchar(256)" json:"name"`
|
||||||
|
Path string `gorm:"type:varchar(256)" json:"path"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ type IComposeTemplateRepo interface {
|
||||||
CreateRecord(compose *model.Compose) error
|
CreateRecord(compose *model.Compose) error
|
||||||
DeleteRecord(opts ...DBOption) error
|
DeleteRecord(opts ...DBOption) error
|
||||||
ListRecord() ([]model.Compose, error)
|
ListRecord() ([]model.Compose, error)
|
||||||
|
UpdateRecord(name string, vars map[string]interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIComposeTemplateRepo() IComposeTemplateRepo {
|
func NewIComposeTemplateRepo() IComposeTemplateRepo {
|
||||||
|
@ -102,3 +103,7 @@ func (u *ComposeTemplateRepo) DeleteRecord(opts ...DBOption) error {
|
||||||
}
|
}
|
||||||
return db.Delete(&model.Compose{}).Error
|
return db.Delete(&model.Compose{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ComposeTemplateRepo) UpdateRecord(name string, vars map[string]interface{}) error {
|
||||||
|
return global.DB.Model(&model.Compose{}).Where("name = ?", name).Updates(vars).Error
|
||||||
|
}
|
||||||
|
|
|
@ -898,6 +898,10 @@ func (u *ContainerService) LoadContainerLogs(req dto.OperationWithNameAndType) s
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(containers) == 0 {
|
||||||
|
composeItem, _ := composeRepo.GetRecord(commonRepo.WithByName(req.Name))
|
||||||
|
filePath = composeItem.Path
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(filePath); err != nil {
|
if _, err := os.Stat(filePath); err != nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -52,6 +52,20 @@ func (u *ContainerService) PageCompose(req dto.SearchWithPage) (int64, interface
|
||||||
}
|
}
|
||||||
|
|
||||||
composeCreatedByLocal, _ := composeRepo.ListRecord()
|
composeCreatedByLocal, _ := composeRepo.ListRecord()
|
||||||
|
|
||||||
|
composeLocalMap := make(map[string]dto.ComposeInfo)
|
||||||
|
for _, localItem := range composeCreatedByLocal {
|
||||||
|
composeItemLocal := dto.ComposeInfo{
|
||||||
|
ContainerNumber: 0,
|
||||||
|
CreatedAt: localItem.CreatedAt.Format(constant.DateTimeLayout),
|
||||||
|
ConfigFile: localItem.Path,
|
||||||
|
Workdir: strings.TrimSuffix(localItem.Path, "/docker-compose.yml"),
|
||||||
|
}
|
||||||
|
composeItemLocal.CreatedBy = "1Panel"
|
||||||
|
composeItemLocal.Path = localItem.Path
|
||||||
|
composeLocalMap[localItem.Name] = composeItemLocal
|
||||||
|
}
|
||||||
|
|
||||||
composeMap := make(map[string]dto.ComposeInfo)
|
composeMap := make(map[string]dto.ComposeInfo)
|
||||||
for _, container := range list {
|
for _, container := range list {
|
||||||
if name, ok := container.Labels[composeProjectLabel]; ok {
|
if name, ok := container.Labels[composeProjectLabel]; ok {
|
||||||
|
@ -95,12 +109,24 @@ func (u *ContainerService) PageCompose(req dto.SearchWithPage) (int64, interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, item := range composeCreatedByLocal {
|
|
||||||
if err := composeRepo.DeleteRecord(commonRepo.WithByID(item.ID)); err != nil {
|
mergedMap := make(map[string]dto.ComposeInfo)
|
||||||
global.LOG.Error(err)
|
for key, localItem := range composeLocalMap {
|
||||||
|
mergedMap[key] = localItem
|
||||||
|
}
|
||||||
|
for key, item := range composeMap {
|
||||||
|
if existingItem, exists := mergedMap[key]; exists {
|
||||||
|
if item.ContainerNumber > 0 {
|
||||||
|
if existingItem.ContainerNumber <= 0 {
|
||||||
|
mergedMap[key] = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mergedMap[key] = item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for key, value := range composeMap {
|
|
||||||
|
for key, value := range mergedMap {
|
||||||
value.Name = key
|
value.Name = key
|
||||||
records = append(records, value)
|
records = append(records, value)
|
||||||
}
|
}
|
||||||
|
@ -186,7 +212,7 @@ func (u *ContainerService) CreateCompose(req dto.ComposeCreate) (string, error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Infof("docker-compose up %s successful!", req.Name)
|
global.LOG.Infof("docker-compose up %s successful!", req.Name)
|
||||||
_ = composeRepo.CreateRecord(&model.Compose{Name: req.Name})
|
_ = composeRepo.CreateRecord(&model.Compose{Name: req.Name, Path: req.Path})
|
||||||
_, _ = file.WriteString("docker-compose up successful!")
|
_, _ = file.WriteString("docker-compose up successful!")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -200,14 +226,27 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
||||||
if _, err := os.Stat(req.Path); err != nil {
|
if _, err := os.Stat(req.Path); err != nil {
|
||||||
return fmt.Errorf("load file with path %s failed, %v", req.Path, err)
|
return fmt.Errorf("load file with path %s failed, %v", req.Path, err)
|
||||||
}
|
}
|
||||||
if stdout, err := compose.Operate(req.Path, req.Operation); err != nil {
|
if req.Operation == "up" {
|
||||||
return errors.New(string(stdout))
|
if stdout, err := compose.Up(req.Path); err != nil {
|
||||||
|
return errors.New(string(stdout))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if stdout, err := compose.Operate(req.Path, req.Operation); err != nil {
|
||||||
|
return errors.New(string(stdout))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
global.LOG.Infof("docker-compose %s %s successful", req.Operation, req.Name)
|
global.LOG.Infof("docker-compose %s %s successful", req.Operation, req.Name)
|
||||||
if req.Operation == "down" {
|
if req.Operation == "down" {
|
||||||
_ = composeRepo.DeleteRecord(commonRepo.WithByName(req.Name))
|
|
||||||
if req.WithFile {
|
if req.WithFile {
|
||||||
|
_ = composeRepo.DeleteRecord(commonRepo.WithByName(req.Name))
|
||||||
_ = os.RemoveAll(path.Dir(req.Path))
|
_ = os.RemoveAll(path.Dir(req.Path))
|
||||||
|
} else {
|
||||||
|
composeItem, _ := composeRepo.GetRecord(commonRepo.WithByName(req.Name))
|
||||||
|
if composeItem.Path == "" {
|
||||||
|
upMap := make(map[string]interface{})
|
||||||
|
upMap["path"] = req.Path
|
||||||
|
_ = composeRepo.UpdateRecord(req.Name, upMap)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ func Init() {
|
||||||
migrations.AddClam,
|
migrations.AddClam,
|
||||||
migrations.AddClamStatus,
|
migrations.AddClamStatus,
|
||||||
migrations.AddAlertMenu,
|
migrations.AddAlertMenu,
|
||||||
|
migrations.AddComposeColumn,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
|
|
@ -314,3 +314,13 @@ var AddAlertMenu = &gormigrate.Migration{
|
||||||
return tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").Updates(map[string]interface{}{"value": string(data)}).Error
|
return tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").Updates(map[string]interface{}{"value": string(data)}).Error
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AddComposeColumn = &gormigrate.Migration{
|
||||||
|
ID: "20240906-add-compose-command",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
if err := tx.AutoMigrate(&model.Compose{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<el-tag effect="dark" type="success">{{ composeName }}</el-tag>
|
<el-tag effect="dark" type="success">{{ composeName }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="createdBy === '1Panel'" style="margin-left: 50px">
|
<div v-if="createdBy === '1Panel'" style="margin-left: 50px">
|
||||||
<el-button link type="primary" @click="onComposeOperate('start')">
|
<el-button link type="primary" @click="onComposeOperate('up')">
|
||||||
{{ $t('container.start') }}
|
{{ $t('container.start') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-divider direction="vertical" />
|
<el-divider direction="vertical" />
|
||||||
|
|
Loading…
Reference in a new issue