Skip to content

Commit

Permalink
podman save use named pipe
Browse files Browse the repository at this point in the history
podman save uses named pipe as output path, not directly using /dev/stdout.
fix containers#7017

Signed-off-by: Qi Wang <qiwan@redhat.com>
  • Loading branch information
QiWang19 committed Aug 7, 2020
1 parent 51159e7 commit 6890d2c
Showing 1 changed file with 53 additions and 4 deletions.
57 changes: 53 additions & 4 deletions cmd/podman/images/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ package images

import (
"context"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"syscall"

"github.com/containers/podman/v2/libpod/define"
"golang.org/x/crypto/ssh/terminal"

"github.com/containers/podman/v2/cmd/podman/parse"
"github.com/containers/podman/v2/cmd/podman/registry"
Expand All @@ -14,7 +19,6 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/crypto/ssh/terminal"
)

var validFormats = []string{define.OCIManifestDir, define.OCIArchive, define.V2s2ManifestDir, define.V2s2Archive}
Expand Down Expand Up @@ -85,7 +89,10 @@ func saveFlags(flags *pflag.FlagSet) {

func save(cmd *cobra.Command, args []string) error {
var (
tags []string
tags []string
pipePath string
cleanup func() error
err error
)
if cmd.Flag("compress").Changed && (saveOpts.Format != define.OCIManifestDir && saveOpts.Format != define.V2s2ManifestDir && saveOpts.Format == "") {
return errors.Errorf("--compress can only be set when --format is either 'oci-dir' or 'docker-dir'")
Expand All @@ -95,13 +102,55 @@ func save(cmd *cobra.Command, args []string) error {
if terminal.IsTerminal(int(fi.Fd())) {
return errors.Errorf("refusing to save to terminal. Use -o flag or redirect")
}
saveOpts.Output = "/dev/stdout"
pipePath, cleanup, err = setupPipe()
if err != nil {
return err
}
saveOpts.Output = pipePath
}
if err := parse.ValidateFileName(saveOpts.Output); err != nil {
return err
}
if len(args) > 1 {
tags = args[1:]
}
return registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts)
// return registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts)
err = registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts)
if err != nil {
return err
}
if cleanup != nil {
if err = cleanup(); err != nil {
return err
}
}
return nil
}

func setupPipe() (string, func() error, error) {
errc := make(chan error)
pipeDir, err := ioutil.TempDir(os.TempDir(), "pipeDir")
if err != nil {
return "", nil, err
}
pipePath := filepath.Join(pipeDir, "saveio")
err = syscall.Mkfifo(pipePath, 0600)
if err != nil {
return "", nil, errors.Wrapf(err, "error creating named pipe")
}
go func() {
fpipe, err := os.Open(pipePath)
if err != nil {
errc <- err
return
}
_, err = io.Copy(os.Stdout, fpipe)
fpipe.Close()
errc <- err
}()
return pipePath, func() error {
err := <-errc
os.RemoveAll(pipeDir)
return err
}, nil
}

0 comments on commit 6890d2c

Please sign in to comment.