mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 对接 docker compose SDK
This commit is contained in:
parent
3de0ae1b0f
commit
bf9a37623a
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
||||||
|
composeV2 "github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -223,12 +224,7 @@ func updateInstall(installId uint, detailId uint) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getContainerNames(install model.AppInstall) ([]string, error) {
|
func getContainerNames(install model.AppInstall) ([]string, error) {
|
||||||
composeMap := install.DockerCompose
|
project, err := composeV2.GetComposeProject(install.Name, install.GetPath(), []byte(install.DockerCompose), []byte(install.Env))
|
||||||
envMap := make(map[string]interface{})
|
|
||||||
_ = json.Unmarshal([]byte(install.Env), &envMap)
|
|
||||||
newEnvMap := make(map[string]string, len(envMap))
|
|
||||||
handleMap(envMap, newEnvMap)
|
|
||||||
project, err := compose.GetComposeProject([]byte(composeMap), newEnvMap)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -225,9 +225,9 @@ func (u *ContainerService) ContainerOperation(req dto.ContainerOperation) error
|
|||||||
case constant.ContainerOpStart:
|
case constant.ContainerOpStart:
|
||||||
err = client.ContainerStart(ctx, req.Name, types.ContainerStartOptions{})
|
err = client.ContainerStart(ctx, req.Name, types.ContainerStartOptions{})
|
||||||
case constant.ContainerOpStop:
|
case constant.ContainerOpStop:
|
||||||
err = client.ContainerStop(ctx, req.Name, nil)
|
err = client.ContainerStop(ctx, req.Name, container.StopOptions{})
|
||||||
case constant.ContainerOpRestart:
|
case constant.ContainerOpRestart:
|
||||||
err = client.ContainerRestart(ctx, req.Name, nil)
|
err = client.ContainerRestart(ctx, req.Name, container.StopOptions{})
|
||||||
case constant.ContainerOpKill:
|
case constant.ContainerOpKill:
|
||||||
err = client.ContainerKill(ctx, req.Name, "SIGKILL")
|
err = client.ContainerKill(ctx, req.Name, "SIGKILL")
|
||||||
case constant.ContainerOpPause:
|
case constant.ContainerOpPause:
|
||||||
|
@ -2,8 +2,6 @@ package compose
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||||
"github.com/compose-spec/compose-go/loader"
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Up(filePath string) (string, error) {
|
func Up(filePath string) (string, error) {
|
||||||
@ -35,24 +33,3 @@ func Operate(filePath, operation string) (string, error) {
|
|||||||
stdout, err := cmd.Execf("docker-compose -f %s %s", filePath, operation)
|
stdout, err := cmd.Execf("docker-compose -f %s %s", filePath, operation)
|
||||||
return stdout, err
|
return stdout, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetComposeProject(yml []byte, env map[string]string) (*types.Project, error) {
|
|
||||||
var configFiles []types.ConfigFile
|
|
||||||
configFiles = append(configFiles, types.ConfigFile{
|
|
||||||
Filename: "docker-compose.yml",
|
|
||||||
Content: yml},
|
|
||||||
)
|
|
||||||
details := types.ConfigDetails{
|
|
||||||
WorkingDir: "",
|
|
||||||
ConfigFiles: configFiles,
|
|
||||||
Environment: env,
|
|
||||||
}
|
|
||||||
|
|
||||||
project, err := loader.Load(details, func(options *loader.Options) {
|
|
||||||
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return project, nil
|
|
||||||
}
|
|
||||||
|
114
backend/utils/docker/compose.go
Normal file
114
backend/utils/docker/compose.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/compose-spec/compose-go/loader"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
"github.com/docker/cli/cli/command"
|
||||||
|
"github.com/docker/cli/cli/flags"
|
||||||
|
"github.com/docker/compose/v2/pkg/api"
|
||||||
|
"github.com/docker/compose/v2/pkg/compose"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ComposeService struct {
|
||||||
|
api.Service
|
||||||
|
project *types.Project
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewComposeService(ops ...command.DockerCliOption) (*ComposeService, error) {
|
||||||
|
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ops = append(ops, command.WithAPIClient(apiClient), command.WithDefaultContextStoreConfig())
|
||||||
|
cli, err := command.NewDockerCli(ops...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cliOp := flags.NewClientOptions()
|
||||||
|
if err := cli.Initialize(cliOp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
service := compose.NewComposeService(cli)
|
||||||
|
return &ComposeService{service, nil}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ComposeService) SetProject(project *types.Project) {
|
||||||
|
s.project = project
|
||||||
|
for i, s := range project.Services {
|
||||||
|
s.CustomLabels = map[string]string{
|
||||||
|
api.ProjectLabel: project.Name,
|
||||||
|
api.ServiceLabel: s.Name,
|
||||||
|
api.VersionLabel: api.ComposeVersion,
|
||||||
|
api.WorkingDirLabel: project.WorkingDir,
|
||||||
|
api.ConfigFilesLabel: strings.Join(project.ComposeFiles, ","),
|
||||||
|
api.OneoffLabel: "False",
|
||||||
|
}
|
||||||
|
project.Services[i] = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ComposeService) ComposeUp() error {
|
||||||
|
return s.Up(context.Background(), s.project, api.UpOptions{
|
||||||
|
Create: api.CreateOptions{
|
||||||
|
Timeout: getComposeTimeout(),
|
||||||
|
},
|
||||||
|
Start: api.StartOptions{
|
||||||
|
WaitTimeout: *getComposeTimeout(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ComposeService) ComposeDown() error {
|
||||||
|
return s.Down(context.Background(), s.project.Name, api.DownOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ComposeService) ComposeStart() error {
|
||||||
|
return s.Start(context.Background(), s.project.Name, api.StartOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ComposeService) ComposeRestart() error {
|
||||||
|
return s.Restart(context.Background(), s.project.Name, api.RestartOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ComposeService) ComposeStop() error {
|
||||||
|
return s.Stop(context.Background(), s.project.Name, api.StopOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ComposeService) ComposeCreate() error {
|
||||||
|
return s.Create(context.Background(), s.project, api.CreateOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetComposeProject(projectName, workDir string, yml []byte, env []byte) (*types.Project, error) {
|
||||||
|
var configFiles []types.ConfigFile
|
||||||
|
configFiles = append(configFiles, types.ConfigFile{
|
||||||
|
Filename: "docker-compose.yml",
|
||||||
|
Content: yml},
|
||||||
|
)
|
||||||
|
envMap, err := godotenv.UnmarshalBytes(env)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
details := types.ConfigDetails{
|
||||||
|
WorkingDir: workDir,
|
||||||
|
ConfigFiles: configFiles,
|
||||||
|
Environment: envMap,
|
||||||
|
}
|
||||||
|
project, err := loader.Load(details, func(options *loader.Options) {
|
||||||
|
options.SetProjectName(projectName, true)
|
||||||
|
options.ResolvePaths = true
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return project, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getComposeTimeout() *time.Duration {
|
||||||
|
timeout := time.Minute * time.Duration(10)
|
||||||
|
return &timeout
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user