Uses v2 configration schema

This commit is contained in:
2024-01-25 00:09:39 +08:00
parent 7ad17d9417
commit b906edc022
37 changed files with 542 additions and 437 deletions

View File

@ -0,0 +1,26 @@
package sideload
import (
"code.smartsheep.studio/goatworks/roadsign/pkg/navi"
"code.smartsheep.studio/goatworks/roadsign/pkg/warden"
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
)
func getApplications(c *fiber.Ctx) error {
applications := lo.FlatMap(navi.R.Regions, func(item *navi.Region, idx int) []warden.Application {
return item.Applications
})
return c.JSON(applications)
}
func getApplicationLogs(c *fiber.Ctx) error {
if instance, ok := lo.Find(warden.InstancePool, func(item *warden.AppInstance) bool {
return item.Manifest.ID == c.Params("id")
}); !ok {
return fiber.NewError(fiber.StatusNotFound)
} else {
return c.SendString(instance.Logs())
}
}

View File

@ -5,7 +5,7 @@ import (
"github.com/gofiber/fiber/v2"
)
func responseConnectivity(c *fiber.Ctx) error {
func getMetadata(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"server": "RoadSign",
"version": roadsign.AppVersion,

View File

@ -1,29 +0,0 @@
package sideload
import (
"code.smartsheep.studio/goatworks/roadsign/pkg/sign"
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
)
func getProcesses(c *fiber.Ctx) error {
processes := lo.FlatMap(sign.App.Sites, func(item *sign.SiteConfig, idx int) []*sign.ProcessInstance {
return item.Processes
})
return c.JSON(processes)
}
func getProcessLog(c *fiber.Ctx) error {
processes := lo.FlatMap(sign.App.Sites, func(item *sign.SiteConfig, idx int) []*sign.ProcessInstance {
return item.Processes
})
if target, ok := lo.Find(processes, func(item *sign.ProcessInstance) bool {
return item.ID == c.Params("id")
}); !ok {
return fiber.NewError(fiber.StatusNotFound)
} else {
return c.SendString(target.GetLogs())
}
}

View File

@ -1,6 +1,7 @@
package sideload
import (
"code.smartsheep.studio/goatworks/roadsign/pkg/warden"
"context"
"os"
"path/filepath"
@ -14,23 +15,23 @@ import (
func doPublish(c *fiber.Ctx) error {
var workdir string
var site *sign.SiteConfig
var upstream *sign.UpstreamInstance
var process *sign.ProcessInstance
for _, item := range navi.App.Sites {
var destination *navi.Destination
var application *warden.Application
for _, item := range navi.R.Regions {
if item.ID == c.Params("site") {
site = item
for _, stream := range item.Upstreams {
if stream.ID == c.Params("slug") {
upstream = stream
workdir, _ = stream.GetRawURI()
break
for _, location := range item.Locations {
for _, dest := range location.Destinations {
if dest.ID == c.Params("slug") {
destination = &dest
workdir, _ = dest.GetRawUri()
break
}
}
}
for _, proc := range item.Processes {
if proc.ID == c.Params("slug") {
process = proc
workdir = proc.Workdir
for _, app := range item.Applications {
if app.ID == c.Params("slug") {
application = &app
workdir = app.Workdir
break
}
}
@ -38,14 +39,15 @@ func doPublish(c *fiber.Ctx) error {
}
}
if upstream == nil && process == nil {
return fiber.ErrNotFound
} else if upstream != nil && upstream.GetType() != navi.UpstreamTypeFile {
var instance *warden.AppInstance
if application != nil {
if instance = warden.GetFromPool(application.ID); instance != nil {
instance.Stop()
}
} else if destination != nil && destination.GetType() != navi.DestinationStaticFile {
return fiber.ErrUnprocessableEntity
}
for _, process := range site.Processes {
process.StopProcess()
} else {
return fiber.ErrNotFound
}
if c.Query("overwrite", "yes") == "yes" {
@ -81,5 +83,9 @@ func doPublish(c *fiber.Ctx) error {
}
}
if instance != nil {
instance.Wake()
}
return c.SendStatus(fiber.StatusOK)
}

67
pkg/sideload/regions.go Normal file
View File

@ -0,0 +1,67 @@
package sideload
import (
"fmt"
"os"
"path/filepath"
"code.smartsheep.studio/goatworks/roadsign/pkg/navi"
"code.smartsheep.studio/goatworks/roadsign/pkg/warden"
"github.com/gofiber/fiber/v2"
"github.com/pelletier/go-toml/v2"
"github.com/samber/lo"
"github.com/spf13/viper"
)
func getRegions(c *fiber.Ctx) error {
return c.JSON(navi.R.Regions)
}
func getRegionConfig(c *fiber.Ctx) error {
fp := filepath.Join(viper.GetString("paths.configs"), c.Params("id"))
var err error
var data []byte
if data, err = os.ReadFile(fp + ".toml"); err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
}
return c.Type("toml").SendString(string(data))
}
func doSync(c *fiber.Ctx) error {
req := string(c.Body())
id := c.Params("slug")
path := filepath.Join(viper.GetString("paths.configs"), fmt.Sprintf("%s.toml", id))
if file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755); err != nil {
return fiber.NewError(fiber.ErrInternalServerError.Code, err.Error())
} else {
raw, _ := toml.Marshal(req)
file.Write(raw)
defer file.Close()
}
var rebootQueue []*warden.AppInstance
if region, ok := lo.Find(navi.R.Regions, func(item *navi.Region) bool {
return item.ID == id
}); ok {
for _, application := range region.Applications {
if instance := warden.GetFromPool(application.ID); instance != nil {
instance.Stop()
rebootQueue = append(rebootQueue, instance)
}
}
}
// Reload
navi.ReadInConfig(viper.GetString("paths.configs"))
// Reboot
for _, instance := range rebootQueue {
instance.Wake()
}
return c.SendStatus(fiber.StatusOK)
}

View File

@ -1,11 +1,12 @@
package sideload
import (
"code.smartsheep.studio/goatworks/roadsign/pkg/sideload/view"
"fmt"
"net/http"
"code.smartsheep.studio/goatworks/roadsign/pkg/sideload/view"
"github.com/gofiber/fiber/v2/middleware/filesystem"
jsoniter "github.com/json-iterator/go"
"net/http"
roadsign "code.smartsheep.studio/goatworks/roadsign/pkg"
"github.com/gofiber/fiber/v2"
@ -51,18 +52,18 @@ func InitSideload() *fiber.App {
cgi := app.Group("/cgi").Name("CGI")
{
cgi.All("/connectivity", responseConnectivity)
cgi.Get("/metadata", getMetadata)
cgi.Get("/statistics", getStatistics)
cgi.Get("/sites", getSites)
cgi.Get("/sites/cfg/:id", getSiteConfig)
cgi.Get("/processes", getProcesses)
cgi.Get("/processes/logs/:id", getProcessLog)
cgi.Get("/sites", getRegions)
cgi.Get("/sites/cfg/:id", getRegionConfig)
cgi.Get("/processes", getApplications)
cgi.Get("/processes/logs/:id", getApplicationLogs)
}
webhooks := app.Group("/webhooks").Name("WebHooks")
{
webhooks.Put("/publish/:site/:slug", doPublish)
webhooks.Put("/sync/:slug", doSyncSite)
webhooks.Put("/sync/:slug", doSync)
}
return app

View File

@ -1,64 +0,0 @@
package sideload
import (
"fmt"
"os"
"path/filepath"
"code.smartsheep.studio/goatworks/roadsign/pkg/navi"
"code.smartsheep.studio/goatworks/roadsign/pkg/sign"
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)
func getSites(c *fiber.Ctx) error {
return c.JSON(sign.App.Sites)
}
func getSiteConfig(c *fiber.Ctx) error {
fp := filepath.Join(viper.GetString("paths.configs"), c.Params("id"))
var err error
var data []byte
if data, err = os.ReadFile(fp + ".yml"); err != nil {
if data, err = os.ReadFile(fp + ".yaml"); err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
}
}
return c.Type("yaml").SendString(string(data))
}
func doSyncSite(c *fiber.Ctx) error {
var req navi.SiteConfig
if err := c.BodyParser(&req); err != nil {
return err
}
id := c.Params("slug")
path := filepath.Join(viper.GetString("paths.configs"), fmt.Sprintf("%s.yaml", id))
if file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755); err != nil {
return fiber.NewError(fiber.ErrInternalServerError.Code, err.Error())
} else {
raw, _ := yaml.Marshal(req)
file.Write(raw)
defer file.Close()
}
if site, ok := lo.Find(sign.App.Sites, func(item *sign.SiteConfig) bool {
return item.ID == id
}); ok {
for _, process := range site.Processes {
process.StopProcess()
}
}
// Reload
sign.ReadInConfig(viper.GetString("paths.configs"))
sign.App.PreheatProcesses()
return c.SendStatus(fiber.StatusOK)
}

View File

@ -1,27 +1,27 @@
package sideload
import (
"code.smartsheep.studio/goatworks/roadsign/pkg/navi"
"code.smartsheep.studio/goatworks/roadsign/pkg/warden"
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
)
func getStatistics(c *fiber.Ctx) error {
upstreams := lo.FlatMap(sign.App.Sites, func(item *sign.SiteConfig, idx int) []*sign.UpstreamInstance {
return item.Upstreams
locations := lo.FlatMap(navi.R.Regions, func(item *navi.Region, idx int) []navi.Location {
return item.Locations
})
processes := lo.FlatMap(sign.App.Sites, func(item *sign.SiteConfig, idx int) []*sign.ProcessInstance {
return item.Processes
destinations := lo.FlatMap(locations, func(item navi.Location, idx int) []navi.Destination {
return item.Destinations
})
unhealthy := lo.FlatMap(sign.App.Sites, func(item *sign.SiteConfig, idx int) []*sign.ProcessInstance {
return lo.Filter(item.Processes, func(item *sign.ProcessInstance, idx int) bool {
return item.Status != navi.ProcessStarted
})
applications := lo.FlatMap(navi.R.Regions, func(item *navi.Region, idx int) []warden.Application {
return item.Applications
})
return c.JSON(fiber.Map{
"sites": len(sign.App.Sites),
"upstreams": len(upstreams),
"processes": len(processes),
"status": len(unhealthy) == 0,
"regions": len(navi.R.Regions),
"locations": len(locations),
"destinations": len(destinations),
"applications": len(applications),
})
}