diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/images.go | 21 | ||||
-rw-r--r-- | pkg/bindings/containers/containers.go | 5 | ||||
-rw-r--r-- | pkg/bindings/test/containers_test.go | 6 | ||||
-rw-r--r-- | pkg/channel/writer.go | 13 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/helpers.go | 2 | ||||
-rw-r--r-- | pkg/ps/ps.go | 9 | ||||
-rw-r--r-- | pkg/rootless/rootless.go | 25 | ||||
-rw-r--r-- | pkg/specgen/generate/container_create.go | 16 | ||||
-rw-r--r-- | pkg/specgen/generate/oci.go | 15 |
10 files changed, 84 insertions, 30 deletions
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 940b57343..cc67ebcd1 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -20,9 +20,25 @@ import ( "github.com/containers/podman/v2/pkg/domain/entities" "github.com/docker/docker/api/types" "github.com/gorilla/schema" + "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) +// mergeNameAndTagOrDigest creates an image reference as string from the +// provided image name and tagOrDigest which can be a tag, a digest or empty. +func mergeNameAndTagOrDigest(name, tagOrDigest string) string { + if len(tagOrDigest) == 0 { + return name + } + + separator := ":" // default to tag + if _, err := digest.Parse(tagOrDigest); err == nil { + // We have a digest, so let's change the separator. + separator = "@" + } + return fmt.Sprintf("%s%s%s", name, separator, tagOrDigest) +} + func ExportImage(w http.ResponseWriter, r *http.Request) { // 200 ok // 500 server @@ -252,10 +268,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { return } - fromImage := query.FromImage - if len(query.Tag) >= 1 { - fromImage = fmt.Sprintf("%s:%s", fromImage, query.Tag) - } + fromImage := mergeNameAndTagOrDigest(query.FromImage, query.Tag) authConf, authfile, key, err := auth.GetCredentials(r) if err != nil { diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go index 46e4df1d2..708ad06cb 100644 --- a/pkg/bindings/containers/containers.go +++ b/pkg/bindings/containers/containers.go @@ -25,7 +25,7 @@ var ( // the most recent number of containers. The pod and size booleans indicate that pod information and rootfs // size information should also be included. Finally, the sync bool synchronizes the OCI runtime and // container state. -func List(ctx context.Context, filters map[string][]string, all *bool, last *int, size, sync *bool) ([]entities.ListContainer, error) { // nolint:typecheck +func List(ctx context.Context, filters map[string][]string, all *bool, last *int, namespace, size, sync *bool) ([]entities.ListContainer, error) { // nolint:typecheck conn, err := bindings.GetClient(ctx) if err != nil { return nil, err @@ -44,6 +44,9 @@ func List(ctx context.Context, filters map[string][]string, all *bool, last *int if sync != nil { params.Set("sync", strconv.FormatBool(*sync)) } + if namespace != nil { + params.Set("namespace", strconv.FormatBool(*namespace)) + } if filters != nil { filterString, err := bindings.FiltersToString(filters) if err != nil { diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index bf2ceab2a..408b4769d 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -499,7 +499,7 @@ var _ = Describe("Podman containers ", func() { Expect(err).To(BeNil()) _, err = bt.RunTopContainer(&name2, bindings.PFalse, nil) Expect(err).To(BeNil()) - containerLatestList, err := containers.List(bt.conn, nil, nil, &latestContainers, nil, nil) + containerLatestList, err := containers.List(bt.conn, nil, nil, &latestContainers, nil, nil, nil) Expect(err).To(BeNil()) err = containers.Kill(bt.conn, containerLatestList[0].Names[0], "SIGTERM") Expect(err).To(BeNil()) @@ -744,7 +744,7 @@ var _ = Describe("Podman containers ", func() { // Validate list container with id filter filters := make(map[string][]string) filters["id"] = []string{cid} - c, err := containers.List(bt.conn, filters, bindings.PTrue, nil, nil, nil) + c, err := containers.List(bt.conn, filters, bindings.PTrue, nil, nil, nil, nil) Expect(err).To(BeNil()) Expect(len(c)).To(Equal(1)) }) @@ -758,7 +758,7 @@ var _ = Describe("Podman containers ", func() { lastNum := 1 - c, err := containers.List(bt.conn, nil, bindings.PTrue, &lastNum, nil, nil) + c, err := containers.List(bt.conn, nil, bindings.PTrue, &lastNum, nil, nil, nil) Expect(err).To(BeNil()) Expect(len(c)).To(Equal(1)) Expect(c[0].PodName).To(Equal(podName)) diff --git a/pkg/channel/writer.go b/pkg/channel/writer.go index dbb38e416..28c9d7de5 100644 --- a/pkg/channel/writer.go +++ b/pkg/channel/writer.go @@ -1,6 +1,7 @@ package channel import ( + "fmt" "io" "sync" @@ -32,16 +33,24 @@ func (w *writeCloser) Chan() <-chan []byte { } // Write method for WriteCloser -func (w *writeCloser) Write(b []byte) (int, error) { +func (w *writeCloser) Write(b []byte) (bLen int, err error) { + // https://github.com/containers/podman/issues/7896 + // when podman-remote pull image, if it was killed, the server will panic: send on closed channel + // so handle it + defer func() { + if rErr := recover(); rErr != nil { + err = fmt.Errorf("%s", rErr) + } + }() if w == nil || w.ch == nil { return 0, errors.New("use channel.NewWriter() to initialize a WriteCloser") } w.mux.Lock() + defer w.mux.Unlock() buf := make([]byte, len(b)) copy(buf, b) w.ch <- buf - w.mux.Unlock() return len(b), nil } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 9b03503c6..194bb4b48 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -548,7 +548,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri } func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) { - return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Size, &options.Sync) + return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Namespace, &options.Size, &options.Sync) } func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) { diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go index 7d28f1bd3..63f9546be 100644 --- a/pkg/domain/infra/tunnel/helpers.go +++ b/pkg/domain/infra/tunnel/helpers.go @@ -19,7 +19,7 @@ func getContainersByContext(contextWithConnection context.Context, all, ignore b return nil, errors.New("cannot lookup containers and all") } - allContainers, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, bindings.PTrue) + allContainers, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, nil, bindings.PTrue) if err != nil { return nil, err } diff --git a/pkg/ps/ps.go b/pkg/ps/ps.go index 8087507e2..96b2d754f 100644 --- a/pkg/ps/ps.go +++ b/pkg/ps/ps.go @@ -134,15 +134,16 @@ func ListContainerBatch(rt *libpod.Runtime, ctr *libpod.Container, opts entities logrus.Errorf("error getting exited time for %q: %v", c.ID(), err) } + pid, err = c.PID() + if err != nil { + return errors.Wrapf(err, "unable to obtain container pid") + } + if !opts.Size && !opts.Namespace { return nil } if opts.Namespace { - pid, err = c.PID() - if err != nil { - return errors.Wrapf(err, "unable to obtain container pid") - } ctrPID := strconv.Itoa(pid) cgroup, _ = getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "cgroup")) ipc, _ = getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "ipc")) diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go index d02721ea9..799c793d8 100644 --- a/pkg/rootless/rootless.go +++ b/pkg/rootless/rootless.go @@ -2,8 +2,10 @@ package rootless import ( "os" + "sync" "github.com/containers/storage" + "github.com/opencontainers/runc/libcontainer/user" "github.com/pkg/errors" ) @@ -46,3 +48,26 @@ func TryJoinPauseProcess(pausePidPath string) (bool, int, error) { } return became, ret, err } + +var ( + availableGids int64 + availableGidsErr error + availableGidsOnce sync.Once +) + +// GetAvailableGids returns how many GIDs are available in the +// current user namespace. +func GetAvailableGids() (int64, error) { + availableGidsOnce.Do(func() { + idMap, err := user.ParseIDMapFile("/proc/self/gid_map") + if err != nil { + availableGidsErr = err + return + } + availableGids = int64(0) + for _, r := range idMap { + availableGids += r.Count + } + }) + return availableGids, availableGidsErr +} diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index 2ac3b376f..147450703 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -11,6 +11,7 @@ import ( "github.com/containers/podman/v2/pkg/specgen" "github.com/containers/podman/v2/pkg/util" "github.com/containers/storage" + "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -272,6 +273,21 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen. // Security options if len(s.SelinuxOpts) > 0 { options = append(options, libpod.WithSecLabels(s.SelinuxOpts)) + } else { + if pod != nil { + // duplicate the security options from the pod + processLabel, err := pod.ProcessLabel() + if err != nil { + return nil, err + } + if processLabel != "" { + selinuxOpts, err := label.DupSecOpt(processLabel) + if err != nil { + return nil, err + } + options = append(options, libpod.WithSecLabels(selinuxOpts)) + } + } } options = append(options, libpod.WithPrivileged(s.Privileged)) diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index b57ddf1aa..f02432f5b 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -10,7 +10,6 @@ import ( "github.com/containers/podman/v2/libpod/image" "github.com/containers/podman/v2/pkg/rootless" "github.com/containers/podman/v2/pkg/specgen" - "github.com/opencontainers/runc/libcontainer/user" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" "github.com/pkg/errors" @@ -200,7 +199,7 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt } gid5Available := true if isRootless { - nGids, err := GetAvailableGids() + nGids, err := rootless.GetAvailableGids() if err != nil { return nil, err } @@ -360,15 +359,3 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt return configSpec, nil } - -func GetAvailableGids() (int64, error) { - idMap, err := user.ParseIDMapFile("/proc/self/gid_map") - if err != nil { - return 0, err - } - count := int64(0) - for _, r := range idMap { - count += r.Count - } - return count, nil -} |