Docker ThinDockerClient
// Dispatcher client is initialized with the Dispatcher token.
- // This is a priviledged token used to manage container status
+ // This is a privileged token used to manage container status
// and logs.
//
// We have both dispatcherClient and DispatcherArvClient
ContainerArvClient IArvadosClient
ContainerKeepClient IKeepClient
+ // environment provided by arvados-dispatch-cloud
+ dispatchEnv map[string]interface{}
+
Container arvados.Container
ContainerConfig dockercontainer.Config
HostConfig dockercontainer.HostConfig
return err
}
-// LogNodeRecord logs arvados#node record corresponding to the current host.
+// LogNodeRecord logs the current host's InstanceType config entry (or
+// the arvados#node record, if running via crunch-dispatch-slurm).
func (runner *ContainerRunner) LogNodeRecord() error {
- hostname := os.Getenv("SLURMD_NODENAME")
- if hostname == "" {
- hostname, _ = os.Hostname()
- }
- _, err := runner.logAPIResponse("node", "nodes", map[string]interface{}{"filters": [][]string{{"hostname", "=", hostname}}}, func(resp interface{}) {
- // The "info" field has admin-only info when obtained
- // with a privileged token, and should not be logged.
- node, ok := resp.(map[string]interface{})
- if ok {
- delete(node, "info")
- }
- })
- return err
+ if it, ok := runner.dispatchEnv["InstanceType"]; ok {
+ // Dispatched via arvados-dispatch-cloud. Save
+ // InstanceType config fragment received from
+ // dispatcher on stdin.
+ w, err := runner.LogCollection.OpenFile("node.json", os.O_CREATE|os.O_WRONLY, 0666)
+ if err != nil {
+ return err
+ }
+ defer w.Close()
+ if it, ok := it.(string); ok {
+ // dispatcher supplied JSON data (in order to
+ // stay compatible with old crunch-run
+ // versions)
+ _, err = io.WriteString(w, it)
+ if err != nil {
+ return err
+ }
+ } else {
+ // dispatcher supplied struct
+ enc := json.NewEncoder(w)
+ enc.SetIndent("", " ")
+ err = enc.Encode(it)
+ if err != nil {
+ return err
+ }
+ }
+ return w.Close()
+ } else {
+ // Dispatched via crunch-dispatch-slurm. Look up
+ // apiserver's node record corresponding to
+ // $SLURMD_NODENAME.
+ hostname := os.Getenv("SLURMD_NODENAME")
+ if hostname == "" {
+ hostname, _ = os.Hostname()
+ }
+ _, err := runner.logAPIResponse("node", "nodes", map[string]interface{}{"filters": [][]string{{"hostname", "=", hostname}}}, func(resp interface{}) {
+ // The "info" field has admin-only info when
+ // obtained with a privileged token, and
+ // should not be logged.
+ node, ok := resp.(map[string]interface{})
+ if ok {
+ delete(node, "info")
+ }
+ })
+ return err
+ }
}
func (runner *ContainerRunner) logAPIResponse(label, path string, params map[string]interface{}, munge func(interface{})) (logged bool, err error) {
flag.Parse()
+ var env map[string]interface{}
if *stdinEnv && !ignoreDetachFlag {
// Load env vars on stdin if asked (but not in a
// detached child process, in which case stdin is
// /dev/null).
- loadEnv(os.Stdin)
+ env = loadEnv(os.Stdin)
}
switch {
os.Exit(1)
}
+ cr.dispatchEnv = env
+
parentTemp, tmperr := cr.MkTempDir("", "crunch-run."+containerId+".")
if tmperr != nil {
log.Fatalf("%s: %v", containerId, tmperr)
}
}
-func loadEnv(rdr io.Reader) {
+func loadEnv(rdr io.Reader) map[string]interface{} {
buf, err := ioutil.ReadAll(rdr)
if err != nil {
log.Fatalf("read stdin: %s", err)
}
- var env map[string]string
+ var env map[string]interface{}
err = json.Unmarshal(buf, &env)
if err != nil {
log.Fatalf("decode stdin: %s", err)
}
for k, v := range env {
- err = os.Setenv(k, v)
- if err != nil {
- log.Fatalf("setenv(%q): %s", k, err)
+ if v, ok := v.(string); ok {
+ err = os.Setenv(k, v)
+ if err != nil {
+ log.Fatalf("setenv(%q): %s", k, err)
+ }
}
}
+ return env
}