First working? version with persistent state
This commit is contained in:
parent
4eb1f18bf5
commit
8a1cf0456a
18
main.go
18
main.go
|
@ -3,6 +3,9 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"gitlab.hamburg.ccc.de/ccchh/spaceapid/handlers"
|
"gitlab.hamburg.ccc.de/ccchh/spaceapid/handlers"
|
||||||
"gitlab.hamburg.ccc.de/ccchh/spaceapid/util"
|
"gitlab.hamburg.ccc.de/ccchh/spaceapid/util"
|
||||||
|
@ -15,10 +18,23 @@ func main() {
|
||||||
log.Println("Reading initial SpaceAPI response from", config.TemplatePath)
|
log.Println("Reading initial SpaceAPI response from", config.TemplatePath)
|
||||||
spaceApiResponse := util.ParseTemplate(config.TemplatePath)
|
spaceApiResponse := util.ParseTemplate(config.TemplatePath)
|
||||||
|
|
||||||
|
// Merge old state if present
|
||||||
|
util.MergeOldState(&spaceApiResponse)
|
||||||
|
|
||||||
// Register HTTP handlers
|
// Register HTTP handlers
|
||||||
http.HandleFunc("/", handlers.Root(&spaceApiResponse))
|
http.HandleFunc("/", handlers.Root(&spaceApiResponse))
|
||||||
http.HandleFunc("/state/open", handlers.StateOpen(config.BAUsername, config.BAPassword, &spaceApiResponse))
|
http.HandleFunc("/state/open", handlers.StateOpen(config.BAUsername, config.BAPassword, &spaceApiResponse))
|
||||||
|
|
||||||
|
// Start webserver
|
||||||
log.Println("Starting HTTP server...")
|
log.Println("Starting HTTP server...")
|
||||||
log.Fatalln(http.ListenAndServe(":8080", nil))
|
go log.Fatalln(http.ListenAndServe(":8080", nil))
|
||||||
|
|
||||||
|
// Wait for exit signal
|
||||||
|
sc := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
<-sc
|
||||||
|
|
||||||
|
// Save state for next run
|
||||||
|
log.Println("Saving state and shutting down...")
|
||||||
|
util.SaveCurrentState(spaceApiResponse)
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,3 +38,10 @@ type SpaceAPIResponseV14 struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
} `json:"links"`
|
} `json:"links"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PersistentStateV14 struct {
|
||||||
|
State struct {
|
||||||
|
Open bool `json:"open"`
|
||||||
|
LastChange int64 `json:"lastchange"`
|
||||||
|
} `json:"state"`
|
||||||
|
}
|
||||||
|
|
78
util/util.go
78
util/util.go
|
@ -3,13 +3,17 @@ package util
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
"gitlab.hamburg.ccc.de/ccchh/spaceapid/types"
|
"gitlab.hamburg.ccc.de/ccchh/spaceapid/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const savedStateJSONPath = "/var/lib/spaceapid/spaceapid-state.json"
|
||||||
|
|
||||||
// ParseTemplate parses the given file and
|
// ParseTemplate parses the given file and
|
||||||
func ParseTemplate(file string) (resp types.SpaceAPIResponseV14) {
|
func ParseTemplate(file string) (resp types.SpaceAPIResponseV14) {
|
||||||
|
|
||||||
|
@ -34,3 +38,77 @@ func ParseTemplate(file string) (resp types.SpaceAPIResponseV14) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MergeOldState merges a given SpaceAPIResponse with the state saved at the time of last program exit and then deletes
|
||||||
|
// the file containing the old state.
|
||||||
|
func MergeOldState(response *types.SpaceAPIResponseV14) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
oldState []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create state directory if not present
|
||||||
|
err = os.MkdirAll(path.Dir(savedStateJSONPath), 0750)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed creating", savedStateJSONPath, ", aborting... error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if state.json is present
|
||||||
|
_, err = os.Stat(savedStateJSONPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Old state json not accessible at", savedStateJSONPath, ", skipping merge... error:", err)
|
||||||
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
goto removeOld
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read file and merge
|
||||||
|
oldState, err = os.ReadFile(savedStateJSONPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error reading old state from", savedStateJSONPath, ", skipping merge... error:", err)
|
||||||
|
goto removeOld
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(oldState, response)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(savedStateJSONPath, "doesn't seem to contain valid data... error:", err)
|
||||||
|
goto removeOld
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete old state json
|
||||||
|
removeOld:
|
||||||
|
err = os.RemoveAll(savedStateJSONPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to remove", savedStateJSONPath, ", continuing... error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SaveCurrentState(response types.SpaceAPIResponseV14) {
|
||||||
|
file, err := os.OpenFile(savedStateJSONPath, os.O_RDWR|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed opening", savedStateJSONPath, "while trying to save current state... error:", err)
|
||||||
|
}
|
||||||
|
defer func(file *os.File) {
|
||||||
|
_ = file.Close()
|
||||||
|
}(file)
|
||||||
|
|
||||||
|
// Create persistent state
|
||||||
|
persistentStateV14 := types.PersistentStateV14{
|
||||||
|
State: struct {
|
||||||
|
Open bool `json:"open"`
|
||||||
|
LastChange int64 `json:"lastchange"`
|
||||||
|
}{Open: response.State.Open, LastChange: response.State.LastChange},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize persistent state
|
||||||
|
marshal, err := json.MarshalIndent(persistentStateV14, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed serializing persistent state... error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to file
|
||||||
|
_, err = file.Write(marshal)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed writing persistent state to file", file.Name(), "... error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue