Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
31d2b25
Allow remote url to be passed to the ADD instruction within the builder
creack Jun 6, 2013
eaa2183
Fix issue EXPOSE override CMD within builder
creack Jun 6, 2013
f4a4cfd
Move isUrl to utils.IsURL
creack Jun 6, 2013
01f446e
Allow to docker build URL
creack Jun 6, 2013
a11e616
Move the docker build URL form client to server, prepare for GIT support
creack Jun 6, 2013
12c9b9b
Implement build from git
creack Jun 6, 2013
2cc22de
Update documentation for docker build
creack Jun 6, 2013
b103ac7
Allow multiple tab/spaces between instructions and arguments
creack Jun 10, 2013
8984aef
Fix typo in docs
creack Jun 10, 2013
b38c692
Updated build usage
creack Jun 13, 2013
d0084ce
Remove run from the ADD instruction
creack Jun 13, 2013
f5fe3ce
Remove run from non-running commmands
creack Jun 13, 2013
4b4918f
Merge branch 'master' into builder_server-3
creack Jun 14, 2013
f03ebc2
Fix issue with ADD
creack Jun 14, 2013
2f14dae
Add build UT
creack Jun 14, 2013
78f86ea
Merge branch 'master' into builder_server-3
creack Jun 15, 2013
cc7de8d
Removed deprecated file builder_client.go
Jun 15, 2013
38554fc
* Builder: simplify the upload of the build context. Simply stream a …
Jun 15, 2013
061f8d1
* Builder: reorganized unit tests for better code reuse, and to test …
Jun 15, 2013
f50e400
* Builder: added a regression test for #895
Jun 15, 2013
fe88b50
Merge branch 'master' into simpler-build-upload
Jun 15, 2013
79b3265
Merge branch 'master' into builder_server-3
creack Jun 17, 2013
5555523
Merge branch 'master' into builder_server-3
creack Jun 17, 2013
0809f64
* Builder: upload progress bar
Jun 18, 2013
6e17cc4
Fix merge issue
creack Jun 18, 2013
84ceeaa
Update documentaiton
creack Jun 18, 2013
34a4346
Merge branch 'master' into builder_server-3
creack Jun 18, 2013
90dde9b
*Builder: warn pre-1.3 clients that they need to upgrade. This breaks…
Jun 19, 2013
55edbcd
* Builder: remove duplicate unit test
Jun 19, 2013
d6ab71f
* Remote API: updated docs for 1.3
Jun 19, 2013
79efcb5
Merge branch 'master' into simpler-build-upload
Jun 20, 2013
659e846
Merge branch 'master' into builder_server-3
creack Jun 20, 2013
cff2187
Fixed API version numbers in api docs
Jun 20, 2013
e433232
Merge branch 'master' into simpler-build-upload
Jun 20, 2013
cc0f597
* Builder: simplified unit tests. The tests are now embedded in the b…
Jun 21, 2013
36d610a
- Builder: fixed a regression in ADD. Improved regression tests for b…
Jun 21, 2013
86e8318
Merge branch 'master' into simpler-build-upload
Jun 21, 2013
c1a5318
Merge branch 'build-add-file' into simpler-build-upload
Jun 21, 2013
352991b
Merge branch 'simpler-build-upload' (#900) into builder_server-3 (#848)
Jun 21, 2013
d9bce2d
- Builder: return an error when the build fails
Jun 21, 2013
d0fa692
Update api docs
creack Jun 21, 2013
169ef21
Remove deprecated INSERT from documentation
creack Jun 21, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions FIXME
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ to put them - so we put them here :)
* Caching after an ADD
* entry point config
* bring back git revision info, looks like it was lost
* Clean up the ProgressReader api, it's a PITA to use
69 changes: 51 additions & 18 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import (
"github.com/dotcloud/docker/utils"
"github.com/gorilla/mux"
"io"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"os/exec"
"strconv"
"strings"
)

const APIVERSION = 1.2
const APIVERSION = 1.3
const DEFAULTHTTPHOST string = "127.0.0.1"
const DEFAULTHTTPPORT int = 4243

Expand Down Expand Up @@ -719,34 +721,65 @@ func postImagesGetCache(srv *Server, version float64, w http.ResponseWriter, r *
}

func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := r.ParseMultipartForm(4096); err != nil {
return err
if version < 1.3 {
return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.")
}
remote := r.FormValue("t")
remoteURL := r.FormValue("remote")
repoName := r.FormValue("t")
tag := ""
if strings.Contains(remote, ":") {
remoteParts := strings.Split(remote, ":")
if strings.Contains(repoName, ":") {
remoteParts := strings.Split(repoName, ":")
tag = remoteParts[1]
remote = remoteParts[0]
repoName = remoteParts[0]
}

dockerfile, _, err := r.FormFile("Dockerfile")
if err != nil {
return err
}
var context io.Reader

context, _, err := r.FormFile("Context")
if err != nil {
if err != http.ErrMissingFile {
if remoteURL == "" {
context = r.Body
} else if utils.IsGIT(remoteURL) {
if !strings.HasPrefix(remoteURL, "git://") {
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", remoteURL, root).CombinedOutput(); err != nil {
return fmt.Errorf("Error trying to use git: %s (%s)", err, output)
}

c, err := Tar(root, Bzip2)
if err != nil {
return err
}
context = c
} else if utils.IsURL(remoteURL) {
f, err := utils.Download(remoteURL, ioutil.Discard)
if err != nil {
return err
}
defer f.Body.Close()
dockerFile, err := ioutil.ReadAll(f.Body)
if err != nil {
return err
}
c, err := mkBuildContext(string(dockerFile), nil)
if err != nil {
return err
}
context = c
}
b := NewBuildFile(srv, utils.NewWriteFlusher(w))
if id, err := b.Build(dockerfile, context); err != nil {
id, err := b.Build(context)
if err != nil {
fmt.Fprintf(w, "Error build: %s\n", err)
} else if remote != "" {
srv.runtime.repositories.Set(remote, tag, id, false)
return err
}
if repoName != "" {
srv.runtime.repositories.Set(repoName, tag, id, false)
}
return nil
}
Expand Down
88 changes: 50 additions & 38 deletions archive.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package docker

import (
"archive/tar"
"bufio"
"bytes"
"errors"
"fmt"
"github.com/dotcloud/docker/utils"
Expand All @@ -10,6 +12,7 @@ import (
"os"
"os/exec"
"path"
"path/filepath"
)

type Archive io.Reader
Expand Down Expand Up @@ -160,51 +163,60 @@ func CopyWithTar(src, dst string) error {
if err != nil {
return err
}
var dstExists bool
dstSt, err := os.Stat(dst)
if !srcSt.IsDir() {
return CopyFileWithTar(src, dst)
}
// Create dst, copy src's content into it
utils.Debugf("Creating dest directory: %s", dst)
if err := os.MkdirAll(dst, 0700); err != nil && !os.IsExist(err) {
return err
}
utils.Debugf("Calling TarUntar(%s, %s)", src, dst)
return TarUntar(src, nil, dst)
}

// CopyFileWithTar emulates the behavior of the 'cp' command-line
// for a single file. It copies a regular file from path `src` to
// path `dst`, and preserves all its metadata.
//
// If `dst` ends with a trailing slash '/', the final destination path
// will be `dst/base(src)`.
func CopyFileWithTar(src, dst string) error {
utils.Debugf("CopyFileWithTar(%s, %s)", src, dst)
srcSt, err := os.Stat(src)
if err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
dstExists = true
return err
}
// Things that can go wrong if the source is a directory
if srcSt.IsDir() {
// The destination exists and is a regular file
if dstExists && !dstSt.IsDir() {
return fmt.Errorf("Can't copy a directory over a regular file")
}
// Things that can go wrong if the source is a regular file
} else {
utils.Debugf("The destination exists, it's a directory, and doesn't end in /")
// The destination exists, it's a directory, and doesn't end in /
if dstExists && dstSt.IsDir() && dst[len(dst)-1] != '/' {
return fmt.Errorf("Can't copy a regular file over a directory %s |%s|", dst, dst[len(dst)-1])
}
return fmt.Errorf("Can't copy a directory")
}
// Create the destination
var dstDir string
if srcSt.IsDir() || dst[len(dst)-1] == '/' {
// The destination ends in /, or the source is a directory
// --> dst is the holding directory and needs to be created for -C
dstDir = dst
} else {
// The destination doesn't end in /
// --> dst is the file
dstDir = path.Dir(dst)
// Clean up the trailing /
if dst[len(dst)-1] == '/' {
dst = path.Join(dst, filepath.Base(src))
}
if !dstExists {
// Create the holding directory if necessary
utils.Debugf("Creating the holding directory %s", dstDir)
if err := os.MkdirAll(dstDir, 0700); err != nil && !os.IsExist(err) {
return err
}
// Create the holding directory if necessary
if err := os.MkdirAll(filepath.Dir(dst), 0700); err != nil && !os.IsExist(err) {
return err
}
if !srcSt.IsDir() {
return TarUntar(path.Dir(src), []string{path.Base(src)}, dstDir)
buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)
hdr, err := tar.FileInfoHeader(srcSt, "")
if err != nil {
return err
}
hdr.Name = filepath.Base(dst)
if err := tw.WriteHeader(hdr); err != nil {
return err
}
srcF, err := os.Open(src)
if err != nil {
return err
}
if _, err := io.Copy(tw, srcF); err != nil {
return err
}
return TarUntar(src, nil, dstDir)
tw.Close()
return Untar(buf, filepath.Dir(dst))
}

// CmdStream executes a command, and returns its stdout as a stream.
Expand Down
Loading