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