// Copyright 2015 flannel authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package network import ( "net" "sync" "time" log "github.com/coreos/flannel/Godeps/_workspace/src/github.com/golang/glog" "github.com/coreos/flannel/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/flannel/backend" "github.com/coreos/flannel/subnet" ) type Network struct { Name string Config *subnet.Config ctx context.Context cancelFunc context.CancelFunc sm subnet.Manager ipMasq bool be backend.Backend lease *subnet.Lease } func NewNetwork(ctx context.Context, sm subnet.Manager, name string, ipMasq bool) *Network { ctx, cancel := context.WithCancel(ctx) return &Network{ Name: name, ctx: ctx, cancelFunc: cancel, sm: sm, ipMasq: ipMasq, } } func (n *Network) Init(iface *net.Interface, iaddr net.IP, eaddr net.IP) *backend.SubnetDef { var be backend.Backend var sn *backend.SubnetDef steps := []func() error{ func() (err error) { n.Config, err = n.sm.GetNetworkConfig(n.ctx, n.Name) if err != nil { log.Error("Failed to retrieve network config: ", err) } return }, func() (err error) { be, err = newBackend(n.sm, n.Config.BackendType, iface, iaddr, eaddr) if err != nil { log.Errorf("Failed to create and initialize network %v (type %v): %v", n.Name, n.Config.BackendType, err) } else { n.be = be } return }, func() (err error) { sn, err = be.RegisterNetwork(n.ctx, n.Name, n.Config) if err != nil { log.Errorf("Failed register network %v (type %v): %v", n.Name, n.Config.BackendType, err) } else { n.lease = sn.Lease } return }, func() (err error) { if n.ipMasq { flannelNet := n.Config.Network if err = setupIPMasq(flannelNet); err != nil { log.Errorf("Failed to set up IP Masquerade for network %v: %v", n.Name, err) } } return }, } for _, s := range steps { for { if err := s(); err == nil { break } select { case <-time.After(time.Second): case <-n.ctx.Done(): return nil } } } return sn } func (n *Network) Run() { wg := sync.WaitGroup{} wg.Add(1) go func() { n.be.Run(n.ctx) wg.Done() }() wg.Add(1) go func() { subnet.LeaseRenewer(n.ctx, n.sm, n.Name, n.lease) wg.Done() }() <-n.ctx.Done() n.be.UnregisterNetwork(n.ctx, n.Name) wg.Wait() } func (n *Network) Cancel() { n.cancelFunc() }