@@ -3,6 +3,7 @@ package image
33import (
44 "bytes"
55 "context"
6+ "encoding/csv"
67 "encoding/json"
78 "fmt"
89 "io"
@@ -22,8 +23,10 @@ import (
2223 "github.com/docker/docker/pkg/urlutil"
2324 controlapi "github.com/moby/buildkit/api/services/control"
2425 "github.com/moby/buildkit/client"
26+ "github.com/moby/buildkit/session"
2527 "github.com/moby/buildkit/session/auth/authprovider"
2628 "github.com/moby/buildkit/session/filesync"
29+ "github.com/moby/buildkit/session/secrets/secretsprovider"
2730 "github.com/moby/buildkit/util/appcontext"
2831 "github.com/moby/buildkit/util/progress/progressui"
2932 "github.com/pkg/errors"
@@ -128,6 +131,13 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
128131 }
129132
130133 s .Allow (authprovider .NewDockerAuthProvider ())
134+ if len (options .secrets ) > 0 {
135+ sp , err := parseSecretSpecs (options .secrets )
136+ if err != nil {
137+ return errors .Wrapf (err , "could not parse secrets: %v" , options .secrets )
138+ }
139+ s .Allow (sp )
140+ }
131141
132142 eg , ctx := errgroup .WithContext (ctx )
133143
@@ -204,7 +214,7 @@ func doBuild(ctx context.Context, eg *errgroup.Group, dockerCli command.Cli, opt
204214 }
205215 // not using shared context to not disrupt display but let is finish reporting errors
206216 eg .Go (func () error {
207- return progressui .DisplaySolveStatus (context .TODO (), c , out , displayCh )
217+ return progressui .DisplaySolveStatus (context .TODO (), "" , c , out , displayCh )
208218 })
209219 }
210220
@@ -348,3 +358,53 @@ func (t *tracer) write(msg jsonmessage.JSONMessage) {
348358
349359 t .displayCh <- & s
350360}
361+
362+ func parseSecretSpecs (sl []string ) (session.Attachable , error ) {
363+ fs := make ([]secretsprovider.FileSource , 0 , len (sl ))
364+ for _ , v := range sl {
365+ s , err := parseSecret (v )
366+ if err != nil {
367+ return nil , err
368+ }
369+ fs = append (fs , * s )
370+ }
371+ store , err := secretsprovider .NewFileStore (fs )
372+ if err != nil {
373+ return nil , err
374+ }
375+ return secretsprovider .NewSecretProvider (store ), nil
376+ }
377+
378+ func parseSecret (value string ) (* secretsprovider.FileSource , error ) {
379+ csvReader := csv .NewReader (strings .NewReader (value ))
380+ fields , err := csvReader .Read ()
381+ if err != nil {
382+ return nil , errors .Wrap (err , "failed to parse csv secret" )
383+ }
384+
385+ fs := secretsprovider.FileSource {}
386+
387+ for _ , field := range fields {
388+ parts := strings .SplitN (field , "=" , 2 )
389+ key := strings .ToLower (parts [0 ])
390+
391+ if len (parts ) != 2 {
392+ return nil , errors .Errorf ("invalid field '%s' must be a key=value pair" , field )
393+ }
394+
395+ value := parts [1 ]
396+ switch key {
397+ case "type" :
398+ if value != "file" {
399+ return nil , errors .Errorf ("unsupported secret type %q" , value )
400+ }
401+ case "id" :
402+ fs .ID = value
403+ case "source" , "src" :
404+ fs .FilePath = value
405+ default :
406+ return nil , errors .Errorf ("unexpected key '%s' in '%s'" , key , field )
407+ }
408+ }
409+ return & fs , nil
410+ }
0 commit comments