mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Refactor utility MkBuildContext
to the more generic archive.Generate
This facilitates refactoring commands.go. Docker-DCO-1.1-Signed-off-by: Solomon Hykes <solomon@docker.com> (github: shykes)
This commit is contained in:
parent
a7ecc3ea11
commit
9b56da78e0
4 changed files with 76 additions and 41 deletions
59
archive/wrap.go
Normal file
59
archive/wrap.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package archive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Generate generates a new archive from the content provided
|
||||||
|
// as input.
|
||||||
|
//
|
||||||
|
// `files` is a sequence of path/content pairs. A new file is
|
||||||
|
// added to the archive for each pair.
|
||||||
|
// If the last pair is incomplete, the file is created with an
|
||||||
|
// empty content. For example:
|
||||||
|
//
|
||||||
|
// Generate("foo.txt", "hello world", "emptyfile")
|
||||||
|
//
|
||||||
|
// The above call will return an archive with 2 files:
|
||||||
|
// * ./foo.txt with content "hello world"
|
||||||
|
// * ./empty with empty content
|
||||||
|
//
|
||||||
|
// FIXME: stream content instead of buffering
|
||||||
|
// FIXME: specify permissions and other archive metadata
|
||||||
|
func Generate(input ...string) (Archive, error) {
|
||||||
|
files := parseStringPairs(input...)
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
tw := tar.NewWriter(buf)
|
||||||
|
for _, file := range files {
|
||||||
|
name, content := file[0], file[1]
|
||||||
|
hdr := &tar.Header{
|
||||||
|
Name: name,
|
||||||
|
Size: int64(len(content)),
|
||||||
|
}
|
||||||
|
if err := tw.WriteHeader(hdr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, err := tw.Write([]byte(content)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := tw.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ioutil.NopCloser(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseStringPairs(input ...string) (output [][2]string) {
|
||||||
|
output = make([][2]string, 0, len(input)/2+1)
|
||||||
|
for i := 0; i < len(input); i += 2 {
|
||||||
|
var pair [2]string
|
||||||
|
pair[0] = input[i]
|
||||||
|
if i+1 < len(input) {
|
||||||
|
pair[1] = input[i+1]
|
||||||
|
}
|
||||||
|
output = append(output, pair)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
28
commands.go
28
commands.go
|
@ -1,7 +1,6 @@
|
||||||
package docker
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
@ -136,31 +135,6 @@ func (cli *DockerCli) CmdInsert(args ...string) error {
|
||||||
return cli.stream("POST", "/images/"+cmd.Arg(0)+"/insert?"+v.Encode(), nil, cli.out, nil)
|
return cli.stream("POST", "/images/"+cmd.Arg(0)+"/insert?"+v.Encode(), nil, cli.out, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkBuildContext returns an archive of an empty context with the contents
|
|
||||||
// of `dockerfile` at the path ./Dockerfile
|
|
||||||
func MkBuildContext(dockerfile string, files [][2]string) (archive.Archive, error) {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
tw := tar.NewWriter(buf)
|
|
||||||
files = append(files, [2]string{"Dockerfile", dockerfile})
|
|
||||||
for _, file := range files {
|
|
||||||
name, content := file[0], file[1]
|
|
||||||
hdr := &tar.Header{
|
|
||||||
Name: name,
|
|
||||||
Size: int64(len(content)),
|
|
||||||
}
|
|
||||||
if err := tw.WriteHeader(hdr); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if _, err := tw.Write([]byte(content)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := tw.Close(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ioutil.NopCloser(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *DockerCli) CmdBuild(args ...string) error {
|
func (cli *DockerCli) CmdBuild(args ...string) error {
|
||||||
cmd := cli.Subcmd("build", "[OPTIONS] PATH | URL | -", "Build a new container image from the source code at PATH")
|
cmd := cli.Subcmd("build", "[OPTIONS] PATH | URL | -", "Build a new container image from the source code at PATH")
|
||||||
tag := cmd.String([]string{"t", "-tag"}, "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
|
tag := cmd.String([]string{"t", "-tag"}, "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
|
||||||
|
@ -188,7 +162,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
context, err = MkBuildContext(string(dockerfile), nil)
|
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
|
isRemote = true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,16 +14,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// mkTestContext generates a build context from the contents of the provided dockerfile.
|
|
||||||
// This context is suitable for use as an argument to BuildFile.Build()
|
|
||||||
func mkTestContext(dockerfile string, files [][2]string, t *testing.T) archive.Archive {
|
|
||||||
context, err := docker.MkBuildContext(dockerfile, files)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
return context
|
|
||||||
}
|
|
||||||
|
|
||||||
// A testContextTemplate describes a build context and how to test it
|
// A testContextTemplate describes a build context and how to test it
|
||||||
type testContextTemplate struct {
|
type testContextTemplate struct {
|
||||||
// Contents of the Dockerfile
|
// Contents of the Dockerfile
|
||||||
|
@ -34,6 +24,18 @@ type testContextTemplate struct {
|
||||||
remoteFiles [][2]string
|
remoteFiles [][2]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (context testContextTemplate) Archive(dockerfile string, t *testing.T) archive.Archive {
|
||||||
|
input := []string{"Dockerfile", dockerfile}
|
||||||
|
for _, pair := range context.files {
|
||||||
|
input = append(input, pair[0], pair[1])
|
||||||
|
}
|
||||||
|
a, err := archive.Generate(input...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
// A table of all the contexts to build and test.
|
// A table of all the contexts to build and test.
|
||||||
// A new docker runtime will be created and torn down for each context.
|
// A new docker runtime will be created and torn down for each context.
|
||||||
var testContexts = []testContextTemplate{
|
var testContexts = []testContextTemplate{
|
||||||
|
@ -381,7 +383,7 @@ func buildImage(context testContextTemplate, t *testing.T, eng *engine.Engine, u
|
||||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||||
|
|
||||||
buildfile := docker.NewBuildFile(srv, ioutil.Discard, ioutil.Discard, false, useCache, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
buildfile := docker.NewBuildFile(srv, ioutil.Discard, ioutil.Discard, false, useCache, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
||||||
id, err := buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
id, err := buildfile.Build(context.Archive(dockerfile, t))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -785,7 +787,7 @@ func TestForbiddenContextPath(t *testing.T) {
|
||||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||||
|
|
||||||
buildfile := docker.NewBuildFile(srv, ioutil.Discard, ioutil.Discard, false, true, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
buildfile := docker.NewBuildFile(srv, ioutil.Discard, ioutil.Discard, false, true, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
||||||
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
_, err = buildfile.Build(context.Archive(dockerfile, t))
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Log("Error should not be nil")
|
t.Log("Error should not be nil")
|
||||||
|
@ -831,7 +833,7 @@ func TestBuildADDFileNotFound(t *testing.T) {
|
||||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||||
|
|
||||||
buildfile := docker.NewBuildFile(mkServerFromEngine(eng, t), ioutil.Discard, ioutil.Discard, false, true, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
buildfile := docker.NewBuildFile(mkServerFromEngine(eng, t), ioutil.Discard, ioutil.Discard, false, true, false, ioutil.Discard, utils.NewStreamFormatter(false), nil, nil)
|
||||||
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
_, err = buildfile.Build(context.Archive(dockerfile, t))
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Log("Error should not be nil")
|
t.Log("Error should not be nil")
|
||||||
|
|
|
@ -476,7 +476,7 @@ func (srv *Server) Build(job *engine.Job) engine.Status {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return job.Error(err)
|
return job.Error(err)
|
||||||
}
|
}
|
||||||
c, err := MkBuildContext(string(dockerFile), nil)
|
c, err := archive.Generate("Dockerfile", string(dockerFile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return job.Error(err)
|
return job.Error(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue