9848: Use pointer receiver for all arvadosclient.ArvadosClient methods.
[arvados.git] / sdk / go / crunchrunner / crunchrunner.go
index 081ba50d500babc96fda1af522d9b678c255acb6..5c3d65c56144bab68e322b1040c0fb846e30ddaa 100644 (file)
@@ -11,7 +11,6 @@ import (
        "os"
        "os/exec"
        "os/signal"
-       "path"
        "strings"
        "syscall"
 )
@@ -21,6 +20,7 @@ type TaskDef struct {
        Env                map[string]string `json:"task.env"`
        Stdin              string            `json:"task.stdin"`
        Stdout             string            `json:"task.stdout"`
+       Stderr             string            `json:"task.stderr"`
        Vwd                map[string]string `json:"task.vwd"`
        SuccessCodes       []int             `json:"task.successCodes"`
        PermanentFailCodes []int             `json:"task.permanentFailCodes"`
@@ -81,13 +81,13 @@ func checkOutputFilename(outdir, fn string) error {
        return nil
 }
 
-func setupCommand(cmd *exec.Cmd, taskp TaskDef, outdir string, replacements map[string]string) (stdin, stdout string, err error) {
+func setupCommand(cmd *exec.Cmd, taskp TaskDef, outdir string, replacements map[string]string) (stdin, stdout, stderr string, err error) {
        if taskp.Vwd != nil {
                for k, v := range taskp.Vwd {
                        v = substitute(v, replacements)
                        err = checkOutputFilename(outdir, k)
                        if err != nil {
-                               return "", "", err
+                               return "", "", "", err
                        }
                        os.Symlink(v, outdir+"/"+k)
                }
@@ -98,25 +98,40 @@ func setupCommand(cmd *exec.Cmd, taskp TaskDef, outdir string, replacements map[
                stdin = substitute(taskp.Stdin, replacements)
                cmd.Stdin, err = os.Open(stdin)
                if err != nil {
-                       return "", "", err
+                       return "", "", "", err
                }
        }
 
        if taskp.Stdout != "" {
                err = checkOutputFilename(outdir, taskp.Stdout)
                if err != nil {
-                       return "", "", err
+                       return "", "", "", err
                }
                // Set up stdout redirection
                stdout = outdir + "/" + taskp.Stdout
                cmd.Stdout, err = os.Create(stdout)
                if err != nil {
-                       return "", "", err
+                       return "", "", "", err
                }
        } else {
                cmd.Stdout = os.Stdout
        }
 
+       if taskp.Stderr != "" {
+               err = checkOutputFilename(outdir, taskp.Stderr)
+               if err != nil {
+                       return "", "", "", err
+               }
+               // Set up stderr redirection
+               stderr = outdir + "/" + taskp.Stderr
+               cmd.Stderr, err = os.Create(stderr)
+               if err != nil {
+                       return "", "", "", err
+               }
+       } else {
+               cmd.Stderr = os.Stderr
+       }
+
        if taskp.Env != nil {
                // Set up subprocess environment
                cmd.Env = os.Environ()
@@ -125,7 +140,7 @@ func setupCommand(cmd *exec.Cmd, taskp TaskDef, outdir string, replacements map[
                        cmd.Env = append(cmd.Env, k+"="+v)
                }
        }
-       return stdin, stdout, nil
+       return stdin, stdout, stderr, nil
 }
 
 // Set up signal handlers.  Go sends signal notifications to a "signal
@@ -213,6 +228,10 @@ func runner(api IArvadosClient,
                "$(task.outdir)": outdir,
                "$(task.keep)":   keepmount}
 
+       log.Printf("crunchrunner: $(task.tmpdir)=%v", tmpdir)
+       log.Printf("crunchrunner: $(task.outdir)=%v", outdir)
+       log.Printf("crunchrunner: $(task.keep)=%v", keepmount)
+
        // Set up subprocess
        for k, v := range taskp.Command {
                taskp.Command[k] = substitute(v, replacements)
@@ -222,8 +241,8 @@ func runner(api IArvadosClient,
 
        cmd.Dir = outdir
 
-       var stdin, stdout string
-       stdin, stdout, err = setupCommand(cmd, taskp, outdir, replacements)
+       var stdin, stdout, stderr string
+       stdin, stdout, stderr, err = setupCommand(cmd, taskp, outdir, replacements)
        if err != nil {
                return err
        }
@@ -235,7 +254,10 @@ func runner(api IArvadosClient,
        if stdout != "" {
                stdout = " > " + stdout
        }
-       log.Printf("Running %v%v%v", cmd.Args, stdin, stdout)
+       if stderr != "" {
+               stderr = " 2> " + stderr
+       }
+       log.Printf("Running %v%v%v%v", cmd.Args, stdin, stdout, stderr)
 
        var caughtSignal os.Signal
        sigChan := setupSignals(cmd)
@@ -321,14 +343,23 @@ func main() {
                log.Fatal(err)
        }
 
-       certpath := path.Join(path.Dir(os.Args[0]), "ca-certificates.crt")
-       certdata, err := ioutil.ReadFile(certpath)
-       if err == nil {
-               log.Printf("Using TLS certificates at %v", certpath)
-               certs := x509.NewCertPool()
-               certs.AppendCertsFromPEM(certdata)
-               api.Client.Transport.(*http.Transport).TLSClientConfig.RootCAs = certs
+       // Container may not have certificates installed, so need to look for
+       // /etc/arvados/ca-certificates.crt in addition to normal system certs.
+       var certFiles = []string{
+               "/etc/ssl/certs/ca-certificates.crt", // Debian
+               "/etc/pki/tls/certs/ca-bundle.crt",   // Red Hat
+               "/etc/arvados/ca-certificates.crt",
+       }
+
+       certs := x509.NewCertPool()
+       for _, file := range certFiles {
+               data, err := ioutil.ReadFile(file)
+               if err == nil {
+                       log.Printf("Using TLS certificates at %v", file)
+                       certs.AppendCertsFromPEM(data)
+               }
        }
+       api.Client.Transport.(*http.Transport).TLSClientConfig.RootCAs = certs
 
        jobUuid := os.Getenv("JOB_UUID")
        taskUuid := os.Getenv("TASK_UUID")
@@ -348,7 +379,7 @@ func main() {
        }
 
        var kc IKeepClient
-       kc, err = keepclient.MakeKeepClient(&api)
+       kc, err = keepclient.MakeKeepClient(api)
        if err != nil {
                log.Fatal(err)
        }