99 "context"
1010 "fmt"
1111 "os"
12+ "os/exec"
1213 "path/filepath"
14+ "runtime"
1315 "strconv"
1416 "strings"
1517 "testing"
@@ -369,6 +371,11 @@ func (a *alpha) zeroURL(c *LocalCluster) (string, error) {
369371
370372func publicPort (dcli * docker.Client , dc dnode , privatePort string ) (string , error ) {
371373 // TODO(aman): we should cache the port information
374+
375+ if runtime .GOOS == "darwin" {
376+ return getPortMappingsOnMac (dc .cid (), privatePort )
377+ }
378+
372379 ctx , cancel := context .WithTimeout (context .Background (), requestTimeout )
373380 defer cancel ()
374381
@@ -395,6 +402,31 @@ func publicPort(dcli *docker.Client, dc dnode, privatePort string) (string, erro
395402 return "" , fmt .Errorf ("no mapping found for private port [%v] for container [%v]" , privatePort , dc .cname ())
396403}
397404
405+ // getPortMappingsOnMac parses `docker ps` output to get accurate macOS mappings
406+ // because docker inspect does not know about port mappings at all.
407+ func getPortMappingsOnMac (containerID , privatePort string ) (string , error ) {
408+ out , err := exec .Command ("docker" , "ps" , "--format" , "{{.ID}} {{.Ports}}" ).Output ()
409+ if err != nil {
410+ return "" , fmt .Errorf ("docker ps failed: %w" , err )
411+ }
412+
413+ for line := range strings .SplitSeq (string (out ), "\n " ) {
414+ fields := strings .Fields (line )
415+ if len (fields ) < 2 || ! strings .HasPrefix (containerID , fields [0 ]) {
416+ continue
417+ }
418+
419+ // Example: "0.0.0.0:55069->8080/tcp," => "55069"
420+ for _ , part := range fields [1 :] {
421+ if strings .Contains (part , privatePort + "/tcp" ) {
422+ return strings .Split (strings .Split (part , ":" )[1 ], "->" )[0 ], nil
423+ }
424+ }
425+ }
426+
427+ return "" , fmt .Errorf ("no mapping found for private port [%v] for container [%v]" , privatePort , containerID )
428+ }
429+
398430func mountBinary (c * LocalCluster ) (mount.Mount , error ) {
399431 // We shouldn't need to call setupBinary here, we already call it in LocalCluster.setupBeforeCluster
400432 // function which is called whenever the dgraph's cluster version is initialized or upgraded. Though,
0 commit comments