1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Global alias support

Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
Madhu Venugopal 2016-01-07 19:19:31 -08:00
parent be981267c0
commit 2db863e5d7
9 changed files with 141 additions and 29 deletions

View file

@ -379,6 +379,10 @@ func procCreateEndpoint(c libnetwork.NetworkController, vars map[string]string,
setFctList = append(setFctList, libnetwork.CreateOptionPortMapping(ec.PortMapping)) setFctList = append(setFctList, libnetwork.CreateOptionPortMapping(ec.PortMapping))
} }
for _, str := range ec.MyAliases {
setFctList = append(setFctList, libnetwork.CreateOptionMyAlias(str))
}
ep, err := n.CreateEndpoint(ec.Name, setFctList...) ep, err := n.CreateEndpoint(ec.Name, setFctList...)
if err != nil { if err != nil {
return "", convertNetworkError(err) return "", convertNetworkError(err)
@ -624,6 +628,10 @@ func procPublishService(c libnetwork.NetworkController, vars map[string]string,
setFctList = append(setFctList, libnetwork.CreateOptionPortMapping(sp.PortMapping)) setFctList = append(setFctList, libnetwork.CreateOptionPortMapping(sp.PortMapping))
} }
for _, str := range sp.MyAliases {
setFctList = append(setFctList, libnetwork.CreateOptionMyAlias(str))
}
ep, err := n.CreateEndpoint(sp.Name, setFctList...) ep, err := n.CreateEndpoint(sp.Name, setFctList...)
if err != nil { if err != nil {
return "", endpointToService(convertNetworkError(err)) return "", endpointToService(convertNetworkError(err))

View file

@ -43,6 +43,7 @@ type networkCreate struct {
// endpointCreate represents the body of the "create endpoint" http request message // endpointCreate represents the body of the "create endpoint" http request message
type endpointCreate struct { type endpointCreate struct {
Name string `json:"name"` Name string `json:"name"`
MyAliases []string `json:"my_aliases"`
ExposedPorts []types.TransportPort `json:"exposed_ports"` ExposedPorts []types.TransportPort `json:"exposed_ports"`
PortMapping []types.PortBinding `json:"port_mapping"` PortMapping []types.PortBinding `json:"port_mapping"`
} }
@ -69,6 +70,7 @@ type endpointJoin struct {
// servicePublish represents the body of the "publish service" http request message // servicePublish represents the body of the "publish service" http request message
type servicePublish struct { type servicePublish struct {
Name string `json:"name"` Name string `json:"name"`
MyAliases []string `json:"my_aliases"`
Network string `json:"network_name"` Network string `json:"network_name"`
ExposedPorts []types.TransportPort `json:"exposed_ports"` ExposedPorts []types.TransportPort `json:"exposed_ports"`
PortMapping []types.PortBinding `json:"port_mapping"` PortMapping []types.PortBinding `json:"port_mapping"`

View file

@ -163,6 +163,8 @@ func parseServiceName(name string) (string, string) {
// CmdServicePublish handles service create UI // CmdServicePublish handles service create UI
func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error { func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error {
cmd := cli.Subcmd(chain, "publish", "SERVICE[.NETWORK]", "Publish a new service on a network", false) cmd := cli.Subcmd(chain, "publish", "SERVICE[.NETWORK]", "Publish a new service on a network", false)
flAlias := opts.NewListOpts(netutils.ValidateAlias)
cmd.Var(&flAlias, []string{"-alias"}, "Add alias to self")
cmd.Require(flag.Exact, 1) cmd.Require(flag.Exact, 1)
err := cmd.ParseFlags(args, true) err := cmd.ParseFlags(args, true)
if err != nil { if err != nil {
@ -170,7 +172,7 @@ func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error {
} }
sn, nn := parseServiceName(cmd.Arg(0)) sn, nn := parseServiceName(cmd.Arg(0))
sc := serviceCreate{Name: sn, Network: nn} sc := serviceCreate{Name: sn, Network: nn, MyAliases: flAlias.GetAll()}
obj, _, err := readBody(cli.call("POST", "/services", sc, nil)) obj, _, err := readBody(cli.call("POST", "/services", sc, nil))
if err != nil { if err != nil {
return err return err

View file

@ -43,6 +43,7 @@ type networkCreate struct {
// serviceCreate represents the body of the "publish service" http request message // serviceCreate represents the body of the "publish service" http request message
type serviceCreate struct { type serviceCreate struct {
Name string `json:"name"` Name string `json:"name"`
MyAliases []string `json:"my_aliases"`
Network string `json:"network_name"` Network string `json:"network_name"`
ExposedPorts []types.TransportPort `json:"exposed_ports"` ExposedPorts []types.TransportPort `json:"exposed_ports"`
PortMapping []types.PortBinding `json:"port_mapping"` PortMapping []types.PortBinding `json:"port_mapping"`

View file

@ -65,6 +65,7 @@ type endpoint struct {
prefAddressV6 net.IP prefAddressV6 net.IP
ipamOptions map[string]string ipamOptions map[string]string
aliases map[string]string aliases map[string]string
myAliases []string
dbIndex uint64 dbIndex uint64
dbExists bool dbExists bool
sync.Mutex sync.Mutex
@ -85,6 +86,7 @@ func (ep *endpoint) MarshalJSON() ([]byte, error) {
epMap["sandbox"] = ep.sandboxID epMap["sandbox"] = ep.sandboxID
epMap["anonymous"] = ep.anonymous epMap["anonymous"] = ep.anonymous
epMap["disableResolution"] = ep.disableResolution epMap["disableResolution"] = ep.disableResolution
epMap["myAliases"] = ep.myAliases
return json.Marshal(epMap) return json.Marshal(epMap)
} }
@ -165,6 +167,10 @@ func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
if v, ok := epMap["disableResolution"]; ok { if v, ok := epMap["disableResolution"]; ok {
ep.disableResolution = v.(bool) ep.disableResolution = v.(bool)
} }
ma, _ := json.Marshal(epMap["myAliases"])
var myAliases []string
json.Unmarshal(ma, &myAliases)
ep.myAliases = myAliases
return nil return nil
} }
@ -193,6 +199,9 @@ func (ep *endpoint) CopyTo(o datastore.KVObject) error {
dstEp.exposedPorts = make([]types.TransportPort, len(ep.exposedPorts)) dstEp.exposedPorts = make([]types.TransportPort, len(ep.exposedPorts))
copy(dstEp.exposedPorts, ep.exposedPorts) copy(dstEp.exposedPorts, ep.exposedPorts)
dstEp.myAliases = make([]string, len(ep.myAliases))
copy(dstEp.myAliases, ep.myAliases)
dstEp.generic = options.Generic{} dstEp.generic = options.Generic{}
for k, v := range ep.generic { for k, v := range ep.generic {
dstEp.generic[k] = v dstEp.generic[k] = v
@ -215,6 +224,13 @@ func (ep *endpoint) Name() string {
return ep.name return ep.name
} }
func (ep *endpoint) MyAliases() []string {
ep.Lock()
defer ep.Unlock()
return ep.myAliases
}
func (ep *endpoint) Network() string { func (ep *endpoint) Network() string {
if ep.network == nil { if ep.network == nil {
return "" return ""
@ -759,6 +775,13 @@ func CreateOptionAlias(name string, alias string) EndpointOption {
} }
} }
//CreateOptionMyAlias function returns an option setter for setting endpoint's self alias
func CreateOptionMyAlias(alias string) EndpointOption {
return func(ep *endpoint) {
ep.myAliases = append(ep.myAliases, alias)
}
}
// JoinOptionPriority function returns an option setter for priority option to // JoinOptionPriority function returns an option setter for priority option to
// be passed to the endpoint.Join() method. // be passed to the endpoint.Join() method.
func JoinOptionPriority(ep Endpoint, prio int) EndpointOption { func JoinOptionPriority(ep Endpoint, prio int) EndpointOption {

View file

@ -70,7 +70,7 @@ type NetworkInfo interface {
type EndpointWalker func(ep Endpoint) bool type EndpointWalker func(ep Endpoint) bool
type svcInfo struct { type svcInfo struct {
svcMap map[string]net.IP svcMap map[string][]net.IP
ipMap map[string]string ipMap map[string]string
} }
@ -831,36 +831,77 @@ func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool
return return
} }
epName := ep.Name()
if iface := ep.Iface(); iface.Address() != nil {
myAliases := ep.MyAliases()
if isAdd {
n.addSvcRecords(epName, iface.Address().IP, true)
for _, alias := range myAliases {
n.addSvcRecords(alias, iface.Address().IP, false)
}
} else {
n.deleteSvcRecords(epName, iface.Address().IP, true)
for _, alias := range myAliases {
n.deleteSvcRecords(alias, iface.Address().IP, false)
}
}
}
}
func (n *network) addSvcRecords(name string, epIP net.IP, ipMapUpdate bool) {
c := n.getController() c := n.getController()
c.Lock()
defer c.Unlock()
sr, ok := c.svcDb[n.ID()] sr, ok := c.svcDb[n.ID()]
if !ok { if !ok {
c.svcDb[n.ID()] = svcInfo{ sr = svcInfo{
svcMap: make(map[string]net.IP), svcMap: make(map[string][]net.IP),
ipMap: make(map[string]string), ipMap: make(map[string]string),
} }
sr = c.svcDb[n.ID()] c.svcDb[n.ID()] = sr
} }
epName := ep.Name() if ipMapUpdate {
n.Lock() reverseIP := netutils.ReverseIP(epIP.String())
if iface := ep.Iface(); iface.Address() != nil { if _, ok := sr.ipMap[reverseIP]; !ok {
sr.ipMap[reverseIP] = name
reverseIP := netutils.ReverseIP(iface.Address().IP.String())
if isAdd {
// If we already have this endpoint in service db just return
if _, ok := sr.svcMap[epName]; ok {
n.Unlock()
return
}
sr.svcMap[epName] = iface.Address().IP
sr.ipMap[reverseIP] = epName
} else {
delete(sr.svcMap, epName)
delete(sr.ipMap, reverseIP)
} }
} }
n.Unlock()
ipList := sr.svcMap[name]
for _, ip := range ipList {
if ip.Equal(epIP) {
return
}
}
sr.svcMap[name] = append(sr.svcMap[name], epIP)
}
func (n *network) deleteSvcRecords(name string, epIP net.IP, ipMapUpdate bool) {
c := n.getController()
c.Lock()
defer c.Unlock()
sr, ok := c.svcDb[n.ID()]
if !ok {
return
}
if ipMapUpdate {
delete(sr.ipMap, netutils.ReverseIP(epIP.String()))
}
ipList := sr.svcMap[name]
for i, ip := range ipList {
if ip.Equal(epIP) {
ipList = append(ipList[:i], ipList[i+1:]...)
break
}
}
sr.svcMap[name] = ipList
if len(ipList) == 0 {
delete(sr.svcMap, name)
}
} }
func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record { func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
@ -877,7 +918,7 @@ func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
recs = append(recs, etchosts.Record{ recs = append(recs, etchosts.Record{
Hosts: h, Hosts: h,
IP: ip.String(), IP: ip[0].String(),
}) })
} }

View file

@ -481,7 +481,7 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
ip, ok := sr.svcMap[name] ip, ok := sr.svcMap[name]
n.Unlock() n.Unlock()
if ok { if ok {
return ip return ip[0]
} }
} }
return nil return nil

View file

@ -249,3 +249,33 @@ function test_single_network_connectivity() {
dnet_cmd $(inst_id2port 1) container rm container_2 dnet_cmd $(inst_id2port 1) container rm container_2
dnet_cmd $(inst_id2port 1) network rm br1 dnet_cmd $(inst_id2port 1) network rm br1
} }
@test "Test bridge network global alias support" {
skip_for_circleci
dnet_cmd $(inst_id2port 1) network create -d bridge br1
dnet_cmd $(inst_id2port 1) network create -d bridge br2
dnet_cmd $(inst_id2port 1) container create container_1
net_connect 1 container_1 br1 : c1
dnet_cmd $(inst_id2port 1) container create container_2
net_connect 1 container_2 br1 : shared
dnet_cmd $(inst_id2port 1) container create container_3
net_connect 1 container_3 br1 : shared
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_2) "ping -c 1 container_1"
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_2) "ping -c 1 c1"
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 container_2"
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 shared"
net_disconnect 1 container_2 br1
dnet_cmd $(inst_id2port 1) container rm container_2
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 container_3"
runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 shared"
net_disconnect 1 container_1 br1
dnet_cmd $(inst_id2port 1) container rm container_1
net_disconnect 1 container_3 br1
dnet_cmd $(inst_id2port 1) container rm container_3
dnet_cmd $(inst_id2port 1) network rm br1
}

View file

@ -18,12 +18,17 @@ function get_sbox_id() {
} }
function net_connect() { function net_connect() {
local al local al gl
if [ -n "$4" ]; then if [ -n "$4" ]; then
al="--alias=${4}" if [ "${4}" != ":" ]; then
al="--alias=${4}"
fi
fi fi
dnet_cmd $(inst_id2port ${1}) service publish ${2}.${3} if [ -n "$5" ]; then
dnet_cmd $(inst_id2port ${1}) service attach $al ${2} ${2}.${3} gl="--alias=${5}"
fi
dnet_cmd $(inst_id2port ${1}) service publish $gl ${2}.${3}
dnet_cmd $(inst_id2port ${1}) service attach $al ${2} ${2}.${3}
} }
function net_disconnect() { function net_disconnect() {