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  }