feat: Add ability to push to multiple registries (#303)

Co-authored-by: Robert Kaussow <xoxys@rknet.org>
This commit is contained in:
Maxim Slipenko 2023-08-09 12:35:58 +03:00 committed by GitHub
parent 56914d2332
commit 13c17d9c3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 9 deletions

View File

@ -95,6 +95,36 @@ steps:
tags: latest
```
**Multiple registries:**
```yaml
kind: pipeline
name: default
steps:
- name: docker
image: thegeeklab/drone-docker-buildx:23
privileged: true
environment:
DOCKER_REGISTRY_PASSWORD:
from_secret: docker_registry_password
GITHUB_REGISTRY_PASSWORD:
from_secret: github_registry_password
settings:
repo:
- octocat/example
- ghcr.io/octocat/example
tags: latest
registries: |
registries:
- username: "octocat"
password: "$DOCKER_REGISTRY_PASSWORD"
- registry: "ghcr.io"
username: "octocat"
password: "$GITHUB_REGISTRY_PASSWORD"
```
## Build
Build the binary with the following command:

View File

@ -208,7 +208,7 @@ properties:
description: |
Repository name for the image. If the image is to be pushed to registries other than the default DockerHub,
it is necessary to set `repo` as fully-qualified name.
type: string
type: list
required: false
- name: registry
@ -293,3 +293,8 @@ properties:
This should be used with caution and avoided whenever possible.
type: list
required: false
- name: registries
description: Credentials for multiple registries described in YAML format. Check out the Examples for more information.
type: string
required: false

View File

@ -235,7 +235,7 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
Destination: &settings.Build.Compress,
Category: category,
},
&cli.StringFlag{
&cli.StringSliceFlag{
Name: "repo",
EnvVars: []string{"PLUGIN_REPO"},
Usage: "repository name for the image",
@ -328,5 +328,12 @@ func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
Value: &drone.StringSliceFlag{},
Category: category,
},
&cli.StringFlag{
Name: "docker.registries",
EnvVars: []string{"PLUGIN_REGISTRIES"},
Usage: "credentials for registries",
Destination: &settings.Login.RegistriesYaml,
Category: category,
},
}
}

1
go.mod
View File

@ -15,4 +15,5 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
gopkg.in/yaml.v3 v3.0.1
)

View File

@ -11,7 +11,7 @@ import (
)
// helper function to create the docker login command.
func commandLogin(login Login) *execabs.Cmd {
func commandLogin(login RegistryData) *execabs.Cmd {
if login.Email != "" {
return commandLoginEmail(login)
}
@ -28,7 +28,7 @@ func commandLogin(login Login) *execabs.Cmd {
)
}
func commandLoginEmail(login Login) *execabs.Cmd {
func commandLoginEmail(login RegistryData) *execabs.Cmd {
args := []string{
"login",
"-u", login.Username,
@ -140,8 +140,10 @@ func commandBuild(build Build, dryrun bool) *execabs.Cmd {
args = append(args, "--platform", strings.Join(build.Platforms.Value(), ","))
}
for _, arg := range build.Tags.Value() {
args = append(args, "-t", fmt.Sprintf("%s:%s", build.Repo, arg))
for _, repo := range build.Repo.Value() {
for _, arg := range build.Tags.Value() {
args = append(args, "-t", fmt.Sprintf("%s:%s", repo, arg))
}
}
for _, arg := range build.ExtraTags.Value() {

View File

@ -9,6 +9,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
"golang.org/x/sys/execabs"
"gopkg.in/yaml.v3"
)
// Daemon defines Docker daemon parameters.
@ -31,11 +32,20 @@ type Daemon struct {
// Login defines Docker login parameters.
type Login struct {
RegistryData
Config string // Docker Auth Config
RegistriesYaml string // Docker Auth with YAML config
}
type RegistryData struct {
Registry string // Docker registry address
Username string // Docker registry username
Password string // Docker registry password
Email string // Docker registry email
Config string // Docker Auth Config
}
type RegistriesYaml struct {
Registries []RegistryData `yaml:"registries"`
}
// Build defines Docker build parameters.
@ -56,7 +66,7 @@ type Build struct {
CacheFrom []string // Docker build cache-from
CacheTo string // Docker build cache-to
Compress bool // Docker build compress
Repo string // Docker build repository
Repo cli.StringSlice // Docker build repositories
NoCache bool // Docker build no-cache
AddHost cli.StringSlice // Docker build add-host
Quiet bool // Docker build quiet
@ -167,7 +177,7 @@ func (p *Plugin) Execute() error {
// login to the Docker registry
if p.settings.Login.Password != "" {
cmd := commandLogin(p.settings.Login)
cmd := commandLogin(p.settings.Login.RegistryData)
err := cmd.Run()
if err != nil {
@ -175,6 +185,28 @@ func (p *Plugin) Execute() error {
}
}
if p.settings.Login.RegistriesYaml != "" {
var t RegistriesYaml
err := yaml.Unmarshal([]byte(p.settings.Login.RegistriesYaml), &t)
if err != nil {
return fmt.Errorf("error unmarshal registries: %w", err)
}
for _, registryData := range t.Registries {
if registryData.Registry == "" {
registryData.Registry = "https://index.docker.io/v1/"
}
cmd := commandLogin(registryData)
err := cmd.Run()
if err != nil {
return fmt.Errorf("error authenticating: %w", err)
}
}
}
if p.settings.Daemon.BuildkitConfig != "" {
err := os.WriteFile(buildkitConfig, []byte(p.settings.Daemon.BuildkitConfig), strictFilePerm)
if err != nil {
@ -185,6 +217,8 @@ func (p *Plugin) Execute() error {
switch {
case p.settings.Login.Password != "":
logrus.Info("Detected registry credentials")
case p.settings.Login.RegistriesYaml != "":
logrus.Info("Detected multiple registry credentials")
case p.settings.Login.Config != "":
logrus.Info("Detected registry credentials file")
default: