diff options
Diffstat (limited to 'pkg/varlinkapi/images.go')
-rw-r--r-- | pkg/varlinkapi/images.go | 104 |
1 files changed, 62 insertions, 42 deletions
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index fa1a0a109..739a3e582 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -23,7 +23,9 @@ import ( "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/channelwriter" "github.com/containers/libpod/pkg/util" "github.com/containers/libpod/utils" "github.com/containers/storage/pkg/archive" @@ -67,6 +69,7 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error { Containers: int64(len(containers)), Labels: labels, IsParent: isParent, + ReadOnly: image.IsReadOnly(), } imageList = append(imageList, i) } @@ -107,6 +110,7 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, id string) error { Containers: int64(len(containers)), Labels: labels, TopLayer: newImage.TopLayer(), + ReadOnly: newImage.IsReadOnly(), } return call.ReplyGetImage(il) } @@ -371,7 +375,6 @@ func (i *LibpodAPI) PushImage(call iopodman.VarlinkCall, name, tag string, compr done = true default: if !call.WantsMore() { - time.Sleep(1 * time.Second) break } br := iopodman.MoreResponse{ @@ -495,6 +498,19 @@ func (i *LibpodAPI) DeleteUnusedImages(call iopodman.VarlinkCall) error { // Commit ... func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, changes []string, author, message string, pause bool, manifestType string) error { + var ( + newImage *image.Image + log []string + mimeType string + ) + output := channelwriter.NewChannelWriter() + channelClose := func() { + if err := output.Close(); err != nil { + logrus.Errorf("failed to close channel writer: %q", err) + } + } + defer channelClose() + ctr, err := i.Runtime.LookupContainer(name) if err != nil { return call.ReplyContainerNotFound(name, err.Error()) @@ -504,7 +520,6 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch return call.ReplyErrorOccurred(err.Error()) } sc := image.GetSystemContext(rtc.SignaturePolicyPath, "", false) - var mimeType string switch manifestType { case "oci", "": //nolint mimeType = buildah.OCIv1ImageManifest @@ -515,7 +530,7 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch } coptions := buildah.CommitOptions{ SignaturePolicyPath: rtc.SignaturePolicyPath, - ReportWriter: nil, + ReportWriter: output, SystemContext: sc, PreferredManifestType: mimeType, } @@ -527,11 +542,36 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch Author: author, } - newImage, err := ctr.Commit(getContext(), imageName, options) + if call.WantsMore() { + call.Continues = true + } + + c := make(chan error) + defer close(c) + + go func() { + newImage, err = ctr.Commit(getContext(), imageName, options) + if err != nil { + c <- err + } + c <- nil + }() + + // reply is the func being sent to the output forwarder. in this case it is replying + // with a more response struct + reply := func(br iopodman.MoreResponse) error { + return call.ReplyCommit(br) + } + log, err = forwardOutput(log, c, call.WantsMore(), output, reply) if err != nil { return call.ReplyErrorOccurred(err.Error()) } - return call.ReplyCommit(newImage.ID()) + call.Continues = false + br := iopodman.MoreResponse{ + Logs: log, + Id: newImage.ID(), + } + return call.ReplyCommit(br) } // ImportImage imports an image from a tarball to the image store @@ -583,6 +623,7 @@ func (i *LibpodAPI) ExportImage(call iopodman.VarlinkCall, name, destination str func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { var ( imageID string + err error ) dockerRegistryOptions := image.DockerRegistryOptions{} so := image.SigningOptions{} @@ -590,8 +631,16 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { if call.WantsMore() { call.Continues = true } - output := bytes.NewBuffer([]byte{}) + output := channelwriter.NewChannelWriter() + channelClose := func() { + if err := output.Close(); err != nil { + logrus.Errorf("failed to close channel writer: %q", err) + } + } + defer channelClose() c := make(chan error) + defer close(c) + go func() { if strings.HasPrefix(name, dockerarchive.Transport.Name()+":") { srcRef, err := alltransports.ParseImageName(name) @@ -613,44 +662,17 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { } } c <- nil - close(c) }() var log []string - done := false - for { - line, err := output.ReadString('\n') - if err == nil { - log = append(log, line) - continue - } else if err == io.EOF { - select { - case err := <-c: - if err != nil { - logrus.Errorf("reading of output during pull failed for %s", name) - return call.ReplyErrorOccurred(err.Error()) - } - done = true - default: - if !call.WantsMore() { - time.Sleep(1 * time.Second) - break - } - br := iopodman.MoreResponse{ - Logs: log, - } - call.ReplyPullImage(br) - log = []string{} - } - } else { - return call.ReplyErrorOccurred(err.Error()) - } - if done { - break - } + reply := func(br iopodman.MoreResponse) error { + return call.ReplyPullImage(br) + } + log, err = forwardOutput(log, c, call.WantsMore(), output, reply) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) } call.Continues = false - br := iopodman.MoreResponse{ Logs: log, Id: imageID, @@ -709,7 +731,7 @@ func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall, all bool) error { func (i *LibpodAPI) ImageSave(call iopodman.VarlinkCall, options iopodman.ImageSaveOptions) error { newImage, err := i.Runtime.ImageRuntime().NewFromLocal(options.Name) if err != nil { - if errors.Cause(err) == libpod.ErrNoSuchImage { + if errors.Cause(err) == define.ErrNoSuchImage { return call.ReplyImageNotFound(options.Name, err.Error()) } return call.ReplyErrorOccurred(err.Error()) @@ -764,7 +786,6 @@ func (i *LibpodAPI) ImageSave(call iopodman.VarlinkCall, options iopodman.ImageS done = true default: if !call.WantsMore() { - time.Sleep(1 * time.Second) break } br := iopodman.MoreResponse{ @@ -844,7 +865,6 @@ func (i *LibpodAPI) LoadImage(call iopodman.VarlinkCall, name, inputFile string, done = true default: if !call.WantsMore() { - time.Sleep(1 * time.Second) break } br := iopodman.MoreResponse{ |