Skip to content

Commit cb142fa

Browse files
authored
Merge pull request #1288 from tiborvass/build-secrets
Build --secret with buildkit
2 parents 9641739 + b4057f0 commit cb142fa

52 files changed

Lines changed: 4653 additions & 786 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cli/command/image/build.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ type buildOptions struct {
7272
stream bool
7373
platform string
7474
untrusted bool
75+
secrets []string
7576
}
7677

7778
// dockerfileFromStdin returns true when the user specified that the Dockerfile
@@ -156,6 +157,10 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
156157
flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (only if BuildKit enabled) (auto, plain, tty). Use plain to show container output")
157158
flags.SetAnnotation("progress", "experimental", nil)
158159
flags.SetAnnotation("progress", "version", []string{"1.38"})
160+
161+
flags.StringArrayVar(&options.secrets, "secret", []string{}, "Secret file to expose to the build (only if BuildKit enabled): id=mysecret,src=/local/secret")
162+
flags.SetAnnotation("secret", "experimental", nil)
163+
flags.SetAnnotation("secret", "version", []string{"1.39"})
159164
return cmd
160165
}
161166

cli/command/image/build_buildkit.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package image
33
import (
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+
}

cli/command/image/build_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"bytes"
66
"compress/gzip"
77
"context"
8+
"fmt"
89
"io"
910
"io/ioutil"
1011
"os"
@@ -17,6 +18,7 @@ import (
1718
"github.com/docker/docker/api/types"
1819
"github.com/docker/docker/pkg/archive"
1920
"github.com/google/go-cmp/cmp"
21+
"github.com/moby/buildkit/session/secrets/secretsprovider"
2022
"gotest.tools/assert"
2123
"gotest.tools/fs"
2224
"gotest.tools/skip"
@@ -173,6 +175,66 @@ RUN echo hello world
173175
assert.DeepEqual(t, fakeBuild.filenames(t), []string{"Dockerfile"})
174176
}
175177

178+
func TestParseSecret(t *testing.T) {
179+
type testcase struct {
180+
value string
181+
errExpected bool
182+
errMatch string
183+
filesource *secretsprovider.FileSource
184+
}
185+
var testcases = []testcase{
186+
{
187+
value: "",
188+
errExpected: true,
189+
}, {
190+
value: "foobar",
191+
errExpected: true,
192+
errMatch: "must be a key=value pair",
193+
}, {
194+
value: "foo,bar",
195+
errExpected: true,
196+
errMatch: "must be a key=value pair",
197+
}, {
198+
value: "foo=bar",
199+
errExpected: true,
200+
errMatch: "unexpected key",
201+
}, {
202+
value: "src=somefile",
203+
filesource: &secretsprovider.FileSource{FilePath: "somefile"},
204+
}, {
205+
value: "source=somefile",
206+
filesource: &secretsprovider.FileSource{FilePath: "somefile"},
207+
}, {
208+
value: "id=mysecret",
209+
filesource: &secretsprovider.FileSource{ID: "mysecret"},
210+
}, {
211+
value: "id=mysecret,src=somefile",
212+
filesource: &secretsprovider.FileSource{ID: "mysecret", FilePath: "somefile"},
213+
}, {
214+
value: "id=mysecret,source=somefile,type=file",
215+
filesource: &secretsprovider.FileSource{ID: "mysecret", FilePath: "somefile"},
216+
}, {
217+
value: "id=mysecret,src=somefile,src=othersecretfile",
218+
filesource: &secretsprovider.FileSource{ID: "mysecret", FilePath: "othersecretfile"},
219+
}, {
220+
value: "type=invalid",
221+
errExpected: true,
222+
errMatch: "unsupported secret type",
223+
},
224+
}
225+
226+
for _, tc := range testcases {
227+
t.Run(tc.value, func(t *testing.T) {
228+
secret, err := parseSecret(tc.value)
229+
assert.Equal(t, err != nil, tc.errExpected, fmt.Sprintf("err=%v errExpected=%t", err, tc.errExpected))
230+
if tc.errMatch != "" {
231+
assert.ErrorContains(t, err, tc.errMatch)
232+
}
233+
assert.DeepEqual(t, secret, tc.filesource)
234+
})
235+
}
236+
}
237+
176238
type fakeBuild struct {
177239
context *tar.Reader
178240
options types.ImageBuildOptions

vendor.conf

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
github.com/agl/ed25519 5312a61534124124185d41f09206b9fef1d88403
22
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
33
github.com/beorn7/perks 3a771d992973f24aa725d07868b467d1ddfceafb
4-
github.com/containerd/console cb7008ab3d8359b78c5f464cb7cf160107ad5925
5-
github.com/containerd/containerd 08f7ee9828af1783dc98cc5cc1739e915697c667
4+
github.com/containerd/console 5d1b48d6114b8c9666f0c8b916f871af97b0a761
5+
github.com/containerd/containerd a88b6319614de846458750ff882723479ca7b1a1
66
github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371
77
github.com/coreos/etcd v3.3.9
88
github.com/cpuguy83/go-md2man v1.0.8
99
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 # v1.1.0
1010
github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5
11-
github.com/docker/docker 562df8c2d6f48601c8d1df7256389569d25c0bf1
11+
github.com/docker/docker a7ff19d69a90dfe152abd146221c8b9b46a0903d
1212
github.com/docker/docker-credential-helpers 5241b46610f2491efdf9d1c85f1ddf5b02f6d962
1313
# the docker/go package contains a customized version of canonical/json
1414
# and is used by Notary. The package is periodically rebased on current Go versions.
@@ -42,7 +42,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1
4242
github.com/Microsoft/go-winio v0.4.9
4343
github.com/miekg/pkcs11 287d9350987cc9334667882061e202e96cdfb4d0
4444
github.com/mitchellh/mapstructure f15292f7a699fcc1a38a80977f80a046874ba8ac
45-
github.com/moby/buildkit 9acf51e49185b348608e0096b2903dd72907adcb
45+
github.com/moby/buildkit 785436a312230fcc79b41aa044c1643528c91913
4646
github.com/modern-go/concurrent bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3
4747
github.com/modern-go/reflect2 4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1
4848
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b
@@ -63,15 +63,15 @@ github.com/sirupsen/logrus v1.0.6
6363
github.com/spf13/cobra v0.0.3
6464
github.com/spf13/pflag v1.0.1
6565
github.com/theupdateframework/notary v0.6.1
66-
github.com/tonistiigi/fsutil 8abad97ee3969cdf5e9c367f46adba2c212b3ddb
67-
github.com/tonistiigi/units 29de085e9400559bd68aea2e7bc21566e7b8281d
66+
github.com/tonistiigi/fsutil b19464cd1b6a00773b4f2eb7acf9c30426f9df42
67+
github.com/tonistiigi/units 6950e57a87eaf136bbe44ef2ec8e75b9e3569de2
6868
github.com/xeipuuv/gojsonpointer 4e3ac2762d5f479393488629ee9370b50873b3a6
6969
github.com/xeipuuv/gojsonreference bd5ef7bd5415a7ac448318e64f11a24cd21e594b
7070
github.com/xeipuuv/gojsonschema 93e72a773fade158921402d6a24c819b48aba29d
7171
golang.org/x/crypto a2144134853fc9a27a7b1e3eb4f19f1a76df13c9
7272
golang.org/x/net a680a1efc54dd51c040b3b5ce4939ea3cf2ea0d1
7373
golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca
74-
golang.org/x/sys ac767d655b305d4e9612f5f6e33120b9176c4ad4
74+
golang.org/x/sys 1b2967e3c290b7c545b3db0deeda16e9be4f98a2
7575
golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0
7676
golang.org/x/time fbb02b2291d28baffd63558aa44b4b56f178d650
7777
google.golang.org/genproto 02b4e95473316948020af0b7a4f0f22c73929b0e

vendor/github.com/containerd/console/console_linux.go

Lines changed: 12 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)