add custom snapshot

This commit is contained in:
shoopea 2025-10-19 21:40:30 +02:00
parent 73f9551c8f
commit 05054be795
5 changed files with 140 additions and 39 deletions

View File

@ -48,6 +48,14 @@ func (a *AdminConfig) Run() {
r.GET("/run", ApiRun) r.GET("/run", ApiRun)
r.GET("/run/:app", ApiRunApp) 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("/save", ApiSave)
r.GET("/config", ApiConfig) r.GET("/config", ApiConfig)

66
api.go
View File

@ -2,6 +2,7 @@ package main
import ( import (
"net/http" "net/http"
"time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -13,9 +14,72 @@ func ApiRun(c *gin.Context) {
}) })
} }
func ApiSnapshotAdd(c *gin.Context) {
if app, ok := cfg.apps[c.Param("app")]; ok {
schedule := c.Param("schedule")
if _, ok := app.schedule[schedule]; ok {
if err := app.RunStandaloneSchedule(schedule); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": err,
})
} else {
c.JSON(http.StatusOK, gin.H{
"message": "done",
})
}
} else {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": "no schedule found",
})
}
} else {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": "no app found",
})
}
}
func ApiSnapshotDel(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": "not implemented",
})
}
func ApiSnapshotList(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": "not implemented",
})
}
func ApiScheduleAdd(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": "not implemented",
})
}
func ApiScheduleDel(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": "not implemented",
})
}
func ApiScheduleList(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "error",
"error": "not implemented",
})
}
func ApiRunApp(c *gin.Context) { func ApiRunApp(c *gin.Context) {
if app, ok := cfg.apps[c.Param("app")]; ok { if app, ok := cfg.apps[c.Param("app")]; ok {
if err := app.RunFull(); err != nil { if err := app.RunStandaloneTime(time.Now()); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{ c.JSON(http.StatusInternalServerError, gin.H{
"message": "error", "message": "error",
"error": err, "error": err,

95
app.go
View File

@ -260,6 +260,11 @@ func (a *App) RunSchedule(schedule string, now time.Time) error {
log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now}).Debugf("starting") log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now}).Debugf("starting")
defer log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now}).Debugf("done") defer log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now}).Debugf("done")
if err := a.SanityCheck(); err != nil {
log.WithFields(log.Fields{"app": a.name, "now": now, "call": "SanityCheck", "error": err}).Errorf("")
return err
}
snapshotName := SnapshotName(schedule, now) snapshotName := SnapshotName(schedule, now)
log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now, "snapshot": snapshotName}).Debugf("snapshot name") log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now, "snapshot": snapshotName}).Debugf("snapshot name")
@ -279,19 +284,31 @@ func (a *App) RunSchedule(schedule string, now time.Time) error {
log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now, "call": "RunAfter", "attr": schedule, "error": err}).Errorf("") log.WithFields(log.Fields{"app": a.name, "schedule": schedule, "now": now, "call": "RunAfter", "attr": schedule, "error": err}).Errorf("")
} }
for _, src := range a.sources {
if err := src.SetManaged(true); err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "src.SetManaged", "error": err}).Errorf("")
return err
}
}
if err := a.Transfer(); err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "Transfer", "error": err}).Errorf("")
return err
}
if err := a.Cleanup(now); err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "Cleanup", "error": err}).Errorf("")
return err
}
return nil return nil
} }
func (a *App) Run(now time.Time) (string, error) { func (a *App) RunTime(now time.Time) (string, error) {
log.WithFields(log.Fields{"app": a.name, "now": now}).Debugf("starting") log.WithFields(log.Fields{"app": a.name, "now": now}).Debugf("starting")
defer log.WithFields(log.Fields{"app": a.name, "now": now}).Debugf("done") defer log.WithFields(log.Fields{"app": a.name, "now": now}).Debugf("done")
if err := a.SanityCheck(); err != nil {
log.WithFields(log.Fields{"app": a.name, "now": now, "call": "SanityCheck", "error": err}).Errorf("")
return "", err
}
schedule, err := a.NextSchedule(now) schedule, err := a.NextSchedule(now)
if err != nil { if err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "NextSchedule", "error": err}).Errorf("") log.WithFields(log.Fields{"app": a.name, "call": "NextSchedule", "error": err}).Errorf("")
@ -299,31 +316,7 @@ func (a *App) Run(now time.Time) (string, error) {
} }
log.WithFields(log.Fields{"app": a.name, "now": now, "schedule": schedule}).Debugf("schedule") log.WithFields(log.Fields{"app": a.name, "now": now, "schedule": schedule}).Debugf("schedule")
if schedule != "" { return schedule, a.RunSchedule(schedule, now)
if err := a.RunSchedule(schedule, now); err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "NextSchedule", "error": err}).Errorf("")
return "", err
}
}
for _, src := range a.sources {
if err := src.SetManaged(true); err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "src.SetManaged", "error": err}).Errorf("")
return "", err
}
}
if err := a.Transfer(); err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "Transfer", "error": err}).Errorf("")
return "", err
}
if err := a.Cleanup(now); err != nil {
log.WithFields(log.Fields{"app": a.name, "call": "Cleanup", "error": err}).Errorf("")
return "", err
}
return schedule, nil
} }
func (a *App) NextSchedule(now time.Time) (string, error) { func (a *App) NextSchedule(now time.Time) (string, error) {
@ -541,7 +534,7 @@ func (a *App) Boxes() []*Box {
return bx return bx
} }
func (a *App) RunFull() error { func (a *App) RunStandaloneTime(now time.Time) error {
log.WithFields(log.Fields{"app": a.name}).Debugf("starting") log.WithFields(log.Fields{"app": a.name}).Debugf("starting")
defer log.WithFields(log.Fields{"app": a.name}).Debugf("done") defer log.WithFields(log.Fields{"app": a.name}).Debugf("done")
@ -574,7 +567,7 @@ func (a *App) RunFull() error {
wg.Wait() wg.Wait()
if sched, err := a.Run(time.Now()); err != nil { if sched, err := a.RunTime(now); err != nil {
log.WithFields(log.Fields{"call": "Run", "error": err}).Errorf("") log.WithFields(log.Fields{"call": "Run", "error": err}).Errorf("")
return err return err
} else { } else {
@ -585,3 +578,39 @@ func (a *App) RunFull() error {
return nil return nil
} }
func (a *App) RunStandaloneSchedule(name string) error {
log.WithFields(log.Fields{"app": a.name, "name": name}).Debugf("starting")
defer log.WithFields(log.Fields{"app": a.name, "name": name}).Debugf("done")
if cfgRun {
return fmt.Errorf("backup already running")
}
CfgLock()
defer CfgUnlock()
cfgRun = true
defer func() { cfgRun = false }()
boxes := a.Boxes()
var wg sync.WaitGroup
// Open boxes
for _, b := range boxes {
wg.Add(1)
go func(box *Box) {
defer wg.Done()
if err := box.Open(); err != nil {
log.WithFields(log.Fields{"name": box.name, "call": "Open", "error": err}).Errorf("")
return
}
}(b)
defer b.Close()
}
wg.Wait()
return a.RunSchedule(name, time.Now())
}

View File

@ -298,7 +298,7 @@ func (c *Config) Run() {
for _, a := range cfg.apps { for _, a := range cfg.apps {
wg.Add(1) wg.Add(1)
go func(app *App) { go func(app *App) {
if sched, err := app.Run(e.startTime); err != nil { if sched, err := app.RunTime(e.startTime); err != nil {
e.AddItem(fmt.Sprintf(" - App : Error running %s (%s)", app.name, err)) e.AddItem(fmt.Sprintf(" - App : Error running %s (%s)", app.name, err))
} else if *debug { } else if *debug {
if sched != "" { if sched != "" {

View File

@ -1,7 +1,7 @@
// Code generated by version.sh (@generated) DO NOT EDIT. // Code generated by version.sh (@generated) DO NOT EDIT.
package main package main
var githash = "ace13b6" var githash = "73f9551"
var branch = "master" var branch = "master"
var buildstamp = "2025-10-19_12:12:16" var buildstamp = "2025-10-19_19:40:05"
var commits = "114" var commits = "115"
var version = "ace13b6-b114 - 2025-10-19_12:12:16" var version = "73f9551-b115 - 2025-10-19_19:40:05"