package main import ( "log" "net" "os" "github.com/joho/godotenv" "penguins.lan/api" "penguins.lan/args" "penguins.lan/database" "penguins.lan/dnsd" "penguins.lan/scheduled" ) func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) if err := godotenv.Load(); err != nil { log.Println("no .env file loaded:", err) } argv, err := args.GetArgs() if err != nil { log.Fatal(err) } dbConn := database.MakeConn(&argv.DatabasePath) defer dbConn.Close() if argv.Migrate { if _, err := database.Migrate(dbConn); err != nil { log.Fatal(err) } log.Println("database migrated successfully") } if argv.Scheduler { scheduled.StartScheduler(argv, dbConn) log.Println("scheduler started") } if argv.Server { server := api.MakeServer(argv, dbConn) if argv.Socket != "" { listener := unixListener(argv.Socket) log.Printf("listening on unix socket %s", argv.Socket) go func() { if err := server.Serve(listener); err != nil { log.Fatal(err) } }() } else { log.Printf("listening on :%d", argv.Port) go func() { if err := server.ListenAndServe(); err != nil { log.Fatal(err) } }() } } if argv.Dns { dnsServer := dnsd.MakeServer(argv, dbConn) log.Printf("dns listening on :%d for zone %s", argv.DnsPort, argv.DnsZone) go func() { if err := dnsServer.ListenAndServe(); err != nil { log.Fatal(err) } }() } if argv.Scheduler || argv.Server || argv.Dns { select {} } } // unixListener binds an HTTP unix socket, clearing any stale socket left by a // previous run and relaxing perms to 0660 so a same-group reverse proxy can // reach it. func unixListener(path string) net.Listener { if err := os.Remove(path); err != nil && !os.IsNotExist(err) { log.Fatalf("could not clear stale socket %s: %v", path, err) } listener, err := net.Listen("unix", path) if err != nil { log.Fatal(err) } if err := os.Chmod(path, 0o660); err != nil { log.Fatalf("could not chmod socket %s: %v", path, err) } return listener }