9
9
"context"
10
10
"fmt"
11
11
"os"
12
+ "os/exec"
12
13
"path/filepath"
14
+ "runtime"
13
15
"strconv"
14
16
"strings"
15
17
"testing"
@@ -369,6 +371,11 @@ func (a *alpha) zeroURL(c *LocalCluster) (string, error) {
369
371
370
372
func publicPort (dcli * docker.Client , dc dnode , privatePort string ) (string , error ) {
371
373
// TODO(aman): we should cache the port information
374
+
375
+ if runtime .GOOS == "darwin" {
376
+ return getPortMappingsOnMac (dc .cid (), privatePort )
377
+ }
378
+
372
379
ctx , cancel := context .WithTimeout (context .Background (), requestTimeout )
373
380
defer cancel ()
374
381
@@ -395,6 +402,31 @@ func publicPort(dcli *docker.Client, dc dnode, privatePort string) (string, erro
395
402
return "" , fmt .Errorf ("no mapping found for private port [%v] for container [%v]" , privatePort , dc .cname ())
396
403
}
397
404
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
+
398
430
func mountBinary (c * LocalCluster ) (mount.Mount , error ) {
399
431
// We shouldn't need to call setupBinary here, we already call it in LocalCluster.setupBeforeCluster
400
432
// function which is called whenever the dgraph's cluster version is initialized or upgraded. Though,
0 commit comments