Skip to content

Commit

Permalink
[wip] capture output from run to use elsewhere
Browse files Browse the repository at this point in the history
  • Loading branch information
coryb committed May 4, 2020
1 parent 134b46d commit 1330090
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 9 deletions.
3 changes: 3 additions & 0 deletions builtin/builtin.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 53 additions & 9 deletions codegen/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,13 +349,22 @@ func (cg *CodeGen) EmitFilesystemBuiltinChainStmt(ctx context.Context, scope *pa
// to be in the context of a specific function run is in.
case with.Expr.FuncLit != nil:
for _, stmt := range with.Expr.FuncLit.Body.NonEmptyStmts() {
if stmt.Call.Func.Name() != "mount" || stmt.Call.Alias == nil {
if stmt.Call.Alias == nil {
continue
}

target, err := cg.EmitStringExpr(ctx, scope, stmt.Call.Args[1])
if err != nil {
return fc, err
var target string
switch stmt.Call.Func.Name() {
case "mount":
target, err = cg.EmitStringExpr(ctx, scope, stmt.Call.Args[1])
if err != nil {
return fc, err
}
case "capture":
target = "capture"
}
if target == "" {
continue
}

calls[target] = stmt.Call
Expand All @@ -381,7 +390,40 @@ func (cg *CodeGen) EmitFilesystemBuiltinChainStmt(ctx context.Context, scope *pa
for _, target := range targets {
// Mounts are unique by its mountpoint, and its vertex representing the
// mount after execing can be aliased.
cont := ac(calls[target], exec.GetMount(target))
var cont bool
switch calls[target].Func.Name() {
case "mount":
cont = ac(calls[target], exec.GetMount(target))
case "capture":
cont = ac(calls[target], func() (string, error) {
st := exec.Root()
pw := cg.mw.WithPrefix("", false)

s, err := cg.newSession(ctx)
if err != nil {
return "", err
}

g, ctx := errgroup.WithContext(ctx)

g.Go(func() error {
return s.Run(ctx, cg.cln.Dialer())
})

var captureBuf strings.Builder
g.Go(func() error {
opts, err := cg.SolveOptions(ctx, st)
opts = append(opts, solver.WithOutputCapture(&captureBuf))
def, err := st.Marshal(ctx, llb.LinuxAmd64)
if err != nil {
return err
}
return solver.Solve(ctx, cg.cln, s, pw, def, opts...)
})
err = g.Wait()
return captureBuf.String(), err
})
}
if !cont {
return exec.Root(), ErrAliasReached
}
Expand Down Expand Up @@ -940,11 +982,13 @@ func (cg *CodeGen) EmitStringChainStmt(ctx context.Context, scope *parser.Scope,
return nil, err
}
return func(_ string) (string, error) {
str, ok := v.(string)
if !ok {
return str, errors.WithStack(ErrCodeGen{obj.Node, ErrBadCast})
switch s := v.(type) {
case string:
return s, nil
case func() (string, error):
return s()
}
return str, nil
return "", errors.WithStack(ErrCodeGen{obj.Node, ErrBadCast})
}, nil
}
}
Expand Down
2 changes: 2 additions & 0 deletions codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,8 @@ func (cg *CodeGen) EmitExecOptions(ctx context.Context, scope *parser.Scope, op
opts = append(opts, llb.Security(securityMode))
case "shlex":
opts = append(opts, &shlexOption{})
case "capture":
// no op, only relevant if aliased, handled in alias callback
case "host":
host, err := cg.EmitStringExpr(ctx, scope, args[0])
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ If more than one arg is given, it will be executed directly, without a shell.
#!hlb
fs default() {
run "arg" with option {
capture
dir "path"
env "key" "value"
forward "src" "dest"
Expand All @@ -497,6 +498,11 @@ If more than one arg is given, it will be executed directly, without a shell.
}


#### <span class='hlb-type'>option::run</span> <span class='hlb-name'>capture</span>()




#### <span class='hlb-type'>option::run</span> <span class='hlb-name'>dir</span>(<span class='hlb-type'>string</span> <span class='hlb-variable'>path</span>)

!!! info "<span class='hlb-type'>string</span> <span class='hlb-variable'>path</span>"
Expand Down
2 changes: 2 additions & 0 deletions language/builtin.hlb
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ fs shell(variadic string arg)
# @return the filesystem after the command has executed.
fs run(variadic string arg)

option::run capture()

# Sets the rootfs as read-only for the duration of the run command.
#
# @return an option to set the rootfs as read-only.
Expand Down
39 changes: 39 additions & 0 deletions solver/solve.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package solver
import (
"context"
"encoding/json"
"io"

"github.com/docker/buildx/util/progress"
"github.com/moby/buildkit/client"
Expand All @@ -26,6 +27,7 @@ type SolveInfo struct {
Callbacks []func() error `json:"-"`
ImageSpec *specs.Image
Entitlements []entitlements.Entitlement
OutputCapture io.Writer
}

func WithDownloadDockerTarball(ref string) SolveOption {
Expand Down Expand Up @@ -63,6 +65,13 @@ func WithDownloadOCITarball() SolveOption {
}
}

func WithOutputCapture(w io.Writer) SolveOption {
return func(info *SolveInfo) error {
info.OutputCapture = w
return nil
}
}

func WithCallback(fn func() error) SolveOption {
return func(info *SolveInfo) error {
info.Callbacks = append(info.Callbacks, fn)
Expand Down Expand Up @@ -174,6 +183,36 @@ func Build(ctx context.Context, c *client.Client, s *session.Session, pw progres
statusCh = pw.Status()
}

if info.OutputCapture != nil {
captureStatusCh := make(chan *client.SolveStatus)
go func(origStatusCh chan *client.SolveStatus) {
defer func() {
if origStatusCh != nil {
close(origStatusCh)
}
}()
for {
select {
case <-pw.Done():
return
case <-ctx.Done():
return
case status, ok := <-captureStatusCh:
if !ok {
return
}
for _, log := range status.Logs {
info.OutputCapture.Write(log.Data)
}
if origStatusCh != nil {
origStatusCh <- status
}
}
}
}(statusCh)
statusCh = captureStatusCh
}

g.Go(func() error {
_, err := c.Build(ctx, solveOpt, "", f, statusCh)
return err
Expand Down

0 comments on commit 1330090

Please sign in to comment.