Skip to content

Instantly share code, notes, and snippets.

@aaronlehmann
Created August 10, 2021 18:57

Revisions

  1. aaronlehmann created this gist Aug 10, 2021.
    8 changes: 8 additions & 0 deletions go.mod
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    module github.com/aaronlehmann/bkcacherepro

    go 1.16

    require (
    github.com/moby/buildkit v0.9.0
    golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
    )
    100 changes: 100 additions & 0 deletions main.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,100 @@
    package main

    import (
    "context"
    "fmt"
    "os"

    _ "github.com/moby/buildkit/client/connhelper/dockercontainer"

    "github.com/moby/buildkit/client"
    "github.com/moby/buildkit/client/llb"
    "github.com/moby/buildkit/util/appdefaults"
    "github.com/moby/buildkit/util/progress/progresswriter"
    "golang.org/x/sync/errgroup"
    )

    func main() {
    st := llb.Image("alpine")

    st = st.Run(
    llb.Shlex(`sh -c "mkdir -p /mnt/data/d1 && ln -s /mnt/data /data"`),
    ).Root()

    st1 := st.Run(
    llb.Shlex(`sh -c "echo abc > /data/d1/foo"`),
    ).Root()

    fmt.Println("Copying from st1 with a single file at /data/d1/foo:")
    if err := copyAndList(st1); err != nil {
    panic(err)
    }

    fmt.Println("Copying from stock alpine image - copy should not be cached!:")
    if err := copyAndList(llb.Image("alpine")); err != nil {
    panic(err)
    }
    }

    func copyAndList(st llb.State) error {
    copied := llb.Scratch().File(
    llb.Copy(st, "/mnt/data/d1", "/", &llb.CopyInfo{IncludePatterns: []string{"f*"}}),
    )

    findSt := llb.Image("alpine").Run(
    llb.Shlex(`sh -c "apk add -U findutils"`),
    ).Root().Run(
    llb.Shlex(`sh -c "find . -ls"`),
    llb.AddMount("/d", copied),
    llb.Dir("/d"),
    llb.IgnoreCache,
    )

    ctx := context.Background()
    def, err := findSt.Marshal(ctx, llb.LinuxAmd64)
    if err != nil {
    return err
    }

    addr := os.Getenv("BUILDKIT_HOST")
    if addr == "" {
    addr = appdefaults.Address
    }

    c, err := client.New(ctx, addr, client.WithFailFast())
    if err != nil {
    return err
    }

    pw, err := progresswriter.NewPrinter(context.TODO(), os.Stderr, "plain")
    if err != nil {
    return err
    }
    mw := progresswriter.NewMultiWriter(pw)

    eg, ctx := errgroup.WithContext(ctx)

    cwd, err := os.Getwd()
    if err != nil {
    return err
    }

    eg.Go(func() error {
    solveOpt := client.SolveOpt{
    Exports: []client.ExportEntry{{
    Type: client.ExporterLocal,
    OutputDir: cwd,
    }},
    }

    _, err := c.Solve(ctx, def, solveOpt, progresswriter.ResetTime(mw.WithPrefix("", false)).Status())
    return err
    })

    eg.Go(func() error {
    <-pw.Done()
    return pw.Err()
    })

    return eg.Wait()
    }