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  }