summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2023-02-08 20:53:20 +0100
committerxengineering <me@xengineering.eu>2023-02-08 21:01:27 +0100
commitf9a5140071703faf0c7515a05f52e69fdc1f11ba (patch)
treeee073f3c7fc1a6bbda1eee6e3bec076e73363740 /utils
parent9005de11ef8b7cf32cc8503e8b5f134eca47b4fb (diff)
downloadceres-f9a5140071703faf0c7515a05f52e69fdc1f11ba.tar
ceres-f9a5140071703faf0c7515a05f52e69fdc1f11ba.tar.zst
ceres-f9a5140071703faf0c7515a05f52e69fdc1f11ba.zip
Move all sources to package main
This project is not so big that it needs multiple packages.
Diffstat (limited to 'utils')
-rw-r--r--utils/database.go175
-rw-r--r--utils/errors.go84
-rw-r--r--utils/runtime_config.go65
-rw-r--r--utils/storage.go31
-rw-r--r--utils/templates.go32
5 files changed, 0 insertions, 387 deletions
diff --git a/utils/database.go b/utils/database.go
deleted file mode 100644
index f48af35..0000000
--- a/utils/database.go
+++ /dev/null
@@ -1,175 +0,0 @@
-
-package utils
-
-import (
- "log"
- "fmt"
- "path/filepath"
- "io"
- "os"
- "os/signal"
- "os/user"
- "os/exec"
- "strconv"
- "syscall"
- "database/sql"
-
- _ "github.com/go-sql-driver/mysql"
-)
-
-const databaseSchemaVersion int = 2 // this defines the needed version for the
- // executable
-
-type Database struct {
- config DatabaseConfig
- target string
- Backend *sql.DB
-}
-
-func InitDatabase(config DatabaseConfig) Database {
-
- db := NewDatabase(config)
- db.Connect()
- db.Ping()
- db.Migrate(config.Migrations)
-
- // allow graceful shutdown
- var listener = make(chan os.Signal)
- signal.Notify(listener, syscall.SIGTERM)
- signal.Notify(listener, syscall.SIGINT)
- go func() {
- signal := <-listener
- log.Printf("\nGot signal '%+v'. Shutting down ...\n", signal)
- db.Cleanup()
- os.Exit(0) // TODO this does not belong to a database - write utils file 'shutdown.go'
- }()
-
- return db
-}
-
-func NewDatabase(config DatabaseConfig) Database {
-
- db := Database{}
-
- db.config = config
- var username string
- user_ptr,err := user.Current()
- if err != nil {
- log.Fatal(err)
- }
- username = user_ptr.Username
- db.target = fmt.Sprintf("%s@unix(%s)/%s", username, config.Socket, config.Database)
-
- return db
-}
-
-func (db *Database) Connect() {
- var err error
- db.Backend,err = sql.Open("mysql", db.target)
- if err != nil {
- log.Fatal(err)
- }
- log.Printf("Connected to database '%s'\n", db.target)
-}
-
-func (db *Database) Ping() {
- err := db.Backend.Ping()
- if err != nil {
- log.Fatal(err)
- } else {
- log.Println("Database is responding")
- }
-}
-
-func (db *Database) Migrate(dir string) {
-
- const t = databaseSchemaVersion // targeted database schema version
-
- for {
- v := db.SchemaVersion() // read schema version from DB table
-
- // handle current database schema which is newer than targeted one
- if v > t {
- log.Fatalf(
- "Current database schema version is %d but newest is %d!", v, t)
- }
-
- // break if targeted version is already reached
- if v == t {
- break
- }
-
- // execute migration
- log.Printf("Starting database schema migration to version %d.\n", v+1)
- path := filepath.Join(dir, fmt.Sprintf("%04d_migration.sql", v+1))
- RunSql(path)
- log.Printf("Finished database schema migration to version %d.\n", v+1)
- }
-}
-
-func RunSql(path string) {
-
- script, err := os.Open(path)
- if err != nil {
- log.Fatalf("Could not open SQL script '%s'!\n", path)
- }
-
- cmd := exec.Command("mariadb")
- stdin, err := cmd.StdinPipe()
- if err != nil {
- log.Fatalf("Could not open stdin of mariadb process!\n%v", err)
- }
-
- err = cmd.Start()
- if err != nil {
- log.Fatalf("Could not start mariadb process!\n%v", err)
- }
- io.Copy(stdin, script)
- stdin.Close()
-
- err = cmd.Wait()
- if err != nil {
- log.Fatalf("Failed to wait for SQL script to finish!\n%v", err)
- }
-}
-
-func (db *Database) SchemaVersion() int {
-
- // ask database for schema version
- cmd := "SELECT value FROM meta WHERE (identifier='version');"
- rows, err := db.Backend.Query(cmd)
-
- // handle missing meta table
- if err != nil {
- log.Fatal(err)
- }
-
- // handle successful schema version query
- defer rows.Close()
- rows.Next()
- var version string
- err = rows.Scan(&version)
-
- // handle missing version field in meta table
- if err != nil {
- log.Fatal(err)
- }
-
- // convert to integer and handle error
- v, err := strconv.Atoi(version)
- if err != nil {
- log.Fatalf("Could not convert database schema version '%s' to int.\n",
- version)
- }
-
- return v
-}
-
-func (db *Database) Cleanup() {
- err := db.Backend.Close()
- if err != nil {
- log.Println("Could not close database connection")
- } else {
- log.Println("Closed database connection")
- }
-}
diff --git a/utils/errors.go b/utils/errors.go
deleted file mode 100644
index 757d2a1..0000000
--- a/utils/errors.go
+++ /dev/null
@@ -1,84 +0,0 @@
-
-package utils
-
-import (
- "fmt"
- "log"
- "net/http"
-)
-
-func Err(w http.ResponseWriter, code int, a ...interface{}) {
-
- var msg string // format string for error message
- var hc int // HTTP error code
-
- var prefix string = fmt.Sprintf("Error %d - ", code)
-
- // ATTENTION: the used error codes in this switch statements should be
- // stable. Do not change them, just append to the list!
- switch code {
-
- case 1:
- msg = "Failed to load recipes from database."
- hc = http.StatusInternalServerError
-
- case 2:
- msg = "Could not parse recipe from database request."
- hc = http.StatusInternalServerError
-
- case 3:
- msg = "Exactly 1 'id' URL parameter expected but %d provided."
- hc = http.StatusBadRequest
-
- case 4:
- msg = "'id' URL parameter '%s' doas not match the regex '%s'."
- hc = http.StatusBadRequest
-
- case 5:
- msg = "Received error from database: '%s'."
- hc = http.StatusInternalServerError
-
- case 6:
- msg = "Expected exactly 1 recipe from database but got %d."
- hc = http.StatusInternalServerError
-
- // deprecated
- case 7:
- msg = "Exactly 1 'type' URL parameter expected but %d provided."
- hc = http.StatusBadRequest
-
- case 8:
- msg = "Form data does not contain recipe URL (key is '%s')."
- hc = http.StatusBadRequest
-
- case 9:
- msg = "Could not add recipe: '%s'."
- hc = http.StatusInternalServerError
-
- case 10:
- msg = "Expected exactly 1 recipe URL in '%s' but got %d (regex is '%s')."
- hc = http.StatusBadRequest
-
- case 11:
- msg = "Could not get recipe ID from database: '%s'."
- hc = http.StatusInternalServerError
-
- // deprecated
- case 12:
- msg = "Given recipe type '%s' is unknown."
- hc = http.StatusBadRequest
-
- default:
- msg = "An unknown error occured."
- hc = http.StatusInternalServerError
-
- }
-
- // format full error message
- final := fmt.Sprintf(prefix + msg, a...)
-
- // send message to log and user
- log.Println(final)
- http.Error(w, final, hc)
-
-}
diff --git a/utils/runtime_config.go b/utils/runtime_config.go
deleted file mode 100644
index fb5bd72..0000000
--- a/utils/runtime_config.go
+++ /dev/null
@@ -1,65 +0,0 @@
-
-package utils
-
-import (
- "fmt"
- "log"
- "flag"
- "os"
- "io/ioutil"
- "encoding/json"
-)
-
-type RuntimeConfig struct {
- Path string
- Http HttpConfig `json:"http"`
- Database DatabaseConfig `json:"database"`
-}
-
-type HttpConfig struct {
- Host string `json:"bind_host"`
- Port string `json:"bind_port"`
- Static string `json:"static"`
- Templates string `json:"templates"`
- Storage string `json:"storage"`
-}
-
-type DatabaseConfig struct {
- Socket string `json:"socket"`
- User string `json:"user"`
- Database string `json:"database"`
- Migrations string `json:"migrations"`
-}
-
-func GetRuntimeConfig() RuntimeConfig {
-
- // init empty return value
- config := RuntimeConfig{}
-
- // read command line flags
- flag.StringVar(&config.Path, "c", "/etc/ceres/config.json", "Path to ceres configuration file")
- flag.Parse()
-
- // open config file
- configFile, err := os.Open(config.Path)
- defer configFile.Close()
- if err != nil {
- log.Fatalf("Could not open configuration file %s", config.Path)
- }
-
- // read byte content
- configData, err := ioutil.ReadAll(configFile)
- if err != nil {
- log.Fatalf("Could not read configuration file %s", config.Path)
- }
-
- fmt.Print("Used config: " + string(configData) + "\n")
-
- // parse content to config structs
- err = json.Unmarshal(configData, &config)
- if err != nil {
- log.Fatalf("Could not parse configuration file %s", config.Path)
- }
-
- return config
-}
diff --git a/utils/storage.go b/utils/storage.go
deleted file mode 100644
index ee5b7bf..0000000
--- a/utils/storage.go
+++ /dev/null
@@ -1,31 +0,0 @@
-
-package utils
-
-import (
- "log"
- "net/http"
- "io/ioutil"
- "path/filepath"
-)
-
-func ServeStorage(w http.ResponseWriter, r *http.Request, storage string, path string) {
-
- // generate absolute, cleaned path of ressource
- path = filepath.Join(storage, path)
- path,err := filepath.Abs(path)
- if err != nil {
- log.Print(err)
- http.Error(w, http.StatusText(400), 400)
- return
- }
-
- // TODO check if path is still in storage folder
-
- // serve the file if nothing has been wrong
- http.ServeFile(w, r, path)
-}
-
-func SaveStorageFile(data *[]byte, storage string, path string) error {
- fullpath := filepath.Join(storage, path)
- return ioutil.WriteFile(fullpath, *data, 0644)
-}
diff --git a/utils/templates.go b/utils/templates.go
deleted file mode 100644
index 00a8eb2..0000000
--- a/utils/templates.go
+++ /dev/null
@@ -1,32 +0,0 @@
-
-package utils
-
-import (
- "log"
- "net/http"
- "io/ioutil"
- "text/template" // FIXME switch to html/template for security reasons
- // and make a workaround for rendered Markdown insertion
-)
-
-func ServeTemplate(w http.ResponseWriter, name string, path string, data interface{}) {
-
- templateFile,err := ioutil.ReadFile(path)
- if err != nil {
- log.Print(err)
- http.Error(w, http.StatusText(404), 404)
- return
- }
- tmpl,err := template.New(name).Parse(string(templateFile))
- if err != nil {
- log.Print(err)
- http.Error(w, http.StatusText(404), 404)
- return
- }
- err = tmpl.Execute(w, data)
- if err != nil {
- log.Print(err)
- http.Error(w, http.StatusText(404), 404)
- return
- }
-}