--- a/docker/run.go Sun Jan 14 04:07:43 2018 -0600
+++ b/docker/run.go Sun Jan 14 04:39:16 2018 -0600
@@ -95,7 +95,28 @@
{{.Image}}{{if .Command}} {{.Command}}{{end}}`
// writeScript will write a shell script to the given tempfile for the given commands
-func (r *Run) writeScript(st *state.State, script *os.File, fullEnv []string) (string, string, string, error) {
+func (r *Run) writeScript(st *state.State, fullEnv []string) (string, string, string, error) { + // figure out the current working directory + // now get the absolute path + absPwd, err := filepath.Abs(pwd) + // create the temp file to write the script to + script, err := ioutil.TempFile(absPwd, "convey-script-") + // set scriptFile to the name of the temp file + scriptFile := script.Name() @@ -108,12 +129,10 @@
// bash if you need that kind of control.
scripts, err := environment.SliceMapper(r.Script, fullEnv)
- // set scriptFile to the name of the temp file
- scriptFile := script.Name()
// set the run command argument to the script file
@@ -128,6 +147,115 @@
return scriptFile, entryPoint, commandArg, nil
+// detach will run the container detached +func (r *Run) detach(name, runTemplate string, params map[string]interface{}, st *state.State, logger *gomol.LogAdapter) error { + stdout, stderr, err := DockerOutput(name, runTemplate, params, st) + logger.Errorf("%s", stderr) + cid := strings.TrimSpace(stdout) + logger.Infof("started detached container %s", cid) + logger.Infof("checking for healthcheck") + // check if the container has a health check + hasHealth, err := containerHasHealthCheck(name, cid, st, logger) + healthChan := make(chan error) + logger.Infof("waiting for container to go healthy") + duration := 5 * time.Second + healthy, err := containerIsHealthy(name, cid, st, logger) + logger.Infof("container still not healthy, waiting %v", duration) + logger.Infof("container is ready") + logger.Infof("no healthcheck found") +func (r *Run) mapVariables(fullEnv []string, st *state.State, workSpace string) (map[string]interface{}, error) { + dockerWorkspace := st.Workspace.(*Workspace) + username, err := environment.Mapper(r.User, fullEnv) + image, err := environment.Mapper(r.Image, fullEnv) + hostname, err := environment.Mapper(r.Hostname, fullEnv) + labels, err := st.MapSlice(r.Labels, fullEnv) + workdir, err := environment.Mapper(r.WorkDir, fullEnv) + workspacePath, err := environment.Mapper(dockerWorkspace.mountPoint, fullEnv) + workspaceMount, err := environment.Mapper(workSpace, fullEnv) + return map[string]interface{}{ + "workspacePath": workspacePath, + "workspaceMount": workspaceMount, // Execute runs the run task.
func (r *Run) Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error {
fullEnv := environment.Merge(env, r.Environment)
@@ -165,77 +293,26 @@
// if we're using a script defined in the yaml, create it and override
- // figure out the current working directory
- // now get the absolute path
- absPwd, err := filepath.Abs(pwd)
- // create the temp file to write the script to
- script, err := ioutil.TempFile(absPwd, "convey-script-")
+ scriptFile, entryPoint, commandArg, err = r.writeScript(st, fullEnv) // Be sure to clean up the script on app exit
- cleanupFn := st.CleanupList.Add(func() { os.Remove(script.Name()) })
+ cleanupFn := st.CleanupList.Add(func() { os.Remove(scriptFile) }) // Call cleanup function on defer, which may instead be called
// if the cleanup thread traps a signal.
- scriptFile, entryPoint, commandArg, err = r.writeScript(st, script, fullEnv)
taskLabel := normalize.Normalize(
fmt.Sprintf("convey-%d-task=%s", os.Getpid(), name),
- dockerWorkspace := st.Workspace.(*Workspace)
- username, err := environment.Mapper(r.User, fullEnv)
- image, err := environment.Mapper(r.Image, fullEnv)
- hostname, err := environment.Mapper(r.Hostname, fullEnv)
- labels, err := st.MapSlice(r.Labels, fullEnv)
- workdir, err := environment.Mapper(r.WorkDir, fullEnv)
- workspacePath, err := environment.Mapper(dockerWorkspace.mountPoint, fullEnv)
- workspaceMount, err := environment.Mapper(workSpace, fullEnv)
+ vars, err := r.mapVariables(fullEnv, st, workSpace) @@ -248,84 +325,29 @@
"CPUShares": st.CPUShares,
+ "Hostname": vars["hostname"], "Environment": environment.Prune(fullEnv),
"EntryPoint": entryPoint,
+ "Username": vars["username"], "HealthCheck": r.HealthCheck,
+ "Image": vars["image"], + "Labels": vars["labels"], "Network": st.Network.Name(),
"ScriptFile": scriptFile,
"SSHAgent": st.EnableSSHAgent,
"SSHAuthSock": os.Getenv("SSH_AUTH_SOCK"),
- "WorkspacePath": workspacePath,
- "WorkspaceMount": workspaceMount,
+ "WorkDir": vars["workdir"], + "WorkspacePath": vars["workspacePath"], + "WorkspaceMount": vars["workspaceMount"], - stdout, stderr, err := DockerOutput(name, runTemplate, params, st)
- logger.Errorf("%s", stderr)
- cid := strings.TrimSpace(stdout)
- logger.Infof("started detached container %s", cid)
- logger.Infof("checking for healthcheck")
- // check if the container has a health check
- hasHealth, err := containerHasHealthCheck(name, cid, st, logger)
- healthChan := make(chan error)
- logger.Infof("waiting for container to go healthy")
- duration := 5 * time.Second
- healthy, err := containerIsHealthy(name, cid, st, logger)
- logger.Infof("container still not healthy, waiting %v", duration)
- logger.Infof("container is ready")
- logger.Infof("no healthcheck found")
+ return r.detach(name, runTemplate, params, st, logger) // Mark running so we can detach this container form the network