hmdeploy/deployers/swarm.go
2025-04-02 11:18:23 +02:00

99 lines
2.3 KiB
Go

package deployers
import (
"context"
"fmt"
"os"
"path/filepath"
"gitea.thegux.fr/hmdeploy/connection"
"gitea.thegux.fr/hmdeploy/docker"
"gitea.thegux.fr/hmdeploy/models"
"github.com/rs/zerolog/log"
)
type SwarmDeployer struct {
ctx context.Context
fnCancel context.CancelFunc
conn connection.IConnection
dcli docker.IClient
project *models.Project
}
var _ IDeployer = (*SwarmDeployer)(nil)
func NewSwarmDeployer(ctx context.Context, dockerClient docker.IClient, netInfo *models.HMNetInfo, project *models.Project) (SwarmDeployer, error) {
var sm SwarmDeployer
conn, err := connection.NewSSHConn(netInfo.IP.String(), netInfo.SSH.User, netInfo.SSH.Port, netInfo.SSH.PrivKey)
if err != nil {
return sm, err
}
ctxChild, fnCancel := context.WithCancel(ctx)
sm.ctx = ctxChild
sm.fnCancel = fnCancel
sm.conn = &conn
sm.dcli = dockerClient
sm.project = project
return sm, nil
}
func (sd *SwarmDeployer) Close() error {
return sd.conn.Close()
}
func (sd *SwarmDeployer) clean() (err error) {
_, err = sd.conn.Execute(fmt.Sprintf("rm -f %s %s", models.ComposeFile, models.EnvFile))
return
}
func (sd *SwarmDeployer) Deploy() error {
defer sd.clean()
if imageName := sd.project.ImageName; imageName != "" {
log.Info().Str("image", imageName).Msg("saving image for transfert...")
tarFile, err := sd.dcli.Save(imageName, sd.project.Dir)
if err != nil {
return err
}
log.Info().Str("image", imageName).Str("dir", sd.project.Dir).Msg("image saved successfully")
defer os.Remove(tarFile)
tarFileBase := filepath.Base(tarFile)
if err := sd.conn.CopyFile(tarFile, tarFileBase); err != nil {
return err
}
if _, err := sd.conn.Execute(fmt.Sprintf("docker load -i %s && rm %s", tarFileBase, tarFileBase)); err != nil {
return err
}
}
if envFilePath := sd.project.Deps.EnvFile; envFilePath != "" {
envFileBase := filepath.Base(envFilePath)
if err := sd.conn.CopyFile(filepath.Join(sd.project.Dir, envFileBase), envFileBase); err != nil {
return err
}
}
composeFileBase := filepath.Base(sd.project.Deps.ComposeFile)
if err := sd.conn.CopyFile(filepath.Join(sd.project.Dir, composeFileBase), composeFileBase); err != nil {
return err
}
if _, err := sd.conn.Execute(fmt.Sprintf("docker stack deploy -c %s %s", composeFileBase, sd.project.Name)); err != nil {
return err
}
return nil
}