~rogpeppe/juju-core/438-local-instance-Addresses

« back to all changes in this revision

Viewing changes to upstart/installer.go

  • Committer: William Reade
  • Date: 2012-05-04 13:43:57 UTC
  • mto: This revision was merged to the branch mainline in revision 193.
  • Revision ID: fwereade@gmail.com-20120504134357-trzcbnfhx2eh2c9r
first cut, untested

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package upstart
 
2
 
 
3
import (
 
4
        "errors"
 
5
        "fmt"
 
6
        "io/ioutil"
 
7
        "strings"
 
8
)
 
9
 
 
10
const (
 
11
        descT = `description "%s"
 
12
author "Juju Team <juju@lists.ubuntu.com>"
 
13
`
 
14
        start = `start on runlevel [2345]
 
15
stop on runlevel [!2345]
 
16
respawn
 
17
`
 
18
        envT  = "env %s=%q\n"
 
19
        outT  = "/tmp/%s.output"
 
20
        execT = "exec %s >> %s 2>&1\n"
 
21
)
 
22
 
 
23
// Conf is responsible for defining and installing upstart services.
 
24
type Conf struct {
 
25
        Service
 
26
        Desc string
 
27
        Env  map[string]string
 
28
        Cmd  string
 
29
        Out  string
 
30
}
 
31
 
 
32
// validate returns an error if the service is not adequately defined.
 
33
func (c *Conf) validate() error {
 
34
        if c.Name == "" {
 
35
                return errors.New("missing Name")
 
36
        }
 
37
        if c.InitDir == "" {
 
38
                return errors.New("missing InitDir")
 
39
        }
 
40
        if c.Desc == "" {
 
41
                return errors.New("missing Desc")
 
42
        }
 
43
        if c.Cmd == "" {
 
44
                return errors.New("missing Cmd")
 
45
        }
 
46
        return nil
 
47
}
 
48
 
 
49
// render returns the upstart configuration for the service as a string.
 
50
func (c *Conf) render() (string, error) {
 
51
        if err := c.validate(); err != nil {
 
52
                return "", err
 
53
        }
 
54
        parts := []string{fmt.Sprintf(descT, c.Desc), start}
 
55
        for k, v := range c.Env {
 
56
                parts = append(parts, fmt.Sprintf(envT, k, v))
 
57
        }
 
58
        out := c.Out
 
59
        if out == "" {
 
60
                out = fmt.Sprintf(outT, c.Name)
 
61
        }
 
62
        parts = append(parts, fmt.Sprintf(execT, c.Cmd, out))
 
63
        return strings.Join(parts, ""), nil
 
64
}
 
65
 
 
66
// Install installs and starts the service.
 
67
func (c *Conf) Install() error {
 
68
        conf, err := c.render()
 
69
        if err != nil {
 
70
                return err
 
71
        }
 
72
        if c.Installed() {
 
73
                if err := c.Stop(); err != nil {
 
74
                        return err
 
75
                }
 
76
        }
 
77
        if err := ioutil.WriteFile(c.path(), []byte(conf), 0644); err != nil {
 
78
                return err
 
79
        }
 
80
        return c.Start()
 
81
}
 
82
 
 
83
// InstallCommands returns shell commands to install and start the service.
 
84
func (c *Conf) InstallCommands() ([]string, error) {
 
85
        conf, err := c.render()
 
86
        if err != nil {
 
87
                return nil, err
 
88
        }
 
89
        return []string{
 
90
                fmt.Sprintf("cat >> %c << EOF\n%sEOF\n", c.path(), conf),
 
91
                "start " + c.Name,
 
92
        }, nil
 
93
}