Factor out adding dockerfile from stdin.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-04-05 12:09:26 -04:00
parent 3f6dc81e10
commit 56bf6de9f7
2 changed files with 49 additions and 42 deletions

View file

@ -247,46 +247,10 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
// replace Dockerfile if added dynamically
if dockerfileCtx != nil {
file, err := ioutil.ReadAll(dockerfileCtx)
dockerfileCtx.Close()
buildCtx, relDockerfile, err = addDockerfileToBuildContext(dockerfileCtx, buildCtx)
if err != nil {
return err
}
now := time.Now()
hdrTmpl := &tar.Header{
Mode: 0600,
Uid: 0,
Gid: 0,
ModTime: now,
Typeflag: tar.TypeReg,
AccessTime: now,
ChangeTime: now,
}
randomName := ".dockerfile." + stringid.GenerateRandomID()[:20]
buildCtx = archive.ReplaceFileTarWrapper(buildCtx, map[string]archive.TarModifierFunc{
randomName: func(_ string, h *tar.Header, content io.Reader) (*tar.Header, []byte, error) {
return hdrTmpl, file, nil
},
".dockerignore": func(_ string, h *tar.Header, content io.Reader) (*tar.Header, []byte, error) {
if h == nil {
h = hdrTmpl
}
extraIgnore := randomName + "\n"
b := &bytes.Buffer{}
if content != nil {
_, err := b.ReadFrom(content)
if err != nil {
return nil, nil, err
}
} else {
extraIgnore += ".dockerignore\n"
}
b.Write([]byte("\n" + extraIgnore))
return h, b.Bytes(), nil
},
})
relDockerfile = randomName
}
ctx := context.Background()
@ -392,6 +356,51 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
return nil
}
func addDockerfileToBuildContext(dockerfileCtx io.ReadCloser, buildCtx io.ReadCloser) (io.ReadCloser, string, error) {
file, err := ioutil.ReadAll(dockerfileCtx)
dockerfileCtx.Close()
if err != nil {
return nil, "", err
}
now := time.Now()
hdrTmpl := &tar.Header{
Mode: 0600,
Uid: 0,
Gid: 0,
ModTime: now,
Typeflag: tar.TypeReg,
AccessTime: now,
ChangeTime: now,
}
randomName := ".dockerfile." + stringid.GenerateRandomID()[:20]
buildCtx = archive.ReplaceFileTarWrapper(buildCtx, map[string]archive.TarModifierFunc{
// Add the dockerfile with a random filename
randomName: func(_ string, h *tar.Header, content io.Reader) (*tar.Header, []byte, error) {
return hdrTmpl, file, nil
},
// Update .dockerignore to include the random filename
".dockerignore": func(_ string, h *tar.Header, content io.Reader) (*tar.Header, []byte, error) {
if h == nil {
h = hdrTmpl
}
extraIgnore := randomName + "\n"
b := &bytes.Buffer{}
if content != nil {
_, err := b.ReadFrom(content)
if err != nil {
return nil, nil, err
}
} else {
extraIgnore += ".dockerignore\n"
}
b.Write([]byte("\n" + extraIgnore))
return h, b.Bytes(), nil
},
})
return buildCtx, randomName, nil
}
func isLocalDir(c string) bool {
_, err := os.Stat(c)
return err == nil

View file

@ -230,10 +230,8 @@ func CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, er
// define a modification step for a single path
type TarModifierFunc func(path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error)
// ReplaceFileTarWrapper converts inputTarStream to a new tar stream
// while replacing a single file called header.Name with new contents.
// If the file with header.Name does not exist it is added to the tar stream.
// TODO: make this into a generic tar conversion function with walkFn argument
// ReplaceFileTarWrapper converts inputTarStream to a new tar stream. Files in the
// tar stream are modified if they match any of the keys in mods.
func ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]TarModifierFunc) io.ReadCloser {
pipeReader, pipeWriter := io.Pipe()
@ -255,7 +253,7 @@ func ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]TarModi
for len(modKeys) > 0 && (err == io.EOF || err == nil && hdr.Name >= modKeys[0]) {
var h *tar.Header
var rdr io.Reader
if hdr != nil && hdr.Name == modKeys[0] {
if err == nil && hdr != nil && hdr.Name == modKeys[0] {
h = hdr
rdr = tarReader
}