Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ls: add format, quiet and no-trunc opts #830

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

crazy-max
Copy link
Member

@crazy-max crazy-max commented Nov 8, 2021

Fixes #325
Fixes #380
Fixes #764

Adds filter, format and no-trunc options for ls command:

$ docker buildx ls
NAME/NODE             DRIVER/ENDPOINT                                             STATUS     BUILDKIT   PLATFORMS
builder               docker-container
 \_ builder0           \_ unix:///var/run/docker.sock                             running    7615120    linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le,…
 \_ mac-mini-m1        \_ tcp://mac-mini-m1.home.foo.com:2376                     stopped               linux/arm64*
builder2*             docker-container
 \_ builder20          \_ unix:///var/run/docker.sock                             running    7615120    linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le,…
remote-builder        remote
 \_ remote-builder0    \_ docker-container://buildx_buildkit_dk-remote-builder0   inactive
 \_ aws_graviton2      \_ tcp://10.0.0.1:1234                                     running               darwin/arm64*, linux/arm64*, linux/arm/v5*, linux/arm/v6*, linux/arm/v7*, windows/arm64*
 \_ linuxone_s390x     \_ tcp://10.0.0.2:1234                                     running               linux/s390x*
default               docker
 \_ default            \_ default                                                 running    20.10.21   linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386,…
desktop-linux         docker
 \_ desktop-linux      \_ desktop-linux                                           error
desktop-windows       docker
 \_ desktop-windows    \_ desktop-windows                                         error
docker1903            docker
 \_ docker1903         \_ docker1903                                              running    19.03.15   linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386,…
docker2010            docker
 \_ docker2010         \_ docker2010                                              running    20.10.21   linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386,…

Failed to get status for desktop-linux (desktop-linux): protocol not available
Failed to get status for desktop-windows (desktop-windows): protocol not available
$ docker buildx ls --no-trunc
NAME/NODE             DRIVER/ENDPOINT                                             STATUS     BUILDKIT   PLATFORMS
builder               docker-container
 \_ builder0           \_ unix:///var/run/docker.sock                             running    7615120    linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
 \_ mac-mini-m1        \_ tcp://mac-mini-m1.home.foo.com:2376                     stopped               linux/arm64*
builder2*             docker-container
 \_ builder20          \_ unix:///var/run/docker.sock                             running    7615120    linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
remote-builder        remote
 \_ remote-builder0    \_ docker-container://buildx_buildkit_dk-remote-builder0   inactive
 \_ aws_graviton2      \_ tcp://10.0.0.1:1234                                     running               darwin/arm64*, linux/arm64*, linux/arm/v5*, linux/arm/v6*, linux/arm/v7*, windows/arm64*
 \_ linuxone_s390x     \_ tcp://10.0.0.2:1234                                     running               linux/s390x*
default               docker
 \_ default            \_ default                                                 running    20.10.21   linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
desktop-linux         docker
 \_ desktop-linux      \_ desktop-linux                                           error
desktop-windows       docker
 \_ desktop-windows    \_ desktop-windows                                         error
docker1903            docker
 \_ docker1903         \_ docker1903                                              running    19.03.15   linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
docker2010            docker
 \_ docker2010         \_ docker2010                                              running    20.10.21   linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

Failed to get status for desktop-linux (desktop-linux): protocol not available
Failed to get status for desktop-windows (desktop-windows): protocol not available
$ docker buildx ls --quiet
builder
builder2
remote-builder
default
desktop-linux
desktop-windows
docker1903
docker2010
$ docker buildx ls --format json
{"Name":"builder","Driver":"docker-container","Dynamic":false,"Nodes":[{"Name":"builder0","Endpoint":"unix:///var/run/docker.sock","Platforms":["linux/amd64","linux/amd64/v2","linux/amd64/v3","linux/arm64","linux/riscv64","linux/ppc64le","linux/s390x","linux/386","linux/mips64le","linux/mips64","linux/arm/v7","linux/arm/v6"],"Flags":["--debug","--allow-insecure-entitlement","security.insecure","--allow-insecure-entitlement","network.host"],"DriverOpts":{"env.BUILDKIT_STEP_LOG_MAX_SIZE":"10485760","env.BUILDKIT_STEP_LOG_MAX_SPEED":"10485760","env.JAEGER_TRACE":"localhost:6831","image":"moby/buildkit:master","network":"host"},"Status":"running","Version":"7615120"},{"Name":"mac-mini-m1","Endpoint":"tcp://mac-mini-m1.home.foo.com:2376","DriverOpts":{"image":"moby/buildkit:master"},"Status":"stopped"}]}
{"Name":"builder2","Driver":"docker-container","Dynamic":false,"Nodes":[{"Name":"builder20","Endpoint":"unix:///var/run/docker.sock","Platforms":["linux/amd64","linux/amd64/v2","linux/amd64/v3","linux/arm64","linux/riscv64","linux/ppc64le","linux/s390x","linux/386","linux/mips64le","linux/mips64","linux/arm/v7","linux/arm/v6"],"Flags":["--debug","--allow-insecure-entitlement","security.insecure","--allow-insecure-entitlement","network.host"],"DriverOpts":{"env.BUILDKIT_STEP_LOG_MAX_SIZE":"10485760","env.BUILDKIT_STEP_LOG_MAX_SPEED":"10485760","env.JAEGER_TRACE":"localhost:6831","image":"moby/buildkit:master","network":"host"},"Status":"running","Version":"7615120"}]}
{"Name":"remote-builder","Driver":"remote","Dynamic":false,"Nodes":[{"Name":"remote-builder0","Endpoint":"docker-container://buildx_buildkit_dk-remote-builder0","Status":"inactive"},{"Name":"aws_graviton2","Endpoint":"tcp://10.0.0.2:1234","Platforms":["linux/arm64","linux/arm/v7","linux/arm/v6"],"DriverOpts":{"cacert":"/home/crazy/.certs/aws_graviton2/ca.pem","cert":"/home/crazy/.certs/aws_graviton2/cert.pem","key":"/home/crazy/.certs/aws_graviton2/key.pem"},"Status":"running"},{"Name":"linuxone_s390x","Endpoint":"tcp://10.0.0.1:1234","Platforms":["linux/s390x"],"DriverOpts":{"cacert":"/home/crazy/.certs/linuxone_s390x/ca.pem","cert":"/home/crazy/.certs/linuxone_s390x/cert.pem","key":"/home/crazy/.certs/linuxone_s390x/key.pem"},"Status":"running"}]}
{"Name":"default","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"default","Endpoint":"default","Platforms":["linux/amd64","linux/arm64","linux/riscv64","linux/ppc64le","linux/s390x","linux/386","linux/arm/v7","linux/arm/v6"],"Status":"running","Version":"20.10.21"}]}
{"Name":"desktop-linux","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"desktop-linux","Endpoint":"desktop-linux","Status":"error","Err":"protocol not available"}]}
{"Name":"desktop-windows","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"desktop-windows","Endpoint":"desktop-windows","Status":"error","Err":"protocol not available"}]}
{"Name":"docker1903","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"docker1903","Endpoint":"docker1903","Platforms":["linux/amd64","linux/arm64","linux/riscv64","linux/ppc64le","linux/s390x","linux/386","linux/arm/v7","linux/arm/v6"],"Status":"running","Version":"19.03.15"}]}
{"Name":"docker2010","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"docker2010","Endpoint":"docker2010","Platforms":["linux/amd64","linux/arm64","linux/riscv64","linux/ppc64le","linux/s390x","linux/386","linux/arm/v7","linux/arm/v6"],"Status":"running","Version":"20.10.21"}]}
$ docker buildx ls --format raw
name: builder
driver: docker-container
nodes:

  name: builder0
  endpoint: unix:///var/run/docker.sock
  status: running
  buildkit: v0.10.6
  platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6

  name: mac-mini-m1
  endpoint: tcp://mac-mini-m1.home.foo.com:2376
  status: running
  buildkit: v0.10.6
  platforms: linux/arm64*, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6

name: builder2*
driver: docker-container
nodes:

  name: builder20
  endpoint: unix:///var/run/docker.sock
  status: running
  buildkit: v0.10.6
  platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6

name: remote-builder
driver: remote
nodes:

  name: remote-builder0
  endpoint: docker-container://buildx_buildkit_dk-remote-builder0
  status: inactive

  name: aws_graviton2
  endpoint: tcp://10.0.0.1:1234
  status: running
  platforms: darwin/arm64*, linux/arm64*, linux/arm/v5*, linux/arm/v6*, linux/arm/v7*, windows/arm64*

  name: linuxone_s390x
  endpoint: tcp://10.0.0.2:1234
  status: running
  platforms: linux/s390x*

name: default
driver: docker
nodes:

  name: default
  endpoint: default
  status: running
  buildkit: 20.10.21
  platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

name: desktop-linux
error: protocol not available

name: desktop-windows
error: protocol not available

name: docker1903
driver: docker
nodes:

  name: docker1903
  endpoint: docker1903
  status: running
  buildkit: 19.03.15
  platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

name: docker2010
driver: docker
nodes:

  name: docker2010
  endpoint: docker2010
  status: running
  buildkit: 20.10.21
  platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

bake/remote.go Outdated Show resolved Hide resolved
driver/driverutil/driverutil.go Outdated Show resolved Hide resolved
commands/bake.go Outdated Show resolved Hide resolved
commands/create.go Outdated Show resolved Hide resolved
util/dockerutil/docker.go Outdated Show resolved Hide resolved
util/formatter/formatter.go Outdated Show resolved Hide resolved
commands/ls.go Outdated Show resolved Hide resolved
commands/ls.go Outdated Show resolved Hide resolved
@thaJeztah
Copy link
Member

I'll try to have a closer look, but some quick thoughts

For the table format (default), errors are now displayed below the table to avoid a messy output as suggested by @thaJeztah in #764.

Hm.. yes, so I suggested that indeed. I think my initial thought there was that the problem in the current output was that the error message took the place of the STATUS column, so the STATUS columnn either had a "known" status, or contained an error message; the WARN[0020] commandConn.CloseWrite: commandconn: failed to wait: signal: killed lines definitely felt out of place though.

Looking at your example output, I'm now wondering if (instead) it would make sense to add an ERROR column; this would still allop the error to be grouped with the builder, but the STATUS column to show more useful information.

Similar to docker stack ps;

docker service create --name foobar nginx:alpine
docker service ps foobar

ID             NAME       IMAGE          NODE             DESIRED STATE   CURRENT STATE            ERROR     PORTS
a9b0sgzs04ej   foobar.1   nginx:alpine   docker-desktop   Running         Running 11 seconds ago

docker service create --name failing --detach busybox sh -c 'sleep 2; exit 1'
docker service ps failing
ID             NAME            IMAGE            NODE             DESIRED STATE   CURRENT STATE          ERROR                       PORTS
jskpciju2hpw   failing.1       busybox:latest   docker-desktop   Ready           Ready 1 second ago
mfl1c0dr88wf    \_ failing.1   busybox:latest   docker-desktop   Shutdown        Failed 1 second ago    "task: non-zero exit (1)"
wmg9tn7w6btk    \_ failing.1   busybox:latest   docker-desktop   Shutdown        Failed 9 seconds ago   "task: non-zero exit (1)"

I think docker stack ps by default truncates output (to keep a shorter line length), so to view the full error message, the --no-trunc option may be needed in some cases.

A progress output has also been added but we could hide it if you prefer.

Yes, I'm a bit on the fence on that one. That said, "it's tricky" docker service ps is of course handled server-side, which allows it to keep state, and present the current results without delay, whereas docker buildx ls will have to connect to all builders every time it's called.

Something "in between" would be to have a way to stay "attached" (like docker stats); print all builders, and refresh their status once we get those results, but that may feel a bit foreign as well (compared to other ps / ls commands).

Overall, I'm wondering if we could find some middle-ground where docker buildx ls / docker builder ls would provide a quick overview of the builders that are defined (perhaps skipping actually checking status), as currently a single offline builder blocks / slows down the output, which makes it quite cumbersome to use.

I'm also looking if we can format the output more so that the "essential" information can be presented as "one row per builder", instead of the staggered (multiple lines per builder) output, which makes it hard to see "at a glance" what nodes I have, and to find the information.

Currently we have;

  • Name
  • Node
  • Driver
  • Endpoint
  • Status
  • Platforms
  • (Error)

Of those;

  • Name, Driver, and (possibly) Platforms are useful information (although Platforms can get wieldy easily).
  • Status will be useful, but is the tricky one (see discussion above)
  • I'm a bit on the fence on Node and Endpoint; I guess the information is specifically useful if a builder uses multiple nodes, but may not always be needed to get a quick overview? Depending on how builders are used, giving a sensible name to your nodes would help. Perhaps we need a --verbose option to expand builders to include the nodes that are part of it.

@crazy-max
Copy link
Member Author

@thaJeztah Switched to cli formatter. See updated PR description.

return json.Marshal(struct {
Name string
Endpoint string
Platforms []string `json:",omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we haven't been very consistent in these, but wondering if we should include an explicit name to use in the json output; wdyt? i.e., if we explicitly want the output to be starting with an uppercase;

Suggested change
Platforms []string `json:",omitempty"`
Platforms []string `json:"Platforms,omitempty"`

Comment on lines +179 to +183
var pp []string
for _, p := range n.Platforms {
pp = append(pp, platforms.Format(p))
}
return json.Marshal(struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was initially wondering if we should have an actual type for this; possibly if we need specific formatting functions for printing, we could define those on the type.

Then I wondered what we needed the ad-hoc type for (was it because of recursion happening during MarshalJSON?); but then noticed the platforms handling above.

Do you know what specifically was needed to use the platforms.Format()? Out of curiousity, I tried what happened if we use []ocispecs.Platform as-is, and (at a glance ⚠️), the output seems to look fine.

This is still using the ad-hoc type, but updating it to use OCI platform;

diff --git a/builder/node.go b/builder/node.go
index 665413f7..2954b153 100644
--- a/builder/node.go
+++ b/builder/node.go
@@ -5,7 +5,6 @@ import (
        "encoding/json"
        "strings"

-       "github.com/containerd/containerd/platforms"
        "github.com/docker/buildx/driver"
        ctxkube "github.com/docker/buildx/driver/kubernetes/context"
        "github.com/docker/buildx/store"
@@ -176,25 +175,21 @@ func (n *Node) MarshalJSON() ([]byte, error) {
                status = "error"
                err = strings.TrimSpace(n.Err.Error())
        }
-       var pp []string
-       for _, p := range n.Platforms {
-               pp = append(pp, platforms.Format(p))
-       }
        return json.Marshal(struct {
                Name        string
                Endpoint    string
-               Platforms   []string          `json:",omitempty"`
-               Flags       []string          `json:",omitempty"`
-               DriverOpts  map[string]string `json:",omitempty"`
-               Files       map[string][]byte `json:",omitempty"`
-               Status      string            `json:",omitempty"`
-               ProxyConfig map[string]string `json:",omitempty"`
-               Version     string            `json:",omitempty"`
-               Err         string            `json:",omitempty"`
+               Platforms   []ocispecs.Platform `json:",omitempty"`
+               Flags       []string            `json:",omitempty"`
+               DriverOpts  map[string]string   `json:",omitempty"`
+               Files       map[string][]byte   `json:",omitempty"`
+               Status      string              `json:",omitempty"`
+               ProxyConfig map[string]string   `json:",omitempty"`
+               Version     string              `json:",omitempty"`
+               Err         string              `json:",omitempty"`
        }{
                Name:        n.Name,
                Endpoint:    n.Endpoint,
-               Platforms:   pp,
+               Platforms:   n.Platforms,
                Flags:       n.Flags,
                DriverOpts:  n.DriverOpts,
                Files:       n.Files,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the above, the output seems to be fine (but perhaps there's specific corner-cases we're not accounting for?)

./bin/build/docker-buildx ls
NAME/NODE           DRIVER/ENDPOINT     STATUS    BUILDKIT                           PLATFORMS
default *           docker
 \_ default          \_ default         running   22.06.0-beta.0-902-g2708be0db4.m   linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x,…
desktop-linux       docker
 \_ desktop-linux    \_ desktop-linux   running   22.06.0-beta.0-902-g2708be0db4.m   linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x,…
foo                 docker
 \_ foo              \_ foo             error

Failed to get status for foo (foo): Unix socket path "/var/folders/6f/tz5jf4nn1_n5jb0ctrrw5p2w0000gn/T/TestBuildWithBuildercustom_context67217891/001/docker.sock" is too long

👆 😂 Ah, fun; looks like I ran some integration test on my machine, and macOS "temp" directories are symlinks, and the actual location looks to be too long.

I also tried outputing only the .Platforms, which also seems to work, although (not sure where those come from), it looks like there's empty lines in between each row 🤔

 ./bin/build/docker-buildx ls --format '{{.Platforms}}'

linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64

linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but perhaps there's specific corner-cases we're not accounting for?

Oh! Perhaps this was for the JSON format? As without it, it would render the platform as a struct? (Wondering if perhaps we should actually keep that 🤔)

 ./bin/build/docker-buildx ls --format json
{"Name":"default","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"default","Endpoint":"default","Platforms":[{"architecture":"arm64","os":"linux"},{"architecture":"amd64","os":"linux"},{"architecture":"amd64","os":"linux","variant":"v2"},{"architecture":"riscv64","os":"linux"},{"architecture":"ppc64le","os":"linux"},{"architecture":"s390x","os":"linux"},{"architecture":"mips64le","os":"linux"},{"architecture":"mips64","os":"linux"}],"Status":"running","Version":"22.06.0-beta.0-902-g2708be0db4.m"}]}
{"Name":"desktop-linux","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"desktop-linux","Endpoint":"desktop-linux","Platforms":[{"architecture":"arm64","os":"linux"},{"architecture":"amd64","os":"linux"},{"architecture":"amd64","os":"linux","variant":"v2"},{"architecture":"riscv64","os":"linux"},{"architecture":"ppc64le","os":"linux"},{"architecture":"s390x","os":"linux"},{"architecture":"mips64le","os":"linux"},{"architecture":"mips64","os":"linux"}],"Status":"running","Version":"22.06.0-beta.0-902-g2708be0db4.m"}]}
{"Name":"foo","Driver":"docker","Dynamic":false,"Nodes":[{"Name":"foo","Endpoint":"foo","Status":"error","Err":"Unix socket path \"/var/folders/6f/tz5jf4nn1_n5jb0ctrrw5p2w0000gn/T/TestBuildWithBuildercustom_context67217891/001/docker.sock\" is too long"}]}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, and I guess it doesn't show the default / native platform; (linux/arm64* vs linux/arm64);

edit: ⚠️ actually, that's not it (where is that added?)

If we really want a string presentation in all cases, we could have a local type that wraps oci.Platform and implements MarshalText;

diff --git a/builder/node.go b/builder/node.go
index 665413f7..5ee00381 100644
--- a/builder/node.go
+++ b/builder/node.go
@@ -166,6 +166,12 @@ func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err e
        return b.nodes, nil
 }

+type Platform ocispecs.Platform
+
+func (p *Platform) MarshalText() ([]byte, error) {
+       return []byte(platforms.Format(ocispecs.Platform(*p))), nil
+}
+
 func (n *Node) MarshalJSON() ([]byte, error) {
        var status string
        if n.DriverInfo != nil {
@@ -176,14 +182,14 @@ func (n *Node) MarshalJSON() ([]byte, error) {
                status = "error"
                err = strings.TrimSpace(n.Err.Error())
        }
-       var pp []string
+       var pp []Platform
        for _, p := range n.Platforms {
-               pp = append(pp, platforms.Format(p))
+               pp = append(pp, Platform(p))
        }
        return json.Marshal(struct {
                Name        string
                Endpoint    string
-               Platforms   []string          `json:",omitempty"`
+               Platforms   []Platform        `json:",omitempty"`
                Flags       []string          `json:",omitempty"`
                DriverOpts  map[string]string `json:",omitempty"`
                Files       map[string][]byte `json:",omitempty"`

Copy link
Member Author

@crazy-max crazy-max Dec 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know what specifically was needed to use the platforms.Format()?

This is for the --format json so we are consistent with table / raw result.

I also tried outputing only the .Platforms, which also seems to work, although (not sure where those come from), it looks like there's empty lines in between each row 🤔

Blank lines are the builders that don't carry platforms (only nodes). I'm not sure how we can handle this with custom go template as builders and nodes are really different.

Oh, and I guess it doesn't show the default / native platform; (linux/arm64* vs linux/arm64);

* on platform means user enforces this platform when creating the builder or appending a node (create --platform linux/amd64) so it will build on this node if it matches the target platform. Atm table, raw format shows supported and preferred platforms but json format doesn't (maybe it should?).

@thaJeztah
Copy link
Member

For the raw output; do we need some header to indicate that it's a list of nodes? Something like;

./bin/build/docker-buildx ls --format raw
name: default *
driver: docker
nodes:
  name: default
  endpoint: default
  status: running
  buildkit: 22.06.0-beta.0-902-g2708be0db4.m
  platforms: linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64

name: desktop-linux
driver: docker
nodes:
  name: desktop-linux
  endpoint: desktop-linux
  status: running
  buildkit: 22.06.0-beta.0-902-g2708be0db4.m
  platforms: linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64

@jedevc
Copy link
Collaborator

jedevc commented Dec 13, 2022

For buildx ls, we should follow similar conventions to buildx inspect. i.e. the following should be the same:

$ docker buildx inspect desktop-linux
Name:   desktop-linux
Driver: docker

Nodes:
Name:      desktop-linux
Endpoint:  desktop-linux
Status:    running
Buildkit:  20.10.21
Platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

$ buildx ls --format raw
...
name: desktop-linux
driver: docker

  name: desktop-linux
  endpoint: desktop-linux
  status: running
  buildkit: 20.10.21
  platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

I think we should stick to the title-case naming of inspect, and follow the status-quo there. However, I think maybe we could indent the Nodes of inspect, and keep the nodes key as suggested by @thaJeztah here.

buildx ls should also take at least one argument (ideally, arbitrary), which should do the job of filtering, similar to how docker image ls operates:

$ docker image ls registry
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
registry     2         81c944c2288b   4 weeks ago   24.1MB

I think this makes buildx inspect X = buildx ls X --raw? I think it's fine to have inspect as an effective alias (even if they're implemented slightly differently under the hood) for this.


Slightly unrelated, since this has been an issue for a while - how do we determine the size of the table? The produced table is quite large, and now that we're shortening the list of platforms, I was wondering if maybe we could consider setting the default size of the table to the width of the terminal window if that info is accessible? It can be kinda frustrating to view in smaller terminals as is, though it's mostly a separate issue, since it has been like this for a while.

@crazy-max
Copy link
Member Author

For buildx ls, we should follow similar conventions to buildx inspect. i.e. the following should be the same:

I think it should be the other way around to be consistent with docker/cli like:

$ docker image ls --format raw
repository: buildkit-tests
tag: latest
image_id: 86c59caf767c
created_at: 2022-12-13 07:58:20 +0100 CET
virtual_size: 1.65GB

repository: <none>
tag: <none>
image_id: d57078eda7ec
created_at: 2022-12-13 07:53:45 +0100 CET
virtual_size: 1.65GB

repository: <none>
tag: <none>
image_id: fdc8939962ce
created_at: 2022-12-13 07:47:31 +0100 CET
virtual_size: 1.65GB

I want to also add the same flags for the inspect command so we can get rid of this: https://github.com/docker/setup-buildx-action/blob/39a1a82492fd1ad19af19d61b5f748e4cb6cd1af/src/buildx.ts#L111-L182 😅

buildx ls should also take at least one argument (ideally, arbitrary), which should do the job of filtering, similar to how docker image ls operates:

sgtm for a follow-up as well

Slightly unrelated, since this has been an issue for a while - how do we determine the size of the table? The produced table is quite large, and now that we're shortening the list of platforms, I was wondering if maybe we could consider setting the default size of the table to the width of the terminal window if that info is accessible? It can be kinda frustrating to view in smaller terminals as is, though it's mostly a separate issue, since it has been like this for a while.

Depends if docker/cli provides this, I'm not sure.

@thaJeztah
Copy link
Member

thaJeztah commented Dec 19, 2022

Slightly unrelated, since this has been an issue for a while - how do we determine the size of the table?

I'm still a bit on the fence how relevant showing all platforms is in the default presentation?

  • Do we know how it's used?
  • Should it default to show the default (native) platform only?
  • ^^ and only show the emulated platforms on inspect ?

In general, for the "overview" I (personally) feel like it's "just to get a quick list of builders", so that I can

  • "pick" one (docker builder use / docker buildx use)
  • have a quick overview of builders that may need to be updated (seeing an older version in the VERSION BUILDKIT column
  • manage them (docker builder rm /docker buildx rm etc.).

Within that context, perhaps "native" platform is relevant (I want to use a native arm64 builder), but emulated platforms may be less relevant (but we could add a --filter platform=.... option if I want to make a selection of builders that can support a specific platform).

@jedevc jedevc added this to the v0.11.0 milestone May 9, 2023
@crazy-max crazy-max mentioned this pull request May 10, 2023
@crazy-max crazy-max removed this from the v0.11.0 milestone May 11, 2023
@crazy-max crazy-max marked this pull request as draft May 11, 2023 10:00
@jsumners
Copy link

Is there any alternative to this for getting buildx ls results in a parseable format? It looks like this isn't going to available any time soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
7 participants