1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Fix support for registry auth with Dockerfile build.

Docker-DCO-1.1-Signed-off-by: Jake Moshenko <jake@devtable.com> (github: jakedt)
This commit is contained in:
Jake Moshenko 2014-01-03 15:13:32 -05:00 committed by yackob03
parent c2501942cf
commit 6e6ff85362
6 changed files with 47 additions and 9 deletions

20
api.go
View file

@ -925,10 +925,17 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
rawRm = r.FormValue("rm")
authEncoded = r.Header.Get("X-Registry-Auth")
authConfig = &auth.AuthConfig{}
configFileEncoded = r.Header.Get("X-Registry-Config")
configFile = &auth.ConfigFile{}
tag string
)
repoName, tag = utils.ParseRepositoryTag(repoName)
if authEncoded != "" {
// This block can be removed when API versions prior to 1.9 are deprecated.
// Both headers will be parsed and sent along to the daemon, but if a non-empty
// ConfigFile is present, any value provided as an AuthConfig directly will
// be overridden. See BuildFile::CmdFrom for details.
if version < 1.9 && authEncoded != "" {
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
// for a pull it is not an error if no auth was given
@ -937,6 +944,15 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
}
}
if configFileEncoded != "" {
configFileJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(configFileEncoded))
if err := json.NewDecoder(configFileJson).Decode(configFile); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
configFile = &auth.ConfigFile{}
}
}
var context io.Reader
if remoteURL == "" {
@ -1003,7 +1019,7 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
Writer: utils.NewWriteFlusher(w),
StreamFormatter: sf,
},
!suppressOutput, !noCache, rm, utils.NewWriteFlusher(w), sf, authConfig)
!suppressOutput, !noCache, rm, utils.NewWriteFlusher(w), sf, authConfig, configFile)
id, err := b.Build(context)
if err != nil {
if sf.Used() {

View file

@ -8,6 +8,7 @@ import (
"fmt"
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/auth"
"github.com/dotcloud/docker/registry"
"github.com/dotcloud/docker/utils"
"io"
"io/ioutil"
@ -47,6 +48,7 @@ type buildFile struct {
rm bool
authConfig *auth.AuthConfig
configFile *auth.ConfigFile
tmpContainers map[string]struct{}
tmpImages map[string]struct{}
@ -72,7 +74,17 @@ func (b *buildFile) CmdFrom(name string) error {
if err != nil {
if b.runtime.graph.IsNotExist(err) {
remote, tag := utils.ParseRepositoryTag(name)
if err := b.srv.ImagePull(remote, tag, b.outOld, b.sf, b.authConfig, nil, true); err != nil {
pullRegistryAuth := b.authConfig
if len(b.configFile.Configs) > 0 {
// The request came with a full auth config file, we prefer to use that
endpoint, _, err := registry.ResolveRepositoryName(remote)
if err != nil {
return err
}
resolvedAuth := b.configFile.ResolveAuthConfig(endpoint)
pullRegistryAuth = &resolvedAuth
}
if err := b.srv.ImagePull(remote, tag, b.outOld, b.sf, pullRegistryAuth, nil, true); err != nil {
return err
}
image, err = b.runtime.repositories.LookupImage(name)
@ -696,7 +708,7 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
return "", fmt.Errorf("No image was generated. This may be because the Dockerfile does not, like, do anything.\n")
}
func NewBuildFile(srv *Server, outStream, errStream io.Writer, verbose, utilizeCache, rm bool, outOld io.Writer, sf *utils.StreamFormatter, auth *auth.AuthConfig) BuildFile {
func NewBuildFile(srv *Server, outStream, errStream io.Writer, verbose, utilizeCache, rm bool, outOld io.Writer, sf *utils.StreamFormatter, auth *auth.AuthConfig, authConfigFile *auth.ConfigFile) BuildFile {
return &buildFile{
runtime: srv.runtime,
srv: srv,
@ -710,6 +722,7 @@ func NewBuildFile(srv *Server, outStream, errStream io.Writer, verbose, utilizeC
rm: rm,
sf: sf,
authConfig: auth,
configFile: authConfigFile,
outOld: outOld,
}
}

View file

@ -227,12 +227,14 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
v.Set("rm", "1")
}
cli.LoadConfigFile()
headers := http.Header(make(map[string][]string))
buf, err := json.Marshal(cli.configFile)
if err != nil {
return err
}
headers.Add("X-Registry-Auth", base64.URLEncoding.EncodeToString(buf))
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
if context != nil {
headers.Set("Content-Type", "application/tar")

View file

@ -54,6 +54,13 @@ What's new
**New!** This endpoint now returns a list of json message, like the events endpoint
.. http:post:: /build
**New!** This endpoint now takes a serialized ConfigFile which it uses to
resolve the proper registry auth credentials for pulling the base image.
Clients which previously implemented the version accepting an AuthConfig
object must be updated.
v1.8
****

View file

@ -1025,7 +1025,7 @@ Build an image from Dockerfile via stdin
:query q: suppress verbose build output
:query nocache: do not use the cache when building the image
:reqheader Content-type: should be set to ``"application/tar"``.
:reqheader X-Registry-Auth: base64-encoded AuthConfig object
:reqheader X-Registry-Config: base64-encoded ConfigFile object
:statuscode 200: no error
:statuscode 500: server error

View file

@ -296,7 +296,7 @@ func buildImage(context testContextTemplate, t *testing.T, eng *engine.Engine, u
}
dockerfile := constructDockerfile(context.dockerfile, ip, port)
buildfile := docker.NewBuildFile(srv, ioutil.Discard, ioutil.Discard, false, useCache, false, ioutil.Discard, utils.NewStreamFormatter(false), 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))
if err != nil {
return nil, err
@ -700,7 +700,7 @@ func TestForbiddenContextPath(t *testing.T) {
}
dockerfile := constructDockerfile(context.dockerfile, ip, port)
buildfile := docker.NewBuildFile(srv, ioutil.Discard, ioutil.Discard, false, true, false, ioutil.Discard, utils.NewStreamFormatter(false), 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))
if err == nil {
@ -746,7 +746,7 @@ func TestBuildADDFileNotFound(t *testing.T) {
}
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)
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))
if err == nil {