Merge pull request #859 from mavenugo/globalalias

Global alias support
This commit is contained in:
Jana Radhakrishnan 2016-01-08 12:38:51 -08:00
commit 06ff0a98a0
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))
}
for _, str := range ec.MyAliases {
setFctList = append(setFctList, libnetwork.CreateOptionMyAlias(str))
}
ep, err := n.CreateEndpoint(ec.Name, setFctList...)
if err != nil {
return "", convertNetworkError(err)
@ -624,6 +628,10 @@ func procPublishService(c libnetwork.NetworkController, vars map[string]string,
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...)
if err != nil {
return "", endpointToService(convertNetworkError(err))

View File

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

View File

@ -163,6 +163,8 @@ func parseServiceName(name string) (string, string) {
// CmdServicePublish handles service create UI
func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error {
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)
err := cmd.ParseFlags(args, true)
if err != nil {
@ -170,7 +172,7 @@ func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error {
}
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))
if err != nil {
return err

View File

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

View File

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

View File

@ -70,7 +70,7 @@ type NetworkInfo interface {
type EndpointWalker func(ep Endpoint) bool
type svcInfo struct {
svcMap map[string]net.IP
svcMap map[string][]net.IP
ipMap map[string]string
}
@ -825,36 +825,77 @@ func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool
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.Lock()
defer c.Unlock()
sr, ok := c.svcDb[n.ID()]
if !ok {
c.svcDb[n.ID()] = svcInfo{
svcMap: make(map[string]net.IP),
sr = svcInfo{
svcMap: make(map[string][]net.IP),
ipMap: make(map[string]string),
}
sr = c.svcDb[n.ID()]
c.svcDb[n.ID()] = sr
}
epName := ep.Name()
n.Lock()
if iface := ep.Iface(); iface.Address() != nil {
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)
if ipMapUpdate {
reverseIP := netutils.ReverseIP(epIP.String())
if _, ok := sr.ipMap[reverseIP]; !ok {
sr.ipMap[reverseIP] = name
}
}
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 {
@ -871,7 +912,7 @@ func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record {
recs = append(recs, etchosts.Record{
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]
n.Unlock()
if ok {
return ip
return ip[0]
}
}
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) 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() {
local al
local al gl
if [ -n "$4" ]; then
al="--alias=${4}"
if [ "${4}" != ":" ]; then
al="--alias=${4}"
fi
fi
dnet_cmd $(inst_id2port ${1}) service publish ${2}.${3}
dnet_cmd $(inst_id2port ${1}) service attach $al ${2} ${2}.${3}
if [ -n "$5" ]; then
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() {