diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/libpod/images_pull.go | 9 | ||||
-rw-r--r-- | pkg/api/handlers/types.go | 2 | ||||
-rw-r--r-- | pkg/api/server/handler_api.go | 17 | ||||
-rw-r--r-- | pkg/bindings/images/pull.go | 1 | ||||
-rw-r--r-- | pkg/bindings/test/images_test.go | 8 | ||||
-rw-r--r-- | pkg/domain/entities/images.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 9 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 9 | ||||
-rw-r--r-- | pkg/hooks/1.0.0/hook.go | 9 | ||||
-rw-r--r-- | pkg/hooks/hooks.go | 6 |
10 files changed, 59 insertions, 13 deletions
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go index 8a2f4f4cf..ad8d1f38e 100644 --- a/pkg/api/handlers/libpod/images_pull.go +++ b/pkg/api/handlers/libpod/images_pull.go @@ -178,10 +178,19 @@ loop: // break out of for/select infinite loop flush() case <-runCtx.Done(): if !failed { + // Send all image id's pulled in 'images' stanza report.Images = images if err := enc.Encode(report); err != nil { logrus.Warnf("Failed to json encode error %q", err.Error()) } + + report.Images = nil + // Pull last ID from list and publish in 'id' stanza. This maintains previous API contract + report.ID = images[len(images)-1] + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to json encode error %q", err.Error()) + } + flush() } break loop // break out of for/select infinite loop diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index 0ccaa95bb..9e503dbb0 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -33,7 +33,7 @@ type LibpodImagesLoadReport struct { } type LibpodImagesPullReport struct { - ID string `json:"id"` + entities.ImagePullReport } // LibpodImagesRemoveReport is the return type for image removal via the rest diff --git a/pkg/api/server/handler_api.go b/pkg/api/server/handler_api.go index f2ce0301b..920811c51 100644 --- a/pkg/api/server/handler_api.go +++ b/pkg/api/server/handler_api.go @@ -34,15 +34,18 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc { } // TODO: Use r.ConnContext when ported to go 1.13 - c := context.WithValue(r.Context(), "decoder", s.Decoder) //nolint - c = context.WithValue(c, "runtime", s.Runtime) //nolint - c = context.WithValue(c, "shutdownFunc", s.Shutdown) //nolint - c = context.WithValue(c, "idletracker", s.idleTracker) //nolint + c := context.WithValue(r.Context(), "decoder", s.Decoder) // nolint + c = context.WithValue(c, "runtime", s.Runtime) // nolint + c = context.WithValue(c, "shutdownFunc", s.Shutdown) // nolint + c = context.WithValue(c, "idletracker", s.idleTracker) // nolint r = r.WithContext(c) - v := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion] - w.Header().Set("API-Version", fmt.Sprintf("%d.%d", v.Major, v.Minor)) - w.Header().Set("Libpod-API-Version", utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String()) + cv := utils.APIVersion[utils.CompatTree][utils.CurrentAPIVersion] + w.Header().Set("API-Version", fmt.Sprintf("%d.%d", cv.Major, cv.Minor)) + + lv := utils.APIVersion[utils.LibpodTree][utils.CurrentAPIVersion].String() + w.Header().Set("Libpod-API-Version", lv) + w.Header().Set("Server", "Libpod/"+lv+" ("+runtime.GOOS+")") h(w, r) } diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go index 261a481a2..2bfbbb2ac 100644 --- a/pkg/bindings/images/pull.go +++ b/pkg/bindings/images/pull.go @@ -89,6 +89,7 @@ func Pull(ctx context.Context, rawImage string, options entities.ImagePullOption mErr = multierror.Append(mErr, errors.New(report.Error)) case len(report.Images) > 0: images = report.Images + case report.ID != "": default: return images, errors.New("failed to parse pull results stream, unexpected input") } diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index e0dd28d7a..681855293 100644 --- a/pkg/bindings/test/images_test.go +++ b/pkg/bindings/test/images_test.go @@ -360,19 +360,19 @@ var _ = Describe("Podman images", func() { rawImage := "docker.io/library/busybox:latest" pulledImages, err := images.Pull(bt.conn, rawImage, entities.ImagePullOptions{}) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred()) Expect(len(pulledImages)).To(Equal(1)) exists, err := images.Exists(bt.conn, rawImage) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred()) Expect(exists).To(BeTrue()) // Make sure the normalization AND the full-transport reference works. _, err = images.Pull(bt.conn, "docker://"+rawImage, entities.ImagePullOptions{}) - Expect(err).To(BeNil()) + Expect(err).NotTo(HaveOccurred()) // The v2 endpoint only supports the docker transport. Let's see if that's really true. _, err = images.Pull(bt.conn, "bogus-transport:bogus.com/image:reference", entities.ImagePullOptions{}) - Expect(err).To(Not(BeNil())) + Expect(err).To(HaveOccurred()) }) }) diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index d0b738934..cad6693fa 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -156,6 +156,8 @@ type ImagePullReport struct { Error string `json:"error,omitempty"` // Images contains the ID's of the images pulled Images []string `json:"images,omitempty"` + // ID contains image id (retained for backwards compatibility) + ID string `json:"id,omitempty"` } // ImagePushOptions are the arguments for pushing images. diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index cc62c3f27..25c0c184f 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -191,6 +191,15 @@ func (ir *ImageEngine) Unmount(ctx context.Context, nameOrIDs []string, options reports := []*entities.ImageUnmountReport{} for _, img := range images { report := entities.ImageUnmountReport{Id: img.ID()} + mounted, _, err := img.Mounted() + if err != nil { + // Errors will be caught in Unmount call below + // Default assumption to mounted + mounted = true + } + if !mounted { + continue + } if err := img.Unmount(options.Force); err != nil { if options.All && errors.Cause(err) == storage.ErrLayerNotMounted { logrus.Debugf("Error umounting image %s, storage.ErrLayerNotMounted", img.ID()) diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 3e99b73b6..d0f90d900 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -389,6 +389,15 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string, } func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrID string, options entities.AttachOptions) error { + ctrs, err := getContainersByContext(ic.ClientCxt, false, false, []string{nameOrID}) + if err != nil { + return err + } + ctr := ctrs[0] + if ctr.State != define.ContainerStateRunning.String() { + return errors.Errorf("you can only attach to running containers") + } + return containers.Attach(ic.ClientCxt, nameOrID, &options.DetachKeys, nil, bindings.PTrue, options.Stdin, options.Stdout, options.Stderr, nil) } diff --git a/pkg/hooks/1.0.0/hook.go b/pkg/hooks/1.0.0/hook.go index 77fbab5aa..244e8800f 100644 --- a/pkg/hooks/1.0.0/hook.go +++ b/pkg/hooks/1.0.0/hook.go @@ -67,7 +67,14 @@ func (hook *Hook) Validate(extensionStages []string) (err error) { return errors.New("missing required property: stages") } - validStages := map[string]bool{"prestart": true, "poststart": true, "poststop": true} + validStages := map[string]bool{ + "createContainer": true, + "createRuntime": true, + "prestart": true, + "poststart": true, + "poststop": true, + "startContainer": true, + } for _, stage := range extensionStages { validStages[stage] = true } diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go index 2a12eceac..6257529ab 100644 --- a/pkg/hooks/hooks.go +++ b/pkg/hooks/hooks.go @@ -120,12 +120,18 @@ func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBi extensionStageHooks[stage] = append(extensionStageHooks[stage], namedHook.hook.Hook) } else { switch stage { + case "createContainer": + config.Hooks.CreateContainer = append(config.Hooks.CreateContainer, namedHook.hook.Hook) + case "createRuntime": + config.Hooks.CreateRuntime = append(config.Hooks.CreateRuntime, namedHook.hook.Hook) case "prestart": config.Hooks.Prestart = append(config.Hooks.Prestart, namedHook.hook.Hook) case "poststart": config.Hooks.Poststart = append(config.Hooks.Poststart, namedHook.hook.Hook) case "poststop": config.Hooks.Poststop = append(config.Hooks.Poststop, namedHook.hook.Hook) + case "startContainer": + config.Hooks.StartContainer = append(config.Hooks.StartContainer, namedHook.hook.Hook) default: return extensionStageHooks, fmt.Errorf("hook %q: unknown stage %q", namedHook.name, stage) } |