From 64c8fb7c2460eb561c8496f781f26d65443eea59 Mon Sep 17 00:00:00 2001 From: baude Date: Sun, 27 Jan 2019 09:57:44 -0600 Subject: podman-remote import|export addition of import and export for the podman-remote client. This includes the ability to send and receive files between the remote-client and the "podman" host using an upgraded varlink connection. Signed-off-by: baude --- cmd/podman/commands.go | 2 - cmd/podman/container.go | 1 + cmd/podman/export.go | 51 ++++-------------------- cmd/podman/image.go | 1 + cmd/podman/import.go | 77 ++++-------------------------------- cmd/podman/main.go | 2 + cmd/podman/varlink/io.podman.varlink | 5 ++- 7 files changed, 22 insertions(+), 117 deletions(-) (limited to 'cmd') diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index 718717009..d8fdd556f 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -12,8 +12,6 @@ func getAppCommands() []cli.Command { createCommand, diffCommand, execCommand, - exportCommand, - importCommand, killCommand, kubeCommand, loadCommand, diff --git a/cmd/podman/container.go b/cmd/podman/container.go index acbcbb644..29300a6a4 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -8,6 +8,7 @@ import ( var ( containerSubCommands = []cli.Command{ + exportCommand, inspectCommand, } containerDescription = "Manage containers" diff --git a/cmd/podman/export.go b/cmd/podman/export.go index c0e63bd2a..eaa4e38a2 100644 --- a/cmd/podman/export.go +++ b/cmd/podman/export.go @@ -1,12 +1,9 @@ package main import ( - "io/ioutil" "os" - "strconv" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/adapter" "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -43,7 +40,7 @@ func exportCmd(c *cli.Context) error { rootless.SetSkipStorageSetup(true) } - runtime, err := libpodruntime.GetRuntime(c) + runtime, err := adapter.GetRuntime(c) if err != nil { return errors.Wrapf(err, "could not get runtime") } @@ -58,52 +55,18 @@ func exportCmd(c *cli.Context) error { } output := c.String("output") + if runtime.Remote && (output == "/dev/stdout" || len(output) == 0) { + return errors.New("remote client usage must specify an output file (-o)") + } if output == "/dev/stdout" { file := os.Stdout if logrus.IsTerminal(file) { return errors.Errorf("refusing to export to terminal. Use -o flag or redirect") } } + if err := validateFileName(output); err != nil { return err } - - ctr, err := runtime.LookupContainer(args[0]) - if err != nil { - return errors.Wrapf(err, "error looking up container %q", args[0]) - } - - if os.Geteuid() != 0 { - state, err := ctr.State() - if err != nil { - return errors.Wrapf(err, "cannot read container state %q", ctr.ID()) - } - if state == libpod.ContainerStateRunning || state == libpod.ContainerStatePaused { - data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile) - if err != nil { - return errors.Wrapf(err, "cannot read conmon PID file %q", ctr.Config().ConmonPidFile) - } - conmonPid, err := strconv.Atoi(string(data)) - if err != nil { - return errors.Wrapf(err, "cannot parse PID %q", data) - } - became, ret, err := rootless.JoinDirectUserAndMountNS(uint(conmonPid)) - if err != nil { - return err - } - if became { - os.Exit(ret) - } - } else { - became, ret, err := rootless.BecomeRootInUserNS() - if err != nil { - return err - } - if became { - os.Exit(ret) - } - } - } - - return ctr.Export(output) + return runtime.Export(args[0], c.String("output")) } diff --git a/cmd/podman/image.go b/cmd/podman/image.go index a51a90b0e..6b451a1ca 100644 --- a/cmd/podman/image.go +++ b/cmd/podman/image.go @@ -8,6 +8,7 @@ import ( var ( imageSubCommands = []cli.Command{ + importCommand, historyCommand, imageExistsCommand, inspectCommand, diff --git a/cmd/podman/import.go b/cmd/podman/import.go index 144354fa6..661bd5a65 100644 --- a/cmd/podman/import.go +++ b/cmd/podman/import.go @@ -2,16 +2,8 @@ package main import ( "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod/image" - "github.com/containers/libpod/pkg/util" - "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" "github.com/urfave/cli" ) @@ -51,7 +43,7 @@ func importCmd(c *cli.Context) error { return err } - runtime, err := libpodruntime.GetRuntime(c) + runtime, err := adapter.GetRuntime(c) if err != nil { return errors.Wrapf(err, "could not get runtime") } @@ -60,7 +52,6 @@ func importCmd(c *cli.Context) error { var ( source string reference string - writer io.Writer ) args := c.Args() @@ -80,67 +71,13 @@ func importCmd(c *cli.Context) error { return err } - changes := v1.ImageConfig{} - if c.IsSet("change") || c.IsSet("c") { - changes, err = util.GetImageConfig(c.StringSlice("change")) - if err != nil { - return errors.Wrapf(err, "error adding config changes to image %q", source) - } + quiet := c.Bool("quiet") + if runtime.Remote { + quiet = false } - - history := []v1.History{ - {Comment: c.String("message")}, - } - - config := v1.Image{ - Config: changes, - History: history, - } - - writer = nil - if !c.Bool("quiet") { - writer = os.Stderr - } - - // if source is a url, download it and save to a temp file - u, err := url.ParseRequestURI(source) - if err == nil && u.Scheme != "" { - file, err := downloadFromURL(source) - if err != nil { - return err - } - defer os.Remove(file) - source = file - } - - newImage, err := runtime.ImageRuntime().Import(getContext(), source, reference, writer, image.SigningOptions{}, config) + iid, err := runtime.Import(getContext(), source, reference, c.StringSlice("change"), c.String("message"), quiet) if err == nil { - fmt.Println(newImage.ID()) + fmt.Println(iid) } return err } - -// donwloadFromURL downloads an image in the format "https:/example.com/myimage.tar" -// and temporarily saves in it /var/tmp/importxyz, which is deleted after the image is imported -func downloadFromURL(source string) (string, error) { - fmt.Printf("Downloading from %q\n", source) - - outFile, err := ioutil.TempFile("/var/tmp", "import") - if err != nil { - return "", errors.Wrap(err, "error creating file") - } - defer outFile.Close() - - response, err := http.Get(source) - if err != nil { - return "", errors.Wrapf(err, "error downloading %q", source) - } - defer response.Body.Close() - - _, err = io.Copy(outFile, response.Body) - if err != nil { - return "", errors.Wrapf(err, "error saving %s to %s", source, outFile.Name()) - } - - return outFile.Name(), nil -} diff --git a/cmd/podman/main.go b/cmd/podman/main.go index c10590006..1ca8882eb 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -88,9 +88,11 @@ func main() { app.Commands = []cli.Command{ containerCommand, + exportCommand, historyCommand, imageCommand, imagesCommand, + importCommand, infoCommand, inspectCommand, pullCommand, diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 8b02057a1..101232b0c 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -688,7 +688,7 @@ method Commit(name: string, image_name: string, changes: []string, author: strin # ImportImage imports an image from a source (like tarball) into local storage. The image can have additional # descriptions added to it using the message and changes options. See also [ExportImage](ExportImage). -method ImportImage(source: string, reference: string, message: string, changes: []string) -> (image: string) +method ImportImage(source: string, reference: string, message: string, changes: []string, delete: bool) -> (image: string) # ExportImage takes the name or ID of an image and exports it to a destination like a tarball. There is also # a booleon option to force compression. It also takes in a string array of tags to be able to save multiple @@ -1050,6 +1050,9 @@ method ContainerInspectData(name: string) -> (config: string) # development of Podman only and generally should not be used. method ContainerStateData(name: string) -> (config: string) +method SendFile(type: string, length: int) -> (file_handle: string) +method ReceiveFile(path: string, delete: bool) -> (len: int) + # ImageNotFound means the image could not be found by the provided name or ID in local storage. error ImageNotFound (name: string) -- cgit v1.2.3-54-g00ecf