2023-07-15 22:32:46 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-04-14 20:00:34 +01:00
|
|
|
"fmt"
|
2023-07-21 12:12:16 +01:00
|
|
|
"os"
|
|
|
|
"os/signal"
|
2024-04-28 10:25:41 +01:00
|
|
|
"os/user"
|
2023-07-21 12:12:16 +01:00
|
|
|
"syscall"
|
2024-03-25 14:03:19 +00:00
|
|
|
"time"
|
2024-03-27 23:08:40 +00:00
|
|
|
_ "time/tzdata"
|
2023-07-21 12:12:16 +01:00
|
|
|
|
2024-03-26 11:44:19 +00:00
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/background"
|
2024-04-08 21:08:07 +01:00
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/cif"
|
2024-04-08 21:22:56 +01:00
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/corpus"
|
2024-03-25 11:26:07 +00:00
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/dbAccess"
|
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/helpers"
|
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/log"
|
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/messaging"
|
2024-10-24 20:39:49 +01:00
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/pis"
|
2024-06-30 09:45:16 +01:00
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/stations"
|
2024-03-25 11:26:07 +00:00
|
|
|
"git.fjla.uk/owlboard/timetable-mgr/vstp"
|
2024-04-14 19:03:13 +01:00
|
|
|
"go.uber.org/zap"
|
2023-07-15 22:32:46 +01:00
|
|
|
)
|
|
|
|
|
2024-04-16 19:20:19 +01:00
|
|
|
const (
|
|
|
|
bold = "\033[1m"
|
|
|
|
redB = "\033[1;31m"
|
|
|
|
blue = "\033[32m" //Actually green!
|
|
|
|
cyan = "\033[36m"
|
|
|
|
reset = "\033[0m"
|
|
|
|
)
|
|
|
|
|
2024-04-14 20:00:34 +01:00
|
|
|
func init() {
|
|
|
|
printStartupBanner()
|
2024-04-16 19:20:19 +01:00
|
|
|
fmt.Printf("%sVersion %s \n\n%s", bold+blue, helpers.Version, reset)
|
|
|
|
|
2024-04-28 10:25:41 +01:00
|
|
|
// Exits is being run as root
|
|
|
|
// not necessary and not secure
|
|
|
|
checkRunAsRoot()
|
2024-04-14 20:00:34 +01:00
|
|
|
}
|
|
|
|
|
2023-07-15 22:32:46 +01:00
|
|
|
func main() {
|
2024-04-14 20:00:34 +01:00
|
|
|
log.InitLogger()
|
|
|
|
defer log.Cleanup()
|
2024-04-14 19:03:13 +01:00
|
|
|
log.Info("Initialising OwlBoard timetable-mgr", zap.String("version", helpers.Version))
|
2024-03-25 00:42:36 +00:00
|
|
|
cfg, err := helpers.LoadConfig()
|
|
|
|
if err != nil {
|
2024-04-14 19:03:13 +01:00
|
|
|
log.Fatal("Unable to load configuration", zap.Error(err))
|
2024-03-25 00:42:36 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
cfg.PrintConfig()
|
|
|
|
|
2024-03-25 12:21:59 +00:00
|
|
|
dbAccess.InitDataAccess(cfg)
|
|
|
|
dbAccess.PushVersionToDb()
|
|
|
|
|
2024-03-25 14:03:19 +00:00
|
|
|
// Initialise a `stop` channel to signal goroutines to cleanup
|
|
|
|
stop := make(chan struct{})
|
|
|
|
|
2024-03-25 12:21:59 +00:00
|
|
|
// Start CIF Task Ticker
|
2024-03-26 11:44:19 +00:00
|
|
|
background.InitTicker(cfg, stop)
|
2024-03-25 12:21:59 +00:00
|
|
|
|
2024-04-08 21:22:56 +01:00
|
|
|
// Handle signals from the OS
|
|
|
|
go handleSignals(cfg, stop)
|
|
|
|
|
|
|
|
// Manually call CIF and CORPUS checks to ensure that they are
|
|
|
|
// not delayed until the first ticker event.
|
2024-04-08 21:08:07 +01:00
|
|
|
go cif.CheckCif(cfg)
|
2024-04-08 21:22:56 +01:00
|
|
|
go corpus.CheckCorpus(cfg)
|
2024-06-30 19:29:41 +01:00
|
|
|
go stations.Check()
|
2024-10-24 20:39:49 +01:00
|
|
|
go pis.Check()
|
2024-06-30 09:45:16 +01:00
|
|
|
|
2024-03-25 11:26:07 +00:00
|
|
|
if cfg.VstpOn {
|
|
|
|
messaging.StompInit(cfg)
|
|
|
|
vstp.Subscribe()
|
|
|
|
}
|
2024-03-25 12:21:59 +00:00
|
|
|
|
2024-03-25 14:03:19 +00:00
|
|
|
<-stop
|
2023-07-18 14:09:28 +01:00
|
|
|
}
|
2023-07-21 10:02:55 +01:00
|
|
|
|
2023-07-21 12:12:16 +01:00
|
|
|
// Traps SIGINT and SIGTERM signals and ensures cleanup() is run
|
2024-03-25 14:03:19 +00:00
|
|
|
func handleSignals(cfg *helpers.Configuration, stop chan<- struct{}) {
|
2023-07-21 12:12:16 +01:00
|
|
|
sigChan := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
|
|
|
|
sig := <-sigChan
|
2024-04-14 19:03:13 +01:00
|
|
|
log.Warn("Signal received: " + sig.String())
|
2024-03-25 14:03:19 +00:00
|
|
|
cleanup(cfg, stop)
|
2023-07-21 12:12:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Cleans up open connections ready for a clean exit of the program
|
2024-03-25 14:03:19 +00:00
|
|
|
func cleanup(cfg *helpers.Configuration, stop chan<- struct{}) {
|
2024-04-14 19:03:13 +01:00
|
|
|
log.Debug("Cleaning up open connections")
|
2024-03-25 11:26:07 +00:00
|
|
|
if cfg.VstpOn {
|
2024-04-15 20:36:33 +01:00
|
|
|
log.Info("Closing STOMP Client")
|
|
|
|
messaging.Disconnect(messaging.Client)
|
|
|
|
|
2023-07-21 12:12:16 +01:00
|
|
|
}
|
|
|
|
if dbAccess.MongoClient != nil {
|
2024-04-14 19:03:13 +01:00
|
|
|
log.Info("Closing MongoDB Client")
|
2023-07-21 12:12:16 +01:00
|
|
|
dbAccess.CloseMongoClient()
|
|
|
|
}
|
2024-04-14 19:03:13 +01:00
|
|
|
log.Info("Signalling to other goroutines")
|
2024-03-25 14:03:19 +00:00
|
|
|
close(stop)
|
|
|
|
|
2024-04-14 19:03:13 +01:00
|
|
|
log.Info("Program ready to exit")
|
2024-03-25 14:03:19 +00:00
|
|
|
|
|
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
|
2024-04-14 20:00:34 +01:00
|
|
|
log.Cleanup()
|
|
|
|
|
2024-03-25 14:03:19 +00:00
|
|
|
os.Exit(0)
|
2023-07-21 10:02:55 +01:00
|
|
|
}
|
2024-04-14 20:00:34 +01:00
|
|
|
|
|
|
|
func printStartupBanner() {
|
|
|
|
art := `
|
|
|
|
___ _ ____ _
|
|
|
|
/ _ \__ _| | __ ) ___ __ _ _ __ __| |
|
|
|
|
| | | \ \ /\ / / | _ \ / _ \ / _' | '__/ _' |
|
|
|
|
| |_| |\ V V /| | |_) | (_) | (_| | | | (_| |
|
|
|
|
\___/ \_/\_/ |_|____/ \___/ \__,_|_| \__,_|
|
|
|
|
|
|
|
|
_ _ _ _ _
|
|
|
|
| |_(_)_ __ ___ ___| |_ __ _| |__ | | ___ _ __ ___ __ _ _ __
|
|
|
|
| __| | '_ ' _ \ / _ \ __/ _' | '_ \| |/ _ \_____| '_ ' _ \ / _' | '__|
|
|
|
|
| |_| | | | | | | __/ || (_| | |_) | | __/_____| | | | | | (_| | |
|
|
|
|
\__|_|_| |_| |_|\___|\__\__,_|_.__/|_|\___| |_| |_| |_|\__, |_|
|
|
|
|
|___/
|
|
|
|
`
|
|
|
|
|
2024-04-16 19:20:19 +01:00
|
|
|
fmt.Println(cyan + art + reset)
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkRunAsRoot() {
|
|
|
|
uid := os.Getuid()
|
|
|
|
if uid != 0 {
|
2024-04-28 10:25:41 +01:00
|
|
|
currUser, err := user.Current()
|
|
|
|
var msg string
|
|
|
|
if err != nil {
|
2024-04-28 10:33:58 +01:00
|
|
|
msg = "Unable to determine which user is running the application."
|
2024-04-28 10:25:41 +01:00
|
|
|
} else {
|
|
|
|
msg = fmt.Sprintf("Running as user: %s, %s", currUser.Uid, currUser.Username)
|
|
|
|
}
|
2024-04-28 10:33:58 +01:00
|
|
|
fmt.Println(blue + msg + "\nRunning as non-root user" + reset)
|
2024-04-16 19:20:19 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(redB + "This program must not be run as the root user" + reset)
|
|
|
|
fmt.Println("")
|
|
|
|
os.Exit(1)
|
2024-04-14 20:00:34 +01:00
|
|
|
}
|