From 8301fc8e56503d5a0ea2316a0778faf4cf5f5f1e Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 26 Feb 2014 23:20:58 +0000 Subject: [PATCH 1/2] move git clone from daemon to client Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) add a little doc --- api/client.go | 26 ++++++++++++++++++---- docs/sources/reference/commandline/cli.rst | 16 ++++++++----- utils/utils.go | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/api/client.go b/api/client.go index 7f8921d9e1..6dabeac835 100644 --- a/api/client.go +++ b/api/client.go @@ -24,6 +24,7 @@ import ( "net/http/httputil" "net/url" "os" + "os/exec" gosignal "os/signal" "path" "reflect" @@ -168,17 +169,34 @@ func (cli *DockerCli) CmdBuild(args ...string) error { return err } 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)) { isRemote = true } 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 } - filename := path.Join(cmd.Arg(0), "Dockerfile") + filename := path.Join(root, "Dockerfile") if _, err = os.Stat(filename); os.IsNotExist(err) { 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 // Setup an upload progress bar diff --git a/docs/sources/reference/commandline/cli.rst b/docs/sources/reference/commandline/cli.rst index 2404e29b29..6fe2e2943e 100644 --- a/docs/sources/reference/commandline/cli.rst +++ b/docs/sources/reference/commandline/cli.rst @@ -202,12 +202,16 @@ Examples: --no-cache: Do not use the cache when building the image. --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 ` 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 ` 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: diff --git a/utils/utils.go b/utils/utils.go index e4cb04f39c..57a8200a7c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -714,7 +714,7 @@ func IsURL(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. From 0d6275b298ebb9161c2f55d4b4ac0f87603a11cd Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 5 Mar 2014 01:54:08 +0000 Subject: [PATCH 2/2] if client has no git, use server Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api/client.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/client.go b/api/client.go index 6dabeac835..4854c19013 100644 --- a/api/client.go +++ b/api/client.go @@ -161,6 +161,8 @@ func (cli *DockerCli) CmdBuild(args ...string) error { err error ) + _, err = exec.LookPath("git") + hasGit := err == nil if cmd.Arg(0) == "-" { // As a special case, 'docker build -' will build from an empty context with the // contents of stdin as a Dockerfile @@ -169,7 +171,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error { return err } 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 } else { root := cmd.Arg(0)