feat(controller): added in update server channel and refactors for more actions
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -184,3 +184,5 @@ go.work.sum
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lstWrapper/Program_working_node_ws.txt
|
||||||
|
lstWrapper/web.config.txt
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ meta {
|
|||||||
seq: 1
|
seq: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
get {
|
||||||
url: http://localhost:8080/build
|
url: http://localhost:8080/check
|
||||||
body: none
|
body: none
|
||||||
auth: inherit
|
auth: inherit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ const main = async () => {
|
|||||||
if (process.env.NODE_ENV?.trim() !== "production") {
|
if (process.env.NODE_ENV?.trim() !== "production") {
|
||||||
app.use(morgan("tiny"));
|
app.use(morgan("tiny"));
|
||||||
basePath = "/lst";
|
basePath = "/lst";
|
||||||
|
|
||||||
|
app.use(
|
||||||
|
basePath + "/test",
|
||||||
|
express.static(join(__dirname, "../../controller"))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// docs and api stuff
|
// docs and api stuff
|
||||||
@@ -78,6 +83,11 @@ const main = async () => {
|
|||||||
express.static(join(__dirname, "../../frontend/dist"))
|
express.static(join(__dirname, "../../frontend/dist"))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
app.use(
|
||||||
|
basePath + "/test",
|
||||||
|
express.static(join(__dirname, "../../frontend/dist"))
|
||||||
|
);
|
||||||
|
|
||||||
// register app
|
// register app
|
||||||
setupRoutes(app, basePath);
|
setupRoutes(app, basePath);
|
||||||
|
|
||||||
|
|||||||
68
controller/internal/route_handler/router.go
Normal file
68
controller/internal/route_handler/router.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdatePayload struct {
|
||||||
|
Action string `json:"action"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setup(basePath string) *gin.Engine {
|
||||||
|
|
||||||
|
r := gin.Default()
|
||||||
|
|
||||||
|
if os.Getenv("NODE") == "production" {
|
||||||
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.GET(basePath+"/check", func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusAccepted, gin.H{"check": "good"})
|
||||||
|
})
|
||||||
|
|
||||||
|
//logger.RegisterLoggerRoutes(r, basePath, db)
|
||||||
|
r.POST(basePath+"/update", func(c *gin.Context) {
|
||||||
|
var payload UpdatePayload
|
||||||
|
if err := c.BindJSON(&payload); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Writer.Header().Set("Content-Type", "text/event-stream")
|
||||||
|
c.Writer.Header().Set("Cache-Control", "no-cache")
|
||||||
|
c.Writer.Header().Set("Connection", "keep-alive")
|
||||||
|
|
||||||
|
flusher, ok := c.Writer.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
c.String(http.StatusInternalServerError, "Streaming not supported")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
steps := []string{"🚀 Starting...", "📂 Copying...", "🔧 Migrating...", "✅ Done!"}
|
||||||
|
for _, step := range steps {
|
||||||
|
fmt.Fprintf(c.Writer, "event: log\ndata: %s\n\n", step)
|
||||||
|
flusher.Flush() // 🔑 actually push chunk
|
||||||
|
time.Sleep(1 * time.Second) // simulate work
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Any(basePath+"/", func(c *gin.Context) { errorApiLoc(c) })
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func errorApiLoc(c *gin.Context) {
|
||||||
|
|
||||||
|
// log.Error("Api endpoint hit that dose not exist", "system", map[string]interface{}{
|
||||||
|
// "endpoint": c.Request.URL.Path,
|
||||||
|
// "client_ip": c.ClientIP(),
|
||||||
|
// "user_agent": c.Request.UserAgent(),
|
||||||
|
// })
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"message": "looks like you have encountered a route that dose not exist"})
|
||||||
|
}
|
||||||
@@ -1,11 +1,24 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
socketio "github.com/googollee/go-socket.io"
|
socketio "github.com/googollee/go-socket.io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type UpdatePayload struct {
|
||||||
|
Action string `json:"action"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
}
|
||||||
|
|
||||||
func registerUpdateChannel(server *socketio.Server) {
|
func registerUpdateChannel(server *socketio.Server) {
|
||||||
|
|
||||||
server.OnEvent("/", "subscribe:update", func(s socketio.Conn) {
|
server.OnEvent("/", "subscribe:update", func(s socketio.Conn) {
|
||||||
@@ -15,21 +28,91 @@ func registerUpdateChannel(server *socketio.Server) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// copy files based on the target passed over
|
// copy files based on the target passed over
|
||||||
server.OnEvent("/", "update", func(s socketio.Conn, target string) {
|
server.OnEvent("/", "update", func(s socketio.Conn, payload UpdatePayload) {
|
||||||
server.BroadcastToRoom("/", "update", "updateLogs",
|
switch strings.ToLower(payload.Action) {
|
||||||
fmt.Sprintf("🚀 Copying latest build to %v", target))
|
case "copy":
|
||||||
copyBuild(server, target)
|
server.BroadcastToRoom("/", "update", "updateLogs",
|
||||||
|
fmt.Sprintf("🚀 Copying latest build to %v", payload.Target))
|
||||||
|
copyLatestBuild(server, payload.Target)
|
||||||
|
|
||||||
|
case "update":
|
||||||
|
updateServer(server, payload.Target)
|
||||||
|
|
||||||
|
default:
|
||||||
|
server.BroadcastToRoom("/", "update", "updateLogs",
|
||||||
|
fmt.Sprintf("❓ Unknown action: %s", payload.Action))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// update the server
|
|
||||||
// server.OnEvent("/", "update", func(s socketio.Conn, target string) {
|
|
||||||
// msg := fmt.Sprintf("🔧 Running updateServer on: %s", target)
|
|
||||||
// server.BroadcastToRoom("/update", "update", "updateLogs", msg)
|
|
||||||
|
|
||||||
// })
|
|
||||||
|
|
||||||
server.OnEvent("/", "unsubscribe:update", func(s socketio.Conn) {
|
server.OnEvent("/", "unsubscribe:update", func(s socketio.Conn) {
|
||||||
s.Leave("update")
|
s.Leave("update")
|
||||||
s.Emit("updateLogs", "👋 Unsubscribed from update logs")
|
s.Emit("updateLogs", "👋 Unsubscribed from update logs")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateServer(server *socketio.Server, target string) {
|
||||||
|
host, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
server.BroadcastToRoom("/", "update", "updateLogs", "Could not retrieve hostname")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(host, "VMS") || strings.Contains(host, "vms") {
|
||||||
|
server.BroadcastToRoom("/", "update", "updateLogs", "Your are about to check for a new build and then update the server.")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if target == "" {
|
||||||
|
server.BroadcastToRoom("/", "update", "updateLogs", "You seem to be on a dev server or not an actual production server, you MUST pass a server over. I.E. USMCD1VMS036")
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
server.BroadcastToRoom("/", "update", "updateLogs", fmt.Sprintf("Running the update on: %v", target))
|
||||||
|
go triggerRemoteUpdate(server, target, UpdatePayload{Action: "update", Target: target})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyLatestBuild(server *socketio.Server, target string) {
|
||||||
|
server.BroadcastToRoom("/", "update", "updateLogs",
|
||||||
|
fmt.Sprintf("🚀 Copying latest build to %v", target))
|
||||||
|
copyBuild(server, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
func triggerRemoteUpdate(server *socketio.Server, remoteURL string, payload UpdatePayload) {
|
||||||
|
|
||||||
|
basePath := "/api/controller"
|
||||||
|
if os.Getenv("NODE_ENV") != "production" {
|
||||||
|
basePath = "/lst/api/controller"
|
||||||
|
}
|
||||||
|
|
||||||
|
// send POST request with JSON, expect SSE / streaming text back
|
||||||
|
body, _ := json.Marshal(payload)
|
||||||
|
|
||||||
|
url := fmt.Sprintf("https://%v.alpla.net%v/update", remoteURL, basePath)
|
||||||
|
//url := fmt.Sprintf("http://localhost:8080%v/update", basePath)
|
||||||
|
fmt.Println(url)
|
||||||
|
resp, err := http.Post(url, "application/json", bytes.NewBuffer(body))
|
||||||
|
if err != nil {
|
||||||
|
log.Println("❌ Cannot connect remote:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
decoder := bufio.NewReader(resp.Body)
|
||||||
|
for {
|
||||||
|
line, err := decoder.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
log.Println("❌ Error reading stream:", err)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Println(line)
|
||||||
|
parsed := strings.TrimSpace(line)
|
||||||
|
if parsed != "" {
|
||||||
|
log.Println("📡 Remote log:", parsed)
|
||||||
|
server.BroadcastToRoom("/", "update", "updateLogs", parsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user