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:
parent
c2501942cf
commit
6e6ff85362
6 changed files with 47 additions and 9 deletions
20
api.go
20
api.go
|
@ -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() {
|
||||
|
|
17
buildfile.go
17
buildfile.go
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
****
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue