package deployers import ( "context" "fmt" "os" "path/filepath" "gitea.thegux.fr/hmdeploy/connection" "gitea.thegux.fr/hmdeploy/models" "gitea.thegux.fr/hmdeploy/utils" "github.com/rs/zerolog/log" ) // NginxDeployer handles the deployment of an Nginx configuration. type NginxDeployer struct { *deployer conn connection.IConnection } var _ IDeployer = (*NginxDeployer)(nil) func NewNginxDeployer( ctx context.Context, project *models.Project, netInfo *models.HMNetInfo, ) (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.deployer = newDeployer(ctx, Nginx, project) return nd, nil } func (nd NginxDeployer) getConfPath() string { return nd.project.GetNginxConfPath() } func (nd NginxDeployer) getAssetsPath() string { return nd.project.GetNginxAssetsPath() } func (nd *NginxDeployer) close() error { return nd.conn.Close() } func (nd *NginxDeployer) clean() (err error) { if err = os.Remove(nd.archivePath); err != nil { log.Err(err).Str("archive", nd.archivePath).Msg("unable to clean local nginx archive file") } cmd := "rm -rf nginx.conf build/ *.tar.gz" if ap := nd.getAssetsPath(); ap != "" { cmd += " " + filepath.Base(nd.getAssetsPath()) } _, err = nd.conn.Execute(cmd) return } 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.setDone(nil) return fmt.Errorf("%w, build nginx archive skipped", ErrContextDone) default: } log.Info().Msg("building nginx archive for deployment...") filesToArchive := []string{} if ap := nd.getAssetsPath(); ap != "" { filesToArchive = append(filesToArchive, ap) } if cp := nd.getConfPath(); cp != "" { filesToArchive = append(filesToArchive, cp) } if len(filesToArchive) == 0 { return ErrEmptyArchive } archivePath, err := utils.CreateArchive( nd.project.Dir, fmt.Sprintf("%s-%s", nd.project.Name, "nginx"), filesToArchive..., ) if err != nil { return err } nd.archivePath = archivePath log.Info().Str("archive", archivePath).Msg("nginx archive built") return nil } func (nd *NginxDeployer) Deploy() error { nd.processing.Store(true) defer nd.processing.Store(false) select { case <-nd.ctx.Done(): nd.setDone(nil) return fmt.Errorf("%w, nginx deployment skipped", ErrContextDone) default: } archiveDestPath := filepath.Base(nd.archivePath) if err := nd.conn.CopyFile(nd.archivePath, archiveDestPath); err != nil { nd.setDone(err) return err } if _, err := nd.conn.Execute(fmt.Sprintf("tar xzvf %s", archiveDestPath)); err != nil { nd.setDone(err) return err } if ap := nd.getAssetsPath(); ap != "" { log.Info().Msg("deploying nginx assets...") if _, err := nd.conn.Execute( fmt.Sprintf( "rm -rf /var/www/static/%s/* && mkdir -p /var/www/static/%s && mv %s/* /var/www/static/%s", nd.project.Name, nd.project.Name, filepath.Base(nd.getAssetsPath()), nd.project.Name, ), ); err != nil { nd.setDone(err) return err } } if cp := nd.getConfPath(); cp != "" { nginxConf := nd.project.Name + ".conf" log.Info().Str("nginx", nginxConf).Msg("deploying nginx conf...") if _, err := nd.conn.Execute( fmt.Sprintf( "mv %s /etc/nginx/sites-available/%s && ln -sf /etc/nginx/sites-available/%s /etc/nginx/sites-enabled/%s", filepath.Base(cp), nginxConf, nginxConf, nginxConf, ), ); err != nil { nd.setDone(err) return err } } log.Info().Msg("nginx project successfully deployed") nd.setDone(nil) return nil } func (nd *NginxDeployer) Destroy() (err error) { nd.processing.Store(true) defer nd.processing.Store(false) select { case <-nd.ctx.Done(): nd.setDone(nil) return fmt.Errorf("%w, nginx destroy skipped", ErrContextDone) default: } nginxConf := nd.project.Name + ".conf" log.Info().Str("nginx", nginxConf).Msg("destroying nginx conf...") _, err = nd.conn.Execute( fmt.Sprintf( "rm -f /etc/nginx/sites-enabled/%s", nginxConf, ), ) nd.setDone(err) if err == nil { log.Info().Str("nginx", nginxConf).Msg("nginx conf successfully destroyed") } return err }