aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/images_pull.go9
-rw-r--r--pkg/api/handlers/types.go2
-rw-r--r--pkg/api/server/handler_api.go17
-rw-r--r--pkg/bindings/images/pull.go1
-rw-r--r--pkg/bindings/test/images_test.go8
-rw-r--r--pkg/domain/entities/images.go2
-rw-r--r--pkg/domain/infra/abi/images.go9
-rw-r--r--pkg/domain/infra/tunnel/containers.go9
-rw-r--r--pkg/hooks/1.0.0/hook.go9
-rw-r--r--pkg/hooks/hooks.go6
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)
}