github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/cli/command/image/load.go (about)

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