grim/convey

84254a76aa89
Parents 3bc8d82a158e
Children f5b544495b15
Initial support for detaching containers. Refs #21
--- a/docker/run.go Tue Sep 05 20:41:11 2017 -0500
+++ b/docker/run.go Tue Sep 05 22:40:24 2017 -0500
@@ -18,6 +18,7 @@
package docker
import (
+ "fmt"
"io/ioutil"
"os"
"os/user"
@@ -34,6 +35,7 @@
type Run struct {
Command string `yaml:"command"`
+ Detach bool `yaml:"detach"`
EntryPoint string `yaml:"entrypoint"`
Environment yaml.StringOrSlice `yaml:"environment"`
Image string `yaml:"image"`
@@ -60,6 +62,7 @@
const runTemplate = `run --rm
{{if .UID}} -e UID={{.UID}}{{end}}
{{if .GID}} -e GID={{.GID}}{{end}}
+{{if .Detach}} -d{{end}}
-v {{.WorkspacePath}}:{{.WorkspaceMount}}
-e CONVEY_WORKSPACE={{.WorkspaceMount}}
{{if .CPUShares }} --cpu-shares {{.CPUShares}}{{end}}
@@ -70,6 +73,7 @@
{{if .WorkDir}} -w {{.WorkDir}}{{end}}
{{if .Network}} --network {{.Network}}{{end}}
{{range .Labels}} -l '{{.}}'{{end}}
+ -l {{.TaskLabel}}
{{range .Environment}} -e {{.}}{{end}}
{{.Image}}{{if .Command}} {{.Command}}{{end}}`
@@ -157,10 +161,13 @@
defer os.Remove(scriptFile)
}
+ taskLabel := fmt.Sprintf("convey-%d-task=%s", os.Getpid(), name)
+
// build the dict for the template
params := map[string]interface{}{
"Command": commandArg,
"CPUShares": st.CPUShares,
+ "Detach": r.Detach,
"Environment": fullEnv,
"EntryPoint": entryPoint,
"GID": user.Gid,
@@ -175,6 +182,21 @@
"WorkDir": environment.Mapper(r.WorkDir, fullEnv),
"WorkspacePath": environment.Mapper(st.Workspace.MountPoint, fullEnv),
"WorkspaceMount": environment.Mapper(workSpace, fullEnv),
+ "TaskLabel": taskLabel,
+ }
+
+ if r.Detach {
+ stdout, _, err := DockerOutput(name, runTemplate, params, st)
+ if err != nil {
+ return err
+ }
+
+ cid := strings.TrimSpace(stdout)
+ st.DetachedContainers = append(st.DetachedContainers, cid)
+
+ logger.Infof("started container %s", cid)
+
+ return nil
}
// run the command
--- a/docker/util.go Tue Sep 05 20:41:11 2017 -0500
+++ b/docker/util.go Tue Sep 05 22:40:24 2017 -0500
@@ -19,6 +19,10 @@
import (
"strings"
+
+ "github.com/aphistic/gomol"
+
+ "bitbucket.org/rw_grim/convey/state"
)
// ParseImage will convert an image like python:3 to it's registry, name, and tag
@@ -42,3 +46,23 @@
return registry, name, tag
}
+
+// StopContainer will call 'docker stop' on the given container id
+func StopContainer(cid string, logger *gomol.LogAdapter, st *state.State) error {
+ template := `stop {{.CID}}`
+
+ params := map[string]interface{}{
+ "CID": cid,
+ }
+
+ _, stderr, err := DockerOutput("stop container", template, params, st)
+ if err != nil {
+ return err
+ }
+
+ if stderr != "" {
+ logger.Warnf("%s", strings.TrimSpace(stderr))
+ }
+
+ return nil
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/detach.yml Tue Sep 05 22:40:24 2017 -0500
@@ -0,0 +1,9 @@
+tasks:
+ background:
+ image: alpine:edge
+ command: sleep 300
+ detach: true
+plans:
+ default:
+ stages:
+ - tasks: [background, background]
--- a/plans/plans.go Tue Sep 05 20:41:11 2017 -0500
+++ b/plans/plans.go Tue Sep 05 22:40:24 2017 -0500
@@ -22,6 +22,7 @@
"github.com/aphistic/gomol"
+ "bitbucket.org/rw_grim/convey/docker"
"bitbucket.org/rw_grim/convey/environment"
"bitbucket.org/rw_grim/convey/logging"
"bitbucket.org/rw_grim/convey/network"
@@ -64,6 +65,13 @@
}
func (p *Plan) teardown(logger *gomol.LogAdapter, st *state.State) {
+ // run through the DetachedContainers and stop them
+ for _, cid := range st.DetachedContainers {
+ logger.Infof("removing detached container %s", cid)
+
+ docker.StopContainer(cid, logger, st)
+ }
+
// remove the workspace (if requested)
if st.KeepWorkspace {
logger.Infof("not removing workspace %s as requested", st.Workspace.Name)
--- a/state/state.go Tue Sep 05 20:41:11 2017 -0500
+++ b/state/state.go Tue Sep 05 22:40:24 2017 -0500
@@ -39,6 +39,8 @@
DockerConfig string
CPUShares string
Memory string
+
+ DetachedContainers []string
}
func (st *State) Valid() error {