Quellcode durchsuchen

Merge pull request #4364 from vieux/move_clone

move git clone from daemon to client
Guillaume J. Charmes vor 11 Jahren
Ursprung
Commit
f9bd6c860d
3 geänderte Dateien mit 35 neuen und 11 gelöschten Zeilen
  1. 24 4
      api/client.go
  2. 10 6
      docs/sources/reference/commandline/cli.rst
  3. 1 1
      utils/utils.go

+ 24 - 4
api/client.go

@@ -24,6 +24,7 @@ import (
 	"net/http/httputil"
 	"net/http/httputil"
 	"net/url"
 	"net/url"
 	"os"
 	"os"
+	"os/exec"
 	gosignal "os/signal"
 	gosignal "os/signal"
 	"path"
 	"path"
 	"reflect"
 	"reflect"
@@ -158,6 +159,8 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 		err      error
 		err      error
 	)
 	)
 
 
+	_, err = exec.LookPath("git")
+	hasGit := err == nil
 	if cmd.Arg(0) == "-" {
 	if cmd.Arg(0) == "-" {
 		// As a special case, 'docker build -' will build from an empty context with the
 		// As a special case, 'docker build -' will build from an empty context with the
 		// contents of stdin as a Dockerfile
 		// contents of stdin as a Dockerfile
@@ -166,17 +169,34 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 			return err
 			return err
 		}
 		}
 		context, err = archive.Generate("Dockerfile", string(dockerfile))
 		context, err = archive.Generate("Dockerfile", string(dockerfile))
-	} else if utils.IsURL(cmd.Arg(0)) || utils.IsGIT(cmd.Arg(0)) {
+	} else if utils.IsURL(cmd.Arg(0)) && (!utils.IsGIT(cmd.Arg(0)) || !hasGit) {
 		isRemote = true
 		isRemote = true
 	} else {
 	} else {
-		if _, err := os.Stat(cmd.Arg(0)); err != nil {
+		root := cmd.Arg(0)
+		if utils.IsGIT(root) {
+			remoteURL := cmd.Arg(0)
+			if !strings.HasPrefix(remoteURL, "git://") && !strings.HasPrefix(remoteURL, "git@") && !utils.IsURL(remoteURL) {
+				remoteURL = "https://" + remoteURL
+			}
+
+			root, err = ioutil.TempDir("", "docker-build-git")
+			if err != nil {
+				return err
+			}
+			defer os.RemoveAll(root)
+
+			if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
+				return fmt.Errorf("Error trying to use git: %s (%s)", err, output)
+			}
+		}
+		if _, err := os.Stat(root); err != nil {
 			return err
 			return err
 		}
 		}
-		filename := path.Join(cmd.Arg(0), "Dockerfile")
+		filename := path.Join(root, "Dockerfile")
 		if _, err = os.Stat(filename); os.IsNotExist(err) {
 		if _, err = os.Stat(filename); os.IsNotExist(err) {
 			return fmt.Errorf("no Dockerfile found in %s", cmd.Arg(0))
 			return fmt.Errorf("no Dockerfile found in %s", cmd.Arg(0))
 		}
 		}
-		context, err = archive.Tar(cmd.Arg(0), archive.Uncompressed)
+		context, err = archive.Tar(root, archive.Uncompressed)
 	}
 	}
 	var body io.Reader
 	var body io.Reader
 	// Setup an upload progress bar
 	// Setup an upload progress bar

+ 10 - 6
docs/sources/reference/commandline/cli.rst

@@ -203,12 +203,16 @@ Examples:
       --no-cache: Do not use the cache when building the image.
       --no-cache: Do not use the cache when building the image.
       --rm=true: Remove intermediate containers after a successful build
       --rm=true: Remove intermediate containers after a successful build
 
 
-The files at ``PATH`` or ``URL`` are called the "context" of the build. The
-build process may refer to any of the files in the context, for example when
-using an :ref:`ADD <dockerfile_add>` instruction.  When a single ``Dockerfile``
-is given as ``URL``, then no context is set.  When a Git repository is set as
-``URL``, then the repository is used as the context. Git repositories are
-cloned with their submodules (`git clone --recursive`).
+The files at ``PATH`` or ``URL`` are called the "context" of the build.
+The build process may refer to any of the files in the context, for example when
+using an :ref:`ADD <dockerfile_add>` instruction.
+When a single ``Dockerfile`` is given as ``URL``, then no context is set.
+
+When a Git repository is set as ``URL``, then the repository is used as the context. 
+The Git repository is cloned with its submodules (`git clone --recursive`).
+A fresh git clone occurs in a temporary directory on your local host, and then this 
+is sent to the Docker daemon as the context. 
+This way, your local user credentials and vpn's etc can be used to access private repositories
 
 
 .. _cli_build_examples:
 .. _cli_build_examples:
 
 

+ 1 - 1
utils/utils.go

@@ -714,7 +714,7 @@ func IsURL(str string) bool {
 }
 }
 
 
 func IsGIT(str string) bool {
 func IsGIT(str string) bool {
-	return strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "github.com/")
+	return strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "github.com/") || strings.HasPrefix(str, "git@github.com:") || (strings.HasSuffix(str, ".git") && IsURL(str))
 }
 }
 
 
 // GetResolvConf opens and read the content of /etc/resolv.conf.
 // GetResolvConf opens and read the content of /etc/resolv.conf.