github.com/masahide/goansible@v0.0.0-20160116054156-01eac649e9f2/procmgmt/upstart/upstart.go (about) 1 package upstart 2 3 import ( 4 "fmt" 5 "github.com/masahide/goansible" 6 us "github.com/masahide/goansible/upstart" 7 "io/ioutil" 8 "path/filepath" 9 "strings" 10 ) 11 12 type Install struct { 13 Name string `goansible:"name"` 14 File string `goansible:"file"` 15 } 16 17 func (d *Install) Run(env *goansible.CommandEnv) (*goansible.Result, error) { 18 dest := filepath.Join("/etc/init", d.Name+".conf") 19 20 cpy := &goansible.CopyCmd{ 21 Src: d.File, 22 Dest: dest, 23 } 24 25 res, err := cpy.Run(env) 26 if err != nil { 27 return nil, err 28 } 29 30 res.Add("name", d.Name) 31 32 return res, nil 33 } 34 35 type Daemon struct { 36 Name string `goansible:"name"` 37 Command string `goansible:"command"` 38 Foreground bool `goansible:"foreground"` 39 OneFork bool `goansible:"one_fork"` 40 Instance string `goansible:"instance"` 41 PreStart string `goansible:"pre_start"` 42 PostStart string `goansible:"post_start"` 43 PreStop string `goansible:"pre_stop"` 44 PostStop string `goansible:"post_stop"` 45 Env map[string]string `goansible:"env"` 46 } 47 48 func setScript(env *goansible.CommandEnv, code *us.Code, val string) error { 49 if val == "" { 50 return nil 51 } 52 53 if val[0] == '@' { 54 body, err := ioutil.ReadFile(env.Paths.File(val[1:])) 55 if err != nil { 56 return err 57 } 58 59 code.Script = us.Script(body) 60 } else { 61 code.Script = us.Script(val) 62 } 63 64 return nil 65 } 66 67 func (d *Daemon) Run(env *goansible.CommandEnv) (*goansible.Result, error) { 68 cfg := us.DaemonConfig(d.Name, d.Command) 69 cfg.Env = d.Env 70 71 if d.Foreground { 72 cfg.Foreground() 73 } 74 75 if d.OneFork { 76 cfg.Expect = "fork" 77 } 78 79 err := setScript(env, &cfg.PreStart, d.PreStart) 80 if err != nil { 81 return nil, err 82 } 83 84 err = setScript(env, &cfg.PostStart, d.PostStart) 85 if err != nil { 86 return nil, err 87 } 88 89 err = setScript(env, &cfg.PreStop, d.PreStop) 90 if err != nil { 91 return nil, err 92 } 93 94 err = setScript(env, &cfg.PostStop, d.PostStop) 95 if err != nil { 96 return nil, err 97 } 98 99 cfg.Instance = d.Instance 100 101 err = cfg.Install() 102 if err != nil { 103 return nil, err 104 } 105 106 res := goansible.NewResult(true) 107 res.Add("name", d.Name) 108 109 return res, nil 110 } 111 112 type Task struct { 113 Name string `goansible:"name"` 114 Command string `goansible:"command"` 115 Instance string `goansible:"instance"` 116 PreStart string `goansible:"pre_start"` 117 PostStart string `goansible:"post_start"` 118 PreStop string `goansible:"pre_stop"` 119 PostStop string `goansible:"post_stop"` 120 Env map[string]string `goansible:"env"` 121 } 122 123 func (t *Task) Run(env *goansible.CommandEnv) (*goansible.Result, error) { 124 cfg := us.TaskConfig(t.Name, t.Command) 125 cfg.Env = t.Env 126 127 cfg.Instance = t.Instance 128 129 err := setScript(env, &cfg.PreStart, t.PreStart) 130 if err != nil { 131 return nil, err 132 } 133 134 err = setScript(env, &cfg.PostStart, t.PostStart) 135 if err != nil { 136 return nil, err 137 } 138 139 err = setScript(env, &cfg.PreStop, t.PreStop) 140 if err != nil { 141 return nil, err 142 } 143 144 err = setScript(env, &cfg.PostStop, t.PostStop) 145 if err != nil { 146 return nil, err 147 } 148 149 err = cfg.Install() 150 if err != nil { 151 return nil, err 152 } 153 154 res := goansible.NewResult(true) 155 res.Add("name", t.Name) 156 157 return res, nil 158 } 159 160 type Restart struct { 161 Name string `goansible:"name"` 162 } 163 164 func (r *Restart) Run(env *goansible.CommandEnv) (*goansible.Result, error) { 165 conn, err := us.Dial() 166 if err != nil { 167 return nil, err 168 } 169 170 job, err := conn.Job(r.Name) 171 if err != nil { 172 return nil, err 173 } 174 175 inst, err := job.Restart() 176 if err != nil { 177 return nil, err 178 } 179 180 pid, err := inst.Pid() 181 if err != nil { 182 return nil, err 183 } 184 185 res := goansible.NewResult(true) 186 res.Add("name", r.Name) 187 res.Add("pid", pid) 188 189 return res, nil 190 } 191 192 type Stop struct { 193 Name string `goansible:"name"` 194 } 195 196 func (r *Stop) Run(env *goansible.CommandEnv) (*goansible.Result, error) { 197 conn, err := us.Dial() 198 if err != nil { 199 return nil, err 200 } 201 202 job, err := conn.Job(r.Name) 203 if err != nil { 204 return nil, err 205 } 206 207 err = job.Stop() 208 if err != nil { 209 if strings.Index(err.Error(), "Unknown instance") == 0 { 210 res := goansible.NewResult(false) 211 res.Add("name", r.Name) 212 213 return res, nil 214 } 215 } 216 217 res := goansible.NewResult(true) 218 res.Add("name", r.Name) 219 220 return res, nil 221 } 222 223 type Start struct { 224 Name string `goansible:"name"` 225 Env map[string]string `goansible:"env"` 226 } 227 228 func (r *Start) Run(env *goansible.CommandEnv) (*goansible.Result, error) { 229 conn, err := us.Dial() 230 if err != nil { 231 return nil, err 232 } 233 234 var ienv []string 235 236 for k, v := range r.Env { 237 ienv = append(ienv, fmt.Sprintf("%s=%s", k, v)) 238 } 239 240 job, err := conn.Job(r.Name) 241 if err != nil { 242 return nil, err 243 } 244 245 inst, err := job.StartWithOptions(ienv, true) 246 if err != nil { 247 if strings.Index(err.Error(), "Job is already running") == 0 { 248 res := goansible.NewResult(false) 249 res.Add("name", r.Name) 250 251 return res, nil 252 } 253 return nil, err 254 } 255 256 pid, err := inst.Pid() 257 if err != nil { 258 return nil, err 259 } 260 261 res := goansible.NewResult(true) 262 res.Add("name", r.Name) 263 res.Add("pid", pid) 264 265 return res, nil 266 } 267 268 func init() { 269 goansible.RegisterCommand("upstart/install", &Install{}) 270 goansible.RegisterCommand("upstart/daemon", &Daemon{}) 271 goansible.RegisterCommand("upstart/task", &Task{}) 272 goansible.RegisterCommand("upstart/restart", &Restart{}) 273 goansible.RegisterCommand("upstart/stop", &Stop{}) 274 goansible.RegisterCommand("upstart/start", &Start{}) 275 }