X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b77893f2a8ae755f22615054f2c267d990995e1c..ae970cb115251915c0a8e1052b23acdd2ab70fee:/services/crunch-run/crunchrun.go diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go index a3338ec87f..062126d6ff 100644 --- a/services/crunch-run/crunchrun.go +++ b/services/crunch-run/crunchrun.go @@ -33,6 +33,7 @@ type IArvadosClient interface { Get(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) error Update(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) error Call(method, resourceType, uuid, action string, parameters arvadosclient.Dict, output interface{}) error + CallRaw(method string, resourceType string, uuid string, action string, parameters arvadosclient.Dict) (reader io.ReadCloser, err error) Discovery(key string) (interface{}, error) } @@ -116,6 +117,9 @@ type ContainerRunner struct { cStateLock sync.Mutex cStarted bool // StartContainer() succeeded cCancelled bool // StopContainer() invoked + + enableNetwork string // one of "default" or "always" + networkMode string // passed through to HostConfig.NetworkMode } // SetupSignals sets up signal handling to gracefully terminate the underlying @@ -128,7 +132,6 @@ func (runner *ContainerRunner) SetupSignals() { go func(sig chan os.Signal) { <-sig - log.Print("signal handler calling runner.stop()") runner.stop() signal.Stop(sig) }(runner.SigChan) @@ -533,17 +536,21 @@ func (runner *ContainerRunner) LogNodeInfo() (err error) { }, infoCommand{ label: "Disk Space", - cmd: []string{"df", "-m"}, + cmd: []string{"df", "-m", "/", os.TempDir()}, + }, + infoCommand{ + label: "Disk INodes", + cmd: []string{"df", "-i", "/", os.TempDir()}, }, } // Run commands with informational output to be logged. var out []byte for _, command := range commands { - out, err = exec.Command(command.cmd[0], command.cmd[1:]...).Output() + out, err = exec.Command(command.cmd[0], command.cmd[1:]...).CombinedOutput() if err != nil { - return fmt.Errorf("While running command '%s': %v", - command.cmd[0], err) + return fmt.Errorf("While running command %q: %v", + command.cmd, err) } logger.Println(command.label) for _, line := range strings.Split(string(out), "\n") { @@ -566,19 +573,28 @@ func (runner *ContainerRunner) LogContainerRecord() (err error) { "container", runner.LogCollection.Open("container.json"), } - logger := log.New(w, "container", 0) - - // Convert container record to pretty-printed JSON []byte - rec, err := json.MarshalIndent(runner.Container, "", " ") + // Get Container record JSON from the API Server + reader, err := runner.ArvClient.CallRaw("GET", "containers", runner.Container.UUID, "", nil) if err != nil { - return fmt.Errorf("While converting container record to JSON: %v", err) + return fmt.Errorf("While retrieving container record from the API server: %v", err) } - - // Write JSON record line-by-line - for _, line := range strings.Split(string(rec), "\n") { - logger.Println(line) + defer reader.Close() + // Read the API server response as []byte + json_bytes, err := ioutil.ReadAll(reader) + if err != nil { + return fmt.Errorf("While reading container record API server response: %v", err) + } + // Decode the JSON []byte + var cr map[string]interface{} + if err = json.Unmarshal(json_bytes, &cr); err != nil { + return fmt.Errorf("While decoding the container record JSON response: %v", err) + } + // Re-encode it using indentation to improve readability + enc := json.NewEncoder(w) + enc.SetIndent("", " ") + if err = enc.Encode(cr); err != nil { + return fmt.Errorf("While logging the JSON container record: %v", err) } - err = w.Close() if err != nil { return fmt.Errorf("While closing container.json log: %v", err) @@ -645,6 +661,15 @@ func (runner *ContainerRunner) CreateContainer() error { for k, v := range runner.Container.Environment { runner.ContainerConfig.Env = append(runner.ContainerConfig.Env, k+"="+v) } + + runner.HostConfig = dockerclient.HostConfig{ + Binds: runner.Binds, + CgroupParent: runner.setCgroupParent, + LogConfig: dockerclient.LogConfig{ + Type: "none", + }, + } + if wantAPI := runner.Container.RuntimeConstraints.API; wantAPI != nil && *wantAPI { tok, err := runner.ContainerToken() if err != nil { @@ -655,9 +680,13 @@ func (runner *ContainerRunner) CreateContainer() error { "ARVADOS_API_HOST="+os.Getenv("ARVADOS_API_HOST"), "ARVADOS_API_HOST_INSECURE="+os.Getenv("ARVADOS_API_HOST_INSECURE"), ) - runner.ContainerConfig.NetworkDisabled = false + runner.HostConfig.NetworkMode = runner.networkMode } else { - runner.ContainerConfig.NetworkDisabled = true + if runner.enableNetwork == "always" { + runner.HostConfig.NetworkMode = runner.networkMode + } else { + runner.HostConfig.NetworkMode = "none" + } } var err error @@ -666,14 +695,6 @@ func (runner *ContainerRunner) CreateContainer() error { return fmt.Errorf("While creating container: %v", err) } - runner.HostConfig = dockerclient.HostConfig{ - Binds: runner.Binds, - CgroupParent: runner.setCgroupParent, - LogConfig: dockerclient.LogConfig{ - Type: "none", - }, - } - return runner.AttachStreams() } @@ -1136,6 +1157,14 @@ func main() { cgroupParent := flag.String("cgroup-parent", "docker", "name of container's parent cgroup (ignored if -cgroup-parent-subsystem is used)") cgroupParentSubsystem := flag.String("cgroup-parent-subsystem", "", "use current cgroup for given subsystem as parent cgroup for container") caCertsPath := flag.String("ca-certs", "", "Path to TLS root certificates") + enableNetwork := flag.String("container-enable-networking", "default", + `Specify if networking should be enabled for container. One of 'default', 'always': + default: only enable networking if container requests it. + always: containers always have networking enabled + `) + networkMode := flag.String("container-network-mode", "default", + `Set networking mode for container. Corresponds to Docker network mode (--net). + `) flag.Parse() containerId := flag.Arg(0) @@ -1167,6 +1196,8 @@ func main() { cr.statInterval = *statInterval cr.cgroupRoot = *cgroupRoot cr.expectCgroupParent = *cgroupParent + cr.enableNetwork = *enableNetwork + cr.networkMode = *networkMode if *cgroupParentSubsystem != "" { p := findCgroup(*cgroupParentSubsystem) cr.setCgroupParent = p