Browse code

Merge pull request #4364 from vieux/move_clone

move git clone from daemon to client

Guillaume J. Charmes authored on 2014/03/18 03:36:56
Showing 3 changed files
... ...
@@ -24,6 +24,7 @@ import (
24 24
 	"net/http/httputil"
25 25
 	"net/url"
26 26
 	"os"
27
+	"os/exec"
27 28
 	gosignal "os/signal"
28 29
 	"path"
29 30
 	"reflect"
... ...
@@ -158,6 +159,8 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
158 158
 		err      error
159 159
 	)
160 160
 
161
+	_, err = exec.LookPath("git")
162
+	hasGit := err == nil
161 163
 	if cmd.Arg(0) == "-" {
162 164
 		// As a special case, 'docker build -' will build from an empty context with the
163 165
 		// contents of stdin as a Dockerfile
... ...
@@ -166,17 +169,34 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
166 166
 			return err
167 167
 		}
168 168
 		context, err = archive.Generate("Dockerfile", string(dockerfile))
169
-	} else if utils.IsURL(cmd.Arg(0)) || utils.IsGIT(cmd.Arg(0)) {
169
+	} else if utils.IsURL(cmd.Arg(0)) && (!utils.IsGIT(cmd.Arg(0)) || !hasGit) {
170 170
 		isRemote = true
171 171
 	} else {
172
-		if _, err := os.Stat(cmd.Arg(0)); err != nil {
172
+		root := cmd.Arg(0)
173
+		if utils.IsGIT(root) {
174
+			remoteURL := cmd.Arg(0)
175
+			if !strings.HasPrefix(remoteURL, "git://") && !strings.HasPrefix(remoteURL, "git@") && !utils.IsURL(remoteURL) {
176
+				remoteURL = "https://" + remoteURL
177
+			}
178
+
179
+			root, err = ioutil.TempDir("", "docker-build-git")
180
+			if err != nil {
181
+				return err
182
+			}
183
+			defer os.RemoveAll(root)
184
+
185
+			if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
186
+				return fmt.Errorf("Error trying to use git: %s (%s)", err, output)
187
+			}
188
+		}
189
+		if _, err := os.Stat(root); err != nil {
173 190
 			return err
174 191
 		}
175
-		filename := path.Join(cmd.Arg(0), "Dockerfile")
192
+		filename := path.Join(root, "Dockerfile")
176 193
 		if _, err = os.Stat(filename); os.IsNotExist(err) {
177 194
 			return fmt.Errorf("no Dockerfile found in %s", cmd.Arg(0))
178 195
 		}
179
-		context, err = archive.Tar(cmd.Arg(0), archive.Uncompressed)
196
+		context, err = archive.Tar(root, archive.Uncompressed)
180 197
 	}
181 198
 	var body io.Reader
182 199
 	// Setup an upload progress bar
... ...
@@ -203,12 +203,16 @@ Examples:
203 203
       --no-cache: Do not use the cache when building the image.
204 204
       --rm=true: Remove intermediate containers after a successful build
205 205
 
206
-The files at ``PATH`` or ``URL`` are called the "context" of the build. The
207
-build process may refer to any of the files in the context, for example when
208
-using an :ref:`ADD <dockerfile_add>` instruction.  When a single ``Dockerfile``
209
-is given as ``URL``, then no context is set.  When a Git repository is set as
210
-``URL``, then the repository is used as the context. Git repositories are
211
-cloned with their submodules (`git clone --recursive`).
206
+The files at ``PATH`` or ``URL`` are called the "context" of the build.
207
+The build process may refer to any of the files in the context, for example when
208
+using an :ref:`ADD <dockerfile_add>` instruction.
209
+When a single ``Dockerfile`` is given as ``URL``, then no context is set.
210
+
211
+When a Git repository is set as ``URL``, then the repository is used as the context. 
212
+The Git repository is cloned with its submodules (`git clone --recursive`).
213
+A fresh git clone occurs in a temporary directory on your local host, and then this 
214
+is sent to the Docker daemon as the context. 
215
+This way, your local user credentials and vpn's etc can be used to access private repositories
212 216
 
213 217
 .. _cli_build_examples:
214 218
 
... ...
@@ -714,7 +714,7 @@ func IsURL(str string) bool {
714 714
 }
715 715
 
716 716
 func IsGIT(str string) bool {
717
-	return strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "github.com/")
717
+	return strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "github.com/") || strings.HasPrefix(str, "git@github.com:") || (strings.HasSuffix(str, ".git") && IsURL(str))
718 718
 }
719 719
 
720 720
 // GetResolvConf opens and read the content of /etc/resolv.conf.