You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1Panel/backend/app/service/runtime.go

133 lines
3.5 KiB

package service
import (
"context"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/app/repo"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/docker"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/subosito/gotenv"
"path"
)
type RuntimeService struct {
}
type IRuntimeService interface {
Page(req request.RuntimeSearch) (int64, []response.RuntimeRes, error)
Create(create request.RuntimeCreate) error
}
func NewRuntimeService() IRuntimeService {
return &RuntimeService{}
}
func (r *RuntimeService) Create(create request.RuntimeCreate) error {
if create.Resource == constant.ResourceLocal {
runtime := &model.Runtime{
Name: create.Name,
Resource: create.Resource,
Type: create.Type,
Status: constant.RuntimeNormal,
}
return runtimeRepo.Create(context.Background(), runtime)
}
var err error
appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(create.AppDetailID))
if err != nil {
return err
}
app, err := appRepo.GetFirst(commonRepo.WithByID(appDetail.AppId))
if err != nil {
return err
}
fileOp := files.NewFileOp()
buildDir := path.Join(constant.AppResourceDir, app.Key, "versions", appDetail.Version, "build")
if !fileOp.Stat(buildDir) {
return buserr.New(constant.ErrDirNotFound)
}
tempDir := path.Join(constant.RuntimeDir, app.Key)
if err := fileOp.CopyDir(buildDir, tempDir); err != nil {
return err
}
oldDir := path.Join(tempDir, "build")
newNameDir := path.Join(tempDir, create.Name)
defer func(defErr *error) {
if defErr != nil {
_ = fileOp.DeleteDir(newNameDir)
}
}(&err)
if oldDir != newNameDir {
if err := fileOp.Rename(oldDir, newNameDir); err != nil {
return err
}
}
composeFile, err := fileOp.GetContent(path.Join(newNameDir, "docker-compose.yml"))
if err != nil {
return err
}
env, err := gotenv.Read(path.Join(newNameDir, ".env"))
if err != nil {
return err
}
newMap := make(map[string]string)
handleMap(create.Params, newMap)
for k, v := range newMap {
env[k] = v
}
envStr, err := gotenv.Marshal(env)
if err != nil {
return err
}
if err := gotenv.Write(env, path.Join(newNameDir, ".env")); err != nil {
return err
}
project, err := docker.GetComposeProject(create.Name, newNameDir, composeFile, []byte(envStr))
if err != nil {
return err
}
composeService, err := docker.NewComposeService()
if err != nil {
return err
}
composeService.SetProject(project)
if err := composeService.ComposeBuild(); err != nil {
return err
}
runtime := &model.Runtime{
Name: create.Name,
DockerCompose: string(composeFile),
Env: envStr,
AppDetailID: create.AppDetailID,
Type: create.Type,
Image: create.Image,
Resource: create.Resource,
Status: constant.RuntimeNormal,
}
return runtimeRepo.Create(context.Background(), runtime)
}
func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.RuntimeRes, error) {
var (
opts []repo.DBOption
res []response.RuntimeRes
)
if req.Name != "" {
opts = append(opts, commonRepo.WithLikeName(req.Name))
}
total, runtimes, err := runtimeRepo.Page(req.Page, req.PageSize, opts...)
if err != nil {
return 0, nil, err
}
for _, runtime := range runtimes {
res = append(res, response.RuntimeRes{
Runtime: runtime,
})
}
return total, res, nil
}