152 lines
3.9 KiB
Go
152 lines
3.9 KiB
Go
// TODO: Add EUPL banner everywhere
|
|
package main
|
|
|
|
import (
|
|
"embed"
|
|
"flag"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"path"
|
|
"sync"
|
|
|
|
"git.mstar.dev/mstar/goutils/other"
|
|
"github.com/rs/zerolog/log"
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/gorm"
|
|
|
|
"git.mstar.dev/mstar/linstrom/config"
|
|
"git.mstar.dev/mstar/linstrom/shared"
|
|
storagenew "git.mstar.dev/mstar/linstrom/storage-new"
|
|
"git.mstar.dev/mstar/linstrom/storage-new/dbgen"
|
|
webdebug "git.mstar.dev/mstar/linstrom/web/debug"
|
|
webpublic "git.mstar.dev/mstar/linstrom/web/public"
|
|
)
|
|
|
|
// TODO: Add frontend overwrite
|
|
// Serve frontend files from a given directory instead of embedded data
|
|
|
|
//go:embed frontend-reactive/dist/* frontend-reactive/dist/assets
|
|
var reactiveFS embed.FS
|
|
|
|
//go:embed frontend-noscript
|
|
var nojsFS embed.FS
|
|
|
|
//go:embed duck.webp
|
|
var defaultDuck string
|
|
|
|
//go:embed duck.webp
|
|
var duckFS embed.FS
|
|
|
|
func main() {
|
|
_ = reactiveFS
|
|
_ = nojsFS
|
|
other.SetupFlags()
|
|
flag.Parse()
|
|
logfile := getLogFilePathOrNil()
|
|
if logfile == nil {
|
|
other.ConfigureLogging(nil)
|
|
log.Warn().Msg("Can't write to target logfile, not creating one")
|
|
} else {
|
|
other.ConfigureLogging(&lumberjack.Logger{
|
|
Filename: *logfile,
|
|
MaxSize: 500, // Megabytes
|
|
MaxBackups: 3,
|
|
MaxAge: 3, // Days
|
|
Compress: false,
|
|
})
|
|
log.Info().Str("logfile", *logfile).Msg("Logging to stderr and logfile")
|
|
}
|
|
if err := config.ReadAndWriteToGlobal(*shared.FlagConfigFile); err != nil {
|
|
log.Fatal().
|
|
Err(err).
|
|
Str("config-file", *shared.FlagConfigFile).
|
|
Msg("Failed to read config and couldn't write default")
|
|
}
|
|
log.Trace().Any("config", config.GlobalConfig).Msg("Full config")
|
|
|
|
// Request to only check config
|
|
if *shared.FlagConfigOnly {
|
|
return
|
|
}
|
|
newServer()
|
|
}
|
|
|
|
func getLogFilePathOrNil() *string {
|
|
logfile := *shared.FlagLogFile
|
|
logPath := path.Dir(logfile)
|
|
if shared.IsWritable(logPath) {
|
|
return &logfile
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func newServer() {
|
|
log.Info().Msg("Connecting to db")
|
|
db, err := gorm.Open(
|
|
postgres.Open(config.GlobalConfig.Storage.BuildPostgresDSN()),
|
|
&gorm.Config{
|
|
Logger: shared.NewGormLogger(log.Logger),
|
|
},
|
|
)
|
|
if err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to start db")
|
|
}
|
|
dbgen.SetDefault(db)
|
|
log.Info().Msg("Applying migrations")
|
|
if err = storagenew.Migrate(db); err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to automigrate structure")
|
|
}
|
|
log.Info().Msg("Inserting self into db")
|
|
if err = storagenew.InsertSelf(); err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to insert self properly")
|
|
}
|
|
log.Info().Msg("Inserting placeholder/unknown user")
|
|
if err = storagenew.InsertUnknownActorPlaceholder(); err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to insert self properly")
|
|
}
|
|
debugShutdownChan := make(chan *sync.WaitGroup, 1)
|
|
interuptChan := make(chan os.Signal, 1)
|
|
signal.Notify(interuptChan, os.Interrupt)
|
|
if *shared.FlagStartDebugServer {
|
|
go func() {
|
|
log.Info().Msg("Starting debug server")
|
|
s := webdebug.New(*shared.FlagDebugPort)
|
|
go func() {
|
|
wg := <-debugShutdownChan
|
|
if err := s.Stop(); err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to cleanly stop debug server")
|
|
}
|
|
log.Info().Msg("Debug server stopped")
|
|
wg.Done()
|
|
}()
|
|
if err = s.Start(); err != nil && err != http.ErrServerClosed {
|
|
log.Fatal().Err(err).Msg("Debug server failed")
|
|
}
|
|
}()
|
|
}
|
|
public := webpublic.New(
|
|
fmt.Sprintf(":%v", config.GlobalConfig.General.PrivatePort),
|
|
&defaultDuck,
|
|
duckFS,
|
|
)
|
|
go func() {
|
|
log.Info().Msg("Starting public server")
|
|
if err = public.Start(); err != nil && err != http.ErrServerClosed {
|
|
log.Fatal().Err(err).Msg("Failed to start public server")
|
|
}
|
|
}()
|
|
<-interuptChan
|
|
log.Info().Msg("Received interrupt, shutting down")
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(1)
|
|
debugShutdownChan <- &wg
|
|
if err = public.Stop(); err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to stop public server")
|
|
}
|
|
log.Info().Msg("Public server stopped")
|
|
wg.Wait()
|
|
}
|