/
job.go
143 lines (115 loc) · 2.83 KB
/
job.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package upstart
import (
"fmt"
"github.com/godbus/dbus"
)
const (
// Upstart is available on dbus at this "well known" address
upstartServiceDBusPath = "com.ubuntu.Upstart"
// the manager object where all our queries begin
upstartManagerObject = "/com/ubuntu/Upstart"
)
// job represents an Upstart Job.
type job struct {
Name string
}
// StartWithEnv starts this job (an instance, really) with the specified env.
func (j *job) StartWithEnv(env map[string]string) error {
wait := true // TODO
// connect to the system bus
conn, err := dbus.SystemBus()
if err != nil {
return err
}
jobpath, err := j.dbusPath(conn)
if err != nil {
return err
}
// manipulate env map into env arr
envarr := []string{}
for k, v := range env {
envarr = append(envarr, fmt.Sprintf("%s=%s", k, v))
}
// start a job instance based on the env
err = conn.
Object(upstartServiceDBusPath, jobpath).
Call("com.ubuntu.Upstart0_6.Job.Start", 0, envarr, wait).
Store(&jobpath)
if err != nil {
return err
}
return nil
}
// Stop this job by stopping all its instances
func (j *job) Stop() error {
wait := true // TODO
doStop := func(conn *dbus.Conn, inst dbus.ObjectPath) error {
err := conn.
Object(upstartServiceDBusPath, inst).
Call("com.ubuntu.Upstart0_6.Instance.Stop", 0, wait).
Err
if err != nil {
return fmt.Errorf("Failed to stop %s instance %s: %s", j.Name, inst, err)
}
return nil
}
return j.foreachInstance(doStop)
}
// Restart all instances of this job
func (j *job) Restart() error {
wait := true // TODO
doRestart := func(conn *dbus.Conn, inst dbus.ObjectPath) error {
err := conn.
Object(upstartServiceDBusPath, inst).
Call("com.ubuntu.Upstart0_6.Instance.Restart", 0, wait).
Err
if err != nil {
return fmt.Errorf("Failed to restart inst %s: %s", inst, err)
}
return nil
}
return j.foreachInstance(doRestart)
}
//
// Helpers
//
// dbusPath returns the dbus path of the job object.
func (j *job) dbusPath(conn *dbus.Conn) (dbus.ObjectPath, error) {
var jobpath dbus.ObjectPath
// get the job path
err := conn.
Object(upstartServiceDBusPath, upstartManagerObject).
Call("com.ubuntu.Upstart0_6.GetJobByName", 0, j.Name).
Store(&jobpath)
if err != nil {
return jobpath, err
}
return jobpath, nil
}
// execute function 'f' for each instance of this job.
func (j *job) foreachInstance(f func(*dbus.Conn, dbus.ObjectPath) error) error {
conn, err := dbus.SystemBus()
if err != nil {
return err
}
jobpath, err := j.dbusPath(conn)
if err != nil {
return err
}
// list the instances
var instpaths []dbus.ObjectPath
err = conn.
Object(upstartServiceDBusPath, jobpath).
Call("com.ubuntu.Upstart0_6.Job.GetAllInstances", 0).
Store(&instpaths)
if err != nil {
return err
}
for _, inst := range instpaths {
err = f(conn, inst)
if err != nil {
return err
}
}
return nil
}