之前分析了controller的第一部分,现在接着分析第二部分:管理network。
(二) 管理network
controller和network的联系是通过store进行的,也就是说network是存储在数据库中的,而controller通过store管理network。
controller::NewNetwork()
NewNetwork()可以创建一个新的network。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 
  | func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) { 	if id != "" { 		c.networkLocker.Lock(id) 		defer c.networkLocker.Unlock(id) 		if _, err := c.NetworkByID(id); err == nil { 			return nil, NetworkNameError(id) 		} 	} 	if !config.IsValidName(name) { 		return nil, ErrInvalidName(name) 	} 	if id == "" { 		id = stringid.GenerateRandomID() 	} 	 	 	network := &network{ 		name:        name, 		networkType: networkType, 		generic:     map[string]interface{}{netlabel.GenericData: make(map[string]string)}, 		ipamType:    ipamapi.DefaultIPAM, 		id:          id, 		ctrlr:       c, 		persist:     true, 		drvOnce:     &sync.Once{}, 	} 	 	 	network.processOptions(options...) 	_, cap, err := network.resolveDriver(networkType, true) 	if err != nil { 		return nil, err 	} 	if cap.DataScope == datastore.GlobalScope && !c.isDistributedControl() && !network.dynamic { 		if c.isManager() { 			 			return nil, ManagerRedirectError(name) 		} 		return nil, types.ForbiddenErrorf("Cannot create a multi-host network from a worker node. Please create the network from a manager node.") 	} 	 	 	 	if _, err := network.driver(true); err != nil { 		return nil, err 	} 	 	err = network.ipamAllocate() 	if err != nil { 		return nil, err 	} 	defer func() { 		if err != nil { 			network.ipamRelease() 		} 	}() 	 	err = c.addNetwork(network) 	if err != nil { 		return nil, err 	} 	defer func() { 		if err != nil { 			if e := network.deleteNetwork(); e != nil { 				log.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err) 			} 		} 	}() 	 	 	 	 	epCnt := &endpointCnt{n: network} 	if err = c.updateToStore(epCnt); err != nil { 		return nil, err 	} 	defer func() { 		if err != nil { 			if e := c.deleteFromStore(epCnt); e != nil { 				log.Warnf("couldnt rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e) 			} 		} 	}() 	 	network.epCnt = epCnt 	if err = c.updateToStore(network); err != nil { 		return nil, err 	} 	joinCluster(network) 	if !c.isDistributedControl() { 		arrangeIngressFilterRule() 	} 	return network, nil } 
  | 
NewNetwork()的流程如下:
- 创建network结构体值;
 
- 处理传入的options,option为函数,一般可以设置结构体值的某字段,用户可以用来设置某字段值;
 
- 检查network driver是否存在;
 
- 调用network的ipamAllocate()设置network的ipam相关信息;
 
- 调用addNetwork()把创建底层network;
 
- 初始化epCnt字段;
 
- 调用updateToStore()存储network到store。
 
controller::addNetwork()
addNetwork()把network创建底层的network。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
  | func (c *controller) addNetwork(n *network) error { 	d, err := n.driver(true) 	if err != nil { 		return err 	} 	 	 	if err := d.CreateNetwork(n.id, n.generic, n, n.getIPData(4), n.getIPData(6)); err != nil { 		return err 	} 	return nil } 
  | 
driver的CreateNetwork()实现比较复杂,以后放在driver中分析。
controller::Networks()
Networks()可以从store中获取networks。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
  | func (c *controller) Networks() []Network { 	var list []Network 	 	networks, err := c.getNetworksFromStore() 	if err != nil { 		log.Error(err) 	} 	for _, n := range networks { 		 		if n.inDelete { 			continue 		} 		list = append(list, n) 	} 	return list } 
  | 
controller::WalkNetworks()
WalkNetworks()会返回满足walker()条件的network。
1 2 3 4 5 6 7 8 
  | func (c *controller) WalkNetworks(walker NetworkWalker) { 	for _, n := range c.Networks() { 		if walker(n) { 			return 		} 	} } 
  | 
controller::NetworkByName()
NetworkByName()通过调用WalkNetworks(),其提取函数的功能为提取名为name的network
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 
  | func (c *controller) NetworkByName(name string) (Network, error) { 	if name == "" { 		return nil, ErrInvalidName(name) 	} 	var n Network 	s := func(current Network) bool { 		if current.Name() == name { 			n = current 			return true 		} 		return false 	} 	c.WalkNetworks(s) 	if n == nil { 		return nil, ErrNoSuchNetwork(name) 	} 	return n, nil } 
  | 
controller::NetworkByID()
NetworkByID()可以依据id直接从store中获取network。
1 2 3 4 5 6 7 8 9 10 11 12 
  | func (c *controller) NetworkByID(id string) (Network, error) { 	if id == "" { 		return nil, ErrInvalidID(id) 	} 	n, err := c.getNetworkFromStore(id) 	if err != nil { 		return nil, ErrNoSuchNetwork(id) 	} 	return n, nil } 
  | 
其他
controller还定义有getNetworkFromStore(),getNetworksForScope(),getNetworksFromStore()这些从store中获取network的方法,这些方法从名字上也比较好理解,不会阻塞controller的”管理network”的代码阅读,所以将放到store中分析。
小结
controller可以创建network,并从数据库获取network。但controller不能直接删除network,删除操作定义在network结构体中。controller的network管理的分析比较简单,因为还没涉及network本身的操作,对network的分析将由单独的系列文档承担。