Sfoglia il codice sorgente

work on #11094 allow import from local file

Signed-off-by: Gildas Cuisinier <gildas.cuisinier@gcuisinier.net>
Gildas Cuisinier 10 anni fa
parent
commit
3f64b76d4c

+ 15 - 4
api/client/import.go

@@ -4,20 +4,22 @@ import (
 	"fmt"
 	"io"
 	"net/url"
+	"os"
 
 	"github.com/docker/docker/opts"
 	flag "github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/parsers"
+	"github.com/docker/docker/pkg/urlutil"
 	"github.com/docker/docker/registry"
 )
 
 // CmdImport creates an empty filesystem image, imports the contents of the tarball into the image, and optionally tags the image.
 //
-// The URL argument is the address of a tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) file. If the URL is '-', then the tar file is read from STDIN.
+// The URL argument is the address of a tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) file or a path to local file relative to docker client. If the URL is '-', then the tar file is read from STDIN.
 //
-// Usage: docker import [OPTIONS] URL [REPOSITORY[:TAG]]
+// Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
 func (cli *DockerCli) CmdImport(args ...string) error {
-	cmd := cli.Subcmd("import", []string{"URL|- [REPOSITORY[:TAG]]"}, "Create an empty filesystem image and import the contents of the\ntarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then\noptionally tag it.", true)
+	cmd := cli.Subcmd("import", []string{"file|URL|- [REPOSITORY[:TAG]]"}, "Create an empty filesystem image and import the contents of the\ntarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then\noptionally tag it.", true)
 	flChanges := opts.NewListOpts(nil)
 	cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
 	cmd.Require(flag.Min, 1)
@@ -36,7 +38,7 @@ func (cli *DockerCli) CmdImport(args ...string) error {
 		v.Add("changes", change)
 	}
 	if cmd.NArg() == 3 {
-		fmt.Fprintf(cli.err, "[DEPRECATED] The format 'URL|- [REPOSITORY [TAG]]' has been deprecated. Please use URL|- [REPOSITORY[:TAG]]\n")
+		fmt.Fprintf(cli.err, "[DEPRECATED] The format 'file|URL|- [REPOSITORY [TAG]]' has been deprecated. Please use file|URL|- [REPOSITORY[:TAG]]\n")
 		v.Set("tag", cmd.Arg(2))
 	}
 
@@ -52,6 +54,15 @@ func (cli *DockerCli) CmdImport(args ...string) error {
 
 	if src == "-" {
 		in = cli.in
+	} else if !urlutil.IsURL(src) {
+		v.Set("fromSrc", "-")
+		file, err := os.Open(src)
+		if err != nil {
+			return err
+		}
+		defer file.Close()
+		in = file
+
 	}
 
 	sopts := &streamOpts{

+ 13 - 5
docs/reference/commandline/cli.md

@@ -1455,7 +1455,7 @@ NOTE: Docker will warn you if any containers exist that are using these untagged
 
 ## import
 
-    Usage: docker import URL|- [REPOSITORY[:TAG]]
+    Usage: docker import file|URL|- [REPOSITORY[:TAG]]
 
     Create an empty filesystem image and import the contents of the
 	tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then
@@ -1463,10 +1463,14 @@ NOTE: Docker will warn you if any containers exist that are using these untagged
 
       -c, --change=[]     Apply specified Dockerfile instructions while importing the image
 
-URLs must start with `http` and point to a single file archive (.tar,
-.tar.gz, .tgz, .bzip, .tar.xz, or .txz) containing a root filesystem. If
-you would like to import from a local directory or archive, you can use
-the `-` parameter to take the data from `STDIN`.
+You can specify a `URL` or `-` (dash) to take data directly from `STDIN`. The
+`URL` can point to an archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, or .txz)
+containing a fileystem or to an individual file on the Docker host.  If you
+specify an archive, Docker untars it in the container relative to the `/`
+(root). If you specify an individual file, you must specify the full path within
+the host. To import from a remote location, specify a `URI` that begins with the
+`http://` or `https://` protocol.
+
 
 The `--change` option will apply `Dockerfile` instructions to the image
 that is created.
@@ -1475,6 +1479,10 @@ Supported `Dockerfile` instructions:
 
 #### Examples
 
+**Import from a local file archive:**
+
+    $ sudo docker import /local/path/to/exampleimage.tgz exampleimagedir
+
 **Import from a remote location:**
 
 This will create a new untagged image.

+ 56 - 0
integration-cli/docker_cli_import_test.go

@@ -1,6 +1,9 @@
 package main
 
 import (
+	"bufio"
+	"io/ioutil"
+	"os"
 	"os/exec"
 	"strings"
 
@@ -50,3 +53,56 @@ func (s *DockerSuite) TestImportBadURL(c *check.C) {
 		c.Fatalf("expected an error msg but didn't get one:\n%s", out)
 	}
 }
+
+func (s *DockerSuite) TestImportFile(c *check.C) {
+	runCmd := exec.Command(dockerBinary, "run", "--name", "test-import", "busybox", "true")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatal("failed to create a container", out, err)
+	}
+
+	temporaryFile, err := ioutil.TempFile("", "exportImportTest")
+	if err != nil {
+		c.Fatal("failed to create temporary file", "", err)
+	}
+	defer os.Remove(temporaryFile.Name())
+
+	runCmd = exec.Command(dockerBinary, "export", "test-import")
+	runCmd.Stdout = bufio.NewWriter(temporaryFile)
+
+	_, err = runCommand(runCmd)
+	if err != nil {
+		c.Fatal("failed to export a container", out, err)
+	}
+
+	runCmd = exec.Command(dockerBinary, "import", temporaryFile.Name())
+	out, _, err = runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatal("failed to import a container", out, err)
+	}
+
+	if n := strings.Count(out, "\n"); n != 1 {
+		c.Fatalf("display is messed up: %d '\\n' instead of 1:\n%s", n, out)
+	}
+	image := strings.TrimSpace(out)
+
+	runCmd = exec.Command(dockerBinary, "run", "--rm", image, "true")
+	out, _, err = runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatal("failed to create a container", out, err)
+	}
+
+	if out != "" {
+		c.Fatalf("command output should've been nothing, was %q", out)
+	}
+
+}
+
+func (s *DockerSuite) TestImportFileNonExistentFile(c *check.C) {
+	runCmd := exec.Command(dockerBinary, "import", "example.com/myImage.tar")
+	_, exitCode, err := runCommandWithOutput(runCmd)
+	if exitCode == 0 || err == nil {
+		c.Fatalf("import non-existing file must failed")
+	}
+
+}

+ 6 - 1
man/docker-import.1.md

@@ -8,7 +8,7 @@ docker-import - Create an empty filesystem image and import the contents of the
 **docker import**
 [**-c**|**--change**[= []**]]
 [**--help**]
-URL|- [REPOSITORY[:TAG]]
+file|URL|- [REPOSITORY[:TAG]]
 
 # OPTIONS
 **-c**, **--change**=[]
@@ -35,6 +35,11 @@ Import to docker via pipe and stdin:
 
     # cat exampleimage.tgz | docker import - example/imagelocal
 
+Import to a Docker image from a local file.
+
+    # docker import /path/to/exampleimage.tgz 
+
+
 ## Import from a local file and tag
 
 Import to docker via pipe and stdin: