Skip to content

buildx library as a higher-level buildkit client #1483

Description

@errordeveloper

Problem statement

When I looked at using buildkit API from a Go program, I ended up comparing what buildctl does to what buildx does and very quickly realised that buildx is a lot more advanced. I find it hard to tell what pieces I may need to borrow to create a lightweight and robust client that is able to do nearly as much as buildx.

However, currently it's not very trivial to just call buidx functions, one needs to figure out how to setup the drivers the right way, and may need to also use github.com/docker/cli/cli/command and github.com/docker/buildx/store, which do seem like very desirable dependecies for just any applications that might need embedding a buildkit client. Namely, command.Cli appeare very Docker-spefic, and store package is very specific to buildx's state management needs as CLI.

In my case I have a set of addreesses of remote buildkit deamons and TLS credentials (as structs like struct { ca, cert, key []byte }), and I'd like to either setup generic gRPC clients for each of these and create a buildkit client from that, or otherwise at very least setup buildkit client without owning the gRPC client setup also.

For this case I find that buildx remote driver abstraction is not very useful, and it also took me a lot of time to figure out how to set it up. However, I do find that build.Options struct and most of the logic in build.BuildWithResultHandler is quite useful, especially toSolveOpt appears to have what most comprehensive clients need to do.

I certainly don't want to copy some code from buildx and then maintain it. Neither I want to shell-out (for multiple reasons).

Proposal

Povide a simpler API that does most things that build package currently offers, but without CLI-centric assumptions and design aroind an equivalent of remote driver (i.e. initialised with a gRPC client or a URL). This API doesn't have to offer strong stability guarantees, it could be evolving in the way that buildx project currently does, but it's best if it stays disentanlged from the CLI use-case.


type BuildClient stuct {
  	Platforms     []specs.Platform
        Conn grpc.ClientConn
        Options Options
}

type BuildClientSet []BuildClient

func (*BuildClientSet) BuildWithResultHandler(ctx context.Context, w progress.Writer) (BuildResult, error)
func (*BuildClientSet) BuildWithResultHandler(ctx context.Context, w progress.Writer, resultHandleFunc resultHandler) BuildResult, error)

type resultHandler func(*BuildClient)

type BuildResult struct {
}

I am not sure what BuildResult should look like, but ideally it shouldn't be a nested map like it is right now, it needs to be more structured.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions