diff --git a/backend/app/dto/container.go b/backend/app/dto/container.go index 90a351768..936db57bd 100644 --- a/backend/app/dto/container.go +++ b/backend/app/dto/container.go @@ -116,7 +116,7 @@ type PortHelper struct { type ContainerOperation struct { 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 { @@ -217,7 +217,7 @@ type ComposeCreate struct { type ComposeOperation struct { Name string `json:"name" 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"` } type ComposeUpdate struct { diff --git a/backend/app/model/compose_template.go b/backend/app/model/compose_template.go index 5d5192eb3..4db9b6286 100644 --- a/backend/app/model/compose_template.go +++ b/backend/app/model/compose_template.go @@ -12,4 +12,5 @@ type Compose struct { BaseModel Name string `gorm:"type:varchar(256)" json:"name"` + Path string `gorm:"type:varchar(256)" json:"path"` } diff --git a/backend/app/repo/compose_template.go b/backend/app/repo/compose_template.go index 4259e2fb5..b6f38c24b 100644 --- a/backend/app/repo/compose_template.go +++ b/backend/app/repo/compose_template.go @@ -19,6 +19,7 @@ type IComposeTemplateRepo interface { CreateRecord(compose *model.Compose) error DeleteRecord(opts ...DBOption) error ListRecord() ([]model.Compose, error) + UpdateRecord(name string, vars map[string]interface{}) error } func NewIComposeTemplateRepo() IComposeTemplateRepo { @@ -102,3 +103,7 @@ func (u *ComposeTemplateRepo) DeleteRecord(opts ...DBOption) 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 +} diff --git a/backend/app/service/container.go b/backend/app/service/container.go index bc97676a6..b7a3ab96b 100644 --- a/backend/app/service/container.go +++ b/backend/app/service/container.go @@ -898,6 +898,10 @@ func (u *ContainerService) LoadContainerLogs(req dto.OperationWithNameAndType) s break } } + if len(containers) == 0 { + composeItem, _ := composeRepo.GetRecord(commonRepo.WithByName(req.Name)) + filePath = composeItem.Path + } } if _, err := os.Stat(filePath); err != nil { return "" diff --git a/backend/app/service/container_compose.go b/backend/app/service/container_compose.go index 565abf292..b98734a9d 100644 --- a/backend/app/service/container_compose.go +++ b/backend/app/service/container_compose.go @@ -52,6 +52,20 @@ func (u *ContainerService) PageCompose(req dto.SearchWithPage) (int64, interface } 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) for _, container := range list { 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 { - global.LOG.Error(err) + + mergedMap := make(map[string]dto.ComposeInfo) + 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 records = append(records, value) } @@ -186,7 +212,7 @@ func (u *ContainerService) CreateCompose(req dto.ComposeCreate) (string, error) return } 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!") }() @@ -200,14 +226,27 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error { if _, err := os.Stat(req.Path); err != nil { return fmt.Errorf("load file with path %s failed, %v", req.Path, err) } - if stdout, err := compose.Operate(req.Path, req.Operation); err != nil { - return errors.New(string(stdout)) + if req.Operation == "up" { + 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) if req.Operation == "down" { - _ = composeRepo.DeleteRecord(commonRepo.WithByName(req.Name)) if req.WithFile { + _ = composeRepo.DeleteRecord(commonRepo.WithByName(req.Name)) _ = 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) + } } } diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index a3df39427..faa3ce419 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -94,6 +94,7 @@ func Init() { migrations.AddClam, migrations.AddClamStatus, migrations.AddAlertMenu, + migrations.AddComposeColumn, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/v_1_10.go b/backend/init/migration/migrations/v_1_10.go index f2b5f1d34..2915606b1 100644 --- a/backend/init/migration/migrations/v_1_10.go +++ b/backend/init/migration/migrations/v_1_10.go @@ -314,3 +314,13 @@ var AddAlertMenu = &gormigrate.Migration{ 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 + }, +} diff --git a/frontend/src/views/container/compose/detail/index.vue b/frontend/src/views/container/compose/detail/index.vue index 2b7364ca1..a102f247c 100644 --- a/frontend/src/views/container/compose/detail/index.vue +++ b/frontend/src/views/container/compose/detail/index.vue @@ -7,7 +7,7 @@ {{ composeName }}
- + {{ $t('container.start') }}