Blame cmd/osbuild-composer/main.go

Packit Service 4d2de5
package main
Packit Service 4d2de5
Packit Service 4d2de5
import (
Packit Service 4d2de5
	"crypto/tls"
Packit Service 4d2de5
	"crypto/x509"
Packit Service 4d2de5
	"flag"
Packit Service 4d2de5
	"io/ioutil"
Packit Service 4d2de5
	"log"
Packit Service 4d2de5
	"os"
Packit Service 4d2de5
	"path"
Packit Service 4d2de5
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/distro/fedora31"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/distro/fedora32"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/distro/rhel8"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/jobqueue/fsjobqueue"
Packit Service 4d2de5
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/common"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/distro"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/rpmmd"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/store"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/weldr"
Packit Service 4d2de5
	"github.com/osbuild/osbuild-composer/internal/worker"
Packit Service 4d2de5
Packit Service 4d2de5
	"github.com/coreos/go-systemd/activation"
Packit Service 4d2de5
)
Packit Service 4d2de5
Packit Service 4d2de5
type connectionConfig struct {
Packit Service 4d2de5
	CACertFile     string
Packit Service 4d2de5
	ServerKeyFile  string
Packit Service 4d2de5
	ServerCertFile string
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func createTLSConfig(c *connectionConfig) (*tls.Config, error) {
Packit Service 4d2de5
	caCertPEM, err := ioutil.ReadFile(c.CACertFile)
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	roots := x509.NewCertPool()
Packit Service 4d2de5
	ok := roots.AppendCertsFromPEM(caCertPEM)
Packit Service 4d2de5
	if !ok {
Packit Service 4d2de5
		panic("failed to parse root certificate")
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	cert, err := tls.LoadX509KeyPair(c.ServerCertFile, c.ServerKeyFile)
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
	return &tls.Config{
Packit Service 4d2de5
		Certificates: []tls.Certificate{cert},
Packit Service 4d2de5
		ClientAuth:   tls.RequireAndVerifyClientCert,
Packit Service 4d2de5
		ClientCAs:    roots,
Packit Service 4d2de5
	}, nil
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func main() {
Packit Service 4d2de5
	var verbose bool
Packit Service 4d2de5
	flag.BoolVar(&verbose, "v", false, "Print access log")
Packit Service 4d2de5
	flag.Parse()
Packit Service 4d2de5
Packit Service 4d2de5
	stateDir, ok := os.LookupEnv("STATE_DIRECTORY")
Packit Service 4d2de5
	if !ok {
Packit Service 4d2de5
		log.Fatal("STATE_DIRECTORY is not set. Is the service file missing StateDirectory=?")
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	listeners, err := activation.ListenersWithNames()
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		log.Fatalf("Could not get listening sockets: " + err.Error())
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	if _, exists := listeners["osbuild-composer.socket"]; !exists {
Packit Service 4d2de5
		log.Fatalf("osbuild-composer.socket doesn't exist")
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	composerListeners := listeners["osbuild-composer.socket"]
Packit Service 4d2de5
Packit Service 4d2de5
	if len(composerListeners) != 2 && len(composerListeners) != 3 {
Packit Service 4d2de5
		log.Fatalf("Unexpected number of listening sockets (%d), expected 2 or 3", len(composerListeners))
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	weldrListener := composerListeners[0]
Packit Service 4d2de5
	jobListener := composerListeners[1]
Packit Service 4d2de5
Packit Service 4d2de5
	cacheDirectory, ok := os.LookupEnv("CACHE_DIRECTORY")
Packit Service 4d2de5
	if !ok {
Packit Service 4d2de5
		log.Fatal("CACHE_DIRECTORY is not set. Is the service file missing CacheDirectory=?")
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	rpm := rpmmd.NewRPMMD(path.Join(cacheDirectory, "rpmmd"), "/usr/libexec/osbuild-composer/dnf-json")
Packit Service 4d2de5
Packit Service 4d2de5
	distros, err := distro.NewRegistry(fedora31.New(), fedora32.New(), rhel8.New())
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		log.Fatalf("Error loading distros: %v", err)
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	distribution, beta, err := distros.FromHost()
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		log.Fatalf("Could not determine distro from host: " + err.Error())
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	arch, err := distribution.GetArch(common.CurrentArch())
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		log.Fatalf("Host distro does not support host architecture: " + err.Error())
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	// TODO: refactor to be more generic
Packit Service 4d2de5
	name := distribution.Name()
Packit Service 4d2de5
	if beta {
Packit Service 4d2de5
		name += "-beta"
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	repoMap, err := rpmmd.LoadRepositories([]string{"/etc/osbuild-composer", "/usr/share/osbuild-composer"}, name)
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		log.Fatalf("Could not load repositories for %s: %v", distribution.Name(), err)
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	var logger *log.Logger
Packit Service 4d2de5
	if verbose {
Packit Service 4d2de5
		logger = log.New(os.Stdout, "", 0)
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	store := store.New(&stateDir, arch, logger)
Packit Service 4d2de5
Packit Service 4d2de5
	queueDir := path.Join(stateDir, "jobs")
Packit Service 4d2de5
	err = os.Mkdir(queueDir, 0700)
Packit Service 4d2de5
	if err != nil && !os.IsExist(err) {
Packit Service 4d2de5
		log.Fatalf("cannot create queue directory: %v", err)
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	jobs, err := fsjobqueue.New(queueDir, []string{"osbuild"})
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		log.Fatalf("cannot create jobqueue: %v", err)
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	artifactsDir := path.Join(stateDir, "artifacts")
Packit Service 4d2de5
	err = os.Mkdir(artifactsDir, 0755)
Packit Service 4d2de5
	if err != nil && !os.IsExist(err) {
Packit Service 4d2de5
		log.Fatalf("cannot create artifacts directory: %v", err)
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	compatOutputDir := path.Join(stateDir, "outputs")
Packit Service 4d2de5
Packit Service 4d2de5
	workers := worker.NewServer(logger, jobs, artifactsDir)
Packit Service 4d2de5
	weldrAPI := weldr.New(rpm, arch, distribution, repoMap[common.CurrentArch()], logger, store, workers, compatOutputDir)
Packit Service 4d2de5
Packit Service 4d2de5
	go func() {
Packit Service 4d2de5
		err := workers.Serve(jobListener)
Packit Service 4d2de5
		common.PanicOnError(err)
Packit Service 4d2de5
	}()
Packit Service 4d2de5
Packit Service 4d2de5
	if remoteWorkerListeners, exists := listeners["osbuild-remote-worker.socket"]; exists {
Packit Service 4d2de5
		for _, listener := range remoteWorkerListeners {
Packit Service 4d2de5
			log.Printf("Starting remote listener\n")
Packit Service 4d2de5
Packit Service 4d2de5
			tlsConfig, err := createTLSConfig(&connectionConfig{
Packit Service 4d2de5
				CACertFile:     "/etc/osbuild-composer/ca-crt.pem",
Packit Service 4d2de5
				ServerKeyFile:  "/etc/osbuild-composer/composer-key.pem",
Packit Service 4d2de5
				ServerCertFile: "/etc/osbuild-composer/composer-crt.pem",
Packit Service 4d2de5
			})
Packit Service 4d2de5
Packit Service 4d2de5
			if err != nil {
Packit Service 4d2de5
				log.Fatalf("TLS configuration cannot be created: " + err.Error())
Packit Service 4d2de5
			}
Packit Service 4d2de5
Packit Service 4d2de5
			listener := tls.NewListener(listener, tlsConfig)
Packit Service 4d2de5
			go func() {
Packit Service 4d2de5
				err := workers.Serve(listener)
Packit Service 4d2de5
				common.PanicOnError(err)
Packit Service 4d2de5
			}()
Packit Service 4d2de5
		}
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	err = weldrAPI.Serve(weldrListener)
Packit Service 4d2de5
	common.PanicOnError(err)
Packit Service 4d2de5
Packit Service 4d2de5
}