diff --git a/README.md b/README.md index 33975f5..821fabc 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,20 @@ Next, any of the following optional parameters may be specified: * `$TARGET_FILE` (default empty): path to a file containing the name of the target build stage to build. +* `$PUSH` (default empty): If non-empty the image will use the PUSH variable + as name and push the image. If credentials is required, they can be supplied + as three seperate parameters `$DOCKER_USERNAME`, `DOCKER_PASSWORD` and + `DOCKER_REGISTRY` + + Example here would push the image to docker.io/concourse/oci-build.task + ``` + DOCKER_USERNAME: ((docker_username.secret)) + DOCKER_PASSWORD: ((docker_password.secret)) + DOCKER_REGISTRY: ((docker_registry.secret)) + PUSH: docker.io/concourse/oci-build.task + + ``` + * `$ADDITIONAL_TARGETS` (default empty): a comma-separated (`,`) list of additional target build stages to build. diff --git a/cmd/build/main.go b/cmd/build/main.go index 3e8874d..16f2462 100644 --- a/cmd/build/main.go +++ b/cmd/build/main.go @@ -60,6 +60,12 @@ func main() { } } + //CheckForDockerCredentials only returns an error, if there + //was a problem saving the credentials + //No credentials will just be ignored + err = task.CheckForDockerCredentials() + failIf("docker auth check", err) + logrus.Debugf("read config from env: %#v\n", req.Config) reqPayload, err := json.Marshal(req) diff --git a/docker_auth.go b/docker_auth.go new file mode 100644 index 0000000..8f0214b --- /dev/null +++ b/docker_auth.go @@ -0,0 +1,55 @@ +package task + +import ( + "encoding/json" + "os" + + "github.com/docker/cli/cli/config/configfile" + "github.com/docker/cli/cli/config/types" + "github.com/sirupsen/logrus" +) + +func CheckForDockerCredentials() error { + username := os.Getenv("DOCKER_USERNAME") + password := os.Getenv("DOCKER_PASSWORD") + registry := os.Getenv("DOCKER_REGISTRY") + + if username == "" || password == "" || registry == "" { + logrus.Debugf("No docker credentials in environment variables") + return nil + } + + config := configfile.ConfigFile{ + AuthConfigs: map[string]types.AuthConfig{ + registry: types.AuthConfig{ + Username: username, + Password: password, + }, + }, + } + + fileContents, err := json.MarshalIndent(config, "", " ") + if err != nil { + return err + + } + + fileMode := os.FileMode(0444) + + homedir, err := os.UserHomeDir() + if err != nil { + return err + } + + configPath := homedir + "/.docker" + if err := os.MkdirAll(configPath, fileMode); err != nil { + return err + } + + filePath := configPath + "/config.json" + if err := os.WriteFile(filePath, fileContents, fileMode); err != nil { + return err + } + + return nil +} diff --git a/task.go b/task.go index 1fe3d40..4f55fd5 100644 --- a/task.go +++ b/task.go @@ -136,6 +136,11 @@ func Build(buildkitd *Buildkitd, outputsDir string, req Request) (Response, erro ) } + if cfg.Push != "" { + buildctlArgs = append(buildctlArgs, + "--output", fmt.Sprintf("type=image,name=%s,push=true", cfg.Push)) + } + if cfg.AddHosts != "" { buildctlArgs = append(buildctlArgs, "--opt", "add-hosts="+cfg.AddHosts, diff --git a/types.go b/types.go index 2e4dc58..93cf44b 100644 --- a/types.go +++ b/types.go @@ -53,6 +53,7 @@ type Config struct { Target string `json:"target" envconfig:"optional"` TargetFile string `json:"target_file" envconfig:"optional"` AdditionalTargets []string `json:"additional_targets" envconfig:"ADDITIONAL_TARGETS,optional"` + Push string `json:"push" envconfig:"optional"` BuildArgs []string `json:"build_args" envconfig:"optional"` BuildArgsFile string `json:"build_args_file" envconfig:"optional"`