LEFT | RIGHT |
1 package container | 1 package container |
2 | 2 |
3 import ( | 3 import ( |
4 "fmt" | 4 "fmt" |
5 "launchpad.net/juju-core/state" | 5 "launchpad.net/juju-core/state" |
6 "launchpad.net/juju-core/upstart" | 6 "launchpad.net/juju-core/upstart" |
7 "os" | 7 "os" |
8 "os/exec" | 8 "os/exec" |
9 "path" | |
10 "path/filepath" | 9 "path/filepath" |
11 "strings" | 10 "strings" |
12 ) | 11 ) |
13 | 12 |
14 // Container contains running juju service units. | 13 // Container contains running juju service units. |
15 type Container interface { | 14 type Container interface { |
16 // Deploy deploys the unit into a new container. | 15 // Deploy deploys the unit into a new container. |
17 Deploy(unit *state.Unit) error | 16 Deploy(unit *state.Unit) error |
18 | 17 |
19 // Destroy destroys the unit's container. | 18 // Destroy destroys the unit's container. |
20 Destroy(unit *state.Unit) error | 19 Destroy(unit *state.Unit) error |
21 } | 20 } |
22 | 21 |
23 // TODO: | 22 // Simple is a Container that knows how deploy units within» |
24 //type lxc struct { | |
25 //» name string | |
26 //} | |
27 // | |
28 //func LXC(args...) Container { | |
29 //} | |
30 | |
31 // Simple is a Container that knows how deploy units within | |
32 // the current machine. | 23 // the current machine. |
33 type Simple struct { | 24 type Simple struct { |
34 » VarDir string | 25 » DataDir string |
| 26 » InitDir string |
| 27 } |
| 28 |
| 29 // Config holds information about where containers should |
| 30 // be started. |
| 31 type Config struct { |
| 32 » DataDir string |
35 // InitDir holds the directory where upstart scripts | 33 // InitDir holds the directory where upstart scripts |
36 // will be deployed. If blank, the system default will | 34 // will be deployed. If blank, the system default will |
37 // be used. | 35 // be used. |
38 InitDir string | 36 InitDir string |
| 37 |
| 38 // TODO(rog) add LogDir? |
39 } | 39 } |
40 | 40 |
41 func deslash(s string) string { | 41 func deslash(s string) string { |
42 return strings.Replace(s, "/", "-", -1) | 42 return strings.Replace(s, "/", "-", -1) |
| 43 } |
| 44 |
| 45 func (c *Simple) dirName(unit *state.Unit) string { |
| 46 return filepath.Join(c.DataDir, "units", deslash(unit.Name())) |
43 } | 47 } |
44 | 48 |
45 func (c *Simple) service(unit *state.Unit) *upstart.Service { | 49 func (c *Simple) service(unit *state.Unit) *upstart.Service { |
46 svc := upstart.NewService("juju-agent-" + deslash(unit.Name())) | 50 svc := upstart.NewService("juju-agent-" + deslash(unit.Name())) |
47 if c.InitDir != "" { | 51 if c.InitDir != "" { |
48 svc.InitDir = c.InitDir | 52 svc.InitDir = c.InitDir |
49 } | 53 } |
50 return svc | 54 return svc |
51 } | 55 } |
52 | 56 |
53 func (c *Simple) dirName(unit *state.Unit) string { | 57 func (c *Simple) Deploy(unit *state.Unit) (err error) { |
54 » return filepath.FromSlash(path.Join(c.VarDir, "units", deslash(unit.Name
()))) | |
55 } | |
56 | |
57 func (c *Simple) Deploy(unit *state.Unit) error { | |
58 exe, err := exec.LookPath("jujud") | 58 exe, err := exec.LookPath("jujud") |
59 if err != nil { | 59 if err != nil { |
60 return fmt.Errorf("cannot find executable: %v", err) | 60 return fmt.Errorf("cannot find executable: %v", err) |
61 } | 61 } |
62 conf := &upstart.Conf{ | 62 conf := &upstart.Conf{ |
63 Service: *c.service(unit), | 63 Service: *c.service(unit), |
64 Desc: "juju unit agent for " + unit.Name(), | 64 Desc: "juju unit agent for " + unit.Name(), |
65 Cmd: exe + " unit --unit-name " + unit.Name(), | 65 Cmd: exe + " unit --unit-name " + unit.Name(), |
66 // TODO: Out | 66 // TODO: Out |
67 } | 67 } |
68 dir := c.dirName(unit) | 68 dir := c.dirName(unit) |
69 if err := os.MkdirAll(dir, 0755); err != nil { | 69 if err := os.MkdirAll(dir, 0755); err != nil { |
70 return err | 70 return err |
71 } | 71 } |
72 err = conf.Install() | 72 err = conf.Install() |
73 if err != nil { | 73 if err != nil { |
74 os.Remove(dir) | 74 os.Remove(dir) |
75 return err | 75 return err |
76 } | 76 } |
77 return nil | 77 return nil |
78 } | 78 } |
79 | 79 |
80 func (c *Simple) Destroy(unit *state.Unit) error { | 80 func (c *Simple) Destroy(unit *state.Unit) error { |
81 » svc := c.service(unit) | 81 » if err := c.service(unit).Remove(); err != nil { |
82 » if err := svc.Remove(); err != nil { | |
83 return err | 82 return err |
84 } | 83 } |
85 return os.RemoveAll(c.dirName(unit)) | 84 return os.RemoveAll(c.dirName(unit)) |
86 } | 85 } |
LEFT | RIGHT |