github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/fleet-manager/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"syscall"
     9  	"time"
    10  
    11  	"github.com/Cloud-Foundations/Dominator/fleetmanager/httpd"
    12  	"github.com/Cloud-Foundations/Dominator/fleetmanager/hypervisors"
    13  	"github.com/Cloud-Foundations/Dominator/fleetmanager/hypervisors/fsstorer"
    14  	"github.com/Cloud-Foundations/Dominator/fleetmanager/rpcd"
    15  	"github.com/Cloud-Foundations/Dominator/fleetmanager/topology"
    16  	"github.com/Cloud-Foundations/Dominator/lib/constants"
    17  	"github.com/Cloud-Foundations/Dominator/lib/flags/loadflags"
    18  	"github.com/Cloud-Foundations/Dominator/lib/json"
    19  	"github.com/Cloud-Foundations/Dominator/lib/log"
    20  	"github.com/Cloud-Foundations/Dominator/lib/log/serverlogger"
    21  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    22  	"github.com/Cloud-Foundations/Dominator/lib/srpc/proxy"
    23  	"github.com/Cloud-Foundations/Dominator/lib/srpc/setupserver"
    24  	"github.com/Cloud-Foundations/tricorder/go/tricorder"
    25  )
    26  
    27  const (
    28  	dirPerms = syscall.S_IRWXU | syscall.S_IRGRP | syscall.S_IXGRP |
    29  		syscall.S_IROTH | syscall.S_IXOTH
    30  )
    31  
    32  var (
    33  	checkTopology = flag.Bool("checkTopology", false,
    34  		"If true, perform a one-time check, write to stdout and exit")
    35  	ipmiPasswordFile = flag.String("ipmiPasswordFile", "",
    36  		"Name of password file used to authenticate for IPMI requests")
    37  	ipmiUsername = flag.String("ipmiUsername", "",
    38  		"Name of user to authenticate as when making IPMI requests")
    39  	topologyCheckInterval = flag.Duration("topologyCheckInterval",
    40  		time.Minute, "Configuration check interval")
    41  	portNum = flag.Uint("portNum", constants.FleetManagerPortNumber,
    42  		"Port number to allocate and listen on for HTTP/RPC")
    43  	stateDir = flag.String("stateDir", "/var/lib/fleet-manager",
    44  		"Name of state directory")
    45  	topologyDir = flag.String("topologyDir", "",
    46  		"Name of local topology directory or directory in Git repository")
    47  	topologyRepository = flag.String("topologyRepository", "",
    48  		"URL of Git repository containing repository")
    49  	variablesDir = flag.String("variablesDir", "",
    50  		"Name of local variables directory or directory in Git repository")
    51  )
    52  
    53  func doCheck(logger log.DebugLogger) {
    54  	topo, err := topology.LoadWithParams(topology.Params{
    55  		Logger:       logger,
    56  		TopologyDir:  *topologyDir,
    57  		VariablesDir: *variablesDir,
    58  	})
    59  	if err != nil {
    60  		fmt.Fprintln(os.Stderr, err)
    61  		os.Exit(1)
    62  	}
    63  	if err := json.WriteWithIndent(os.Stdout, "    ", topo); err != nil {
    64  		fmt.Fprintln(os.Stderr, err)
    65  		os.Exit(1)
    66  	}
    67  	os.Exit(0)
    68  }
    69  
    70  func main() {
    71  	if err := loadflags.LoadForDaemon("fleet-manager"); err != nil {
    72  		fmt.Fprintln(os.Stderr, err)
    73  		os.Exit(1)
    74  	}
    75  	flag.Parse()
    76  	tricorder.RegisterFlags()
    77  	logger := serverlogger.New("")
    78  	srpc.SetDefaultLogger(logger)
    79  	if *checkTopology {
    80  		doCheck(logger)
    81  	}
    82  	params := setupserver.Params{Logger: logger}
    83  	if err := setupserver.SetupTlsWithParams(params); err != nil {
    84  		logger.Fatalln(err)
    85  	}
    86  	if err := proxy.New(logger); err != nil {
    87  		logger.Fatalln(err)
    88  	}
    89  	if err := os.MkdirAll(*stateDir, dirPerms); err != nil {
    90  		logger.Fatalf("Cannot create state directory: %s\n", err)
    91  	}
    92  	topologyChannel, err := topology.WatchWithParams(topology.WatchParams{
    93  		Params: topology.Params{
    94  			Logger:       logger,
    95  			TopologyDir:  *topologyDir,
    96  			VariablesDir: *variablesDir,
    97  		},
    98  		CheckInterval:      *topologyCheckInterval,
    99  		LocalRepositoryDir: filepath.Join(*stateDir, "topology"),
   100  		TopologyRepository: *topologyRepository,
   101  	},
   102  	)
   103  	if err != nil {
   104  		logger.Fatalf("Cannot watch for topology: %s\n", err)
   105  	}
   106  	storer, err := fsstorer.New(filepath.Join(*stateDir, "hypervisor-db"),
   107  		logger)
   108  	if err != nil {
   109  		logger.Fatalf("Cannot create DB: %s\n", err)
   110  	}
   111  	hyperManager, err := hypervisors.New(hypervisors.StartOptions{
   112  		IpmiPasswordFile: *ipmiPasswordFile,
   113  		IpmiUsername:     *ipmiUsername,
   114  		Logger:           logger,
   115  		Storer:           storer,
   116  	})
   117  	if err != nil {
   118  		logger.Fatalf("Cannot create hypervisors manager: %s\n", err)
   119  	}
   120  	rpcHtmlWriter, err := rpcd.Setup(hyperManager, logger)
   121  	if err != nil {
   122  		logger.Fatalf("Cannot start rpcd: %s\n", err)
   123  	}
   124  	webServer, err := httpd.StartServer(*portNum, logger)
   125  	if err != nil {
   126  		logger.Fatalf("Unable to create http server: %s\n", err)
   127  	}
   128  	webServer.AddHtmlWriter(hyperManager)
   129  	webServer.AddHtmlWriter(rpcHtmlWriter)
   130  	webServer.AddHtmlWriter(logger)
   131  	for topology := range topologyChannel {
   132  		logger.Println("Received new topology")
   133  		webServer.UpdateTopology(topology)
   134  		hyperManager.UpdateTopology(topology)
   135  	}
   136  }