diff --git a/README.md b/README.md index fad6156..ec14647 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ _(As a convention in the list below, all task parameters are specified with a DO_THING=false ``` -* `$BUILDKIT_SECRET_*`: extra secrets which are made available via +* `$BUILDKIT_SECRET_*`: files with extra secrets which are made available via `--mount=type=secret,id=...`. See [New Docker Build secret information](https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information) for more information on build secrets. For example, running with `BUILDKIT_SECRET_config=my-repo/config` will allow @@ -101,6 +101,13 @@ _(As a convention in the list below, all task parameters are specified with a RUN --mount=type=secret,id=config cat /run/secrets/config ``` +* `$BUILDKIT_SECRETTEXT_*`: literal text of extra secrets to be made available + via the same mechanism described for `$BUILDKIT_SECRET_*` above. The + difference is that this is easier to use with credential managers: + + `BUILDKIT_SECRETTEXT_mysecret=(( mysecret ))` puts the content that + `(( mysecret ))` expands to in `/run/secrets/mysecret`. + * `$IMAGE_ARG_*`: params prefixed with `IMAGE_ARG_*` point to image tarballs (i.e. `docker save` format) to preload so that they do not have to be fetched during the build. An image reference will be provided as the given build arg diff --git a/cmd/build/main.go b/cmd/build/main.go index 3e8874d..e46c128 100644 --- a/cmd/build/main.go +++ b/cmd/build/main.go @@ -17,6 +17,7 @@ const imageArgPrefix = "IMAGE_ARG_" const labelPrefix = "LABEL_" const buildkitSecretPrefix = "BUILDKIT_SECRET_" +const buildkitSecretTextPrefix = "BUILDKIT_SECRETTEXT_" func main() { req := task.Request{ @@ -58,6 +59,14 @@ func main() { req.Config.BuildkitSecrets[seg[0]] = seg[1] } + + if strings.HasPrefix(env, buildkitSecretTextPrefix) { + seg := strings.SplitN( + strings.TrimPrefix(env, buildkitSecretTextPrefix), "=", 2) + + err := task.StoreSecret(&req, seg[0], seg[1]) + failIf("store secret provided as text", err) + } } logrus.Debugf("read config from env: %#v\n", req.Config) diff --git a/task.go b/task.go index 1fe3d40..03f5730 100644 --- a/task.go +++ b/task.go @@ -16,6 +16,25 @@ import ( "github.com/sirupsen/logrus" ) +// Q: Audit name to not include "/"? +func StoreSecret(req *Request, name, value string) error { + secretDir := filepath.Join(os.TempDir(), "buildkit-secrets") + secretFile := filepath.Join(secretDir, name) + err := os.MkdirAll(secretDir, 0700) + if err != nil { + return fmt.Errorf("unable to create secret directory: %w", err) + } + err = ioutil.WriteFile(secretFile, []byte(value), 0600) + if err != nil { + return fmt.Errorf("unable to write secret to file: %w", err) + } + if req.Config.BuildkitSecrets == nil { + req.Config.BuildkitSecrets = make(map[string]string, 1) + } + req.Config.BuildkitSecrets[name] = secretFile + return nil +} + func Build(buildkitd *Buildkitd, outputsDir string, req Request) (Response, error) { if req.Config.Debug { logrus.SetLevel(logrus.DebugLevel) diff --git a/task_test.go b/task_test.go index c0b1a49..75f0192 100644 --- a/task_test.go +++ b/task_test.go @@ -250,6 +250,15 @@ func (s *TaskSuite) TestUnpackRootfs() { s.Equal(meta.Env, []string{"PATH=/darkness", "BA=nana"}) } +func (s *TaskSuite) TestBuildkitTextualSecrets() { + s.req.Config.ContextDir = "testdata/buildkit-secret" + err := task.StoreSecret(&s.req, "secret", "hello-world") + s.NoError(err) + + _, err = s.build() + s.NoError(err) +} + func (s *TaskSuite) TestBuildkitSecrets() { s.req.Config.ContextDir = "testdata/buildkit-secret" s.req.Config.BuildkitSecrets = map[string]string{"secret": "testdata/buildkit-secret/secret"}