131 lines
2.6 KiB
Go
131 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"net"
|
|
"os"
|
|
"os/signal"
|
|
"sync"
|
|
"syscall"
|
|
|
|
"github.com/coreos/go-systemd/daemon"
|
|
"github.com/kardianos/service"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Flags for the server command.
|
|
type ServerCmd struct {
|
|
}
|
|
|
|
// The main App structure.
|
|
type App struct {
|
|
Net struct {
|
|
Listeners []*Listener
|
|
sync.Mutex
|
|
}
|
|
ControllerMac net.HardwareAddr
|
|
grpcServer *GRPCServer
|
|
Stop chan struct{}
|
|
UpdateConfig *UpdateConfig
|
|
}
|
|
|
|
var app *App
|
|
|
|
// Run the server.
|
|
func (a *ServerCmd) Run() error {
|
|
// Start a new app structure.
|
|
app = new(App)
|
|
app.ControllerMac = net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
|
app.Stop = make(chan struct{})
|
|
{
|
|
// Read the configuration from file.
|
|
config := ReadConfig()
|
|
app.UpdateConfig = config.Update
|
|
|
|
// Start the GRPC server for cli communication.
|
|
_, err := NewGRPCServer(config.RPCPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Apply the configuration read.
|
|
err = ApplyConfig(config)
|
|
// If error applying the config, we should fail.
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Send notification that the service is ready.
|
|
daemon.SdNotify(false, daemon.SdNotifyReady)
|
|
|
|
// Setup service.
|
|
if !service.Interactive() {
|
|
s := new(ServiceCmd)
|
|
svc, err := s.service()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
go svc.Run()
|
|
}
|
|
|
|
// Run the update loop to check for updates.
|
|
go app.RunUpdateLoop()
|
|
|
|
// Inform that the service has started.
|
|
log.Println("Service started.")
|
|
|
|
// Monitor common signals.
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
|
|
|
// Run program signal handler.
|
|
for {
|
|
// If this service is stopped by signal, this flag will be changed.
|
|
done := false
|
|
|
|
// Check for a signal.
|
|
select {
|
|
case sig := <-c:
|
|
switch sig {
|
|
// If hangup signal receivied, reload the configurations.
|
|
case syscall.SIGHUP:
|
|
log.Println("Reloading configurations.")
|
|
|
|
// Read the config.
|
|
config := ReadConfig()
|
|
app.UpdateConfig = config.Update
|
|
|
|
// Apply any changes.
|
|
err := ApplyConfig(config)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
|
|
// The default signal is either termination or interruption,
|
|
// so we should stop the loop.
|
|
default:
|
|
done = true
|
|
}
|
|
// If the app stops itself, mark as done.
|
|
case <-app.Stop:
|
|
done = true
|
|
}
|
|
if done {
|
|
close(app.Stop)
|
|
break
|
|
}
|
|
}
|
|
|
|
// We're quitting, close out all listeners.
|
|
for len(app.Net.Listeners) >= 1 {
|
|
app.Net.Listeners[0].Close()
|
|
}
|
|
|
|
// Stop the grpc server.
|
|
if app.grpcServer != nil {
|
|
app.grpcServer.Close()
|
|
}
|
|
|
|
return nil
|
|
}
|