add destroy command
This commit is contained in:
parent
43a78573f5
commit
cfdaa9538b
2
Makefile
2
Makefile
@ -5,7 +5,7 @@ run: lint
|
||||
|
||||
build: lint
|
||||
@echo "building binary..."
|
||||
@go build -o $(BIN_NAME) -race main.go && echo "$(BIN_NAME) built"
|
||||
@go build -o $(BIN_NAME) main.go && echo "$(BIN_NAME) built"
|
||||
|
||||
install:
|
||||
@$(shell whereis $(BIN_NAME) | cut -d ' ' -f2 | xargs rm -f)
|
||||
|
||||
18
README.md
18
README.md
@ -15,12 +15,12 @@ You have an Nginx instance in front of a Docker Swarm instance (ip are here for
|
||||
|docker swarm | |nginx |
|
||||
| | | |
|
||||
|ip: 10.0.0.2 | |ip: 10.0.0.1 |
|
||||
| | | | HTTP Request
|
||||
| +----------+ |<-----------
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| +------+ +------+ +----------+ |<-----------
|
||||
| |app1 | |app2 | | | | HTTP request
|
||||
| | | | | | | |
|
||||
| |:8080 | |:8081 | | | |
|
||||
| +------+ +------+ | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+-------------------------+ +-------------------------+
|
||||
@ -120,14 +120,18 @@ The binary is then installed in your **$GOPATH/bin**.
|
||||
# you can then launch the program directly
|
||||
hmdeploy
|
||||
|
||||
# if you want the deploy a specific project
|
||||
# if you want to deploy a specific project
|
||||
# use --path to point the project dir where `.homeserver` is located
|
||||
hmdeploy --path /path/my-project
|
||||
|
||||
# if you want to undeploy a specific project
|
||||
# do not worry, volumes are preserved
|
||||
hmdeploy --path /path/my-project --destroy
|
||||
```
|
||||
|
||||
## Next steps
|
||||
* Improve the CLI arguments
|
||||
* Destroy
|
||||
* ~~Destroy~~
|
||||
* post-install script
|
||||
* Deals with bugs
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ type IDeployer interface {
|
||||
Type() DeployerType
|
||||
Deploy() error
|
||||
Build() error
|
||||
Destroy() error
|
||||
Clear() error
|
||||
Error() error
|
||||
Done() <-chan struct{}
|
||||
@ -65,7 +66,7 @@ func newDeployer(ctx context.Context, type_ DeployerType, project *models.Projec
|
||||
|
||||
func (d *deployer) setDone(err error) {
|
||||
d.chDone <- struct{}{}
|
||||
d.errFlag = err
|
||||
d.errFlag = errors.Join(d.ctx.Err(), err)
|
||||
if err != nil && d.fnCancel != nil {
|
||||
d.fnCancel()
|
||||
}
|
||||
@ -110,6 +111,10 @@ func (d *deployer) Done() <-chan struct{} {
|
||||
|
||||
timeout := time.NewTicker(GracefulTimeout)
|
||||
tick := time.NewTicker(time.Second)
|
||||
|
||||
defer tick.Stop()
|
||||
defer timeout.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timeout.C:
|
||||
|
||||
@ -70,7 +70,7 @@ func (nd *NginxDeployer) Build() error {
|
||||
|
||||
select {
|
||||
case <-nd.ctx.Done():
|
||||
nd.errFlag = ErrContextDone
|
||||
nd.setDone(nil)
|
||||
return fmt.Errorf("%w, build nginx archive skipped", ErrContextDone)
|
||||
default:
|
||||
}
|
||||
@ -94,7 +94,7 @@ func (nd *NginxDeployer) Deploy() (err error) {
|
||||
|
||||
select {
|
||||
case <-nd.ctx.Done():
|
||||
nd.errFlag = ErrContextDone
|
||||
nd.setDone(nil)
|
||||
return fmt.Errorf("%w, nginx deployment skipped", ErrContextDone)
|
||||
default:
|
||||
}
|
||||
@ -119,3 +119,33 @@ func (nd *NginxDeployer) Deploy() (err error) {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
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(
|
||||
"unlink /etc/nginx/sites-enabled/%s",
|
||||
nginxConf,
|
||||
),
|
||||
)
|
||||
nd.setDone(err)
|
||||
|
||||
if err == nil {
|
||||
log.Info().Str("nginx", nginxConf).Msg("nginx conf successfully destroyed")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -56,7 +56,9 @@ func (sd *SwarmDeployer) close() error {
|
||||
}
|
||||
|
||||
func (sd *SwarmDeployer) clean() (err error) {
|
||||
defer os.Remove(sd.archivePath) //nolint: errcheck // defered
|
||||
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),
|
||||
)
|
||||
@ -89,7 +91,7 @@ func (sd *SwarmDeployer) Build() error {
|
||||
|
||||
select {
|
||||
case <-sd.ctx.Done():
|
||||
sd.errFlag = ErrContextDone
|
||||
sd.setDone(nil)
|
||||
return fmt.Errorf("%w, swarm project build skipped", ErrContextDone)
|
||||
default:
|
||||
}
|
||||
@ -148,7 +150,7 @@ func (sd *SwarmDeployer) Deploy() error {
|
||||
|
||||
select {
|
||||
case <-sd.ctx.Done():
|
||||
sd.errFlag = ErrContextDone
|
||||
sd.setDone(nil)
|
||||
return fmt.Errorf("%w, swarm deployment skipped", ErrContextDone)
|
||||
default:
|
||||
}
|
||||
@ -186,3 +188,19 @@ func (sd *SwarmDeployer) Deploy() error {
|
||||
sd.setDone(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sd *SwarmDeployer) Destroy() error {
|
||||
sd.processing.Store(true)
|
||||
defer sd.processing.Store(false)
|
||||
|
||||
log.Info().Str("project", sd.project.Name).Msg("destroying swarm project...")
|
||||
if _, err := sd.conn.Execute(fmt.Sprintf("docker stack rm %s", sd.project.Name)); err != nil {
|
||||
sd.setDone(err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Msg("swarm undeployment done with success")
|
||||
|
||||
sd.setDone(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
24
main.go
24
main.go
@ -136,7 +136,7 @@ func initDeployers(
|
||||
// generateTasksTree returns a list of linked `Task` to submit.
|
||||
//
|
||||
// It's here that all tasks are linked each other to provide the deployment ordering.
|
||||
func generateTasksTree(deployers []deployers.IDeployer) ([]*scheduler.Task, error) {
|
||||
func generateTasksTree(deployers []deployers.IDeployer, destroy bool) ([]*scheduler.Task, error) {
|
||||
if len(deployers) != MaxDeployers {
|
||||
return nil, fmt.Errorf("%w, deployers len should be equals to 2", ErrGenerateTasksTree)
|
||||
}
|
||||
@ -146,6 +146,13 @@ func generateTasksTree(deployers []deployers.IDeployer) ([]*scheduler.Task, erro
|
||||
|
||||
tasks := []*scheduler.Task{}
|
||||
|
||||
if destroy {
|
||||
swarmDestroy := scheduler.NewTask("swarm-destroy", sd.Destroy)
|
||||
destroyTask := scheduler.NewTask("nginx-destroy", nd.Destroy, swarmDestroy)
|
||||
tasks = append(tasks, destroyTask)
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
var swarmTask *scheduler.Task
|
||||
if nd != nil {
|
||||
deployNginx := scheduler.NewTask("nginx-deploy", nd.Deploy)
|
||||
@ -164,7 +171,11 @@ func generateTasksTree(deployers []deployers.IDeployer) ([]*scheduler.Task, erro
|
||||
//
|
||||
// After the completion, deployers `Clear` methods are executed to clean all ressources.
|
||||
// Then the scheduler is stopped to terminate the engine.
|
||||
func waitForCompletion(deployers []deployers.IDeployer, s *scheduler.Scheduler) error {
|
||||
func waitForCompletion(
|
||||
deployers []deployers.IDeployer,
|
||||
s *scheduler.Scheduler,
|
||||
destroy bool,
|
||||
) error {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for idx := range deployers {
|
||||
@ -183,7 +194,9 @@ func waitForCompletion(deployers []deployers.IDeployer, s *scheduler.Scheduler)
|
||||
for idx := range deployers {
|
||||
if d := deployers[idx]; d != nil {
|
||||
errs = append(errs, d.Error())
|
||||
s.Submit(scheduler.NewTask(string(d.Type()), d.Clear)) //nolint: errcheck // TODO
|
||||
if !destroy {
|
||||
s.Submit(scheduler.NewTask(string(d.Type()), d.Clear)) //nolint: errcheck // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,6 +217,7 @@ func main() {
|
||||
log.Info().Msg("hmdeploy started")
|
||||
|
||||
projectDir := flag.String("path", ".", "define the .homeserver project root dir")
|
||||
destroy := flag.Bool("destroy", false, "delete the deployed project")
|
||||
flag.Parse()
|
||||
|
||||
hmmap, err := loadHMMap()
|
||||
@ -225,7 +239,7 @@ func main() {
|
||||
log.Fatal().Err(err).Msg("unable to init deployers")
|
||||
}
|
||||
|
||||
tasks, err := generateTasksTree(deployers)
|
||||
tasks, err := generateTasksTree(deployers, *destroy)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("unable to generate tasks tree")
|
||||
}
|
||||
@ -237,7 +251,7 @@ func main() {
|
||||
tasks...,
|
||||
)
|
||||
|
||||
if err := waitForCompletion(deployers, s); err != nil {
|
||||
if err := waitForCompletion(deployers, s, *destroy); err != nil {
|
||||
log.Fatal().
|
||||
Err(err).
|
||||
Str("name", project.Name).
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user