From d1bd12cab2775742a621e60918f85ecf71f9eb7d Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 29 Aug 2017 17:05:48 -0700 Subject: [PATCH] llb: skip outputs of readonly mounts Signed-off-by: Tonis Tiigi --- client/llb/exec.go | 47 ++++++++++++++++++++++++++-------- client/llb/state.go | 2 +- examples/buildkit3/buildkit.go | 2 +- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/client/llb/exec.go b/client/llb/exec.go index 8f81c831..de1d887a 100644 --- a/client/llb/exec.go +++ b/client/llb/exec.go @@ -14,14 +14,19 @@ type Meta struct { Cwd string } -func NewExecOp(root Output, meta Meta) *ExecOp { +func NewExecOp(root Output, meta Meta, readOnly bool) *ExecOp { e := &ExecOp{meta: meta} rootMount := &mount{ - target: pb.RootMount, - source: root, + target: pb.RootMount, + source: root, + readonly: readOnly, } e.mounts = append(e.mounts, rootMount) - e.root = &output{vertex: e, getIndex: e.getMountIndexFn(rootMount)} + if readOnly { + e.root = root + } else { + e.root = &output{vertex: e, getIndex: e.getMountIndexFn(rootMount)} + } rootMount.output = e.root return e @@ -52,7 +57,11 @@ func (e *ExecOp) AddMount(target string, source Output, opt ...MountOption) Outp o(m) } e.mounts = append(e.mounts, m) - m.output = &output{vertex: e, getIndex: e.getMountIndexFn(m)} + if m.readonly { + m.output = source + } else { + m.output = &output{vertex: e, getIndex: e.getMountIndexFn(m)} + } e.cachedPB = nil return m.output } @@ -109,7 +118,8 @@ func (e *ExecOp) Marshal() ([]byte, error) { }, } - for i, m := range e.mounts { + outIndex := 0 + for _, m := range e.mounts { inputIndex := pb.InputIndex(len(pop.Inputs)) if m.source != nil { inp, err := m.source.ToInput() @@ -134,11 +144,17 @@ func (e *ExecOp) Marshal() ([]byte, error) { inputIndex = pb.Empty } + outputIndex := pb.OutputIndex(-1) + if !m.readonly { + outputIndex = pb.OutputIndex(outIndex) + outIndex++ + } + pm := &pb.Mount{ Input: inputIndex, Dest: m.target, Readonly: m.readonly, - Output: pb.OutputIndex(i), + Output: outputIndex, Selector: m.selector, } peo.Mounts = append(peo.Mounts, pm) @@ -176,10 +192,15 @@ func (e *ExecOp) getMountIndexFn(m *mount) func() (pb.OutputIndex, error) { return e.mounts[i].target < e.mounts[j].target }) - for i, m2 := range e.mounts { + i := 0 + for _, m2 := range e.mounts { + if m2.readonly { + continue + } if m == m2 { return pb.OutputIndex(i), nil } + i++ } return pb.OutputIndex(0), errors.Errorf("invalid mount") } @@ -268,9 +289,15 @@ func AddMount(dest string, mountState State, opts ...MountOption) RunOption { } } +func ReadonlyRootFS(ei ExecInfo) ExecInfo { + ei.ReadonlyRootFS = true + return ei +} + type ExecInfo struct { - State State - Mounts []MountInfo + State State + Mounts []MountInfo + ReadonlyRootFS bool } type MountInfo struct { diff --git a/client/llb/state.go b/client/llb/state.go index 680ceb7d..236bbccd 100644 --- a/client/llb/state.go +++ b/client/llb/state.go @@ -118,7 +118,7 @@ func (s State) Run(ro ...RunOption) ExecState { Env: getEnv(ei.State), } - exec := NewExecOp(s.Output(), meta) + exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS) for _, m := range ei.Mounts { exec.AddMount(m.Target, m.Source, m.Opts...) } diff --git a/examples/buildkit3/buildkit.go b/examples/buildkit3/buildkit.go index 0e76dd9a..3a82d9e0 100644 --- a/examples/buildkit3/buildkit.go +++ b/examples/buildkit3/buildkit.go @@ -115,7 +115,7 @@ func copyFrom(src llb.State, srcPath, destPath string) llb.StateOption { // copy copies files between 2 states using cp until there is no copyOp func copy(src llb.State, srcPath string, dest llb.State, destPath string) llb.State { cpImage := llb.Image("docker.io/library/alpine:latest") - cp := cpImage.Run(llb.Shlexf("cp -a /src%s /dest%s", srcPath, destPath)) + cp := cpImage.Run(llb.Shlexf("cp -a /src%s /dest%s", srcPath, destPath), llb.ReadonlyRootFS) cp.AddMount("/src", src, llb.Readonly) return cp.AddMount("/dest", dest) }