Reputation: 199
In the advanced authentication methods documentation for google cloud container registry explains a method for login to the registry using a JSON Key file with the docker cli, this just works fine
$ docker login -u _json_key -p "$(cat keyfile.json)" https://gcr.io
However I'm trying to use that same keyfile.json file to login to the registry using the golang docker/engine-api
libraries, I have some working code that this seems to be authenticating fine into other registryies, but always providing a file with the following structure
{
"auths": {
"cr.whatever.com": {
"password": "PASSWORD",
"username": "registry"
}
}
}
By passing that Unmarshal
file into ImageBuildOptions
function here to then be consumed here
However is not working when using the keyfile.json
or a working config.json
...
The docker documentation states that a JSON base64 encoded object with username and password should be used as described here into the Header Parameters section.
I've tried multiple option to produce a file that can be successfully consumed into the docker X-Registry-Config
header without much luck...
Any help/hint would be much appreciated.
Thanks!
Upvotes: 1
Views: 597
Reputation: 199
Thank you for your help jsand, I finally draft a working code function as below
func (d *DockerEngineClient) BuildImage(archive, modelId string, authConfigs map[string]types.AuthConfig) (types.ImageBuildResponse, error) {
buildContext, err := os.Open(archive)
defer buildContext.Close()
c, err := ioutil.ReadFile(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS_FILE"))
if err != nil {
return err
}
var authConfigs2 map[string]types.AuthConfig
authConfigs2 = make(map[string]types.AuthConfig)
authConfigs2["gcr.io"] = types.AuthConfig{
Username: "_json_key",
Password: string(c),
ServerAddress: fmt.Sprintf("https://%s", d.remoteRegistryPrefix),
}
buildOptions := types.ImageBuildOptions{
Tags: []string{fmt.Sprintf("%s/%s", d.remoteRegistryPrefix, modelId)},
AuthConfigs: authConfigs2,
}
var buildResponse types.ImageBuildResponse
buildResponse, err = d.client.ImageBuild(context.TODO(), buildContext, buildOptions)
if err != nil {
return buildResponse, err
}
b, _ := ioutil.ReadAll(buildResponse.Body)
fmt.Printf("%s\n", b)
buildResponse.Body.Close()
return buildResponse, err
}
Upvotes: 2
Reputation: 595
I think the issue is that 'config' is an overloaded term. Looks like X-Registry-Config
contains a base64-encoded version of the JSON-encoded value of options.AuthConfigs, rather than the full docker config file. If you only want to authenticate for https://gcr.io
, your JSON input should be:
{
"gcr.io": {
"username": "_json_key",
"password": "{contents of keyfile.json}"
}
}
Or, if you're willing to use Docker's golang libs:
import (
"encoding/base64"
"encoding/json"
"net/http"
"github.com/docker/engine-api/types"
)
def addDockerAuthsHeader(keyfile_contents string, headers http.Header) error {
authConfigs := map[string]types.AuthConfig{
"gcr.io": {
Username: "_json_key",
Password: keyfile_contents
}
}
buf, err := json.Marshal(authConfigs)
if err != nil {
return err
}
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
return nil
}
Generating keyfile_contents
is left as an exercise for the reader :)
Upvotes: 1