-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrun.go
104 lines (84 loc) · 2.08 KB
/
run.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
package main
import (
"fmt"
"io/ioutil"
"os"
"time"
docker "github.com/fsouza/go-dockerclient"
)
type Run struct {
Id string
VolumePath string
Config *Config
Container *docker.Container
Client *docker.Client
Request *Request
Done chan bool
}
type RunResult struct {
ExitCode int `json:"exit_code"`
Output []byte `json:"output"`
Duration string `json:"-"`
}
type Done struct {
*RunResult
error
}
func NewRun(config *Config, client *docker.Client, req *Request) *Run {
id, _ := randomHex(20)
return &Run{
Id: id,
Config: config,
Client: client,
VolumePath: fmt.Sprintf("%s/%s", config.SharedPath, id),
Request: req,
Done: make(chan bool),
}
}
func (run *Run) Setup() error {
container, err := CreateContainer(run.Client, run.Config, run.Request.Image, 60, run.Request.Env)
if err != nil {
return err
}
volumePath := fmt.Sprintf("%s/%s", run.Config.SharedPath, container.Config.Labels["id"])
fullPath := fmt.Sprintf("%s/%s", volumePath, run.Request.Filename)
if err := ioutil.WriteFile(fullPath, []byte(run.Request.Content), 0666); err != nil {
return err
}
run.Container = container
if err := run.Client.StartContainer(container.ID, nil); err != nil {
return err
}
return nil
}
func (run *Run) Start() (*RunResult, error) {
return run.StartExec(run.Container)
}
func (run *Run) StartWithTimeout() (*RunResult, error) {
duration := run.Config.RunDuration
timeout := time.After(duration)
chDone := make(chan Done)
go func() {
res, err := run.Start()
chDone <- Done{res, err}
}()
select {
case done := <-chDone:
return done.RunResult, done.error
case <-timeout:
return nil, fmt.Errorf("Operation timed out after %s", duration.String())
}
}
func (run *Run) Destroy() error {
if run.Container != nil {
destroyContainer(run.Client, run.Container.ID)
}
return os.RemoveAll(run.VolumePath)
}
func destroyContainer(client *docker.Client, id string) error {
return client.RemoveContainer(docker.RemoveContainerOptions{
ID: id,
RemoveVolumes: true,
Force: true,
})
}