computer-host/main.go

112 lines
2.3 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"os"
"os/signal"
"path/filepath"
"syscall"
"golang.org/x/sync/errgroup"
appconfig "github.com/getcompanion-ai/computer-host/internal/config"
"github.com/getcompanion-ai/computer-host/internal/daemon"
"github.com/getcompanion-ai/computer-host/internal/firecracker"
"github.com/getcompanion-ai/computer-host/internal/httpapi"
"github.com/getcompanion-ai/computer-host/internal/store"
)
func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
cfg, err := appconfig.Load()
if err != nil {
exit(err)
}
fileStore, err := store.NewFileStore(cfg.StatePath, cfg.OperationsPath)
if err != nil {
exit(err)
}
runtime, err := firecracker.NewRuntime(cfg.FirecrackerRuntimeConfig())
if err != nil {
exit(err)
}
hostDaemon, err := daemon.New(cfg, fileStore, runtime)
if err != nil {
exit(err)
}
if err := hostDaemon.Reconcile(ctx); err != nil {
exit(err)
}
handler, err := httpapi.New(hostDaemon)
if err != nil {
exit(err)
}
if err := os.MkdirAll(filepath.Dir(cfg.SocketPath), 0o755); err != nil {
exit(err)
}
if err := os.Remove(cfg.SocketPath); err != nil && !os.IsNotExist(err) {
exit(err)
}
unixListener, err := net.Listen("unix", cfg.SocketPath)
if err != nil {
exit(err)
}
defer func() {
_ = unixListener.Close()
}()
servers := []*http.Server{{Handler: handler.Routes()}}
listeners := []net.Listener{unixListener}
if cfg.HTTPAddr != "" {
httpListener, err := net.Listen("tcp", cfg.HTTPAddr)
if err != nil {
exit(err)
}
defer func() {
_ = httpListener.Close()
}()
servers = append(servers, &http.Server{Handler: handler.Routes()})
listeners = append(listeners, httpListener)
}
group, groupCtx := errgroup.WithContext(ctx)
for i := range servers {
server := servers[i]
listener := listeners[i]
group.Go(func() error {
err := server.Serve(listener)
if errors.Is(err, http.ErrServerClosed) {
return nil
}
return err
})
}
group.Go(func() error {
<-groupCtx.Done()
for _, server := range servers {
_ = server.Shutdown(context.Background())
}
return nil
})
if err := group.Wait(); err != nil {
exit(err)
}
}
func exit(err error) {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}