1package image
2
3import (
4	"context"
5	"io"
6	"os"
7
8	"github.com/docker/cli/cli"
9	"github.com/docker/cli/cli/command"
10	dockeropts "github.com/docker/cli/opts"
11	"github.com/docker/docker/api/types"
12	"github.com/docker/docker/pkg/jsonmessage"
13	"github.com/docker/docker/pkg/urlutil"
14	"github.com/spf13/cobra"
15)
16
17type importOptions struct {
18	source    string
19	reference string
20	changes   dockeropts.ListOpts
21	message   string
22	platform  string
23}
24
25// NewImportCommand creates a new `docker import` command
26func NewImportCommand(dockerCli command.Cli) *cobra.Command {
27	var options importOptions
28
29	cmd := &cobra.Command{
30		Use:   "import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]",
31		Short: "Import the contents from a tarball to create a filesystem image",
32		Args:  cli.RequiresMinArgs(1),
33		RunE: func(cmd *cobra.Command, args []string) error {
34			options.source = args[0]
35			if len(args) > 1 {
36				options.reference = args[1]
37			}
38			return runImport(dockerCli, options)
39		},
40	}
41
42	flags := cmd.Flags()
43
44	options.changes = dockeropts.NewListOpts(nil)
45	flags.VarP(&options.changes, "change", "c", "Apply Dockerfile instruction to the created image")
46	flags.StringVarP(&options.message, "message", "m", "", "Set commit message for imported image")
47	command.AddPlatformFlag(flags, &options.platform)
48
49	return cmd
50}
51
52func runImport(dockerCli command.Cli, options importOptions) error {
53	var (
54		in      io.Reader
55		srcName = options.source
56	)
57
58	if options.source == "-" {
59		in = dockerCli.In()
60	} else if !urlutil.IsURL(options.source) {
61		srcName = "-"
62		file, err := os.Open(options.source)
63		if err != nil {
64			return err
65		}
66		defer file.Close()
67		in = file
68	}
69
70	source := types.ImageImportSource{
71		Source:     in,
72		SourceName: srcName,
73	}
74
75	importOptions := types.ImageImportOptions{
76		Message:  options.message,
77		Changes:  options.changes.GetAll(),
78		Platform: options.platform,
79	}
80
81	clnt := dockerCli.Client()
82
83	responseBody, err := clnt.ImageImport(context.Background(), source, options.reference, importOptions)
84	if err != nil {
85		return err
86	}
87	defer responseBody.Close()
88
89	return jsonmessage.DisplayJSONMessagesToStream(responseBody, dockerCli.Out(), nil)
90}
91