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 }