Support custom registry on pushing image

This commit is contained in:
Lex Cao
2021-08-11 09:58:24 +08:00
parent ef474809e3
commit 82440ed8c0
10 changed files with 256 additions and 63 deletions
+24 -39
View File
@@ -18,9 +18,9 @@ package docker
import (
"bytes"
"strings"
dockerlib "github.com/fsouza/go-dockerclient"
dockerparser "github.com/novln/docker-parser"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
@@ -35,23 +35,15 @@ PushImage pushes a Docker image via the Docker API. Takes the image name,
parses the URL details and then push based on environment authentication
credentials.
*/
func (c *Push) PushImage(fullImageName string) error {
outputBuffer := bytes.NewBuffer(nil)
// Using https://github.com/novln/docker-parser in order to parse the appropriate
// name and registry.
parsedImage, err := dockerparser.Parse(fullImageName)
if err != nil {
return err
}
image, registry := parsedImage.Name(), parsedImage.Registry()
log.Infof("Pushing image '%s' to registry '%s'", image, registry)
func (c *Push) PushImage(image Image) error {
log.Infof("Pushing image '%s' to registry '%s'", image.Name, image.Registry)
// Let's setup the push and authentication options
outputBuffer := bytes.NewBuffer(nil)
options := dockerlib.PushImageOptions{
Name: fullImageName,
Registry: parsedImage.Registry(),
Tag: image.Tag,
Name: image.Repository,
Registry: image.Registry,
OutputStream: outputBuffer,
}
@@ -63,34 +55,27 @@ func (c *Push) PushImage(fullImageName string) error {
log.Warn(errors.Wrap(err, "Unable to retrieve .docker/config.json authentication details. Check that 'docker login' works successfully on the command line."))
}
// Fallback to unauthenticated access in case if no auth credentials are retrieved
if credentials == nil || len(credentials.Configs) == 0 {
log.Info("Authentication credentials are not detected. Will try push without authentication.")
credentials = &dockerlib.AuthConfigurations{
Configs: map[string]dockerlib.AuthConfiguration{
registry: {},
},
}
// Handle legacy docker registry address
if strings.Contains(image.Registry, "docker.io") {
image.Registry = "https://index.docker.io/v1/"
}
// Push the image to the repository (based on the URL)
// We will iterate through all available authentication configurations until we find one that pushes successfully
// and then return nil.
if len(credentials.Configs) > 1 {
log.Info("Multiple authentication credentials detected. Will try each configuration.")
// Find the authentication matched to registry
auth, ok := credentials.Configs[image.Registry]
if !ok {
// Fallback to unauthenticated access in case if no auth credentials are retrieved
log.Infof("Authentication credential of registry '%s' is not found. Will try push without authentication.", image.Registry)
auth = dockerlib.AuthConfiguration{}
}
for k, v := range credentials.Configs {
log.Infof("Attempting authentication credentials '%s", k)
err = c.Client.PushImage(options, v)
if err != nil {
log.Errorf("Unable to push image '%s' to registry '%s'. Error: %s", image, registry, err)
} else {
log.Debugf("Image '%s' push output:\n%s", image, outputBuffer)
log.Infof("Successfully pushed image '%s' to registry '%s'", image, registry)
return nil
}
log.Debugf("Pushing image with options %+v", options)
err = c.Client.PushImage(options, auth)
if err != nil {
log.Errorf("Unable to push image '%s' to registry '%s'. Error: %s", image.Name, image.Registry, err)
return errors.New("unable to push docker image(s). Check that `docker login` works successfully on the command line")
}
return errors.New("unable to push docker image(s). Check that `docker login` works successfully on the command line")
log.Debugf("Image '%+v' push output:\n%s", image, outputBuffer)
log.Infof("Successfully pushed image '%s' to registry '%s'", image.Name, image.Registry)
return nil
}