load.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package image
  2. import (
  3. "fmt"
  4. "io"
  5. "golang.org/x/net/context"
  6. "github.com/docker/docker/cli"
  7. "github.com/docker/docker/cli/command"
  8. "github.com/docker/docker/pkg/jsonmessage"
  9. "github.com/docker/docker/pkg/system"
  10. "github.com/spf13/cobra"
  11. )
  12. type loadOptions struct {
  13. input string
  14. quiet bool
  15. }
  16. // NewLoadCommand creates a new `docker load` command
  17. func NewLoadCommand(dockerCli *command.DockerCli) *cobra.Command {
  18. var opts loadOptions
  19. cmd := &cobra.Command{
  20. Use: "load [OPTIONS]",
  21. Short: "Load an image from a tar archive or STDIN",
  22. Args: cli.NoArgs,
  23. RunE: func(cmd *cobra.Command, args []string) error {
  24. return runLoad(dockerCli, opts)
  25. },
  26. }
  27. flags := cmd.Flags()
  28. flags.StringVarP(&opts.input, "input", "i", "", "Read from tar archive file, instead of STDIN")
  29. flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress the load output")
  30. return cmd
  31. }
  32. func runLoad(dockerCli *command.DockerCli, opts loadOptions) error {
  33. var input io.Reader = dockerCli.In()
  34. if opts.input != "" {
  35. // We use system.OpenSequential to use sequential file access on Windows, avoiding
  36. // depleting the standby list un-necessarily. On Linux, this equates to a regular os.Open.
  37. file, err := system.OpenSequential(opts.input)
  38. if err != nil {
  39. return err
  40. }
  41. defer file.Close()
  42. input = file
  43. }
  44. // To avoid getting stuck, verify that a tar file is given either in
  45. // the input flag or through stdin and if not display an error message and exit.
  46. if opts.input == "" && dockerCli.In().IsTerminal() {
  47. return fmt.Errorf("requested load from stdin, but stdin is empty")
  48. }
  49. if !dockerCli.Out().IsTerminal() {
  50. opts.quiet = true
  51. }
  52. response, err := dockerCli.Client().ImageLoad(context.Background(), input, opts.quiet)
  53. if err != nil {
  54. return err
  55. }
  56. defer response.Body.Close()
  57. if response.Body != nil && response.JSON {
  58. return jsonmessage.DisplayJSONMessagesToStream(response.Body, dockerCli.Out(), nil)
  59. }
  60. _, err = io.Copy(dockerCli.Out(), response.Body)
  61. return err
  62. }