From 34739f44131e9c493c4021d119c368c82d080c84 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sun, 24 Oct 2021 22:23:13 +0200 Subject: Replace 'an user' => 'a user' Signed-off-by: Stefan Weil --- pkg/cgroups/cgroups.go | 2 +- pkg/systemd/dbus.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'pkg') diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index f1ef538e4..1debc020c 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -461,7 +461,7 @@ func (c *CgroupControl) CreateSystemdUnit(path string) error { return systemdCreate(path, conn) } -// GetUserConnection returns an user connection to D-BUS +// GetUserConnection returns a user connection to D-BUS func GetUserConnection(uid int) (*systemdDbus.Conn, error) { return systemdDbus.NewConnection(func() (*dbus.Conn, error) { return dbusAuthConnection(uid, dbus.SessionBusPrivate) diff --git a/pkg/systemd/dbus.go b/pkg/systemd/dbus.go index c49f537b6..04aaa117a 100644 --- a/pkg/systemd/dbus.go +++ b/pkg/systemd/dbus.go @@ -84,7 +84,7 @@ func IsSystemdSessionValid(uid int) bool { return true } -// GetDbusConnection returns an user connection to D-BUS +// GetDbusConnection returns a user connection to D-BUS func GetLogindConnection(uid int) (*godbus.Conn, error) { return dbusAuthConnectionLogind(uid) } -- cgit v1.2.3-54-g00ecf From 8887cc7e449602d5ff371de84e24b83e448d8480 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Mon, 18 Oct 2021 15:04:19 -0400 Subject: podman run --memory=0 ... should not set memory limit On Docker this is ignored, and it should be on Podman as well. This is documented in the man page. Fixes: https://github.com/containers/podman/issues/12002 Signed-off-by: Daniel J Walsh --- pkg/specgenutil/specgen.go | 12 +++++++----- test/system/030-run.bats | 5 +++++ 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'pkg') diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 6a6397257..8007e5d8e 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -133,12 +133,14 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOption if err != nil { return nil, errors.Wrapf(err, "invalid value for memory") } - memory.Limit = &ml - if c.MemorySwap == "" { - limit := 2 * ml - memory.Swap = &(limit) + if ml > 0 { + memory.Limit = &ml + if c.MemorySwap == "" { + limit := 2 * ml + memory.Swap = &(limit) + } + hasLimits = true } - hasLimits = true } if m := c.MemoryReservation; len(m) > 0 { mr, err := units.RAMInBytes(m) diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 8640d427a..2900540de 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -67,6 +67,11 @@ echo $rand | 0 | $rand is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime" } +@test "podman run --memory=0 runtime option" { + run_podman run --memory=0 --rm $IMAGE echo hello + is "$output" "hello" "failed to run when --memory is set to 0" +} + # 'run --preserve-fds' passes a number of additional file descriptors into the container @test "podman run --preserve-fds" { skip_if_remote "preserve-fds is meaningless over remote" -- cgit v1.2.3-54-g00ecf From 729310a85170895ee3b508f0aa29dc9d3225e83c Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Mon, 25 Oct 2021 14:30:10 -0400 Subject: If Dockerfile exists in same directory as service, we should not use it. We should only use the Containerfiles/Dockerfiles found in the context directory. Fixes: https://github.com/containers/podman/issues/12054 [NO NEW TESTS NEEDED] It is difficult to setup a test for this in the CI/CD system, but build tests should find if this PR broke anything. Signed-off-by: Daniel J Walsh --- pkg/api/handlers/compat/images_build.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'pkg') diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 606c52e41..6152f1c02 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -151,22 +151,19 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { var m = []string{} if err := json.Unmarshal([]byte(query.Dockerfile), &m); err != nil { // it's not json, assume just a string - m = append(m, query.Dockerfile) + m = []string{filepath.Join(contextDirectory, query.Dockerfile)} } containerFiles = m } else { - containerFiles = []string{"Dockerfile"} + containerFiles = []string{filepath.Join(contextDirectory, "Dockerfile")} if utils.IsLibpodRequest(r) { - containerFiles = []string{"Containerfile"} - if _, err = os.Stat(filepath.Join(contextDirectory, "Containerfile")); err != nil { - if _, err1 := os.Stat(filepath.Join(contextDirectory, "Dockerfile")); err1 == nil { - containerFiles = []string{"Dockerfile"} - } else { + containerFiles = []string{filepath.Join(contextDirectory, "Containerfile")} + if _, err = os.Stat(containerFiles[0]); err != nil { + containerFiles = []string{filepath.Join(contextDirectory, "Dockerfile")} + if _, err1 := os.Stat(containerFiles[0]); err1 != nil { utils.BadRequest(w, "dockerfile", query.Dockerfile, err) } } - } else { - containerFiles = []string{"Dockerfile"} } } -- cgit v1.2.3-54-g00ecf From 0e1f67b725088c4d7425f56e260ddbb44078d11b Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Tue, 26 Oct 2021 21:05:42 +0200 Subject: cgroups: use SessionBusPrivateNoAutoStartup do not start up a dbus daemon if it is not already running. [NO NEW TESTS NEEDED] the fix is in a dependency. Closes: https://github.com/containers/podman/issues/9727 Signed-off-by: Giuseppe Scrivano --- pkg/cgroups/cgroups.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pkg') diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index 1debc020c..d0c090012 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -464,7 +464,7 @@ func (c *CgroupControl) CreateSystemdUnit(path string) error { // GetUserConnection returns a user connection to D-BUS func GetUserConnection(uid int) (*systemdDbus.Conn, error) { return systemdDbus.NewConnection(func() (*dbus.Conn, error) { - return dbusAuthConnection(uid, dbus.SessionBusPrivate) + return dbusAuthConnection(uid, dbus.SessionBusPrivateNoAutoStartup) }) } -- cgit v1.2.3-54-g00ecf From a208bc24de85f78129859586571fcf25b6793f9e Mon Sep 17 00:00:00 2001 From: Matej Vasek Date: Sat, 23 Oct 2021 00:11:41 +0200 Subject: Set DOCKER_HOST in the VM [NO TESTS NEEDED] Signed-off-by: Matej Vasek --- pkg/machine/ignition.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'pkg') diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go index e211f5ea6..42d729458 100644 --- a/pkg/machine/ignition.go +++ b/pkg/machine/ignition.go @@ -304,6 +304,24 @@ machine_enabled=true }, }) + setDockerHost := `export DOCKER_HOST="unix://$(podman info -f "{{.Host.RemoteSocket.Path}}")" +` + + files = append(files, File{ + Node: Node{ + Group: getNodeGrp("root"), + Path: "/etc/profile.d/docker-host.sh", + User: getNodeUsr("root"), + }, + FileEmbedded1: FileEmbedded1{ + Append: nil, + Contents: Resource{ + Source: encodeDataURLPtr(setDockerHost), + }, + Mode: intToPtr(0644), + }, + }) + return files } -- cgit v1.2.3-54-g00ecf From a8332f69460f687d704cd804673b0ccca8fd5403 Mon Sep 17 00:00:00 2001 From: Matej Vasek Date: Mon, 1 Nov 2021 22:30:57 +0100 Subject: Fix swagger definitions [NO TESTS NEEDED] Signed-off-by: Matej Vasek --- pkg/api/server/register_images.go | 4 ++-- pkg/api/server/swagger.go | 14 +++++++++++--- pkg/domain/entities/images.go | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'pkg') diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 95981226c..f66669256 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -103,7 +103,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // 200: - // $ref: "#/responses/DockerImageSummary" + // $ref: "#/responses/DockerImageSummaryResponse" // 500: // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/json"), s.APIHandler(compat.GetImages)).Methods(http.MethodGet) @@ -831,7 +831,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // 200: - // $ref: "#/responses/DockerImageSummary" + // $ref: "#/responses/LibpodImageSummaryResponse" // 500: // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/json"), s.APIHandler(libpod.GetImages)).Methods(http.MethodGet) diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index 0fd66652e..3f8f6f9c5 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -6,6 +6,7 @@ import ( "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities/reports" "github.com/containers/podman/v3/pkg/errorhandling" + docker "github.com/docker/docker/api/types" ) // No such image @@ -134,9 +135,16 @@ type swagPodAlreadyStopped struct { } } -// Image summary -// swagger:response DockerImageSummary -type swagImageSummary struct { +// Image summary for compat API +// swagger:response DockerImageSummaryResponse +type swagDockerImageSummaryResponse struct { + // in:body + Body []docker.ImageSummary +} + +// Image summary for libpod API +// swagger:response LibpodImageSummaryResponse +type swagLibpodImageSummaryResponse struct { // in:body Body []entities.ImageSummary } diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 5a469d981..6d93ad403 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -50,6 +50,7 @@ func (i *Image) Id() string { // nolint return i.ID } +// swagger:model LibpodImageSummary type ImageSummary struct { ID string `json:"Id"` ParentId string // nolint -- cgit v1.2.3-54-g00ecf From 3bd80ac9ae2ea512a5ce9140bedab742910d0513 Mon Sep 17 00:00:00 2001 From: Ondra Machacek Date: Wed, 20 Oct 2021 18:45:56 +0200 Subject: Handle HTTP 409 error messages properly for Pod actions This PR fixes the case when the API return HTTP 409 response. Where the API return the body format different then for other HTTP error codes. Signed-off-by: Ondra Machacek --- pkg/bindings/connection.go | 5 +++++ pkg/bindings/errors.go | 29 +++++++++++++++++++++-------- pkg/bindings/pods/pods.go | 14 ++++++++------ pkg/bindings/test/common_test.go | 17 ++++++++++++++--- pkg/bindings/test/pods_test.go | 26 ++++++++++++++++++++++++++ pkg/domain/infra/tunnel/containers.go | 2 +- pkg/domain/infra/tunnel/images.go | 2 +- pkg/domain/infra/tunnel/network.go | 2 +- pkg/domain/infra/tunnel/secrets.go | 4 ++-- pkg/domain/infra/tunnel/volumes.go | 2 +- pkg/errorhandling/errorhandling.go | 14 ++++++++++++++ 11 files changed, 94 insertions(+), 23 deletions(-) (limited to 'pkg') diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index e2c46e481..2fe86ca39 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -379,6 +379,11 @@ func (h *APIResponse) IsClientError() bool { return h.Response.StatusCode/100 == 4 } +// IsConflictError returns true if the response code is 409 +func (h *APIResponse) IsConflictError() bool { + return h.Response.StatusCode == 409 +} + // IsServerError returns true if the response code is 5xx func (h *APIResponse) IsServerError() bool { return h.Response.StatusCode/100 == 5 diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go index 9c311d912..ec837b39c 100644 --- a/pkg/bindings/errors.go +++ b/pkg/bindings/errors.go @@ -12,17 +12,22 @@ var ( ErrNotImplemented = errors.New("function not implemented") ) -func handleError(data []byte) error { - e := errorhandling.ErrorModel{} - if err := json.Unmarshal(data, &e); err != nil { +func handleError(data []byte, unmarshalErrorInto interface{}) error { + if err := json.Unmarshal(data, unmarshalErrorInto); err != nil { return err } - return e + return unmarshalErrorInto.(error) } // Process drains the response body, and processes the HTTP status code // Note: Closing the response.Body is left to the caller func (h APIResponse) Process(unmarshalInto interface{}) error { + return h.ProcessWithError(unmarshalInto, &errorhandling.ErrorModel{}) +} + +// Process drains the response body, and processes the HTTP status code +// Note: Closing the response.Body is left to the caller +func (h APIResponse) ProcessWithError(unmarshalInto interface{}, unmarshalErrorInto interface{}) error { data, err := ioutil.ReadAll(h.Response.Body) if err != nil { return errors.Wrap(err, "unable to process API response") @@ -33,14 +38,22 @@ func (h APIResponse) Process(unmarshalInto interface{}) error { } return nil } + + if h.IsConflictError() { + return handleError(data, unmarshalErrorInto) + } + // TODO should we add a debug here with the response code? - return handleError(data) + return handleError(data, &errorhandling.ErrorModel{}) } func CheckResponseCode(inError error) (int, error) { - e, ok := inError.(errorhandling.ErrorModel) - if !ok { + switch e := inError.(type) { + case *errorhandling.ErrorModel: + return e.Code(), nil + case *errorhandling.PodConflictErrorModel: + return e.Code(), nil + default: return -1, errors.New("error is not type ErrorModel") } - return e.Code(), nil } diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go index a1a431a3b..3b5832373 100644 --- a/pkg/bindings/pods/pods.go +++ b/pkg/bindings/pods/pods.go @@ -9,6 +9,7 @@ import ( "github.com/containers/podman/v3/pkg/api/handlers" "github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/containers/podman/v3/pkg/errorhandling" jsoniter "github.com/json-iterator/go" ) @@ -97,7 +98,7 @@ func Kill(ctx context.Context, nameOrID string, options *KillOptions) (*entities } defer response.Body.Close() - return &report, response.Process(&report) + return &report, response.ProcessWithError(&report, &errorhandling.PodConflictErrorModel{}) } // Pause pauses all running containers in a given pod. @@ -117,7 +118,7 @@ func Pause(ctx context.Context, nameOrID string, options *PauseOptions) (*entiti } defer response.Body.Close() - return &report, response.Process(&report) + return &report, response.ProcessWithError(&report, &errorhandling.PodConflictErrorModel{}) } // Prune by default removes all non-running pods in local storage. @@ -184,7 +185,7 @@ func Restart(ctx context.Context, nameOrID string, options *RestartOptions) (*en } defer response.Body.Close() - return &report, response.Process(&report) + return &report, response.ProcessWithError(&report, &errorhandling.PodConflictErrorModel{}) } // Remove deletes a Pod from from local storage. The optional force parameter denotes @@ -232,7 +233,8 @@ func Start(ctx context.Context, nameOrID string, options *StartOptions) (*entiti report.Id = nameOrID return &report, nil } - return &report, response.Process(&report) + + return &report, response.ProcessWithError(&report, &errorhandling.PodConflictErrorModel{}) } // Stop stops all containers in a Pod. The optional timeout parameter can be @@ -260,7 +262,7 @@ func Stop(ctx context.Context, nameOrID string, options *StopOptions) (*entities report.Id = nameOrID return &report, nil } - return &report, response.Process(&report) + return &report, response.ProcessWithError(&report, &errorhandling.PodConflictErrorModel{}) } // Top gathers statistics about the running processes in a pod. The nameOrID can be a pod name @@ -316,7 +318,7 @@ func Unpause(ctx context.Context, nameOrID string, options *UnpauseOptions) (*en } defer response.Body.Close() - return &report, response.Process(&report) + return &report, response.ProcessWithError(&report, &errorhandling.PodConflictErrorModel{}) } // Stats display resource-usage statistics of one or more pods. diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go index 91ebe21fc..d996595bf 100644 --- a/pkg/bindings/test/common_test.go +++ b/pkg/bindings/test/common_test.go @@ -225,12 +225,23 @@ func (b *bindingTest) RunTopContainer(containerName *string, podName *string) (s // This method creates a pod with the given pod name. // Podname is an optional parameter func (b *bindingTest) Podcreate(name *string) { + b.PodcreateAndExpose(name, nil) +} + +// This method creates a pod with the given pod name and publish port. +// Podname is an optional parameter +// port is an optional parameter +func (b *bindingTest) PodcreateAndExpose(name *string, port *string) { + command := []string{"pod", "create"} if name != nil { podname := *name - b.runPodman([]string{"pod", "create", "--name", podname}).Wait(45) - } else { - b.runPodman([]string{"pod", "create"}).Wait(45) + command = append(command, "--name", podname) + } + if port != nil { + podport := *port + command = append(command, "--publish", podport) } + b.runPodman(command).Wait(45) } // StringInSlice returns a boolean based on whether a given diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go index 5331cf439..879d4d00d 100644 --- a/pkg/bindings/test/pods_test.go +++ b/pkg/bindings/test/pods_test.go @@ -1,6 +1,7 @@ package test_bindings import ( + "fmt" "net/http" "strings" "time" @@ -9,7 +10,9 @@ import ( "github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/bindings/pods" "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/specgen" + "github.com/containers/podman/v3/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" @@ -208,6 +211,29 @@ var _ = Describe("Podman pods", func() { } }) + It("start pod with port conflict", func() { + randomport, err := utils.GetRandomPort() + Expect(err).To(BeNil()) + + portPublish := fmt.Sprintf("%d:%d", randomport, randomport) + var podwithport string = "newpodwithport" + bt.PodcreateAndExpose(&podwithport, &portPublish) + + // Start pod and expose port 12345 + _, err = pods.Start(bt.conn, podwithport, nil) + Expect(err).To(BeNil()) + + // Start another pod and expose same port 12345 + var podwithport2 string = "newpodwithport2" + bt.PodcreateAndExpose(&podwithport2, &portPublish) + + _, err = pods.Start(bt.conn, podwithport2, nil) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusConflict)) + Expect(err).To(BeAssignableToTypeOf(&errorhandling.PodConflictErrorModel{})) + }) + It("start stop restart pod", func() { // Start an invalid pod _, err = pods.Start(bt.conn, "dummyName", nil) diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index b638bfe24..c4d62bd89 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -226,7 +226,7 @@ func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []st for _, name := range namesOrIds { inspect, err := containers.Inspect(ic.ClientCtx, name, options) if err != nil { - errModel, ok := err.(errorhandling.ErrorModel) + errModel, ok := err.(*errorhandling.ErrorModel) if !ok { return nil, nil, err } diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 9a746d68c..ab2a93c75 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -188,7 +188,7 @@ func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts en for _, i := range namesOrIDs { r, err := images.GetImage(ir.ClientCtx, i, options) if err != nil { - errModel, ok := err.(errorhandling.ErrorModel) + errModel, ok := err.(*errorhandling.ErrorModel) if !ok { return nil, nil, err } diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go index 7e59e44c2..7c183b1ac 100644 --- a/pkg/domain/infra/tunnel/network.go +++ b/pkg/domain/infra/tunnel/network.go @@ -23,7 +23,7 @@ func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []stri for _, name := range namesOrIds { report, err := network.Inspect(ic.ClientCtx, name, options) if err != nil { - errModel, ok := err.(errorhandling.ErrorModel) + errModel, ok := err.(*errorhandling.ErrorModel) if !ok { return nil, nil, err } diff --git a/pkg/domain/infra/tunnel/secrets.go b/pkg/domain/infra/tunnel/secrets.go index 6337c7fbe..e5fa200bd 100644 --- a/pkg/domain/infra/tunnel/secrets.go +++ b/pkg/domain/infra/tunnel/secrets.go @@ -28,7 +28,7 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string for _, name := range nameOrIDs { inspected, err := secrets.Inspect(ic.ClientCtx, name, nil) if err != nil { - errModel, ok := err.(errorhandling.ErrorModel) + errModel, ok := err.(*errorhandling.ErrorModel) if !ok { return nil, nil, err } @@ -67,7 +67,7 @@ func (ic *ContainerEngine) SecretRm(ctx context.Context, nameOrIDs []string, opt for _, name := range nameOrIDs { secret, err := secrets.Inspect(ic.ClientCtx, name, nil) if err != nil { - errModel, ok := err.(errorhandling.ErrorModel) + errModel, ok := err.(*errorhandling.ErrorModel) if !ok { return nil, err } diff --git a/pkg/domain/infra/tunnel/volumes.go b/pkg/domain/infra/tunnel/volumes.go index 2b2b2c2a1..a3d9e1b6d 100644 --- a/pkg/domain/infra/tunnel/volumes.go +++ b/pkg/domain/infra/tunnel/volumes.go @@ -56,7 +56,7 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin for _, id := range namesOrIds { data, err := volumes.Inspect(ic.ClientCtx, id, nil) if err != nil { - errModel, ok := err.(errorhandling.ErrorModel) + errModel, ok := err.(*errorhandling.ErrorModel) if !ok { return nil, nil, err } diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go index 6adbc9f34..fcb0f7881 100644 --- a/pkg/errorhandling/errorhandling.go +++ b/pkg/errorhandling/errorhandling.go @@ -83,6 +83,12 @@ func Contains(err error, sub error) bool { return strings.Contains(err.Error(), sub.Error()) } +// PodConflictErrorModel is used in remote connections with podman +type PodConflictErrorModel struct { + Errs []string + Id string //nolint +} + // ErrorModel is used in remote connections with podman type ErrorModel struct { // API root cause formatted for automated parsing @@ -106,3 +112,11 @@ func (e ErrorModel) Cause() error { func (e ErrorModel) Code() int { return e.ResponseCode } + +func (e PodConflictErrorModel) Error() string { + return strings.Join(e.Errs, ",") +} + +func (e PodConflictErrorModel) Code() int { + return 409 +} -- cgit v1.2.3-54-g00ecf From 718de67f33982e6cc59009b02b4b96c19842b921 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 4 Nov 2021 15:54:28 +0100 Subject: Fix bindings container log test The returned error was not checked, thus the test could hang forever since it blocks on the log channel. Also handle unexpectedEOF like EOF. Fixes #12176 Signed-off-by: Paul Holzinger --- pkg/bindings/containers/attach.go | 4 ++-- pkg/bindings/containers/logs.go | 2 +- pkg/bindings/test/containers_test.go | 7 ++++++- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'pkg') diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go index 725d06648..32a8978d9 100644 --- a/pkg/bindings/containers/attach.go +++ b/pkg/bindings/containers/attach.go @@ -214,7 +214,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri // Read multiplexed channels and write to appropriate stream fd, l, err := DemuxHeader(socket, buffer) if err != nil { - if errors.Is(err, io.EOF) { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { return nil } return err @@ -531,7 +531,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar // Read multiplexed channels and write to appropriate stream fd, l, err := DemuxHeader(socket, buffer) if err != nil { - if errors.Is(err, io.EOF) { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { return nil } return err diff --git a/pkg/bindings/containers/logs.go b/pkg/bindings/containers/logs.go index 67db94487..37ffdf0a5 100644 --- a/pkg/bindings/containers/logs.go +++ b/pkg/bindings/containers/logs.go @@ -39,7 +39,7 @@ func Logs(ctx context.Context, nameOrID string, options *LogOptions, stdoutChan, for { fd, l, err := DemuxHeader(response.Body, buffer) if err != nil { - if errors.Is(err, io.EOF) { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { return nil } return err diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index b9ed67255..0f535bc31 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -259,6 +259,7 @@ var _ = Describe("Podman containers ", func() { _, err = bt.RunTopContainer(&name, nil) Expect(err).To(BeNil()) go func() { + defer GinkgoRecover() exitCode, err = containers.Wait(bt.conn, name, nil) errChan <- err close(errChan) @@ -281,6 +282,7 @@ var _ = Describe("Podman containers ", func() { _, err := bt.RunTopContainer(&name, nil) Expect(err).To(BeNil()) go func() { + defer GinkgoRecover() exitCode, err = containers.Wait(bt.conn, name, new(containers.WaitOptions).WithCondition([]define.ContainerStatus{pause})) errChan <- err close(errChan) @@ -366,7 +368,10 @@ var _ = Describe("Podman containers ", func() { opts := new(containers.LogOptions).WithStdout(true).WithFollow(true) go func() { - containers.Logs(bt.conn, r.ID, opts, stdoutChan, nil) + defer GinkgoRecover() + err := containers.Logs(bt.conn, r.ID, opts, stdoutChan, nil) + close(stdoutChan) + Expect(err).ShouldNot(HaveOccurred()) }() o := <-stdoutChan o = strings.TrimSpace(o) -- cgit v1.2.3-54-g00ecf From 93a3e720d794d8ae028075a20d92a4ab513d0051 Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Fri, 5 Nov 2021 10:12:32 -0700 Subject: Log Apache access_log-like entries at Info level [NO NEW TESTS NEEDED] Only log API access entries when --log-level set to Info or below. Fixes #12181 Signed-off-by: Jhon Honce --- pkg/api/server/handler_rid.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'pkg') diff --git a/pkg/api/server/handler_rid.go b/pkg/api/server/handler_rid.go index b624b99a6..7dcf436f7 100644 --- a/pkg/api/server/handler_rid.go +++ b/pkg/api/server/handler_rid.go @@ -2,6 +2,7 @@ package server import ( "fmt" + "io/ioutil" "net/http" "github.com/containers/podman/v3/pkg/api/types" @@ -15,7 +16,13 @@ import ( // and Apache style request logging func referenceIDHandler() mux.MiddlewareFunc { return func(h http.Handler) http.Handler { - return handlers.CombinedLoggingHandler(logrus.StandardLogger().Out, + // Only log Apache access_log-like entries at Info level or below + out := ioutil.Discard + if logrus.IsLevelEnabled(logrus.InfoLevel) { + out = logrus.StandardLogger().Out + } + + return handlers.CombinedLoggingHandler(out, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rid := r.Header.Get("X-Reference-Id") if rid == "" { -- cgit v1.2.3-54-g00ecf From cedf1a3d43fbb1f0c40cd286ee6c50863560e627 Mon Sep 17 00:00:00 2001 From: Boaz Shuster Date: Sun, 7 Nov 2021 13:21:25 +0200 Subject: podman-generate-kube - remove empty structs from YAML [NO NEW TESTS NEEDED] Signed-off-by: Boaz Shuster --- libpod/kube.go | 78 ++++++++++++++++++++++++++++++++++++++-- pkg/domain/infra/abi/generate.go | 3 +- 2 files changed, 77 insertions(+), 4 deletions(-) (limited to 'pkg') diff --git a/libpod/kube.go b/libpod/kube.go index d2ac15749..b34734513 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -166,9 +166,83 @@ func (v *Volume) GenerateForKube() *v1.PersistentVolumeClaim { } } +// YAMLPodSpec represents the same k8s API core PodSpec struct with a small +// change and that is having Containers as a pointer to YAMLContainer. +// Because Go doesn't omit empty struct and we want to omit Status in YAML +// if it's empty. Fixes: GH-11998 +type YAMLPodSpec struct { + v1.PodSpec + Containers []*YAMLContainer `json:"containers"` +} + +// YAMLPod represents the same k8s API core Pod struct with a small +// change and that is having Spec as a pointer to YAMLPodSpec and +// Status as a pointer to k8s API core PodStatus. +// Because Go doesn't omit empty struct and we want to omit Status in YAML +// if it's empty. Fixes: GH-11998 +type YAMLPod struct { + v1.Pod + Spec *YAMLPodSpec `json:"spec,omitempty"` + Status *v1.PodStatus `json:"status,omitempty"` +} + +// YAMLService represents the same k8s API core Service struct with a small +// change and that is having Status as a pointer to k8s API core ServiceStatus. +// Because Go doesn't omit empty struct and we want to omit Status in YAML +// if it's empty. Fixes: GH-11998 +type YAMLService struct { + v1.Service + Status *v1.ServiceStatus `json:"status,omitempty"` +} + +// YAMLContainer represents the same k8s API core Container struct with a small +// change and that is having Resources as a pointer to k8s API core ResourceRequirements. +// Because Go doesn't omit empty struct and we want to omit Status in YAML +// if it's empty. Fixes: GH-11998 +type YAMLContainer struct { + v1.Container + Resources *v1.ResourceRequirements `json:"resources,omitempty"` +} + +// ConvertV1PodToYAMLPod takes k8s API core Pod and returns a pointer to YAMLPod +func ConvertV1PodToYAMLPod(pod *v1.Pod) *YAMLPod { + cs := []*YAMLContainer{} + for _, cc := range pod.Spec.Containers { + var res *v1.ResourceRequirements = nil + if len(cc.Resources.Limits) > 0 || len(cc.Resources.Requests) > 0 { + res = &cc.Resources + } + cs = append(cs, &YAMLContainer{Container: cc, Resources: res}) + } + mpo := &YAMLPod{Pod: *pod} + mpo.Spec = &YAMLPodSpec{PodSpec: (*pod).Spec, Containers: cs} + for _, ctr := range pod.Spec.Containers { + if ctr.SecurityContext == nil || ctr.SecurityContext.SELinuxOptions == nil { + continue + } + selinuxOpts := ctr.SecurityContext.SELinuxOptions + if selinuxOpts.User == "" && selinuxOpts.Role == "" && selinuxOpts.Type == "" && selinuxOpts.Level == "" { + ctr.SecurityContext.SELinuxOptions = nil + } + } + dnsCfg := pod.Spec.DNSConfig + if dnsCfg != nil && (len(dnsCfg.Nameservers)+len(dnsCfg.Searches)+len(dnsCfg.Options) > 0) { + mpo.Spec.DNSConfig = dnsCfg + } + status := pod.Status + if status.Phase != "" || len(status.Conditions) > 0 || + status.Message != "" || status.Reason != "" || + status.NominatedNodeName != "" || status.HostIP != "" || + status.PodIP != "" || status.StartTime != nil || + len(status.InitContainerStatuses) > 0 || len(status.ContainerStatuses) > 0 || status.QOSClass != "" || len(status.EphemeralContainerStatuses) > 0 { + mpo.Status = &status + } + return mpo +} + // GenerateKubeServiceFromV1Pod creates a v1 service object from a v1 pod object -func GenerateKubeServiceFromV1Pod(pod *v1.Pod, servicePorts []v1.ServicePort) v1.Service { - service := v1.Service{} +func GenerateKubeServiceFromV1Pod(pod *v1.Pod, servicePorts []v1.ServicePort) YAMLService { + service := YAMLService{} selector := make(map[string]string) selector["app"] = pod.Labels["app"] ports := servicePorts diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go index 081a2464b..a4d6bcf86 100644 --- a/pkg/domain/infra/abi/generate.go +++ b/pkg/domain/infra/abi/generate.go @@ -124,8 +124,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, if err != nil { return nil, err } - - b, err := generateKubeYAML(po) + b, err := generateKubeYAML(libpod.ConvertV1PodToYAMLPod(po)) if err != nil { return nil, err } -- cgit v1.2.3-54-g00ecf