Compare commits
	
		
			4 Commits
		
	
	
		
			feat/nginx
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 9e48569823 | ||
|   | 18605a76e1 | ||
|   | 7c01fa438c | ||
|   | 0e4eda972e | 
| @ -123,6 +123,8 @@ The binary is then installed in your **$GOPATH/bin**. | |||||||
| ```bash | ```bash | ||||||
| hmdeploy --help | hmdeploy --help | ||||||
| Usage of hmdeploy: | Usage of hmdeploy: | ||||||
|  |   -config string | ||||||
|  |         define the configuration directory (default "/home/romain/.homeserver") | ||||||
|   -confirm |   -confirm | ||||||
|         do not ask for confirmation, you're the best, you don't need confirmation |         do not ask for confirmation, you're the best, you don't need confirmation | ||||||
|   -debug |   -debug | ||||||
| @ -133,6 +135,8 @@ Usage of hmdeploy: | |||||||
|         extract swarm details and return |         extract swarm details and return | ||||||
|   -no-nginx |   -no-nginx | ||||||
|         no Nginx deployment |         no Nginx deployment | ||||||
|  |   -no-swarm | ||||||
|  |         no Swarm deployment | ||||||
|   -path string |   -path string | ||||||
|         define the .homeserver project root dir (default ".") |         define the .homeserver project root dir (default ".") | ||||||
|   -version |   -version | ||||||
| @ -155,7 +159,7 @@ hmdeploy --path /path/my-project --destroy | |||||||
| * ~~Improve the CLI arguments~~ | * ~~Improve the CLI arguments~~ | ||||||
| * ~~Destroy~~ | * ~~Destroy~~ | ||||||
| * ~~Check deployment/undeployment state~~ | * ~~Check deployment/undeployment state~~ | ||||||
| * Create a deployment temp dir (lock to avoid concurrent deployments) | * ~~Create a deployment temp dir (lock to avoid concurrent deployments)~~ | ||||||
| * Deals with bugs | * Deals with bugs | ||||||
| * Tests 😮💨 | * Tests 😮💨 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,9 +3,13 @@ package deployers | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
| 	"sync/atomic" | 	"sync/atomic" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"gitea.thegux.fr/hmdeploy/connection" | ||||||
| 	"gitea.thegux.fr/hmdeploy/models" | 	"gitea.thegux.fr/hmdeploy/models" | ||||||
| 	"github.com/rs/zerolog/log" | 	"github.com/rs/zerolog/log" | ||||||
| ) | ) | ||||||
| @ -51,21 +55,43 @@ type deployer struct { //nolint:govet // ll | |||||||
| 	type_      DeployerType | 	type_      DeployerType | ||||||
| 	errFlag    error | 	errFlag    error | ||||||
| 
 | 
 | ||||||
| 	project     *models.Project | 	conn          connection.IConnection | ||||||
| 	archivePath string | 	project       *models.Project | ||||||
|  | 	archivePath   string | ||||||
|  | 	deploymentDir string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func newDeployer(ctx context.Context, type_ DeployerType, project *models.Project) *deployer { | func newDeployer( | ||||||
|  | 	ctx context.Context, | ||||||
|  | 	type_ DeployerType, | ||||||
|  | 	project *models.Project, | ||||||
|  | 	netInfo *models.HMNetInfo, | ||||||
|  | ) (*deployer, error) { | ||||||
|  | 	conn, err := connection.NewSSHConn( | ||||||
|  | 		netInfo.IP.String(), | ||||||
|  | 		netInfo.SSH.User, | ||||||
|  | 		netInfo.SSH.Port, | ||||||
|  | 		netInfo.SSH.PrivKey, | ||||||
|  | 	) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	d := &deployer{ | 	d := &deployer{ | ||||||
| 		ctx:        ctx, | 		ctx:        ctx, | ||||||
| 		type_:      type_, | 		type_:      type_, | ||||||
| 		project:    project, | 		project:    project, | ||||||
| 		processing: atomic.Bool{}, | 		processing: atomic.Bool{}, | ||||||
| 		chDone:     make(chan struct{}, 1), | 		chDone:     make(chan struct{}, 1), | ||||||
|  | 		conn:       &conn, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	d.processing.Store(false) | 	d.processing.Store(false) | ||||||
| 	return d | 	return d, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (d *deployer) close() error { | ||||||
|  | 	return d.conn.Close() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (d *deployer) setDone(err error) { | func (d *deployer) setDone(err error) { | ||||||
| @ -76,6 +102,50 @@ func (d *deployer) setDone(err error) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (d *deployer) clean() { | ||||||
|  | 	if err := os.Remove(d.archivePath); err != nil { | ||||||
|  | 		log.Err(err).Str("archive", d.archivePath).Msg("unable to clean local archive file") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if d.deploymentDir != "" { | ||||||
|  | 		if _, err := d.conn.Execute("rm -rf " + d.deploymentDir); err != nil { | ||||||
|  | 			log.Err(err). | ||||||
|  | 				Str("dir", d.deploymentDir). | ||||||
|  | 				Str("type", string(d.type_)). | ||||||
|  | 				Msg("unable to clean deployment dir") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (d *deployer) copyUntarArchive() error { | ||||||
|  | 	deploymentDir := "." + d.project.Name | ||||||
|  | 
 | ||||||
|  | 	// TODO(rmanach): check cmd error output to check if's not an other error | ||||||
|  | 	if _, err := d.conn.Execute("mkdir " + deploymentDir); err != nil { | ||||||
|  | 		log.Error(). | ||||||
|  | 			Str("dir", deploymentDir). | ||||||
|  | 			Msg("deployment dir already exists, unable to deploy now") | ||||||
|  | 		d.setDone(err) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	d.deploymentDir = deploymentDir | ||||||
|  | 
 | ||||||
|  | 	archiveName := filepath.Base(d.archivePath) | ||||||
|  | 	archiveDestPath := filepath.Join(deploymentDir, archiveName) | ||||||
|  | 	if err := d.conn.CopyFile(d.archivePath, archiveDestPath); err != nil { | ||||||
|  | 		d.setDone(err) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if _, err := d.conn.Execute(fmt.Sprintf("cd %s && tar xzvf %s", deploymentDir, archiveName)); err != nil { | ||||||
|  | 		d.setDone(err) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // SetCancellationFunc sets a context cancellation function for the deployer. | // SetCancellationFunc sets a context cancellation function for the deployer. | ||||||
| // | // | ||||||
| // If two deployers are related on the same context, one failed and you want | // If two deployers are related on the same context, one failed and you want | ||||||
| @ -94,6 +164,18 @@ func (d *deployer) Error() error { | |||||||
| 	return d.errFlag | 	return d.errFlag | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (d *deployer) Clear() error { | ||||||
|  | 	log.Debug().Str("type", string(d.type_)).Msg("clearing deployment...") | ||||||
|  | 	d.clean() | ||||||
|  | 
 | ||||||
|  | 	if err := d.close(); err != nil { | ||||||
|  | 		log.Err(err).Msg("unable to close conn") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	log.Debug().Str("type", string(d.type_)).Msg("clear deployment done") | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Done returns a channel providing the shutdown or the termination | // Done returns a channel providing the shutdown or the termination | ||||||
| // of the deployer. | // of the deployer. | ||||||
| // | // | ||||||
|  | |||||||
| @ -3,10 +3,8 @@ package deployers | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" |  | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 
 | 
 | ||||||
| 	"gitea.thegux.fr/hmdeploy/connection" |  | ||||||
| 	"gitea.thegux.fr/hmdeploy/models" | 	"gitea.thegux.fr/hmdeploy/models" | ||||||
| 	"gitea.thegux.fr/hmdeploy/utils" | 	"gitea.thegux.fr/hmdeploy/utils" | ||||||
| 	"github.com/rs/zerolog/log" | 	"github.com/rs/zerolog/log" | ||||||
| @ -15,7 +13,6 @@ import ( | |||||||
| // NginxDeployer handles the deployment of an Nginx configuration. | // NginxDeployer handles the deployment of an Nginx configuration. | ||||||
| type NginxDeployer struct { | type NginxDeployer struct { | ||||||
| 	*deployer | 	*deployer | ||||||
| 	conn connection.IConnection |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var _ IDeployer = (*NginxDeployer)(nil) | var _ IDeployer = (*NginxDeployer)(nil) | ||||||
| @ -27,18 +24,11 @@ func NewNginxDeployer( | |||||||
| ) (NginxDeployer, error) { | ) (NginxDeployer, error) { | ||||||
| 	var nd NginxDeployer | 	var nd NginxDeployer | ||||||
| 
 | 
 | ||||||
| 	conn, err := connection.NewSSHConn( | 	deployer, err := newDeployer(ctx, Nginx, project, netInfo) | ||||||
| 		netInfo.IP.String(), |  | ||||||
| 		netInfo.SSH.User, |  | ||||||
| 		netInfo.SSH.Port, |  | ||||||
| 		netInfo.SSH.PrivKey, |  | ||||||
| 	) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nd, err | 		return nd, err | ||||||
| 	} | 	} | ||||||
| 
 | 	nd.deployer = deployer | ||||||
| 	nd.conn = &conn |  | ||||||
| 	nd.deployer = newDeployer(ctx, Nginx, project) |  | ||||||
| 
 | 
 | ||||||
| 	return nd, nil | 	return nd, nil | ||||||
| } | } | ||||||
| @ -51,38 +41,6 @@ func (nd NginxDeployer) getAssetsPath() string { | |||||||
| 	return nd.project.GetNginxAssetsPath() | 	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 { | func (nd *NginxDeployer) Build() error { | ||||||
| 	nd.processing.Store(true) | 	nd.processing.Store(true) | ||||||
| 	defer nd.processing.Store(false) | 	defer nd.processing.Store(false) | ||||||
| @ -134,14 +92,7 @@ func (nd *NginxDeployer) Deploy() error { | |||||||
| 	default: | 	default: | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	archiveDestPath := filepath.Base(nd.archivePath) | 	if err := nd.copyUntarArchive(); err != nil { | ||||||
| 	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 | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -153,7 +104,7 @@ func (nd *NginxDeployer) Deploy() error { | |||||||
| 				"rm -rf /var/www/static/%s/* && mkdir -p /var/www/static/%s && mv %s/* /var/www/static/%s", | 				"rm -rf /var/www/static/%s/* && mkdir -p /var/www/static/%s && mv %s/* /var/www/static/%s", | ||||||
| 				nd.project.Name, | 				nd.project.Name, | ||||||
| 				nd.project.Name, | 				nd.project.Name, | ||||||
| 				filepath.Base(nd.getAssetsPath()), | 				filepath.Join(nd.deploymentDir, filepath.Base(nd.getAssetsPath())), | ||||||
| 				nd.project.Name, | 				nd.project.Name, | ||||||
| 			), | 			), | ||||||
| 		); err != nil { | 		); err != nil { | ||||||
| @ -169,7 +120,7 @@ func (nd *NginxDeployer) Deploy() error { | |||||||
| 		if _, err := nd.conn.Execute( | 		if _, err := nd.conn.Execute( | ||||||
| 			fmt.Sprintf( | 			fmt.Sprintf( | ||||||
| 				"mv %s /etc/nginx/sites-available/%s && ln -sf /etc/nginx/sites-available/%s /etc/nginx/sites-enabled/%s", | 				"mv %s /etc/nginx/sites-available/%s && ln -sf /etc/nginx/sites-available/%s /etc/nginx/sites-enabled/%s", | ||||||
| 				filepath.Base(cp), | 				filepath.Join(nd.deploymentDir, filepath.Base(cp)), | ||||||
| 				nginxConf, | 				nginxConf, | ||||||
| 				nginxConf, | 				nginxConf, | ||||||
| 				nginxConf, | 				nginxConf, | ||||||
|  | |||||||
| @ -35,20 +35,14 @@ func NewSwarmDeployer( | |||||||
| ) (SwarmDeployer, error) { | ) (SwarmDeployer, error) { | ||||||
| 	var sd SwarmDeployer | 	var sd SwarmDeployer | ||||||
| 
 | 
 | ||||||
| 	conn, err := connection.NewSSHConn( |  | ||||||
| 		netInfo.IP.String(), |  | ||||||
| 		netInfo.SSH.User, |  | ||||||
| 		netInfo.SSH.Port, |  | ||||||
| 		netInfo.SSH.PrivKey, |  | ||||||
| 	) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return sd, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	sd.conn = &conn |  | ||||||
| 	sd.dloc = dloc | 	sd.dloc = dloc | ||||||
| 	sd.drem = drem | 	sd.drem = drem | ||||||
| 	sd.deployer = newDeployer(ctx, Swarm, project) | 
 | ||||||
|  | 	deployer, err := newDeployer(ctx, Swarm, project, netInfo) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return sd, err | ||||||
|  | 	} | ||||||
|  | 	sd.deployer = deployer | ||||||
| 
 | 
 | ||||||
| 	return sd, nil | 	return sd, nil | ||||||
| } | } | ||||||
| @ -61,36 +55,6 @@ func (sd SwarmDeployer) getEnvPath() string { | |||||||
| 	return sd.project.GetEnvPath() | 	return sd.project.GetEnvPath() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (sd *SwarmDeployer) close() error { |  | ||||||
| 	return sd.conn.Close() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (sd *SwarmDeployer) clean() (err error) { |  | ||||||
| 	if err = os.Remove(sd.archivePath); err != nil { |  | ||||||
| 		log.Err(err).Str("archive", sd.archivePath).Msg("unable to clean local swarm archive file") |  | ||||||
| 	} |  | ||||||
| 	_, err = sd.conn.Execute( |  | ||||||
| 		fmt.Sprintf("rm -f %s %s *.tar.gz *.tar", models.ComposeFile, models.EnvFile), |  | ||||||
| 	) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (sd *SwarmDeployer) Clear() error { |  | ||||||
| 	log.Debug().Msg("clearing swarm deployment...") |  | ||||||
| 
 |  | ||||||
| 	if err := sd.clean(); err != nil { |  | ||||||
| 		log.Err(err).Msg("unable to clean swarm conf remotly") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := sd.close(); err != nil { |  | ||||||
| 		log.Err(err).Msg("unable to close swarm conn") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	log.Debug().Msg("clear swarm deployment done") |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Build builds the archive with mandatory files to deploy a swarm service. | // Build builds the archive with mandatory files to deploy a swarm service. | ||||||
| // | // | ||||||
| // After the build, the path of the local archive built is set in | // After the build, the path of the local archive built is set in | ||||||
| @ -177,20 +141,13 @@ func (sd *SwarmDeployer) Deploy() error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	archiveDestPath := filepath.Base(sd.archivePath) | 	if err := sd.copyUntarArchive(); err != nil { | ||||||
| 	if err := sd.conn.CopyFile(sd.archivePath, archiveDestPath); err != nil { |  | ||||||
| 		sd.setDone(err) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if _, err := sd.conn.Execute(fmt.Sprintf("tar xzvf %s", archiveDestPath)); err != nil { |  | ||||||
| 		sd.setDone(err) |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	log.Info().Str("project", sd.project.Name).Msg("deploying swarm project...") | 	log.Info().Str("project", sd.project.Name).Msg("deploying swarm project...") | ||||||
| 	composeFileBase := filepath.Base(sd.getComposePath()) | 	composeFileBase := filepath.Base(sd.getComposePath()) | ||||||
| 	if err := sd.drem.DeployStack(sd.ctx, sd.project.Name, composeFileBase, docker.WithCheckState()); err != nil { | 	if err := sd.drem.DeployStack(sd.ctx, sd.project.Name, composeFileBase, docker.WithCheckState(), docker.WithBaseDir(sd.deploymentDir)); err != nil { | ||||||
| 		sd.setDone(err) | 		sd.setDone(err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -31,6 +31,7 @@ var ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type stackOption struct { | type stackOption struct { | ||||||
|  | 	baseDir    string | ||||||
| 	checkState bool | 	checkState bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -42,6 +43,12 @@ func WithCheckState() fnStackOption { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func WithBaseDir(dir string) fnStackOption { | ||||||
|  | 	return func(s *stackOption) { | ||||||
|  | 		s.baseDir = dir | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func parseIDs(cmdOutput string) []string { | func parseIDs(cmdOutput string) []string { | ||||||
| 	ids := []string{} | 	ids := []string{} | ||||||
| 	bufLine := []rune{} | 	bufLine := []rune{} | ||||||
| @ -201,15 +208,19 @@ func (c *RemoteClient) DeployStack( | |||||||
| 	projectName, composeFilepath string, | 	projectName, composeFilepath string, | ||||||
| 	options ...fnStackOption, | 	options ...fnStackOption, | ||||||
| ) error { | ) error { | ||||||
| 	if _, err := c.conn.Execute(fmt.Sprintf("docker stack deploy -c %s %s --with-registry-auth", composeFilepath, projectName)); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var opts stackOption | 	var opts stackOption | ||||||
| 	for _, opt := range options { | 	for _, opt := range options { | ||||||
| 		opt(&opts) | 		opt(&opts) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if bd := opts.baseDir; bd != "" { | ||||||
|  | 		composeFilepath = filepath.Join(bd, composeFilepath) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if _, err := c.conn.Execute(fmt.Sprintf("docker stack deploy -c %s %s --with-registry-auth", composeFilepath, projectName)); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if opts.checkState { | 	if opts.checkState { | ||||||
| 		return c.checkState(ctx, projectName, Running) | 		return c.checkState(ctx, projectName, Running) | ||||||
| 	} | 	} | ||||||
| @ -289,6 +300,10 @@ func (c *RemoteClient) checkState( | |||||||
| 				ready := true | 				ready := true | ||||||
| 			mainloop: | 			mainloop: | ||||||
| 				for idx := range srvs { | 				for idx := range srvs { | ||||||
|  | 					// ensure app name is the right one | ||||||
|  | 					if srvs[idx].App != projectName { | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
| 					for idy := range srvs[idx].Replicas { | 					for idy := range srvs[idx].Replicas { | ||||||
| 						if srvs[idx].Replicas[idy].State != target { | 						if srvs[idx].Replicas[idy].State != target { | ||||||
| 							log.Info().Dur("retry (ms)", stateTickDuration).Msg("project not in good state yet, retrying...") | 							log.Info().Dur("retry (ms)", stateTickDuration).Msg("project not in good state yet, retrying...") | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								main.go
									
									
									
									
									
								
							| @ -219,10 +219,10 @@ func initLogger(debug bool) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // loadHMMap loads your instance configuration map from `$HOME/.homeserver` dir. | // loadHMMap loads your instance configuration map from `$HOME/.homeserver` dir. | ||||||
| func loadHMMap() (models.HMMap, error) { | func loadHMMap(baseDir string) (models.HMMap, error) { | ||||||
| 	var hmmap models.HMMap | 	var hmmap models.HMMap | ||||||
| 
 | 
 | ||||||
| 	hmmap_path := path.Join(HOME_PATH, HMDeployDirname, NetworkFilename) | 	hmmap_path := path.Join(baseDir, NetworkFilename) | ||||||
| 	c, err := os.ReadFile(hmmap_path) | 	c, err := os.ReadFile(hmmap_path) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return hmmap, fmt.Errorf( | 		return hmmap, fmt.Errorf( | ||||||
| @ -428,6 +428,11 @@ func main() { //nolint: funlen // TODO: to reduce | |||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	projectDir := flag.String("path", ".", "define the .homeserver project root dir") | 	projectDir := flag.String("path", ".", "define the .homeserver project root dir") | ||||||
|  | 	configDir := flag.String( | ||||||
|  | 		"config", | ||||||
|  | 		path.Join(HOME_PATH, HMDeployDirname), | ||||||
|  | 		"define the configuration directory", | ||||||
|  | 	) | ||||||
| 	destroy := flag.Bool("destroy", false, "delete the deployed project") | 	destroy := flag.Bool("destroy", false, "delete the deployed project") | ||||||
| 	noNginx := flag.Bool("no-nginx", false, "no Nginx deployment") | 	noNginx := flag.Bool("no-nginx", false, "no Nginx deployment") | ||||||
| 	noSwarm := flag.Bool("no-swarm", false, "no Swarm deployment") | 	noSwarm := flag.Bool("no-swarm", false, "no Swarm deployment") | ||||||
| @ -448,7 +453,7 @@ func main() { //nolint: funlen // TODO: to reduce | |||||||
| 
 | 
 | ||||||
| 	initLogger(*debug) | 	initLogger(*debug) | ||||||
| 
 | 
 | ||||||
| 	hmmap, err := loadHMMap() | 	hmmap, err := loadHMMap(*configDir) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Fatal().Err(err).Msg("failed to load conf") | 		log.Fatal().Err(err).Msg("failed to load conf") | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user