This repository has been archived by the owner on May 22, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
116 lines (91 loc) · 3.31 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
import (
"github.com/francoishill/golang-common-ddd/Implementations/Logger/DefaultLogger"
. "github.com/francoishill/golang-web-dry/errors/checkerror"
"github.com/ghodss/yaml"
"io/ioutil"
"log"
"os"
"strings"
"github.com/francoishill/simple-continuous-deployment/pipeline"
"github.com/francoishill/simple-continuous-deployment/ssh_rsync"
)
type setup struct {
SshPrivateKeyPath string `json:"ssh_private_key_path"`
RemoteUser string `json:"remote_user"`
RemoteHost string `json:"remote_host"`
RemotePort int `json:"remote_port"`
BaseRemoteDir string `json:"base_remote_dir"`
StaticDirs []string `json:"static_dirs"`
StaticFiles []string `json:"static_files"`
ExecFiles []string `json:"exec_files"`
StopCmd string `json:"stop_cmd"`
StartCmd string `json:"start_cmd"`
}
func (s *setup) Validate() {
if strings.TrimSpace(s.BaseRemoteDir) == "" {
panic("Please specify BaseRemoteDir")
}
}
func loadSetup() (s *setup, baseLocalDir string) {
if len(os.Args) < 3 {
log.Fatal("Command-line requires two arguments, namely the yaml setup and the base-local-dir")
}
ymlSetupFile := os.Args[1]
baseLocalDir = os.Args[2]
yamlBytes, err := ioutil.ReadFile(ymlSetupFile)
CheckError(err)
s = &setup{}
err = yaml.Unmarshal(yamlBytes, s)
CheckError(err)
s.Validate()
return
}
func main() {
logger := DefaultLogger.New("rolling.log", "[SCD]", true)
defer func() {
if r := recover(); r != nil {
logger.Emergency("Application startup failed: %+v", r)
}
}()
s, baseLocalDir := loadSetup()
client := ssh_rsync.NewBuilder(logger).
PrivateKeyPath(s.SshPrivateKeyPath).
User(s.RemoteUser).Host(s.RemoteHost).Port(s.RemotePort).
Build()
pendingCtx := &pipeline.PipelineContext{
LocalBaseDir: baseLocalDir,
RemoteBaseDir: s.BaseRemoteDir + "_pending",
}
backupCtx := &pipeline.PipelineContext{
LocalBaseDir: baseLocalDir,
RemoteBaseDir: s.BaseRemoteDir + "_backup",
}
finalCtx := &pipeline.PipelineContext{
LocalBaseDir: baseLocalDir,
RemoteBaseDir: s.BaseRemoteDir,
}
dirFlags := "-vrz"
fileFlags := "-vz"
steps := []pipeline.PipelineStep{}
steps = append(steps, pipeline.NewForceRemoveRemoteDirectoryStep(pendingCtx, true, "/"))
for _, d := range s.StaticDirs {
steps = append(steps, pipeline.NewRsyncUploadStep(pendingCtx, true, d, d, dirFlags))
}
for _, f := range s.StaticFiles {
steps = append(steps, pipeline.NewRsyncUploadStep(pendingCtx, false, f, f, fileFlags))
}
steps = append(steps, pipeline.NewSetRemotePermissionsStep(pendingCtx, true, "/", "755"))
steps = append(steps, pipeline.NewSetRemotePermissionsStep(pendingCtx, false, "/", "645"))
for _, ef := range s.ExecFiles {
steps = append(steps, pipeline.NewRsyncUploadStep(pendingCtx, false, ef, ef, fileFlags))
steps = append(steps, pipeline.NewSetRemotePermissionsStep(pendingCtx, false, ef, "755"))
}
steps = append(steps, pipeline.NewForceRemoveRemoteDirectoryStep(backupCtx, true, "/"))
steps = append(steps, pipeline.NewRemoteSSHCommandStep(s.StopCmd))
steps = append(steps, pipeline.NewMoveRemoteDirectoryStep(finalCtx, backupCtx, "/"))
steps = append(steps, pipeline.NewMoveRemoteDirectoryStep(pendingCtx, finalCtx, "/"))
steps = append(steps, pipeline.NewRemoteSSHCommandStep(s.StartCmd))
pipeline := pipeline.NewPipeline(steps)
pipeline.ExecuteAll(logger, client)
}