183 lines
3.7 KiB
Go
183 lines
3.7 KiB
Go
package deployers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path/filepath"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"gitea.thegux.fr/hmdeploy/connection"
|
|
"gitea.thegux.fr/hmdeploy/models"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type NginxDeployer struct {
|
|
ctx context.Context
|
|
|
|
conn connection.IConnection
|
|
project *models.Project
|
|
|
|
processing atomic.Bool
|
|
chDone chan struct{}
|
|
errFlag error
|
|
}
|
|
|
|
var _ IDeployer = (*NginxDeployer)(nil)
|
|
|
|
func NewNginxDeployer(
|
|
ctx context.Context,
|
|
netInfo *models.HMNetInfo,
|
|
project *models.Project,
|
|
) (*NginxDeployer, error) {
|
|
var nd NginxDeployer
|
|
|
|
conn, err := connection.NewSSHConn(
|
|
netInfo.IP.String(),
|
|
netInfo.SSH.User,
|
|
netInfo.SSH.Port,
|
|
netInfo.SSH.PrivKey,
|
|
)
|
|
if err != nil {
|
|
return &nd, err
|
|
}
|
|
|
|
nd.conn = &conn
|
|
nd.project = project
|
|
nd.ctx = ctx
|
|
nd.processing = atomic.Bool{}
|
|
nd.processing.Store(false)
|
|
nd.chDone = make(chan struct{}, 1)
|
|
|
|
return &nd, nil
|
|
}
|
|
|
|
func (nd *NginxDeployer) close() error {
|
|
return nd.conn.Close()
|
|
}
|
|
|
|
func (nd *NginxDeployer) clean() (err error) {
|
|
_, err = nd.conn.Execute("rm -f " + nd.project.Name + ".conf")
|
|
return
|
|
}
|
|
|
|
func (nd *NginxDeployer) setDone(err error) {
|
|
nd.chDone <- struct{}{}
|
|
nd.errFlag = err
|
|
}
|
|
|
|
func (nd *NginxDeployer) Error() error {
|
|
return nd.errFlag
|
|
}
|
|
|
|
func (nd *NginxDeployer) Done() <-chan struct{} {
|
|
chDone := make(chan struct{})
|
|
go func() {
|
|
defer func() {
|
|
close(chDone)
|
|
}()
|
|
|
|
for {
|
|
select {
|
|
case <-nd.ctx.Done():
|
|
log.Warn().Str("deployer", "swarm").Msg("context done catch")
|
|
|
|
timeout := time.NewTicker(10 * time.Second) //nolint:mnd //TODO: to refactor
|
|
tick := time.NewTicker(time.Second)
|
|
for {
|
|
select {
|
|
case <-timeout.C:
|
|
log.Error().
|
|
Msg("timeout while waiting for graceful swarm deployer shutdown")
|
|
chDone <- struct{}{}
|
|
return
|
|
case <-tick.C:
|
|
if !nd.processing.Load() {
|
|
chDone <- struct{}{}
|
|
return
|
|
}
|
|
tick.Reset(1 * time.Second)
|
|
}
|
|
}
|
|
case <-nd.chDone:
|
|
log.Info().Str("deployer", "nginx").Msg("terminated")
|
|
chDone <- struct{}{}
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
return chDone
|
|
}
|
|
|
|
func (nd *NginxDeployer) Clear() error {
|
|
log.Debug().Msg("clearing nginx deployment...")
|
|
|
|
if err := nd.clean(); err != nil {
|
|
log.Err(err).Msg("unable to clean nginx conf remotly")
|
|
}
|
|
|
|
if err := nd.close(); err != nil {
|
|
log.Err(err).Msg("unable to close nginx conn")
|
|
}
|
|
|
|
log.Debug().Msg("clear nginx deployment done")
|
|
return nil
|
|
}
|
|
|
|
func (nd *NginxDeployer) Build() error {
|
|
nd.processing.Store(true)
|
|
defer nd.processing.Store(false)
|
|
|
|
select {
|
|
case <-nd.ctx.Done():
|
|
nd.errFlag = ErrContextDone
|
|
return fmt.Errorf("%w, build nginx archive skipped", ErrContextDone)
|
|
default:
|
|
}
|
|
|
|
nginxPath := filepath.Join(nd.project.Dir, filepath.Base(nd.project.Deps.NginxFile))
|
|
nginxConf := nd.project.Name + ".conf"
|
|
|
|
log.Info().Str("nginx", nginxConf).Msg("transferring nginx conf...")
|
|
|
|
if err := nd.conn.CopyFile(nginxPath, nginxConf); err != nil {
|
|
nd.setDone(err)
|
|
return err
|
|
}
|
|
|
|
log.Info().Str("nginx", nginxConf).Msg("nginx conf transferred with success")
|
|
return nil
|
|
}
|
|
|
|
func (nd *NginxDeployer) Deploy() (err error) {
|
|
nd.processing.Store(true)
|
|
defer nd.processing.Store(false)
|
|
|
|
select {
|
|
case <-nd.ctx.Done():
|
|
nd.errFlag = ErrContextDone
|
|
return fmt.Errorf("%w, nginx deployment skipped", ErrContextDone)
|
|
default:
|
|
}
|
|
|
|
nginxConf := nd.project.Name + ".conf"
|
|
|
|
log.Info().Str("nginx", nginxConf).Msg("deploying nginx conf...")
|
|
|
|
_, err = nd.conn.Execute(
|
|
fmt.Sprintf(
|
|
"cp %s /etc/nginx/sites-available && ln -sf /etc/nginx/sites-available/%s /etc/nginx/sites-enabled/%s",
|
|
nginxConf,
|
|
nginxConf,
|
|
nginxConf,
|
|
),
|
|
)
|
|
nd.setDone(err)
|
|
|
|
if err == nil {
|
|
log.Info().Str("nginx", nginxConf).Msg("nginx conf successfully deployed")
|
|
}
|
|
|
|
return err
|
|
}
|