github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/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/serverlogger"
    20  	"github.com/Cloud-Foundations/Dominator/lib/srpc/proxy"
    21  	"github.com/Cloud-Foundations/Dominator/lib/srpc/setupserver"
    22  	"github.com/Cloud-Foundations/tricorder/go/tricorder"
    23  )
    24  
    25  const (
    26  	dirPerms = syscall.S_IRWXU | syscall.S_IRGRP | syscall.S_IXGRP |
    27  		syscall.S_IROTH | syscall.S_IXOTH
    28  )
    29  
    30  var (
    31  	checkTopology = flag.Bool("checkTopology", false,
    32  		"If true, perform a one-time check, write to stdout and exit")
    33  	ipmiPasswordFile = flag.String("ipmiPasswordFile", "",
    34  		"Name of password file used to authenticate for IPMI requests")
    35  	ipmiUsername = flag.String("ipmiUsername", "",
    36  		"Name of user to authenticate as when making IPMI requests")
    37  	topologyCheckInterval = flag.Duration("topologyCheckInterval",
    38  		time.Minute, "Configuration check interval")
    39  	portNum = flag.Uint("portNum", constants.FleetManagerPortNumber,
    40  		"Port number to allocate and listen on for HTTP/RPC")
    41  	stateDir = flag.String("stateDir", "/var/lib/fleet-manager",
    42  		"Name of state directory")
    43  	topologyDir = flag.String("topologyDir", "",
    44  		"Name of local topology directory or direcory in Git repository")
    45  	topologyRepository = flag.String("topologyRepository", "",
    46  		"URL of Git repository containing repository")
    47  )
    48  
    49  func doCheck() {
    50  	topo, err := topology.Load(*topologyDir)
    51  	if err != nil {
    52  		fmt.Fprintln(os.Stderr, err)
    53  		os.Exit(1)
    54  	}
    55  	if err := json.WriteWithIndent(os.Stdout, "    ", topo); err != nil {
    56  		fmt.Fprintln(os.Stderr, err)
    57  		os.Exit(1)
    58  	}
    59  	os.Exit(0)
    60  }
    61  
    62  func main() {
    63  	if err := loadflags.LoadForDaemon("fleet-manager"); err != nil {
    64  		fmt.Fprintln(os.Stderr, err)
    65  		os.Exit(1)
    66  	}
    67  	flag.Parse()
    68  	if *checkTopology {
    69  		doCheck()
    70  	}
    71  	tricorder.RegisterFlags()
    72  	logger := serverlogger.New("")
    73  	if err := setupserver.SetupTls(); err != nil {
    74  		logger.Fatalln(err)
    75  	}
    76  	if err := proxy.New(logger); err != nil {
    77  		logger.Fatalln(err)
    78  	}
    79  	if err := os.MkdirAll(*stateDir, dirPerms); err != nil {
    80  		logger.Fatalf("Cannot create state directory: %s\n", err)
    81  	}
    82  	topologyChannel, err := topology.Watch(*topologyRepository,
    83  		filepath.Join(*stateDir, "topology"), *topologyDir,
    84  		*topologyCheckInterval, logger)
    85  	if err != nil {
    86  		logger.Fatalf("Cannot watch for topology: %s\n", err)
    87  	}
    88  	storer, err := fsstorer.New(filepath.Join(*stateDir, "hypervisor-db"),
    89  		logger)
    90  	if err != nil {
    91  		logger.Fatalf("Cannot create DB: %s\n", err)
    92  	}
    93  	hyperManager, err := hypervisors.New(hypervisors.StartOptions{
    94  		IpmiPasswordFile: *ipmiPasswordFile,
    95  		IpmiUsername:     *ipmiUsername,
    96  		Logger:           logger,
    97  		Storer:           storer,
    98  	})
    99  	if err != nil {
   100  		logger.Fatalf("Cannot create hypervisors manager: %s\n", err)
   101  	}
   102  	rpcHtmlWriter, err := rpcd.Setup(hyperManager, logger)
   103  	if err != nil {
   104  		logger.Fatalf("Cannot start rpcd: %s\n", err)
   105  	}
   106  	webServer, err := httpd.StartServer(*portNum, logger)
   107  	if err != nil {
   108  		logger.Fatalf("Unable to create http server: %s\n", err)
   109  	}
   110  	webServer.AddHtmlWriter(hyperManager)
   111  	webServer.AddHtmlWriter(rpcHtmlWriter)
   112  	webServer.AddHtmlWriter(logger)
   113  	for topology := range topologyChannel {
   114  		logger.Println("Received new topology")
   115  		webServer.UpdateTopology(topology)
   116  		hyperManager.UpdateTopology(topology)
   117  	}
   118  }