github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/mdbd/loadTopology.go (about) 1 package main 2 3 import ( 4 "errors" 5 "os" 6 "path/filepath" 7 "strings" 8 "sync" 9 "time" 10 11 "github.com/Cloud-Foundations/Dominator/fleetmanager/topology" 12 "github.com/Cloud-Foundations/Dominator/lib/log" 13 "github.com/Cloud-Foundations/Dominator/lib/mdb" 14 ) 15 16 var setupTopology bool 17 18 type topologyGeneratorType struct { 19 eventChannel chan<- struct{} 20 logger log.DebugLogger 21 mutex sync.Mutex 22 topology *topology.Topology 23 } 24 25 func newTopologyGenerator(params makeGeneratorParams) (generator, error) { 26 if setupTopology { 27 return nil, errors.New("only one Topology driver permitted") 28 } 29 var topologyUrl, localRepositoryDir, topologyDir string 30 interval := time.Duration(*fetchInterval) * time.Second 31 if fi, err := os.Stat(params.args[0]); err == nil && fi.IsDir() { 32 localRepositoryDir = params.args[0] 33 } else { 34 topologyUrl = params.args[0] 35 localRepositoryDir = filepath.Join(*stateDir, "topology") 36 if strings.HasPrefix(topologyUrl, "git@") { 37 if interval < 59*time.Second { 38 interval = 59 * time.Second 39 } 40 } 41 } 42 if len(params.args) > 1 { 43 topologyDir = params.args[1] 44 } 45 topoChannel, err := topology.Watch(topologyUrl, localRepositoryDir, 46 topologyDir, interval, params.logger) 47 if err != nil { 48 return nil, err 49 } 50 g := &topologyGeneratorType{ 51 eventChannel: params.eventChannel, 52 logger: params.logger, 53 } 54 params.waitGroup.Add(1) 55 go g.daemon(topoChannel, params.waitGroup) 56 setupTopology = true 57 return g, nil 58 } 59 60 func (g *topologyGeneratorType) daemon(topoChannel <-chan *topology.Topology, 61 waitGroup *sync.WaitGroup) { 62 firstTopo := <-topoChannel 63 g.mutex.Lock() 64 g.topology = firstTopo 65 g.mutex.Unlock() 66 waitGroup.Done() 67 select { 68 case g.eventChannel <- struct{}{}: 69 default: 70 } 71 for topo := range topoChannel { 72 g.logger.Println("Received new topology") 73 g.mutex.Lock() 74 g.topology = topo 75 g.mutex.Unlock() 76 select { 77 case g.eventChannel <- struct{}{}: 78 default: 79 } 80 } 81 } 82 83 func (g *topologyGeneratorType) Generate(unused_datacentre string, 84 logger log.DebugLogger) (*mdb.Mdb, error) { 85 g.mutex.Lock() 86 topo := g.topology 87 g.mutex.Unlock() 88 var newMdb mdb.Mdb 89 if topo == nil { 90 return &newMdb, nil 91 } 92 machines, err := topo.ListMachines("") 93 if err != nil { 94 return nil, err 95 } 96 for _, machine := range machines { 97 var ipAddr string 98 if len(machine.HostIpAddress) > 0 { 99 ipAddr = machine.HostIpAddress.String() 100 } 101 tags := machine.Tags 102 if tags == nil { 103 tags = emptyTags 104 } 105 _, disableUpdates := tags["DisableUpdates"] 106 newMdb.Machines = append(newMdb.Machines, mdb.Machine{ 107 Hostname: machine.Hostname, 108 Location: machine.Location, 109 IpAddress: ipAddr, 110 OwnerGroups: machine.OwnerGroups, 111 OwnerUsers: machine.OwnerUsers, 112 RequiredImage: tags["RequiredImage"], 113 PlannedImage: tags["PlannedImage"], 114 DisableUpdates: disableUpdates, 115 Tags: machine.Tags, 116 }) 117 } 118 return &newMdb, nil 119 } 120 121 func (g *topologyGeneratorType) GetVariables() (map[string]string, error) { 122 g.mutex.Lock() 123 topo := g.topology 124 g.mutex.Unlock() 125 return topo.Variables, nil 126 }