@@ -4,6 +4,7 @@ package daemon
44
55import (
66 "fmt"
7+ "net"
78 "os"
89 "path"
910 "path/filepath"
@@ -25,10 +26,12 @@ import (
2526 "github.com/docker/docker/runconfig"
2627 containertypes "github.com/docker/engine-api/types/container"
2728 networktypes "github.com/docker/engine-api/types/network"
29+ "github.com/docker/go-connections/nat"
2830 "github.com/docker/go-units"
2931 "github.com/docker/libnetwork"
3032 "github.com/docker/libnetwork/netlabel"
3133 "github.com/docker/libnetwork/options"
34+ "github.com/docker/libnetwork/types"
3235 "github.com/opencontainers/runc/libcontainer/configs"
3336 "github.com/opencontainers/runc/libcontainer/devices"
3437 "github.com/opencontainers/runc/libcontainer/label"
@@ -320,6 +323,9 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn
320323 dns []string
321324 dnsSearch []string
322325 dnsOptions []string
326+ bindings = make (nat.PortMap )
327+ pbList []types.PortBinding
328+ exposeList []types.TransportPort
323329 )
324330
325331 sboxOptions = append (sboxOptions , libnetwork .OptionHostname (container .Config .Hostname ),
@@ -394,6 +400,59 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libn
394400 sboxOptions = append (sboxOptions , libnetwork .OptionExtraHost (parts [0 ], parts [1 ]))
395401 }
396402
403+ if container .HostConfig .PortBindings != nil {
404+ for p , b := range container .HostConfig .PortBindings {
405+ bindings [p ] = []nat.PortBinding {}
406+ for _ , bb := range b {
407+ bindings [p ] = append (bindings [p ], nat.PortBinding {
408+ HostIP : bb .HostIP ,
409+ HostPort : bb .HostPort ,
410+ })
411+ }
412+ }
413+ }
414+
415+ portSpecs := container .Config .ExposedPorts
416+ ports := make ([]nat.Port , len (portSpecs ))
417+ var i int
418+ for p := range portSpecs {
419+ ports [i ] = p
420+ i ++
421+ }
422+ nat .SortPortMap (ports , bindings )
423+ for _ , port := range ports {
424+ expose := types.TransportPort {}
425+ expose .Proto = types .ParseProtocol (port .Proto ())
426+ expose .Port = uint16 (port .Int ())
427+ exposeList = append (exposeList , expose )
428+
429+ pb := types.PortBinding {Port : expose .Port , Proto : expose .Proto }
430+ binding := bindings [port ]
431+ for i := 0 ; i < len (binding ); i ++ {
432+ pbCopy := pb .GetCopy ()
433+ newP , err := nat .NewPort (nat .SplitProtoPort (binding [i ].HostPort ))
434+ var portStart , portEnd int
435+ if err == nil {
436+ portStart , portEnd , err = newP .Range ()
437+ }
438+ if err != nil {
439+ return nil , fmt .Errorf ("Error parsing HostPort value(%s):%v" , binding [i ].HostPort , err )
440+ }
441+ pbCopy .HostPort = uint16 (portStart )
442+ pbCopy .HostPortEnd = uint16 (portEnd )
443+ pbCopy .HostIP = net .ParseIP (binding [i ].HostIP )
444+ pbList = append (pbList , pbCopy )
445+ }
446+
447+ if container .HostConfig .PublishAllPorts && len (binding ) == 0 {
448+ pbList = append (pbList , pb )
449+ }
450+ }
451+
452+ sboxOptions = append (sboxOptions ,
453+ libnetwork .OptionPortMapping (pbList ),
454+ libnetwork .OptionExposedPorts (exposeList ))
455+
397456 // Link feature is supported only for the default bridge network.
398457 // return if this call to build join options is not for default bridge network
399458 if n .Name () != "bridge" {
0 commit comments