controller.go 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  1. /*
  2. Package libnetwork provides the basic functionality and extension points to
  3. create network namespaces and allocate interfaces for containers to use.
  4. networkType := "bridge"
  5. // Create a new controller instance
  6. driverOptions := options.Generic{}
  7. genericOption := make(map[string]interface{})
  8. genericOption[netlabel.GenericData] = driverOptions
  9. controller, err := libnetwork.New(config.OptionDriverConfig(networkType, genericOption))
  10. if err != nil {
  11. return
  12. }
  13. // Create a network for containers to join.
  14. // NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can make use of
  15. network, err := controller.NewNetwork(networkType, "network1", "")
  16. if err != nil {
  17. return
  18. }
  19. // For each new container: allocate IP and interfaces. The returned network
  20. // settings will be used for container infos (inspect and such), as well as
  21. // iptables rules for port publishing. This info is contained or accessible
  22. // from the returned endpoint.
  23. ep, err := network.CreateEndpoint("Endpoint1")
  24. if err != nil {
  25. return
  26. }
  27. // Create the sandbox for the container.
  28. // NewSandbox accepts Variadic optional arguments which libnetwork can use.
  29. sbx, err := controller.NewSandbox("container1",
  30. libnetwork.OptionHostname("test"),
  31. libnetwork.OptionDomainname("docker.io"))
  32. // A sandbox can join the endpoint via the join api.
  33. err = ep.Join(sbx)
  34. if err != nil {
  35. return
  36. }
  37. */
  38. package libnetwork
  39. import (
  40. "fmt"
  41. "net"
  42. "path/filepath"
  43. "runtime"
  44. "strings"
  45. "sync"
  46. "time"
  47. "github.com/docker/docker/pkg/discovery"
  48. "github.com/docker/docker/pkg/locker"
  49. "github.com/docker/docker/pkg/plugingetter"
  50. "github.com/docker/docker/pkg/plugins"
  51. "github.com/docker/docker/pkg/stringid"
  52. "github.com/docker/libnetwork/cluster"
  53. "github.com/docker/libnetwork/config"
  54. "github.com/docker/libnetwork/datastore"
  55. "github.com/docker/libnetwork/diagnostic"
  56. "github.com/docker/libnetwork/discoverapi"
  57. "github.com/docker/libnetwork/driverapi"
  58. "github.com/docker/libnetwork/drvregistry"
  59. "github.com/docker/libnetwork/hostdiscovery"
  60. "github.com/docker/libnetwork/ipamapi"
  61. "github.com/docker/libnetwork/netlabel"
  62. "github.com/docker/libnetwork/options"
  63. "github.com/docker/libnetwork/osl"
  64. "github.com/docker/libnetwork/types"
  65. "github.com/pkg/errors"
  66. "github.com/sirupsen/logrus"
  67. )
  68. // NetworkController provides the interface for controller instance which manages
  69. // networks.
  70. type NetworkController interface {
  71. // ID provides a unique identity for the controller
  72. ID() string
  73. // BuiltinDrivers returns list of builtin drivers
  74. BuiltinDrivers() []string
  75. // BuiltinIPAMDrivers returns list of builtin ipam drivers
  76. BuiltinIPAMDrivers() []string
  77. // Config method returns the bootup configuration for the controller
  78. Config() config.Config
  79. // Create a new network. The options parameter carries network specific options.
  80. NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error)
  81. // Networks returns the list of Network(s) managed by this controller.
  82. Networks() []Network
  83. // WalkNetworks uses the provided function to walk the Network(s) managed by this controller.
  84. WalkNetworks(walker NetworkWalker)
  85. // NetworkByName returns the Network which has the passed name. If not found, the error ErrNoSuchNetwork is returned.
  86. NetworkByName(name string) (Network, error)
  87. // NetworkByID returns the Network which has the passed id. If not found, the error ErrNoSuchNetwork is returned.
  88. NetworkByID(id string) (Network, error)
  89. // NewSandbox creates a new network sandbox for the passed container id
  90. NewSandbox(containerID string, options ...SandboxOption) (Sandbox, error)
  91. // Sandboxes returns the list of Sandbox(s) managed by this controller.
  92. Sandboxes() []Sandbox
  93. // WalkSandboxes uses the provided function to walk the Sandbox(s) managed by this controller.
  94. WalkSandboxes(walker SandboxWalker)
  95. // SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
  96. SandboxByID(id string) (Sandbox, error)
  97. // SandboxDestroy destroys a sandbox given a container ID
  98. SandboxDestroy(id string) error
  99. // Stop network controller
  100. Stop()
  101. // ReloadConfiguration updates the controller configuration
  102. ReloadConfiguration(cfgOptions ...config.Option) error
  103. // SetClusterProvider sets cluster provider
  104. SetClusterProvider(provider cluster.Provider)
  105. // Wait for agent initialization complete in libnetwork controller
  106. AgentInitWait()
  107. // Wait for agent to stop if running
  108. AgentStopWait()
  109. // SetKeys configures the encryption key for gossip and overlay data path
  110. SetKeys(keys []*types.EncryptionKey) error
  111. // StartDiagnostic start the network diagnostic mode
  112. StartDiagnostic(port int)
  113. // StopDiagnostic start the network diagnostic mode
  114. StopDiagnostic()
  115. // IsDiagnosticEnabled returns true if the diagnostic is enabled
  116. IsDiagnosticEnabled() bool
  117. }
  118. // NetworkWalker is a client provided function which will be used to walk the Networks.
  119. // When the function returns true, the walk will stop.
  120. type NetworkWalker func(nw Network) bool
  121. // SandboxWalker is a client provided function which will be used to walk the Sandboxes.
  122. // When the function returns true, the walk will stop.
  123. type SandboxWalker func(sb Sandbox) bool
  124. type sandboxTable map[string]*sandbox
  125. type controller struct {
  126. id string
  127. drvRegistry *drvregistry.DrvRegistry
  128. sandboxes sandboxTable
  129. cfg *config.Config
  130. stores []datastore.DataStore
  131. discovery hostdiscovery.HostDiscovery
  132. extKeyListener net.Listener
  133. watchCh chan *endpoint
  134. unWatchCh chan *endpoint
  135. svcRecords map[string]svcInfo
  136. nmap map[string]*netWatch
  137. serviceBindings map[serviceKey]*service
  138. defOsSbox osl.Sandbox
  139. ingressSandbox *sandbox
  140. sboxOnce sync.Once
  141. agent *agent
  142. networkLocker *locker.Locker
  143. agentInitDone chan struct{}
  144. agentStopDone chan struct{}
  145. keys []*types.EncryptionKey
  146. clusterConfigAvailable bool
  147. DiagnosticServer *diagnostic.Server
  148. sync.Mutex
  149. }
  150. type initializer struct {
  151. fn drvregistry.InitFunc
  152. ntype string
  153. }
  154. // New creates a new instance of network controller.
  155. func New(cfgOptions ...config.Option) (NetworkController, error) {
  156. c := &controller{
  157. id: stringid.GenerateRandomID(),
  158. cfg: config.ParseConfigOptions(cfgOptions...),
  159. sandboxes: sandboxTable{},
  160. svcRecords: make(map[string]svcInfo),
  161. serviceBindings: make(map[serviceKey]*service),
  162. agentInitDone: make(chan struct{}),
  163. networkLocker: locker.New(),
  164. DiagnosticServer: diagnostic.New(),
  165. }
  166. c.DiagnosticServer.Init()
  167. if err := c.initStores(); err != nil {
  168. return nil, err
  169. }
  170. drvRegistry, err := drvregistry.New(c.getStore(datastore.LocalScope), c.getStore(datastore.GlobalScope), c.RegisterDriver, nil, c.cfg.PluginGetter)
  171. if err != nil {
  172. return nil, err
  173. }
  174. for _, i := range getInitializers(c.cfg.Daemon.Experimental) {
  175. var dcfg map[string]interface{}
  176. // External plugins don't need config passed through daemon. They can
  177. // bootstrap themselves
  178. if i.ntype != "remote" {
  179. dcfg = c.makeDriverConfig(i.ntype)
  180. }
  181. if err := drvRegistry.AddDriver(i.ntype, i.fn, dcfg); err != nil {
  182. return nil, err
  183. }
  184. }
  185. if err = initIPAMDrivers(drvRegistry, nil, c.getStore(datastore.GlobalScope), c.cfg.Daemon.DefaultAddressPool); err != nil {
  186. return nil, err
  187. }
  188. c.drvRegistry = drvRegistry
  189. if c.cfg != nil && c.cfg.Cluster.Watcher != nil {
  190. if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil {
  191. // Failing to initialize discovery is a bad situation to be in.
  192. // But it cannot fail creating the Controller
  193. logrus.Errorf("Failed to Initialize Discovery : %v", err)
  194. }
  195. }
  196. c.WalkNetworks(populateSpecial)
  197. // Reserve pools first before doing cleanup. Otherwise the
  198. // cleanups of endpoint/network and sandbox below will
  199. // generate many unnecessary warnings
  200. c.reservePools()
  201. // Cleanup resources
  202. c.sandboxCleanup(c.cfg.ActiveSandboxes)
  203. c.cleanupLocalEndpoints()
  204. c.networkCleanup()
  205. if err := c.startExternalKeyListener(); err != nil {
  206. return nil, err
  207. }
  208. setupArrangeUserFilterRule(c)
  209. return c, nil
  210. }
  211. func (c *controller) SetClusterProvider(provider cluster.Provider) {
  212. var sameProvider bool
  213. c.Lock()
  214. // Avoids to spawn multiple goroutine for the same cluster provider
  215. if c.cfg.Daemon.ClusterProvider == provider {
  216. // If the cluster provider is already set, there is already a go routine spawned
  217. // that is listening for events, so nothing to do here
  218. sameProvider = true
  219. } else {
  220. c.cfg.Daemon.ClusterProvider = provider
  221. }
  222. c.Unlock()
  223. if provider == nil || sameProvider {
  224. return
  225. }
  226. // We don't want to spawn a new go routine if the previous one did not exit yet
  227. c.AgentStopWait()
  228. go c.clusterAgentInit()
  229. }
  230. func isValidClusteringIP(addr string) bool {
  231. return addr != "" && !net.ParseIP(addr).IsLoopback() && !net.ParseIP(addr).IsUnspecified()
  232. }
  233. // libnetwork side of agent depends on the keys. On the first receipt of
  234. // keys setup the agent. For subsequent key set handle the key change
  235. func (c *controller) SetKeys(keys []*types.EncryptionKey) error {
  236. subsysKeys := make(map[string]int)
  237. for _, key := range keys {
  238. if key.Subsystem != subsysGossip &&
  239. key.Subsystem != subsysIPSec {
  240. return fmt.Errorf("key received for unrecognized subsystem")
  241. }
  242. subsysKeys[key.Subsystem]++
  243. }
  244. for s, count := range subsysKeys {
  245. if count != keyringSize {
  246. return fmt.Errorf("incorrect number of keys for subsystem %v", s)
  247. }
  248. }
  249. agent := c.getAgent()
  250. if agent == nil {
  251. c.Lock()
  252. c.keys = keys
  253. c.Unlock()
  254. return nil
  255. }
  256. return c.handleKeyChange(keys)
  257. }
  258. func (c *controller) getAgent() *agent {
  259. c.Lock()
  260. defer c.Unlock()
  261. return c.agent
  262. }
  263. func (c *controller) clusterAgentInit() {
  264. clusterProvider := c.cfg.Daemon.ClusterProvider
  265. var keysAvailable bool
  266. for {
  267. eventType := <-clusterProvider.ListenClusterEvents()
  268. // The events: EventSocketChange, EventNodeReady and EventNetworkKeysAvailable are not ordered
  269. // when all the condition for the agent initialization are met then proceed with it
  270. switch eventType {
  271. case cluster.EventNetworkKeysAvailable:
  272. // Validates that the keys are actually available before starting the initialization
  273. // This will handle old spurious messages left on the channel
  274. c.Lock()
  275. keysAvailable = c.keys != nil
  276. c.Unlock()
  277. fallthrough
  278. case cluster.EventSocketChange, cluster.EventNodeReady:
  279. if keysAvailable && !c.isDistributedControl() {
  280. c.agentOperationStart()
  281. if err := c.agentSetup(clusterProvider); err != nil {
  282. c.agentStopComplete()
  283. } else {
  284. c.agentInitComplete()
  285. }
  286. }
  287. case cluster.EventNodeLeave:
  288. c.agentOperationStart()
  289. c.Lock()
  290. c.keys = nil
  291. c.Unlock()
  292. // We are leaving the cluster. Make sure we
  293. // close the gossip so that we stop all
  294. // incoming gossip updates before cleaning up
  295. // any remaining service bindings. But before
  296. // deleting the networks since the networks
  297. // should still be present when cleaning up
  298. // service bindings
  299. c.agentClose()
  300. c.cleanupServiceDiscovery("")
  301. c.cleanupServiceBindings("")
  302. c.agentStopComplete()
  303. return
  304. }
  305. }
  306. }
  307. // AgentInitWait waits for agent initialization to be completed in the controller.
  308. func (c *controller) AgentInitWait() {
  309. c.Lock()
  310. agentInitDone := c.agentInitDone
  311. c.Unlock()
  312. if agentInitDone != nil {
  313. <-agentInitDone
  314. }
  315. }
  316. // AgentStopWait waits for the Agent stop to be completed in the controller
  317. func (c *controller) AgentStopWait() {
  318. c.Lock()
  319. agentStopDone := c.agentStopDone
  320. c.Unlock()
  321. if agentStopDone != nil {
  322. <-agentStopDone
  323. }
  324. }
  325. // agentOperationStart marks the start of an Agent Init or Agent Stop
  326. func (c *controller) agentOperationStart() {
  327. c.Lock()
  328. if c.agentInitDone == nil {
  329. c.agentInitDone = make(chan struct{})
  330. }
  331. if c.agentStopDone == nil {
  332. c.agentStopDone = make(chan struct{})
  333. }
  334. c.Unlock()
  335. }
  336. // agentInitComplete notifies the successful completion of the Agent initialization
  337. func (c *controller) agentInitComplete() {
  338. c.Lock()
  339. if c.agentInitDone != nil {
  340. close(c.agentInitDone)
  341. c.agentInitDone = nil
  342. }
  343. c.Unlock()
  344. }
  345. // agentStopComplete notifies the successful completion of the Agent stop
  346. func (c *controller) agentStopComplete() {
  347. c.Lock()
  348. if c.agentStopDone != nil {
  349. close(c.agentStopDone)
  350. c.agentStopDone = nil
  351. }
  352. c.Unlock()
  353. }
  354. func (c *controller) makeDriverConfig(ntype string) map[string]interface{} {
  355. if c.cfg == nil {
  356. return nil
  357. }
  358. config := make(map[string]interface{})
  359. for _, label := range c.cfg.Daemon.Labels {
  360. if !strings.HasPrefix(netlabel.Key(label), netlabel.DriverPrefix+"."+ntype) {
  361. continue
  362. }
  363. config[netlabel.Key(label)] = netlabel.Value(label)
  364. }
  365. drvCfg, ok := c.cfg.Daemon.DriverCfg[ntype]
  366. if ok {
  367. for k, v := range drvCfg.(map[string]interface{}) {
  368. config[k] = v
  369. }
  370. }
  371. for k, v := range c.cfg.Scopes {
  372. if !v.IsValid() {
  373. continue
  374. }
  375. config[netlabel.MakeKVClient(k)] = discoverapi.DatastoreConfigData{
  376. Scope: k,
  377. Provider: v.Client.Provider,
  378. Address: v.Client.Address,
  379. Config: v.Client.Config,
  380. }
  381. }
  382. return config
  383. }
  384. var procReloadConfig = make(chan (bool), 1)
  385. func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
  386. procReloadConfig <- true
  387. defer func() { <-procReloadConfig }()
  388. // For now we accept the configuration reload only as a mean to provide a global store config after boot.
  389. // Refuse the configuration if it alters an existing datastore client configuration.
  390. update := false
  391. cfg := config.ParseConfigOptions(cfgOptions...)
  392. for s := range c.cfg.Scopes {
  393. if _, ok := cfg.Scopes[s]; !ok {
  394. return types.ForbiddenErrorf("cannot accept new configuration because it removes an existing datastore client")
  395. }
  396. }
  397. for s, nSCfg := range cfg.Scopes {
  398. if eSCfg, ok := c.cfg.Scopes[s]; ok {
  399. if eSCfg.Client.Provider != nSCfg.Client.Provider ||
  400. eSCfg.Client.Address != nSCfg.Client.Address {
  401. return types.ForbiddenErrorf("cannot accept new configuration because it modifies an existing datastore client")
  402. }
  403. } else {
  404. if err := c.initScopedStore(s, nSCfg); err != nil {
  405. return err
  406. }
  407. update = true
  408. }
  409. }
  410. if !update {
  411. return nil
  412. }
  413. c.Lock()
  414. c.cfg = cfg
  415. c.Unlock()
  416. var dsConfig *discoverapi.DatastoreConfigData
  417. for scope, sCfg := range cfg.Scopes {
  418. if scope == datastore.LocalScope || !sCfg.IsValid() {
  419. continue
  420. }
  421. dsConfig = &discoverapi.DatastoreConfigData{
  422. Scope: scope,
  423. Provider: sCfg.Client.Provider,
  424. Address: sCfg.Client.Address,
  425. Config: sCfg.Client.Config,
  426. }
  427. break
  428. }
  429. if dsConfig == nil {
  430. return nil
  431. }
  432. c.drvRegistry.WalkIPAMs(func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) bool {
  433. err := driver.DiscoverNew(discoverapi.DatastoreConfig, *dsConfig)
  434. if err != nil {
  435. logrus.Errorf("Failed to set datastore in driver %s: %v", name, err)
  436. }
  437. return false
  438. })
  439. c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
  440. err := driver.DiscoverNew(discoverapi.DatastoreConfig, *dsConfig)
  441. if err != nil {
  442. logrus.Errorf("Failed to set datastore in driver %s: %v", name, err)
  443. }
  444. return false
  445. })
  446. if c.discovery == nil && c.cfg.Cluster.Watcher != nil {
  447. if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil {
  448. logrus.Errorf("Failed to Initialize Discovery after configuration update: %v", err)
  449. }
  450. }
  451. return nil
  452. }
  453. func (c *controller) ID() string {
  454. return c.id
  455. }
  456. func (c *controller) BuiltinDrivers() []string {
  457. drivers := []string{}
  458. c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
  459. if driver.IsBuiltIn() {
  460. drivers = append(drivers, name)
  461. }
  462. return false
  463. })
  464. return drivers
  465. }
  466. func (c *controller) BuiltinIPAMDrivers() []string {
  467. drivers := []string{}
  468. c.drvRegistry.WalkIPAMs(func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) bool {
  469. if driver.IsBuiltIn() {
  470. drivers = append(drivers, name)
  471. }
  472. return false
  473. })
  474. return drivers
  475. }
  476. func (c *controller) validateHostDiscoveryConfig() bool {
  477. if c.cfg == nil || c.cfg.Cluster.Discovery == "" || c.cfg.Cluster.Address == "" {
  478. return false
  479. }
  480. return true
  481. }
  482. func (c *controller) clusterHostID() string {
  483. c.Lock()
  484. defer c.Unlock()
  485. if c.cfg == nil || c.cfg.Cluster.Address == "" {
  486. return ""
  487. }
  488. addr := strings.Split(c.cfg.Cluster.Address, ":")
  489. return addr[0]
  490. }
  491. func (c *controller) isNodeAlive(node string) bool {
  492. if c.discovery == nil {
  493. return false
  494. }
  495. nodes := c.discovery.Fetch()
  496. for _, n := range nodes {
  497. if n.String() == node {
  498. return true
  499. }
  500. }
  501. return false
  502. }
  503. func (c *controller) initDiscovery(watcher discovery.Watcher) error {
  504. if c.cfg == nil {
  505. return fmt.Errorf("discovery initialization requires a valid configuration")
  506. }
  507. c.discovery = hostdiscovery.NewHostDiscovery(watcher)
  508. return c.discovery.Watch(c.activeCallback, c.hostJoinCallback, c.hostLeaveCallback)
  509. }
  510. func (c *controller) activeCallback() {
  511. ds := c.getStore(datastore.GlobalScope)
  512. if ds != nil && !ds.Active() {
  513. ds.RestartWatch()
  514. }
  515. }
  516. func (c *controller) hostJoinCallback(nodes []net.IP) {
  517. c.processNodeDiscovery(nodes, true)
  518. }
  519. func (c *controller) hostLeaveCallback(nodes []net.IP) {
  520. c.processNodeDiscovery(nodes, false)
  521. }
  522. func (c *controller) processNodeDiscovery(nodes []net.IP, add bool) {
  523. c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
  524. c.pushNodeDiscovery(driver, capability, nodes, add)
  525. return false
  526. })
  527. }
  528. func (c *controller) pushNodeDiscovery(d driverapi.Driver, cap driverapi.Capability, nodes []net.IP, add bool) {
  529. var self net.IP
  530. if c.cfg != nil {
  531. addr := strings.Split(c.cfg.Cluster.Address, ":")
  532. self = net.ParseIP(addr[0])
  533. // if external kvstore is not configured, try swarm-mode config
  534. if self == nil {
  535. if agent := c.getAgent(); agent != nil {
  536. self = net.ParseIP(agent.advertiseAddr)
  537. }
  538. }
  539. }
  540. if d == nil || cap.ConnectivityScope != datastore.GlobalScope || nodes == nil {
  541. return
  542. }
  543. for _, node := range nodes {
  544. nodeData := discoverapi.NodeDiscoveryData{Address: node.String(), Self: node.Equal(self)}
  545. var err error
  546. if add {
  547. err = d.DiscoverNew(discoverapi.NodeDiscovery, nodeData)
  548. } else {
  549. err = d.DiscoverDelete(discoverapi.NodeDiscovery, nodeData)
  550. }
  551. if err != nil {
  552. logrus.Debugf("discovery notification error: %v", err)
  553. }
  554. }
  555. }
  556. func (c *controller) Config() config.Config {
  557. c.Lock()
  558. defer c.Unlock()
  559. if c.cfg == nil {
  560. return config.Config{}
  561. }
  562. return *c.cfg
  563. }
  564. func (c *controller) isManager() bool {
  565. c.Lock()
  566. defer c.Unlock()
  567. if c.cfg == nil || c.cfg.Daemon.ClusterProvider == nil {
  568. return false
  569. }
  570. return c.cfg.Daemon.ClusterProvider.IsManager()
  571. }
  572. func (c *controller) isAgent() bool {
  573. c.Lock()
  574. defer c.Unlock()
  575. if c.cfg == nil || c.cfg.Daemon.ClusterProvider == nil {
  576. return false
  577. }
  578. return c.cfg.Daemon.ClusterProvider.IsAgent()
  579. }
  580. func (c *controller) isDistributedControl() bool {
  581. return !c.isManager() && !c.isAgent()
  582. }
  583. func (c *controller) GetPluginGetter() plugingetter.PluginGetter {
  584. return c.drvRegistry.GetPluginGetter()
  585. }
  586. func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error {
  587. c.Lock()
  588. hd := c.discovery
  589. c.Unlock()
  590. if hd != nil {
  591. c.pushNodeDiscovery(driver, capability, hd.Fetch(), true)
  592. }
  593. c.agentDriverNotify(driver)
  594. return nil
  595. }
  596. // XXX This should be made driver agnostic. See comment below.
  597. const overlayDSROptionString = "dsr"
  598. // NewNetwork creates a new network of the specified network type. The options
  599. // are network specific and modeled in a generic way.
  600. func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
  601. var (
  602. cap *driverapi.Capability
  603. err error
  604. t *network
  605. skipCfgEpCount bool
  606. )
  607. if id != "" {
  608. c.networkLocker.Lock(id)
  609. defer c.networkLocker.Unlock(id)
  610. if _, err = c.NetworkByID(id); err == nil {
  611. return nil, NetworkNameError(id)
  612. }
  613. }
  614. if !config.IsValidName(name) {
  615. return nil, ErrInvalidName(name)
  616. }
  617. if id == "" {
  618. id = stringid.GenerateRandomID()
  619. }
  620. defaultIpam := defaultIpamForNetworkType(networkType)
  621. // Construct the network object
  622. network := &network{
  623. name: name,
  624. networkType: networkType,
  625. generic: map[string]interface{}{netlabel.GenericData: make(map[string]string)},
  626. ipamType: defaultIpam,
  627. id: id,
  628. created: time.Now(),
  629. ctrlr: c,
  630. persist: true,
  631. drvOnce: &sync.Once{},
  632. loadBalancerMode: loadBalancerModeDefault,
  633. }
  634. network.processOptions(options...)
  635. if err = network.validateConfiguration(); err != nil {
  636. return nil, err
  637. }
  638. // Reset network types, force local scope and skip allocation and
  639. // plumbing for configuration networks. Reset of the config-only
  640. // network drivers is needed so that this special network is not
  641. // usable by old engine versions.
  642. if network.configOnly {
  643. network.scope = datastore.LocalScope
  644. network.networkType = "null"
  645. goto addToStore
  646. }
  647. _, cap, err = network.resolveDriver(network.networkType, true)
  648. if err != nil {
  649. return nil, err
  650. }
  651. if network.scope == datastore.LocalScope && cap.DataScope == datastore.GlobalScope {
  652. return nil, types.ForbiddenErrorf("cannot downgrade network scope for %s networks", networkType)
  653. }
  654. if network.ingress && cap.DataScope != datastore.GlobalScope {
  655. return nil, types.ForbiddenErrorf("Ingress network can only be global scope network")
  656. }
  657. // At this point the network scope is still unknown if not set by user
  658. if (cap.DataScope == datastore.GlobalScope || network.scope == datastore.SwarmScope) &&
  659. !c.isDistributedControl() && !network.dynamic {
  660. if c.isManager() {
  661. // For non-distributed controlled environment, globalscoped non-dynamic networks are redirected to Manager
  662. return nil, ManagerRedirectError(name)
  663. }
  664. return nil, types.ForbiddenErrorf("Cannot create a multi-host network from a worker node. Please create the network from a manager node.")
  665. }
  666. if network.scope == datastore.SwarmScope && c.isDistributedControl() {
  667. return nil, types.ForbiddenErrorf("cannot create a swarm scoped network when swarm is not active")
  668. }
  669. // Make sure we have a driver available for this network type
  670. // before we allocate anything.
  671. if _, err := network.driver(true); err != nil {
  672. return nil, err
  673. }
  674. // From this point on, we need the network specific configuration,
  675. // which may come from a configuration-only network
  676. if network.configFrom != "" {
  677. t, err = c.getConfigNetwork(network.configFrom)
  678. if err != nil {
  679. return nil, types.NotFoundErrorf("configuration network %q does not exist", network.configFrom)
  680. }
  681. if err = t.applyConfigurationTo(network); err != nil {
  682. return nil, types.InternalErrorf("Failed to apply configuration: %v", err)
  683. }
  684. network.generic[netlabel.Internal] = network.internal
  685. defer func() {
  686. if err == nil && !skipCfgEpCount {
  687. if err := t.getEpCnt().IncEndpointCnt(); err != nil {
  688. logrus.Warnf("Failed to update reference count for configuration network %q on creation of network %q: %v",
  689. t.Name(), network.Name(), err)
  690. }
  691. }
  692. }()
  693. }
  694. err = network.ipamAllocate()
  695. if err != nil {
  696. return nil, err
  697. }
  698. defer func() {
  699. if err != nil {
  700. network.ipamRelease()
  701. }
  702. }()
  703. err = c.addNetwork(network)
  704. if err != nil {
  705. if _, ok := err.(types.MaskableError); ok {
  706. // This error can be ignored and set this boolean
  707. // value to skip a refcount increment for configOnly networks
  708. skipCfgEpCount = true
  709. } else {
  710. return nil, err
  711. }
  712. }
  713. defer func() {
  714. if err != nil {
  715. if e := network.deleteNetwork(); e != nil {
  716. logrus.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err)
  717. }
  718. }
  719. }()
  720. // XXX If the driver type is "overlay" check the options for DSR
  721. // being set. If so, set the network's load balancing mode to DSR.
  722. // This should really be done in a network option, but due to
  723. // time pressure to get this in without adding changes to moby,
  724. // swarm and CLI, it is being implemented as a driver-specific
  725. // option. Unfortunately, drivers can't influence the core
  726. // "libnetwork.network" data type. Hence we need this hack code
  727. // to implement in this manner.
  728. if gval, ok := network.generic[netlabel.GenericData]; ok && network.networkType == "overlay" {
  729. optMap := gval.(map[string]string)
  730. if _, ok := optMap[overlayDSROptionString]; ok {
  731. network.loadBalancerMode = loadBalancerModeDSR
  732. }
  733. }
  734. addToStore:
  735. // First store the endpoint count, then the network. To avoid to
  736. // end up with a datastore containing a network and not an epCnt,
  737. // in case of an ungraceful shutdown during this function call.
  738. epCnt := &endpointCnt{n: network}
  739. if err = c.updateToStore(epCnt); err != nil {
  740. return nil, err
  741. }
  742. defer func() {
  743. if err != nil {
  744. if e := c.deleteFromStore(epCnt); e != nil {
  745. logrus.Warnf("could not rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e)
  746. }
  747. }
  748. }()
  749. network.epCnt = epCnt
  750. if err = c.updateToStore(network); err != nil {
  751. return nil, err
  752. }
  753. defer func() {
  754. if err != nil {
  755. if e := c.deleteFromStore(network); e != nil {
  756. logrus.Warnf("could not rollback from store, network %v on failure (%v): %v", network, err, e)
  757. }
  758. }
  759. }()
  760. if network.configOnly {
  761. return network, nil
  762. }
  763. joinCluster(network)
  764. defer func() {
  765. if err != nil {
  766. network.cancelDriverWatches()
  767. if e := network.leaveCluster(); e != nil {
  768. logrus.Warnf("Failed to leave agent cluster on network %s on failure (%v): %v", network.name, err, e)
  769. }
  770. }
  771. }()
  772. if network.hasLoadBalancerEndpoint() {
  773. if err = network.createLoadBalancerSandbox(); err != nil {
  774. return nil, err
  775. }
  776. }
  777. if !c.isDistributedControl() {
  778. c.Lock()
  779. arrangeIngressFilterRule()
  780. c.Unlock()
  781. }
  782. arrangeUserFilterRule()
  783. return network, nil
  784. }
  785. var joinCluster NetworkWalker = func(nw Network) bool {
  786. n := nw.(*network)
  787. if n.configOnly {
  788. return false
  789. }
  790. if err := n.joinCluster(); err != nil {
  791. logrus.Errorf("Failed to join network %s (%s) into agent cluster: %v", n.Name(), n.ID(), err)
  792. }
  793. n.addDriverWatches()
  794. return false
  795. }
  796. func (c *controller) reservePools() {
  797. networks, err := c.getNetworksForScope(datastore.LocalScope)
  798. if err != nil {
  799. logrus.Warnf("Could not retrieve networks from local store during ipam allocation for existing networks: %v", err)
  800. return
  801. }
  802. for _, n := range networks {
  803. if n.configOnly {
  804. continue
  805. }
  806. if !doReplayPoolReserve(n) {
  807. continue
  808. }
  809. // Construct pseudo configs for the auto IP case
  810. autoIPv4 := (len(n.ipamV4Config) == 0 || (len(n.ipamV4Config) == 1 && n.ipamV4Config[0].PreferredPool == "")) && len(n.ipamV4Info) > 0
  811. autoIPv6 := (len(n.ipamV6Config) == 0 || (len(n.ipamV6Config) == 1 && n.ipamV6Config[0].PreferredPool == "")) && len(n.ipamV6Info) > 0
  812. if autoIPv4 {
  813. n.ipamV4Config = []*IpamConf{{PreferredPool: n.ipamV4Info[0].Pool.String()}}
  814. }
  815. if n.enableIPv6 && autoIPv6 {
  816. n.ipamV6Config = []*IpamConf{{PreferredPool: n.ipamV6Info[0].Pool.String()}}
  817. }
  818. // Account current network gateways
  819. for i, c := range n.ipamV4Config {
  820. if c.Gateway == "" && n.ipamV4Info[i].Gateway != nil {
  821. c.Gateway = n.ipamV4Info[i].Gateway.IP.String()
  822. }
  823. }
  824. if n.enableIPv6 {
  825. for i, c := range n.ipamV6Config {
  826. if c.Gateway == "" && n.ipamV6Info[i].Gateway != nil {
  827. c.Gateway = n.ipamV6Info[i].Gateway.IP.String()
  828. }
  829. }
  830. }
  831. // Reserve pools
  832. if err := n.ipamAllocate(); err != nil {
  833. logrus.Warnf("Failed to allocate ipam pool(s) for network %q (%s): %v", n.Name(), n.ID(), err)
  834. }
  835. // Reserve existing endpoints' addresses
  836. ipam, _, err := n.getController().getIPAMDriver(n.ipamType)
  837. if err != nil {
  838. logrus.Warnf("Failed to retrieve ipam driver for network %q (%s) during address reservation", n.Name(), n.ID())
  839. continue
  840. }
  841. epl, err := n.getEndpointsFromStore()
  842. if err != nil {
  843. logrus.Warnf("Failed to retrieve list of current endpoints on network %q (%s)", n.Name(), n.ID())
  844. continue
  845. }
  846. for _, ep := range epl {
  847. if ep.Iface() == nil {
  848. logrus.Warnf("endpoint interface is empty for %q (%s)", ep.Name(), ep.ID())
  849. continue
  850. }
  851. if err := ep.assignAddress(ipam, true, ep.Iface().AddressIPv6() != nil); err != nil {
  852. logrus.Warnf("Failed to reserve current address for endpoint %q (%s) on network %q (%s)",
  853. ep.Name(), ep.ID(), n.Name(), n.ID())
  854. }
  855. }
  856. }
  857. }
  858. func doReplayPoolReserve(n *network) bool {
  859. _, caps, err := n.getController().getIPAMDriver(n.ipamType)
  860. if err != nil {
  861. logrus.Warnf("Failed to retrieve ipam driver for network %q (%s): %v", n.Name(), n.ID(), err)
  862. return false
  863. }
  864. return caps.RequiresRequestReplay
  865. }
  866. func (c *controller) addNetwork(n *network) error {
  867. d, err := n.driver(true)
  868. if err != nil {
  869. return err
  870. }
  871. // Create the network
  872. if err := d.CreateNetwork(n.id, n.generic, n, n.getIPData(4), n.getIPData(6)); err != nil {
  873. return err
  874. }
  875. n.startResolver()
  876. return nil
  877. }
  878. func (c *controller) Networks() []Network {
  879. var list []Network
  880. networks, err := c.getNetworksFromStore()
  881. if err != nil {
  882. logrus.Error(err)
  883. }
  884. for _, n := range networks {
  885. if n.inDelete {
  886. continue
  887. }
  888. list = append(list, n)
  889. }
  890. return list
  891. }
  892. func (c *controller) WalkNetworks(walker NetworkWalker) {
  893. for _, n := range c.Networks() {
  894. if walker(n) {
  895. return
  896. }
  897. }
  898. }
  899. func (c *controller) NetworkByName(name string) (Network, error) {
  900. if name == "" {
  901. return nil, ErrInvalidName(name)
  902. }
  903. var n Network
  904. s := func(current Network) bool {
  905. if current.Name() == name {
  906. n = current
  907. return true
  908. }
  909. return false
  910. }
  911. c.WalkNetworks(s)
  912. if n == nil {
  913. return nil, ErrNoSuchNetwork(name)
  914. }
  915. return n, nil
  916. }
  917. func (c *controller) NetworkByID(id string) (Network, error) {
  918. if id == "" {
  919. return nil, ErrInvalidID(id)
  920. }
  921. n, err := c.getNetworkFromStore(id)
  922. if err != nil {
  923. return nil, ErrNoSuchNetwork(id)
  924. }
  925. return n, nil
  926. }
  927. // NewSandbox creates a new sandbox for the passed container id
  928. func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (Sandbox, error) {
  929. if containerID == "" {
  930. return nil, types.BadRequestErrorf("invalid container ID")
  931. }
  932. var sb *sandbox
  933. c.Lock()
  934. for _, s := range c.sandboxes {
  935. if s.containerID == containerID {
  936. // If not a stub, then we already have a complete sandbox.
  937. if !s.isStub {
  938. sbID := s.ID()
  939. c.Unlock()
  940. return nil, types.ForbiddenErrorf("container %s is already present in sandbox %s", containerID, sbID)
  941. }
  942. // We already have a stub sandbox from the
  943. // store. Make use of it so that we don't lose
  944. // the endpoints from store but reset the
  945. // isStub flag.
  946. sb = s
  947. sb.isStub = false
  948. break
  949. }
  950. }
  951. c.Unlock()
  952. sandboxID := stringid.GenerateRandomID()
  953. if runtime.GOOS == "windows" {
  954. sandboxID = containerID
  955. }
  956. // Create sandbox and process options first. Key generation depends on an option
  957. if sb == nil {
  958. sb = &sandbox{
  959. id: sandboxID,
  960. containerID: containerID,
  961. endpoints: []*endpoint{},
  962. epPriority: map[string]int{},
  963. populatedEndpoints: map[string]struct{}{},
  964. config: containerConfig{},
  965. controller: c,
  966. extDNS: []extDNSEntry{},
  967. }
  968. }
  969. sb.processOptions(options...)
  970. c.Lock()
  971. if sb.ingress && c.ingressSandbox != nil {
  972. c.Unlock()
  973. return nil, types.ForbiddenErrorf("ingress sandbox already present")
  974. }
  975. if sb.ingress {
  976. c.ingressSandbox = sb
  977. sb.config.hostsPath = filepath.Join(c.cfg.Daemon.DataDir, "/network/files/hosts")
  978. sb.config.resolvConfPath = filepath.Join(c.cfg.Daemon.DataDir, "/network/files/resolv.conf")
  979. sb.id = "ingress_sbox"
  980. } else if sb.loadBalancerNID != "" {
  981. sb.id = "lb_" + sb.loadBalancerNID
  982. }
  983. c.Unlock()
  984. var err error
  985. defer func() {
  986. if err != nil {
  987. c.Lock()
  988. if sb.ingress {
  989. c.ingressSandbox = nil
  990. }
  991. c.Unlock()
  992. }
  993. }()
  994. if err = sb.setupResolutionFiles(); err != nil {
  995. return nil, err
  996. }
  997. if sb.config.useDefaultSandBox {
  998. c.sboxOnce.Do(func() {
  999. c.defOsSbox, err = osl.NewSandbox(sb.Key(), false, false)
  1000. })
  1001. if err != nil {
  1002. c.sboxOnce = sync.Once{}
  1003. return nil, fmt.Errorf("failed to create default sandbox: %v", err)
  1004. }
  1005. sb.osSbox = c.defOsSbox
  1006. }
  1007. if sb.osSbox == nil && !sb.config.useExternalKey {
  1008. if sb.osSbox, err = osl.NewSandbox(sb.Key(), !sb.config.useDefaultSandBox, false); err != nil {
  1009. return nil, fmt.Errorf("failed to create new osl sandbox: %v", err)
  1010. }
  1011. }
  1012. if sb.osSbox != nil {
  1013. // Apply operating specific knobs on the load balancer sandbox
  1014. sb.osSbox.ApplyOSTweaks(sb.oslTypes)
  1015. }
  1016. c.Lock()
  1017. c.sandboxes[sb.id] = sb
  1018. c.Unlock()
  1019. defer func() {
  1020. if err != nil {
  1021. c.Lock()
  1022. delete(c.sandboxes, sb.id)
  1023. c.Unlock()
  1024. }
  1025. }()
  1026. err = sb.storeUpdate()
  1027. if err != nil {
  1028. return nil, fmt.Errorf("failed to update the store state of sandbox: %v", err)
  1029. }
  1030. return sb, nil
  1031. }
  1032. func (c *controller) Sandboxes() []Sandbox {
  1033. c.Lock()
  1034. defer c.Unlock()
  1035. list := make([]Sandbox, 0, len(c.sandboxes))
  1036. for _, s := range c.sandboxes {
  1037. // Hide stub sandboxes from libnetwork users
  1038. if s.isStub {
  1039. continue
  1040. }
  1041. list = append(list, s)
  1042. }
  1043. return list
  1044. }
  1045. func (c *controller) WalkSandboxes(walker SandboxWalker) {
  1046. for _, sb := range c.Sandboxes() {
  1047. if walker(sb) {
  1048. return
  1049. }
  1050. }
  1051. }
  1052. func (c *controller) SandboxByID(id string) (Sandbox, error) {
  1053. if id == "" {
  1054. return nil, ErrInvalidID(id)
  1055. }
  1056. c.Lock()
  1057. s, ok := c.sandboxes[id]
  1058. c.Unlock()
  1059. if !ok {
  1060. return nil, types.NotFoundErrorf("sandbox %s not found", id)
  1061. }
  1062. return s, nil
  1063. }
  1064. // SandboxDestroy destroys a sandbox given a container ID
  1065. func (c *controller) SandboxDestroy(id string) error {
  1066. var sb *sandbox
  1067. c.Lock()
  1068. for _, s := range c.sandboxes {
  1069. if s.containerID == id {
  1070. sb = s
  1071. break
  1072. }
  1073. }
  1074. c.Unlock()
  1075. // It is not an error if sandbox is not available
  1076. if sb == nil {
  1077. return nil
  1078. }
  1079. return sb.Delete()
  1080. }
  1081. // SandboxContainerWalker returns a Sandbox Walker function which looks for an existing Sandbox with the passed containerID
  1082. func SandboxContainerWalker(out *Sandbox, containerID string) SandboxWalker {
  1083. return func(sb Sandbox) bool {
  1084. if sb.ContainerID() == containerID {
  1085. *out = sb
  1086. return true
  1087. }
  1088. return false
  1089. }
  1090. }
  1091. // SandboxKeyWalker returns a Sandbox Walker function which looks for an existing Sandbox with the passed key
  1092. func SandboxKeyWalker(out *Sandbox, key string) SandboxWalker {
  1093. return func(sb Sandbox) bool {
  1094. if sb.Key() == key {
  1095. *out = sb
  1096. return true
  1097. }
  1098. return false
  1099. }
  1100. }
  1101. func (c *controller) loadDriver(networkType string) error {
  1102. var err error
  1103. if pg := c.GetPluginGetter(); pg != nil {
  1104. _, err = pg.Get(networkType, driverapi.NetworkPluginEndpointType, plugingetter.Lookup)
  1105. } else {
  1106. _, err = plugins.Get(networkType, driverapi.NetworkPluginEndpointType)
  1107. }
  1108. if err != nil {
  1109. if errors.Cause(err) == plugins.ErrNotFound {
  1110. return types.NotFoundErrorf(err.Error())
  1111. }
  1112. return err
  1113. }
  1114. return nil
  1115. }
  1116. func (c *controller) loadIPAMDriver(name string) error {
  1117. var err error
  1118. if pg := c.GetPluginGetter(); pg != nil {
  1119. _, err = pg.Get(name, ipamapi.PluginEndpointType, plugingetter.Lookup)
  1120. } else {
  1121. _, err = plugins.Get(name, ipamapi.PluginEndpointType)
  1122. }
  1123. if err != nil {
  1124. if errors.Cause(err) == plugins.ErrNotFound {
  1125. return types.NotFoundErrorf(err.Error())
  1126. }
  1127. return err
  1128. }
  1129. return nil
  1130. }
  1131. func (c *controller) getIPAMDriver(name string) (ipamapi.Ipam, *ipamapi.Capability, error) {
  1132. id, cap := c.drvRegistry.IPAM(name)
  1133. if id == nil {
  1134. // Might be a plugin name. Try loading it
  1135. if err := c.loadIPAMDriver(name); err != nil {
  1136. return nil, nil, err
  1137. }
  1138. // Now that we resolved the plugin, try again looking up the registry
  1139. id, cap = c.drvRegistry.IPAM(name)
  1140. if id == nil {
  1141. return nil, nil, types.BadRequestErrorf("invalid ipam driver: %q", name)
  1142. }
  1143. }
  1144. return id, cap, nil
  1145. }
  1146. func (c *controller) Stop() {
  1147. c.closeStores()
  1148. c.stopExternalKeyListener()
  1149. osl.GC()
  1150. }
  1151. // StartDiagnostic start the network dias mode
  1152. func (c *controller) StartDiagnostic(port int) {
  1153. c.Lock()
  1154. if !c.DiagnosticServer.IsDiagnosticEnabled() {
  1155. c.DiagnosticServer.EnableDiagnostic("127.0.0.1", port)
  1156. }
  1157. c.Unlock()
  1158. }
  1159. // StopDiagnostic start the network dias mode
  1160. func (c *controller) StopDiagnostic() {
  1161. c.Lock()
  1162. if c.DiagnosticServer.IsDiagnosticEnabled() {
  1163. c.DiagnosticServer.DisableDiagnostic()
  1164. }
  1165. c.Unlock()
  1166. }
  1167. // IsDiagnosticEnabled returns true if the dias is enabled
  1168. func (c *controller) IsDiagnosticEnabled() bool {
  1169. c.Lock()
  1170. defer c.Unlock()
  1171. return c.DiagnosticServer.IsDiagnosticEnabled()
  1172. }
  1173. func (c *controller) iptablesEnabled() bool {
  1174. c.Lock()
  1175. defer c.Unlock()
  1176. if c.cfg == nil {
  1177. return false
  1178. }
  1179. // parse map cfg["bridge"]["generic"]["EnableIPTable"]
  1180. cfgBridge, ok := c.cfg.Daemon.DriverCfg["bridge"].(map[string]interface{})
  1181. if !ok {
  1182. return false
  1183. }
  1184. cfgGeneric, ok := cfgBridge[netlabel.GenericData].(options.Generic)
  1185. if !ok {
  1186. return false
  1187. }
  1188. enabled, ok := cfgGeneric["EnableIPTables"].(bool)
  1189. if !ok {
  1190. // unless user explicitly stated, assume iptable is enabled
  1191. enabled = true
  1192. }
  1193. return enabled
  1194. }