mike10004/containment

Correctly parse IPv6 host:port strings from container inspection

Opened this issue · 0 comments

Currently, the DjStartedContainer's inspector implementation expects the output of docker ps to contain port mappings where the host IP is always an IPv4 address. But as of Docker 20.10.11 (or maybe earlier), sometimes the ps output looks like this:

{
  "Command": "\"/lib/systemd/systemd\"",
  "CreatedAt": "2021-12-02 18:08:09 -0500 EST",
  "ID": "4415125cb0c5",
  "Image": "testing-image",
  "Labels": "",
  "LocalVolumes": "0",
  "Mounts": ",/sys/fs/cgroup,,",
  "Names": "wonderful_galois",
  "Networks": "bridge",
  "Ports": "80/tcp, 443/tcp, 8443/tcp, 0.0.0.0:49167->8080/tcp, :::49167->8080/tcp",
  "RunningFor": "43 seconds ago",
  "Size": "303MB (virtual 837MB)",
  "State": "running",
  "Status": "Up 43 seconds"
}

Note that the port mappings contain IPv4 and IPv6 host addresses. You might argue that Docker should be using brackets around the host part, but whatever, it's not ambiguous, and PsOutputParser should be able to handle it.

Instead, what happens is an IllegalStateException is thrown, because Guava's HostAndPort is used under the hood, and that class interprets :::49167 to be the complete host string and the port part to be absent.

What we should actually be doing is parsing the docker inspect output, anyway. The ports part of that output looks like this:

        "Ports": {
            "443/tcp": null,
            "80/tcp": null,
            "8080/tcp": [
                {
                    "HostIp": "0.0.0.0",
                    "HostPort": "49161"
                },
                {
                    "HostIp": "::",
                    "HostPort": "49161"
                }
            ],
            "8443/tcp": null
        }

It's already got the host and port separated and PsOutputParser doesn't have to do error-prone string tokenization.