diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/containers.go | 10 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_attach.go | 82 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_create.go | 13 | ||||
-rw-r--r-- | pkg/api/handlers/compat/exec.go | 24 | ||||
-rw-r--r-- | pkg/bindings/containers/attach.go | 2 | ||||
-rw-r--r-- | pkg/bindings/containers/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/system.go | 3 | ||||
-rw-r--r-- | pkg/spec/config_linux_cgo.go | 2 | ||||
-rw-r--r-- | pkg/spec/createconfig.go | 13 | ||||
-rw-r--r-- | pkg/spec/spec.go | 11 | ||||
-rw-r--r-- | pkg/specgen/generate/config_linux.go | 2 | ||||
-rw-r--r-- | pkg/specgen/generate/config_linux_cgo.go | 2 | ||||
-rw-r--r-- | pkg/specgen/generate/security.go | 26 | ||||
-rw-r--r-- | pkg/specgen/generate/validate.go | 6 | ||||
-rw-r--r-- | pkg/specgen/specgen.go | 4 |
15 files changed, 99 insertions, 103 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index 6943b15ff..1ae6a990b 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -319,6 +319,14 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, SizeRootFs: &inspect.SizeRootFs, } + // set Path and Args + processArgs := l.Config().Spec.Process.Args + if len(processArgs) > 0 { + cb.Path = processArgs[0] + } + if len(processArgs) > 1 { + cb.Args = processArgs[1:] + } stopTimeout := int(l.StopTimeout()) exposedPorts := make(nat.PortSet) @@ -346,7 +354,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, OpenStdin: inspect.Config.OpenStdin, StdinOnce: inspect.Config.StdinOnce, Env: inspect.Config.Env, - Cmd: inspect.Config.Cmd, + Cmd: l.Command(), Healthcheck: nil, ArgsEscaped: false, Image: imageName, diff --git a/pkg/api/handlers/compat/containers_attach.go b/pkg/api/handlers/compat/containers_attach.go index 2d63ac56d..e20d48d86 100644 --- a/pkg/api/handlers/compat/containers_attach.go +++ b/pkg/api/handlers/compat/containers_attach.go @@ -1,12 +1,7 @@ package compat import ( - "bufio" - "fmt" - "io" - "net" "net/http" - "strings" "github.com/containers/podman/v2/libpod" "github.com/containers/podman/v2/libpod/define" @@ -97,75 +92,30 @@ func AttachContainer(w http.ResponseWriter, r *http.Request) { return } - connection, buffer, err := AttachConnection(w, r) - if err != nil { - utils.InternalServerError(w, err) - return - } - logrus.Debugf("Hijack for attach of container %s successful", ctr.ID()) + idleTracker := r.Context().Value("idletracker").(*idletracker.IdleTracker) + hijackChan := make(chan bool, 1) // Perform HTTP attach. // HTTPAttach will handle everything about the connection from here on // (including closing it and writing errors to it). - if err := ctr.HTTPAttach(connection, buffer, streams, detachKeys, nil, query.Stream, query.Logs); err != nil { + if err := ctr.HTTPAttach(r, w, streams, detachKeys, nil, query.Stream, query.Logs, hijackChan); err != nil { + hijackComplete := <-hijackChan + // We can't really do anything about errors anymore. HTTPAttach // should be writing them to the connection. logrus.Errorf("Error attaching to container %s: %v", ctr.ID(), err) - } - logrus.Debugf("Attach for container %s completed successfully", ctr.ID()) -} - -type HijackedConnection struct { - net.Conn // Connection - idleTracker *idletracker.IdleTracker // Connection tracker -} - -func (c HijackedConnection) Close() error { - logrus.Debugf("Hijacked connection closed") - - c.idleTracker.TrackHijackedClosed() - return c.Conn.Close() -} - -func AttachConnection(w http.ResponseWriter, r *http.Request) (net.Conn, *bufio.ReadWriter, error) { - idleTracker := r.Context().Value("idletracker").(*idletracker.IdleTracker) - - // Hijack the connection - hijacker, ok := w.(http.Hijacker) - if !ok { - return nil, nil, errors.Errorf("unable to hijack connection") - } - - connection, buffer, err := hijacker.Hijack() - if err != nil { - return nil, nil, errors.Wrapf(err, "error hijacking connection") - } - trackedConnection := HijackedConnection{ - Conn: connection, - idleTracker: idleTracker, + if hijackComplete { + // We do need to tell the idle tracker that the + // connection has been closed, though. We can guarantee + // that is true after HTTPAttach exits. + idleTracker.TrackHijackedClosed() + } else { + // A hijack was not successfully completed. We need to + // report the error normally. + utils.InternalServerError(w, err) + } } - WriteAttachHeaders(r, trackedConnection) - - return trackedConnection, buffer, nil -} - -func WriteAttachHeaders(r *http.Request, connection io.Writer) { - // AttachHeader is the literal header sent for upgraded/hijacked connections for - // attach, sourced from Docker at: - // https://raw.githubusercontent.com/moby/moby/b95fad8e51bd064be4f4e58a996924f343846c85/api/server/router/container/container_routes.go - // Using literally to ensure compatibility with existing clients. - c := r.Header.Get("Connection") - proto := r.Header.Get("Upgrade") - if len(proto) == 0 || !strings.EqualFold(c, "Upgrade") { - // OK - can't upgrade if not requested or protocol is not specified - fmt.Fprintf(connection, - "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n") - } else { - // Upraded - fmt.Fprintf(connection, - "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: %s\r\n\r\n", - proto) - } + logrus.Debugf("Attach for container %s completed successfully", ctr.ID()) } diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 8238d2d93..93e4fe540 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -87,20 +87,21 @@ func makeCreateConfig(ctx context.Context, containerConfig *config.Config, input workDir = input.WorkingDir } - if input.Entrypoint == nil { - entrypointSlice, err := newImage.Entrypoint(ctx) + // Only use image's Cmd when the user does not set the entrypoint + if input.Entrypoint == nil && len(input.Cmd) == 0 { + cmdSlice, err := newImage.Cmd(ctx) if err != nil { return createconfig.CreateConfig{}, err } - input.Entrypoint = entrypointSlice + input.Cmd = cmdSlice } - if len(input.Cmd) == 0 { - cmdSlice, err := newImage.Cmd(ctx) + if input.Entrypoint == nil { + entrypointSlice, err := newImage.Entrypoint(ctx) if err != nil { return createconfig.CreateConfig{}, err } - input.Cmd = cmdSlice + input.Entrypoint = entrypointSlice } stopTimeout := containerConfig.Engine.StopTimeout diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go index 7a62a2b58..1db950f85 100644 --- a/pkg/api/handlers/compat/exec.go +++ b/pkg/api/handlers/compat/exec.go @@ -10,6 +10,7 @@ import ( "github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/pkg/api/handlers" "github.com/containers/podman/v2/pkg/api/handlers/utils" + "github.com/containers/podman/v2/pkg/api/server/idletracker" "github.com/containers/podman/v2/pkg/specgen/generate" "github.com/gorilla/mux" "github.com/pkg/errors" @@ -173,15 +174,24 @@ func ExecStartHandler(w http.ResponseWriter, r *http.Request) { return } - connection, buffer, err := AttachConnection(w, r) - if err != nil { - utils.InternalServerError(w, err) - return - } - logrus.Debugf("Hijack for attach of container %s exec session %s successful", sessionCtr.ID(), sessionID) + idleTracker := r.Context().Value("idletracker").(*idletracker.IdleTracker) + hijackChan := make(chan bool, 1) + + if err := sessionCtr.ExecHTTPStartAndAttach(sessionID, r, w, nil, nil, nil, hijackChan); err != nil { + hijackComplete := <-hijackChan - if err := sessionCtr.ExecHTTPStartAndAttach(sessionID, connection, buffer, nil, nil, nil); err != nil { logrus.Errorf("Error attaching to container %s exec session %s: %v", sessionCtr.ID(), sessionID, err) + + if hijackComplete { + // We do need to tell the idle tracker that the + // connection has been closed, though. We can guarantee + // that is true after HTTPAttach exits. + idleTracker.TrackHijackedClosed() + } else { + // A hijack was not successfully completed. We need to + // report the error normally. + utils.InternalServerError(w, err) + } } logrus.Debugf("Attach for container %s exec session %s completed successfully", sessionCtr.ID(), sessionID) diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go index c035b6391..3bd85fbae 100644 --- a/pkg/bindings/containers/attach.go +++ b/pkg/bindings/containers/attach.go @@ -46,6 +46,8 @@ func Attach(ctx context.Context, nameOrID string, detachKeys *string, logs, stre stderr = (io.Writer)(nil) } + logrus.Infof("Going to attach to container %q", nameOrID) + conn, err := bindings.GetClient(ctx) if err != nil { return err diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go index c1eb23233..981912665 100644 --- a/pkg/bindings/containers/containers.go +++ b/pkg/bindings/containers/containers.go @@ -13,6 +13,7 @@ import ( "github.com/containers/podman/v2/pkg/bindings" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) var ( @@ -180,6 +181,7 @@ func Restart(ctx context.Context, nameOrID string, timeout *int) error { // or a partial/full ID. The optional parameter for detach keys are to override the default // detach key sequence. func Start(ctx context.Context, nameOrID string, detachKeys *string) error { + logrus.Infof("Going to start container %q", nameOrID) conn, err := bindings.GetClient(ctx) if err != nil { return err diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index 478fac1d5..ff1052d86 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -8,6 +8,7 @@ import ( "os/exec" "path/filepath" "strconv" + "strings" "github.com/containers/common/pkg/config" "github.com/containers/podman/v2/libpod/define" @@ -73,7 +74,7 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command) initCommand, err := ioutil.ReadFile("/proc/1/comm") // On errors, default to systemd - runsUnderSystemd := err != nil || string(initCommand) == "systemd" + runsUnderSystemd := err != nil || strings.TrimRight(string(initCommand), "\n") == "systemd" unitName := fmt.Sprintf("podman-%d.scope", os.Getpid()) if runsUnderSystemd || conf.Engine.CgroupManager == config.SystemdCgroupsManager { diff --git a/pkg/spec/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go index 186a3a788..da92f511f 100644 --- a/pkg/spec/config_linux_cgo.go +++ b/pkg/spec/config_linux_cgo.go @@ -5,10 +5,10 @@ package createconfig import ( "io/ioutil" + goSeccomp "github.com/containers/common/pkg/seccomp" "github.com/containers/podman/v2/pkg/seccomp" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - goSeccomp "github.com/seccomp/containers-golang" "github.com/sirupsen/logrus" ) diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go index c49d51fc5..e0c875fe9 100644 --- a/pkg/spec/createconfig.go +++ b/pkg/spec/createconfig.go @@ -31,12 +31,13 @@ const ( type CreateResourceConfig struct { BlkioWeight uint16 // blkio-weight BlkioWeightDevice []string // blkio-weight-device - CPUPeriod uint64 // cpu-period - CPUQuota int64 // cpu-quota - CPURtPeriod uint64 // cpu-rt-period - CPURtRuntime int64 // cpu-rt-runtime - CPUShares uint64 // cpu-shares - CPUs float64 // cpus + CgroupConf map[string]string + CPUPeriod uint64 // cpu-period + CPUQuota int64 // cpu-quota + CPURtPeriod uint64 // cpu-rt-period + CPURtRuntime int64 // cpu-rt-runtime + CPUShares uint64 // cpu-shares + CPUs float64 // cpus CPUsetCPUs string CPUsetMems string // cpuset-mems DeviceCgroupRules []string //device-cgroup-rule diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index 893ae3cab..5e97620cc 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -180,7 +180,16 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM g.AddMount(cgroupMnt) } g.SetProcessCwd(config.WorkDir) - g.SetProcessArgs(config.Command) + + ProcessArgs := make([]string, 0) + if len(config.Entrypoint) > 0 { + ProcessArgs = config.Entrypoint + } + if len(config.Command) > 0 { + ProcessArgs = append(ProcessArgs, config.Command...) + } + g.SetProcessArgs(ProcessArgs) + g.SetProcessTerminal(config.Tty) for key, val := range config.Annotations { diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go index 35508c023..1d5dcd8e7 100644 --- a/pkg/specgen/generate/config_linux.go +++ b/pkg/specgen/generate/config_linux.go @@ -90,7 +90,7 @@ func DevicesFromPath(g *generate.Generator, devicePath string) error { } st, err := os.Stat(resolvedDevicePath) if err != nil { - return errors.Wrapf(err, "cannot stat %s", devicePath) + return errors.Wrapf(err, "cannot stat device path %s", devicePath) } if st.IsDir() { found := false diff --git a/pkg/specgen/generate/config_linux_cgo.go b/pkg/specgen/generate/config_linux_cgo.go index f35d56750..21a1c910d 100644 --- a/pkg/specgen/generate/config_linux_cgo.go +++ b/pkg/specgen/generate/config_linux_cgo.go @@ -6,12 +6,12 @@ import ( "context" "io/ioutil" + goSeccomp "github.com/containers/common/pkg/seccomp" "github.com/containers/podman/v2/libpod/image" "github.com/containers/podman/v2/pkg/seccomp" "github.com/containers/podman/v2/pkg/specgen" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - goSeccomp "github.com/seccomp/containers-golang" "github.com/sirupsen/logrus" ) diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go index 5e4cc3399..d3e3d9278 100644 --- a/pkg/specgen/generate/security.go +++ b/pkg/specgen/generate/security.go @@ -112,7 +112,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, // Pass capRequiredRequested in CapAdd field to normalize capabilities names capsRequired, err := capabilities.MergeCapabilities(nil, capsRequiredRequested, nil) if err != nil { - logrus.Errorf("capabilities requested by user or image are not valid: %q", strings.Join(capsRequired, ",")) + return errors.Wrapf(err, "capabilities requested by user or image are not valid: %q", strings.Join(capsRequired, ",")) } else { // Verify all capRequiered are in the capList for _, cap := range capsRequired { @@ -129,12 +129,6 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, } } - g.SetProcessNoNewPrivileges(s.NoNewPrivileges) - - if err := setupApparmor(s, rtc, g); err != nil { - return err - } - configSpec := g.Config configSpec.Process.Capabilities.Bounding = caplist @@ -142,13 +136,21 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, configSpec.Process.Capabilities.Effective = caplist configSpec.Process.Capabilities.Permitted = caplist configSpec.Process.Capabilities.Inheritable = caplist - configSpec.Process.Capabilities.Ambient = caplist } else { - configSpec.Process.Capabilities.Effective = []string{} - configSpec.Process.Capabilities.Permitted = []string{} - configSpec.Process.Capabilities.Inheritable = []string{} - configSpec.Process.Capabilities.Ambient = []string{} + userCaps, err := capabilities.NormalizeCapabilities(s.CapAdd) + if err != nil { + return errors.Wrapf(err, "capabilities requested by user are not valid: %q", strings.Join(s.CapAdd, ",")) + } + configSpec.Process.Capabilities.Effective = userCaps + configSpec.Process.Capabilities.Permitted = userCaps } + + g.SetProcessNoNewPrivileges(s.NoNewPrivileges) + + if err := setupApparmor(s, rtc, g); err != nil { + return err + } + // HANDLE SECCOMP if s.SeccompProfilePath != "unconfined" { seccompConfig, err := getSeccompConfig(s, configSpec, newImage) diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go index dca45cc0e..ed337321b 100644 --- a/pkg/specgen/generate/validate.go +++ b/pkg/specgen/generate/validate.go @@ -23,6 +23,12 @@ func verifyContainerResources(s *specgen.SpecGenerator) ([]string, error) { return warnings, nil } + if s.ResourceLimits.Unified != nil { + if !cgroup2 { + return nil, errors.New("Cannot use --cgroup-conf without cgroup v2") + } + } + // Memory checks if s.ResourceLimits.Memory != nil { memory := s.ResourceLimits.Memory diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index a9161071b..a52225f87 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -415,6 +415,10 @@ type ContainerResourceConfig struct { ThrottleReadIOPSDevice map[string]spec.LinuxThrottleDevice `json:"throttleReadIOPSDevice,omitempty"` // IO write rate limit per cgroup per device, IO per second ThrottleWriteIOPSDevice map[string]spec.LinuxThrottleDevice `json:"throttleWriteIOPSDevice,omitempty"` + // CgroupConf are key-value options passed into the container runtime + // that are used to configure cgroup v2. + // Optional. + CgroupConf map[string]string `json:"unified,omitempty"` } // ContainerHealthCheckConfig describes a container healthcheck with attributes |