getPortMappingsOnMac parses `docker ps` output to get accurate macOS mappings because docker inspect does not know about port mappings at all.
(containerID, privatePort string)
| 426 | // getPortMappingsOnMac parses `docker ps` output to get accurate macOS mappings |
| 427 | // because docker inspect does not know about port mappings at all. |
| 428 | func getPortMappingsOnMac(containerID, privatePort string) (string, error) { |
| 429 | out, err := exec.Command("docker", "ps", "--format", "{{.ID}} {{.Ports}}").Output() |
| 430 | if err != nil { |
| 431 | return "", fmt.Errorf("docker ps failed: %w", err) |
| 432 | } |
| 433 | |
| 434 | for line := range strings.SplitSeq(string(out), "\n") { |
| 435 | fields := strings.Fields(line) |
| 436 | if len(fields) < 2 || !strings.HasPrefix(containerID, fields[0]) { |
| 437 | continue |
| 438 | } |
| 439 | |
| 440 | // Example: "0.0.0.0:55069->8080/tcp," => "55069" |
| 441 | for _, part := range fields[1:] { |
| 442 | if strings.Contains(part, privatePort+"/tcp") { |
| 443 | // A port entry like "8080/tcp" has no colon because the port |
| 444 | // wasn't published to the host; skip it rather than panic on |
| 445 | // an out-of-range index. |
| 446 | colonParts := strings.Split(part, ":") |
| 447 | if len(colonParts) < 2 { |
| 448 | continue |
| 449 | } |
| 450 | return strings.Split(colonParts[1], "->")[0], nil |
| 451 | } |
| 452 | } |
| 453 | } |
| 454 | |
| 455 | return "", fmt.Errorf("no mapping found for private port [%v] for container [%v]", privatePort, containerID) |
| 456 | } |
| 457 | |
| 458 | func mountBinary(c *LocalCluster) (mount.Mount, error) { |
| 459 | // We shouldn't need to call setupBinary here, we already call it in LocalCluster.setupBeforeCluster |
no test coverage detected