98 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"embed"
 | 
						|
	"net/http"
 | 
						|
	"os/signal"
 | 
						|
	"syscall"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/gin-gonic/gin"
 | 
						|
	"github.com/robfig/cron/v3"
 | 
						|
	log "github.com/sirupsen/logrus"
 | 
						|
)
 | 
						|
 | 
						|
type AdminConfig struct {
 | 
						|
	Addr string `json:"addr"`
 | 
						|
}
 | 
						|
 | 
						|
//go:embed assets
 | 
						|
var assets embed.FS
 | 
						|
 | 
						|
func NewAdmin() *AdminConfig {
 | 
						|
	log.WithFields(log.Fields{}).Debugf("starting")
 | 
						|
	defer log.WithFields(log.Fields{}).Debugf("done")
 | 
						|
 | 
						|
	a := &AdminConfig{
 | 
						|
		Addr: "0.0.0.0:8080",
 | 
						|
	}
 | 
						|
 | 
						|
	return a
 | 
						|
}
 | 
						|
 | 
						|
func (a *AdminConfig) Run() {
 | 
						|
	log.WithFields(log.Fields{}).Debugf("starting")
 | 
						|
	defer log.WithFields(log.Fields{}).Debugf("done")
 | 
						|
 | 
						|
	// Create context that listens for the interrupt signal from the OS.
 | 
						|
	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
 | 
						|
	defer stop()
 | 
						|
 | 
						|
	if !*debug {
 | 
						|
		gin.SetMode(gin.ReleaseMode)
 | 
						|
	}
 | 
						|
 | 
						|
	r := gin.Default()
 | 
						|
 | 
						|
	r.GET("/run", ApiRun)
 | 
						|
	r.GET("/run/:app", ApiRunApp)
 | 
						|
 | 
						|
	r.GET("/snapshot/add/:app/:schedule", ApiSnapshotAdd)
 | 
						|
	r.GET("/snapshot/del/:app/:name", ApiSnapshotDel)
 | 
						|
	r.GET("/snapshot/list/:app", ApiSnapshotList)
 | 
						|
 | 
						|
	r.GET("/schedule/list", ApiScheduleList)
 | 
						|
	r.GET("/schedule/add/:name/:duration", ApiScheduleAdd)
 | 
						|
	r.GET("/schedule/del/:name", ApiScheduleDel)
 | 
						|
 | 
						|
	r.GET("/save", ApiSave)
 | 
						|
 | 
						|
	r.GET("/config", ApiConfig)
 | 
						|
	r.GET("/config/:app", ApiConfigApp)
 | 
						|
 | 
						|
	srv := &http.Server{
 | 
						|
		Addr:    a.Addr,
 | 
						|
		Handler: r,
 | 
						|
	}
 | 
						|
 | 
						|
	go func() {
 | 
						|
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
 | 
						|
			log.WithFields(log.Fields{"call": "http.ListenAndServe", "attr": a.Addr, "error": err}).Errorf("")
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	c := cron.New(cron.WithLocation(time.UTC))
 | 
						|
	if _, err := c.AddFunc("0 * * * *", func() { cfg.Run() }); err != nil {
 | 
						|
		log.WithFields(log.Fields{"call": "cron.AddFunc", "error": err}).Errorf("")
 | 
						|
	}
 | 
						|
	c.Start()
 | 
						|
	log.WithFields(log.Fields{"call": "cron.Start"}).Debugf("cron started")
 | 
						|
 | 
						|
	// Listen for the interrupt signal.
 | 
						|
	<-ctx.Done()
 | 
						|
 | 
						|
	// Restore default behavior on the interrupt signal and notify user of shutdown.
 | 
						|
	stop()
 | 
						|
	log.WithFields(log.Fields{"call": "stop"}).Warnf("shutting down")
 | 
						|
 | 
						|
	// The context is used to inform the server it has 5 seconds to finish
 | 
						|
	// the request it is currently handling
 | 
						|
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 | 
						|
	defer cancel()
 | 
						|
	if err := srv.Shutdown(ctx); err != nil {
 | 
						|
		log.WithFields(log.Fields{"call": "http.Shutdown", "error": err}).Errorf("shutting down")
 | 
						|
	}
 | 
						|
 | 
						|
}
 |