aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers.go10
-rw-r--r--pkg/api/handlers/compat/containers_attach.go82
-rw-r--r--pkg/api/handlers/compat/containers_create.go13
-rw-r--r--pkg/api/handlers/compat/exec.go24
-rw-r--r--pkg/bindings/containers/attach.go2
-rw-r--r--pkg/bindings/containers/containers.go2
-rw-r--r--pkg/domain/infra/abi/system.go3
-rw-r--r--pkg/spec/config_linux_cgo.go2
-rw-r--r--pkg/spec/createconfig.go13
-rw-r--r--pkg/spec/spec.go11
-rw-r--r--pkg/specgen/generate/config_linux.go2
-rw-r--r--pkg/specgen/generate/config_linux_cgo.go2
-rw-r--r--pkg/specgen/generate/security.go26
-rw-r--r--pkg/specgen/generate/validate.go6
-rw-r--r--pkg/specgen/specgen.go4
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