Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions frontend/dockerfile/docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ If you are using Docker v18.09 or later, BuildKit mode can be enabled by setting

BuildKit supports loading frontends dynamically from container images. Images for Dockerfile frontends are available at [`docker/dockerfile`](https://hub.docker.com/r/docker/dockerfile/tags/) repository.

To use the external frontend, the first line of your Dockerfile needs to be `# syntax=docker/dockerfile:v1.2` pointing to the
To use the external frontend, the first line of your Dockerfile needs to be `# syntax=docker/dockerfile:1.2` pointing to the
specific image you want to use.

BuildKit also ships with Dockerfile frontend builtin but it is recommended to use an external image to make sure that all
Expand Down Expand Up @@ -73,7 +73,7 @@ it if more storage space is needed.
#### Example: cache Go packages

```dockerfile
# syntax = docker/dockerfile:experimental
# syntax = docker/dockerfile:1.2
FROM golang
...
RUN --mount=type=cache,target=/root/.cache/go-build go build ...
Expand All @@ -82,7 +82,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build go build ...
#### Example: cache apt packages

```dockerfile
# syntax = docker/dockerfile:experimental
# syntax = docker/dockerfile:1.2
FROM ubuntu
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \
Expand Down Expand Up @@ -115,7 +115,7 @@ This mount type allows the build container to access secure files such as privat
#### Example: access to S3

```dockerfile
# syntax = docker/dockerfile:experimental
# syntax = docker/dockerfile:1.2
FROM python:3
RUN pip install awscli
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials aws s3 cp s3://... ...
Expand Down Expand Up @@ -147,7 +147,7 @@ This mount type allows the build container to access SSH keys via SSH agents, wi
#### Example: access to Gitlab

```dockerfile
# syntax = docker/dockerfile:experimental
# syntax = docker/dockerfile:1.2
FROM alpine
RUN apk add --no-cache openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
Expand Down Expand Up @@ -193,7 +193,7 @@ Default sandbox mode can be activated via `--security=sandbox`, but that is no-o
#### Example: check entitlements

```dockerfile
# syntax = docker/dockerfile:experimental
# syntax = docker/dockerfile:1.2-labs
FROM ubuntu
RUN --security=insecure cat /proc/self/status | grep CapEff
```
Expand Down Expand Up @@ -229,7 +229,7 @@ which needs to be enabled when starting the buildkitd daemon
#### Example: isolating external effects

```dockerfile
# syntax = docker/dockerfile:experimental
# syntax = docker/dockerfile:1.2-labs
FROM python:3.6
ADD mypackage.tgz wheels/
RUN --network=none pip install --find-links wheels mypackage
Expand Down
2 changes: 2 additions & 0 deletions frontend/gateway/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ type MountRef struct {
type MountMutableRef struct {
Ref cache.MutableRef
MountIndex int
NoCommit bool
}

type MakeMutable func(m *opspb.Mount, ref cache.ImmutableRef) (cache.MutableRef, error)
Expand Down Expand Up @@ -196,6 +197,7 @@ func PrepareMounts(ctx context.Context, mm *mounts.MountManager, cm cache.Manage
p.Actives = append(p.Actives, MountMutableRef{
MountIndex: i,
Ref: active,
NoCommit: true,
})
if m.Output != opspb.SkipOutput && ref != nil {
p.OutputRefs = append(p.OutputRefs, MountRef{
Expand Down
9 changes: 9 additions & 0 deletions solver/llbsolver/errdefs/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ func (e *ExecError) Unwrap() error {
}

func (e *ExecError) EachRef(fn func(solver.Result) error) (err error) {
m := map[solver.Result]struct{}{}
for _, res := range e.Inputs {
if res == nil {
continue
}
if _, ok := m[res]; ok {
continue
}
m[res] = struct{}{}
if err1 := fn(res); err1 != nil && err == nil {
err = err1
}
Expand All @@ -33,6 +38,10 @@ func (e *ExecError) EachRef(fn func(solver.Result) error) (err error) {
if res == nil {
continue
}
if _, ok := m[res]; ok {
continue
}
m[res] = struct{}{}
if err1 := fn(res); err1 != nil && err == nil {
err = err1
}
Expand Down
16 changes: 10 additions & 6 deletions solver/llbsolver/ops/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,20 +235,24 @@ func (e *execOp) Exec(ctx context.Context, g session.Group, inputs []solver.Resu
if m.Input == -1 {
continue
}
execInputs[i] = inputs[m.Input]
execInputs[i] = inputs[m.Input].Clone()
}
execMounts := make([]solver.Result, len(e.op.Mounts))
copy(execMounts, execInputs)
for i, res := range results {
execMounts[p.OutputRefs[i].MountIndex] = res
}
for _, active := range p.Actives {
ref, cerr := active.Ref.Commit(ctx)
if cerr != nil {
err = errors.Wrapf(err, "error committing %s: %s", active.Ref.ID(), cerr)
continue
if active.NoCommit {
active.Ref.Release(context.TODO())
} else {
ref, cerr := active.Ref.Commit(ctx)
if cerr != nil {
err = errors.Wrapf(err, "error committing %s: %s", active.Ref.ID(), cerr)
continue
}
execMounts[active.MountIndex] = worker.NewWorkerRefResult(ref, e.w)
}
execMounts[active.MountIndex] = worker.NewWorkerRefResult(ref, e.w)
}
err = errdefs.WithExecError(err, execInputs, execMounts)
} else {
Expand Down
1 change: 0 additions & 1 deletion solver/llbsolver/ops/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ func (s *FileOpSolver) getInput(ctx context.Context, idx int, inputs []fileoptyp
if cerr == nil {
outputRes[idx-len(inputs)] = worker.NewWorkerRefResult(ref.(cache.ImmutableRef), s.w)
}
inpMount.Release(context.TODO())
}

// If the action has a secondary input, commit it and set the ref on
Expand Down
8 changes: 6 additions & 2 deletions solver/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type splitResult struct {

func (r *splitResult) Release(ctx context.Context) error {
if atomic.AddInt64(&r.released, 1) > 1 {
err := errors.Errorf("releasing already released reference")
err := errors.Errorf("releasing already released reference %+v", r.Result.ID())
logrus.Error(err)
return err
}
Expand Down Expand Up @@ -78,10 +78,14 @@ func NewSharedCachedResult(res CachedResult) *SharedCachedResult {
}
}

func (r *SharedCachedResult) Clone() CachedResult {
func (r *SharedCachedResult) CloneCachedResult() CachedResult {
return &clonedCachedResult{Result: r.SharedResult.Clone(), cr: r.CachedResult}
}

func (r *SharedCachedResult) Clone() Result {
return r.CloneCachedResult()
}

func (r *SharedCachedResult) Release(ctx context.Context) error {
return r.SharedResult.Release(ctx)
}
Expand Down
2 changes: 1 addition & 1 deletion solver/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func (s *scheduler) build(ctx context.Context, edge Edge) (CachedResult, error)
if err := p.Receiver.Status().Err; err != nil {
return nil, err
}
return p.Receiver.Status().Value.(*edgeState).result.Clone(), nil
return p.Receiver.Status().Value.(*edgeState).result.CloneCachedResult(), nil
}

// newPipe creates a new request pipe between two edges
Expand Down
1 change: 1 addition & 0 deletions solver/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3640,6 +3640,7 @@ type dummyResult struct {
func (r *dummyResult) ID() string { return r.id }
func (r *dummyResult) Release(context.Context) error { return nil }
func (r *dummyResult) Sys() interface{} { return r }
func (r *dummyResult) Clone() Result { return r }

func testOpResolver(v Vertex, b Builder) (Op, error) {
if op, ok := v.Sys().(Op); ok {
Expand Down
1 change: 1 addition & 0 deletions solver/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type Result interface {
ID() string
Release(context.Context) error
Sys() interface{}
Clone() Result
}

// CachedResult is a result connected with its cache key
Expand Down
8 changes: 8 additions & 0 deletions worker/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,11 @@ func (r *workerRefResult) Release(ctx context.Context) error {
func (r *workerRefResult) Sys() interface{} {
return r.WorkerRef
}

func (r *workerRefResult) Clone() solver.Result {
r2 := *r
if r.ImmutableRef != nil {
r.ImmutableRef = r.ImmutableRef.Clone()
}
return &r2
}