github.com/grahambrereton-form3/tilt@v0.10.18/cmd/buildkitapi/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "encoding/json" 6 "flag" 7 "io" 8 "log" 9 "os" 10 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/client" 13 "github.com/docker/docker/pkg/jsonmessage" 14 controlapi "github.com/moby/buildkit/api/services/control" 15 "github.com/pkg/errors" 16 17 "github.com/windmilleng/tilt/internal/build" 18 ) 19 20 var useCache bool 21 22 // A small utility for running Buildkit on the dockerfile 23 // in the current directory printing out all the buildkit api 24 // response protobufs. 25 func main() { 26 flag.BoolVar(&useCache, "cache", false, "Enable docker caching") 27 flag.Parse() 28 29 err := run() 30 if err != nil { 31 log.Fatal(err) 32 } 33 } 34 35 func run() error { 36 ctx := context.Background() 37 d, err := client.NewEnvClient() 38 if err != nil { 39 return err 40 } 41 42 d.NegotiateAPIVersion(ctx) 43 44 pr, pw := io.Pipe() 45 go func() { 46 err := build.TarPath(ctx, pw, ".") 47 if err != nil { 48 _ = pw.CloseWithError(err) 49 } else { 50 _ = pw.Close() 51 } 52 }() 53 54 opts := types.ImageBuildOptions{} 55 opts.Version = types.BuilderBuildKit 56 opts.Dockerfile = "Dockerfile" 57 opts.Context = pr 58 if !useCache { 59 opts.NoCache = true 60 } 61 62 response, err := d.ImageBuild(ctx, pr, opts) 63 if err != nil { 64 return err 65 } 66 defer func() { 67 _ = response.Body.Close() 68 }() 69 70 return readDockerOutput(ctx, response.Body) 71 } 72 73 func readDockerOutput(ctx context.Context, reader io.Reader) error { 74 decoder := json.NewDecoder(reader) 75 76 for decoder.More() { 77 message := jsonmessage.JSONMessage{} 78 err := decoder.Decode(&message) 79 if err != nil { 80 return errors.Wrap(err, "decoding docker output") 81 } 82 83 if messageIsFromBuildkit(message) { 84 err := writeBuildkitStatus(message.Aux) 85 if err != nil { 86 return err 87 } 88 } 89 } 90 return nil 91 } 92 93 func writeBuildkitStatus(aux *json.RawMessage) error { 94 var resp controlapi.StatusResponse 95 var dt []byte 96 if err := json.Unmarshal(*aux, &dt); err != nil { 97 return err 98 } 99 if err := (&resp).Unmarshal(dt); err != nil { 100 return err 101 } 102 103 return json.NewEncoder(os.Stdout).Encode(resp) 104 } 105 106 func messageIsFromBuildkit(msg jsonmessage.JSONMessage) bool { 107 return msg.ID == "moby.buildkit.trace" 108 }