github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/imaginator/main.go (about)

     1  // +build linux
     2  
     3  package main
     4  
     5  import (
     6  	"flag"
     7  	"fmt"
     8  	"os"
     9  	"syscall"
    10  	"time"
    11  
    12  	"github.com/Cloud-Foundations/Dominator/imagebuilder/builder"
    13  	"github.com/Cloud-Foundations/Dominator/imagebuilder/httpd"
    14  	"github.com/Cloud-Foundations/Dominator/imagebuilder/rpcd"
    15  	"github.com/Cloud-Foundations/Dominator/lib/constants"
    16  	"github.com/Cloud-Foundations/Dominator/lib/flags/loadflags"
    17  	"github.com/Cloud-Foundations/Dominator/lib/log/serverlogger"
    18  	"github.com/Cloud-Foundations/Dominator/lib/srpc/setupserver"
    19  	"github.com/Cloud-Foundations/tricorder/go/tricorder"
    20  )
    21  
    22  const (
    23  	dirPerms = syscall.S_IRWXU | syscall.S_IRGRP | syscall.S_IXGRP |
    24  		syscall.S_IROTH | syscall.S_IXOTH
    25  )
    26  
    27  var (
    28  	configurationUrl = flag.String("configurationUrl",
    29  		"file:///etc/imaginator/conf.json", "URL containing configuration")
    30  	imageServerHostname = flag.String("imageServerHostname", "localhost",
    31  		"Hostname of image server")
    32  	imageServerPortNum = flag.Uint("imageServerPortNum",
    33  		constants.ImageServerPortNumber,
    34  		"Port number of image server")
    35  	imageRebuildInterval = flag.Duration("imageRebuildInterval", time.Hour,
    36  		"time between automatic rebuilds of images")
    37  	portNum = flag.Uint("portNum", constants.ImaginatorPortNumber,
    38  		"Port number to allocate and listen on for HTTP/RPC")
    39  	slaveDriverConfigurationFile = flag.String("slaveDriverConfigurationFile",
    40  		"", "Name of configuration file for slave builders")
    41  	stateDir = flag.String("stateDir", "/var/lib/imaginator",
    42  		"Name of state directory")
    43  	variablesFile = flag.String("variablesFile", "",
    44  		"A JSON encoded file containing special variables (i.e. secrets)")
    45  )
    46  
    47  func main() {
    48  	if err := loadflags.LoadForDaemon("imaginator"); err != nil {
    49  		fmt.Fprintln(os.Stderr, err)
    50  		os.Exit(1)
    51  	}
    52  	flag.Parse()
    53  	tricorder.RegisterFlags()
    54  	if os.Geteuid() != 0 {
    55  		fmt.Fprintln(os.Stderr, "Must run the Image Builder as root")
    56  		os.Exit(1)
    57  	}
    58  	logger := serverlogger.New("")
    59  	if umask := syscall.Umask(022); umask != 022 {
    60  		// Since we can't cleanly fix umask for all threads, fail instead.
    61  		logger.Fatalf("Umask must be 022, not 0%o\n", umask)
    62  	}
    63  	if err := setupserver.SetupTls(); err != nil {
    64  		logger.Fatalln(err)
    65  	}
    66  	if err := os.MkdirAll(*stateDir, dirPerms); err != nil {
    67  		logger.Fatalf("Cannot create state directory: %s\n", err)
    68  	}
    69  	slaveDriver, err := createSlaveDriver(logger)
    70  	if err != nil {
    71  		logger.Fatalf("Error starting slave driver: %s\n", err)
    72  	}
    73  	builderObj, err := builder.Load(*configurationUrl, *variablesFile,
    74  		*stateDir,
    75  		fmt.Sprintf("%s:%d", *imageServerHostname, *imageServerPortNum),
    76  		*imageRebuildInterval, slaveDriver, logger)
    77  	if err != nil {
    78  		logger.Fatalf("Cannot start builder: %s\n", err)
    79  	}
    80  	rpcHtmlWriter, err := rpcd.Setup(builderObj, logger)
    81  	if err != nil {
    82  		logger.Fatalf("Cannot start builder: %s\n", err)
    83  	}
    84  	httpd.AddHtmlWriter(builderObj)
    85  	if slaveDriver != nil {
    86  		httpd.AddHtmlWriter(slaveDriver)
    87  	}
    88  	httpd.AddHtmlWriter(rpcHtmlWriter)
    89  	httpd.AddHtmlWriter(logger)
    90  	if err = httpd.StartServer(*portNum, builderObj, false); err != nil {
    91  		logger.Fatalf("Unable to create http server: %s\n", err)
    92  	}
    93  }