Skip to content

Commit

Permalink
Add the ability to request a specific IP address when creating a new …
Browse files Browse the repository at this point in the history
…endpoint.

Docker-DCO-1.1-Signed-off-by: Ross Boucher <rboucher@gmail.com> (github: boucher)
  • Loading branch information
boucher committed May 24, 2015
1 parent 7c289ef commit 6dec499
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
18 changes: 17 additions & 1 deletion drivers/bridge/bridge.go
Expand Up @@ -57,6 +57,7 @@ type networkConfiguration struct {

// endpointConfiguration represents the user specified configuration for the sandbox endpoint
type endpointConfiguration struct {
IPAddress net.IP
MacAddress net.HardwareAddr
PortBindings []types.PortBinding
ExposedPorts []types.TransportPort
Expand Down Expand Up @@ -724,7 +725,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
}

// v4 address for the sandbox side pipe interface
ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, requestedIPAddress(epConfig))
if err != nil {
return err
}
Expand Down Expand Up @@ -1083,6 +1084,14 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfigurat
}
}

if opt, ok := epOptions[netlabel.IPAddress]; ok {
if ip, ok := opt.(net.IP); ok {

This comment has been minimized.

Copy link
@mavenugo

mavenugo May 26, 2015

Being an user provided label with no translation in between, this is going to be a string.

ec.IPAddress = ip

This comment has been minimized.

Copy link
@mavenugo

mavenugo May 26, 2015

and hence, ec.IPAddress = net.ParseIP(ip)

} else {
return nil, &ErrInvalidEndpointConfig{}
}
}

if opt, ok := epOptions[netlabel.PortMap]; ok {
if bs, ok := opt.([]types.PortBinding); ok {
ec.PortBindings = bs
Expand Down Expand Up @@ -1131,6 +1140,13 @@ func electMacAddress(epConfig *endpointConfiguration) net.HardwareAddr {
return netutils.GenerateRandomMAC()
}

func requestedIPAddress(epConfig *endpointConfiguration) net.IP {
if epConfig != nil && epConfig.IPAddress != nil {
return epConfig.IPAddress
}
return nil
}

// Generates a name to be used for a virtual ethernet
// interface. The name is constructed by 'veth' appended
// by a randomly generated hex value. (example: veth0f60e2c)
Expand Down
10 changes: 9 additions & 1 deletion drivers/bridge/bridge_test.go
Expand Up @@ -244,6 +244,9 @@ func TestCreateLinkWithOptions(t *testing.T) {
epOptions := make(map[string]interface{})
epOptions[netlabel.MacAddress] = mac

ip := net.ParseIP("172.17.42.111")
epOptions[netlabel.IPAddress] = ip

This comment has been minimized.

Copy link
@mavenugo

mavenugo May 26, 2015

Please change the tests to reflect the change from IPAddress to string

te := &testEndpoint{ifaces: []*testInterface{}}
err = d.CreateEndpoint("net1", "ep", te, epOptions)
if err != nil {
Expand All @@ -262,7 +265,12 @@ func TestCreateLinkWithOptions(t *testing.T) {
}

if !bytes.Equal(mac, veth.Attrs().HardwareAddr) {
t.Fatalf("Failed to parse and program endpoint configuration")
t.Fatalf("Failed to parse and program endpoint MAC configuration")
}

teIP4 := te.ifaces[0].addr.IP.To4()
if !ip.Equal(teIP4) {
t.Fatalf("Failed to parse and program endpoint IP configuration")
}
}

Expand Down
3 changes: 3 additions & 0 deletions netlabel/labels.go
Expand Up @@ -10,6 +10,9 @@ const (
// MacAddress constant represents Mac Address config of a Container
MacAddress = "io.docker.network.endpoint.macaddress"

// IPAddress constant represents requesting a specific IP address for a Container
IPAddress = "io.docker.network.endpoint.ipaddress"

// ExposedPorts constant represents exposedports of a Container
ExposedPorts = "io.docker.network.endpoint.exposedports"

Expand Down

0 comments on commit 6dec499

Please sign in to comment.