Round Robin DNS fix for deployments (update, rollback etc)

This commit is contained in:
anonpenguin23 2026-01-29 09:53:11 +02:00
parent cd4189f64b
commit 42c0c61d19
6 changed files with 57 additions and 11 deletions

View File

@ -114,7 +114,7 @@ func deployStatic(cmd *cobra.Command, args []string) error {
endpoint := "/v1/deployments/static/upload" endpoint := "/v1/deployments/static/upload"
if deployUpdate { if deployUpdate {
endpoint = "/v1/deployments/static/update" endpoint = "/v1/deployments/static/update?name=" + deployName
} }
resp, err := uploadDeployment(endpoint, tarball, map[string]string{ resp, err := uploadDeployment(endpoint, tarball, map[string]string{
@ -202,7 +202,7 @@ func deployNextJS(cmd *cobra.Command, args []string) error {
endpoint := "/v1/deployments/nextjs/upload" endpoint := "/v1/deployments/nextjs/upload"
if deployUpdate { if deployUpdate {
endpoint = "/v1/deployments/nextjs/update" endpoint = "/v1/deployments/nextjs/update?name=" + deployName
} }
resp, err := uploadDeployment(endpoint, tarball, map[string]string{ resp, err := uploadDeployment(endpoint, tarball, map[string]string{
@ -258,7 +258,7 @@ func deployGo(cmd *cobra.Command, args []string) error {
endpoint := "/v1/deployments/go/upload" endpoint := "/v1/deployments/go/upload"
if deployUpdate { if deployUpdate {
endpoint = "/v1/deployments/go/update" endpoint = "/v1/deployments/go/update?name=" + deployName
} }
resp, err := uploadDeployment(endpoint, tarball, map[string]string{ resp, err := uploadDeployment(endpoint, tarball, map[string]string{
@ -313,7 +313,7 @@ func deployNodeJS(cmd *cobra.Command, args []string) error {
endpoint := "/v1/deployments/nodejs/upload" endpoint := "/v1/deployments/nodejs/upload"
if deployUpdate { if deployUpdate {
endpoint = "/v1/deployments/nodejs/update" endpoint = "/v1/deployments/nodejs/update?name=" + deployName
} }
resp, err := uploadDeployment(endpoint, tarball, map[string]string{ resp, err := uploadDeployment(endpoint, tarball, map[string]string{

View File

@ -276,7 +276,7 @@ func rollbackDeployment(cmd *cobra.Command, args []string) error {
} }
apiURL := getAPIURL() apiURL := getAPIURL()
url := apiURL + "/v1/deployments/rollback" url := apiURL + "/v1/deployments/rollback?name=" + name
payload := map[string]interface{}{ payload := map[string]interface{}{
"name": name, "name": name,

View File

@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"os"
"time" "time"
"github.com/DeBrosOfficial/network/pkg/deployments" "github.com/DeBrosOfficial/network/pkg/deployments"
@ -236,6 +237,9 @@ func (h *RollbackHandler) rollbackDynamic(ctx context.Context, current *deployme
stagingPath := deployPath + ".rollback" stagingPath := deployPath + ".rollback"
// Extract historical version // Extract historical version
if err := os.MkdirAll(stagingPath, 0755); err != nil {
return nil, fmt.Errorf("failed to create staging directory: %w", err)
}
if err := h.updateHandler.nextjsHandler.extractFromIPFS(ctx, cid, stagingPath); err != nil { if err := h.updateHandler.nextjsHandler.extractFromIPFS(ctx, cid, stagingPath); err != nil {
return nil, fmt.Errorf("failed to extract historical version: %w", err) return nil, fmt.Errorf("failed to extract historical version: %w", err)
} }

View File

@ -196,6 +196,9 @@ func (h *UpdateHandler) updateDynamic(ctx context.Context, existing *deployments
// Extract to staging directory // Extract to staging directory
stagingPath := fmt.Sprintf("%s.new", h.nextjsHandler.baseDeployPath+"/"+existing.Namespace+"/"+existing.Name) stagingPath := fmt.Sprintf("%s.new", h.nextjsHandler.baseDeployPath+"/"+existing.Namespace+"/"+existing.Name)
if err := os.MkdirAll(stagingPath, 0755); err != nil {
return nil, fmt.Errorf("failed to create staging directory: %w", err)
}
if err := h.nextjsHandler.extractFromIPFS(ctx, cid, stagingPath); err != nil { if err := h.nextjsHandler.extractFromIPFS(ctx, cid, stagingPath); err != nil {
return nil, fmt.Errorf("failed to extract new build: %w", err) return nil, fmt.Errorf("failed to extract new build: %w", err)
} }

View File

@ -926,7 +926,7 @@ func (g *Gateway) proxyCrossNode(w http.ResponseWriter, r *http.Request, deploym
// Simple HTTP client for internal node-to-node communication // Simple HTTP client for internal node-to-node communication
httpClient := &http.Client{ httpClient := &http.Client{
Timeout: 30 * time.Second, Timeout: 120 * time.Second,
} }
resp, err := httpClient.Do(proxyReq) resp, err := httpClient.Do(proxyReq)

View File

@ -2,6 +2,8 @@ package gateway
import ( import (
"net/http" "net/http"
"github.com/DeBrosOfficial/network/pkg/gateway/ctxkeys"
) )
// Routes returns the http.Handler with all routes and middleware configured // Routes returns the http.Handler with all routes and middleware configured
@ -93,29 +95,31 @@ func (g *Gateway) Routes() http.Handler {
if g.deploymentService != nil { if g.deploymentService != nil {
// Static deployments // Static deployments
mux.HandleFunc("/v1/deployments/static/upload", g.staticHandler.HandleUpload) mux.HandleFunc("/v1/deployments/static/upload", g.staticHandler.HandleUpload)
mux.HandleFunc("/v1/deployments/static/update", g.updateHandler.HandleUpdate) mux.HandleFunc("/v1/deployments/static/update", g.withHomeNodeProxy(g.updateHandler.HandleUpdate))
// Next.js deployments // Next.js deployments
mux.HandleFunc("/v1/deployments/nextjs/upload", g.nextjsHandler.HandleUpload) mux.HandleFunc("/v1/deployments/nextjs/upload", g.nextjsHandler.HandleUpload)
mux.HandleFunc("/v1/deployments/nextjs/update", g.updateHandler.HandleUpdate) mux.HandleFunc("/v1/deployments/nextjs/update", g.withHomeNodeProxy(g.updateHandler.HandleUpdate))
// Go backend deployments // Go backend deployments
if g.goHandler != nil { if g.goHandler != nil {
mux.HandleFunc("/v1/deployments/go/upload", g.goHandler.HandleUpload) mux.HandleFunc("/v1/deployments/go/upload", g.goHandler.HandleUpload)
mux.HandleFunc("/v1/deployments/go/update", g.withHomeNodeProxy(g.updateHandler.HandleUpdate))
} }
// Node.js backend deployments // Node.js backend deployments
if g.nodejsHandler != nil { if g.nodejsHandler != nil {
mux.HandleFunc("/v1/deployments/nodejs/upload", g.nodejsHandler.HandleUpload) mux.HandleFunc("/v1/deployments/nodejs/upload", g.nodejsHandler.HandleUpload)
mux.HandleFunc("/v1/deployments/nodejs/update", g.withHomeNodeProxy(g.updateHandler.HandleUpdate))
} }
// Deployment management // Deployment management
mux.HandleFunc("/v1/deployments/list", g.listHandler.HandleList) mux.HandleFunc("/v1/deployments/list", g.listHandler.HandleList)
mux.HandleFunc("/v1/deployments/get", g.listHandler.HandleGet) mux.HandleFunc("/v1/deployments/get", g.listHandler.HandleGet)
mux.HandleFunc("/v1/deployments/delete", g.listHandler.HandleDelete) mux.HandleFunc("/v1/deployments/delete", g.withHomeNodeProxy(g.listHandler.HandleDelete))
mux.HandleFunc("/v1/deployments/rollback", g.rollbackHandler.HandleRollback) mux.HandleFunc("/v1/deployments/rollback", g.withHomeNodeProxy(g.rollbackHandler.HandleRollback))
mux.HandleFunc("/v1/deployments/versions", g.rollbackHandler.HandleListVersions) mux.HandleFunc("/v1/deployments/versions", g.rollbackHandler.HandleListVersions)
mux.HandleFunc("/v1/deployments/logs", g.logsHandler.HandleLogs) mux.HandleFunc("/v1/deployments/logs", g.withHomeNodeProxy(g.logsHandler.HandleLogs))
mux.HandleFunc("/v1/deployments/events", g.logsHandler.HandleGetEvents) mux.HandleFunc("/v1/deployments/events", g.logsHandler.HandleGetEvents)
// Custom domains // Custom domains
@ -136,3 +140,38 @@ func (g *Gateway) Routes() http.Handler {
return g.withMiddleware(mux) return g.withMiddleware(mux)
} }
// withHomeNodeProxy wraps a deployment handler to proxy requests to the home node
// if the current node is not the home node for the deployment.
func (g *Gateway) withHomeNodeProxy(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Already proxied — prevent loops
if r.Header.Get("X-Orama-Proxy-Node") != "" {
handler(w, r)
return
}
name := r.URL.Query().Get("name")
if name == "" {
handler(w, r)
return
}
ctx := r.Context()
namespace, _ := ctx.Value(ctxkeys.NamespaceOverride).(string)
if namespace == "" {
handler(w, r)
return
}
deployment, err := g.deploymentService.GetDeployment(ctx, namespace, name)
if err != nil {
handler(w, r) // let handler return proper error
return
}
if g.nodePeerID != "" && deployment.HomeNodeID != "" &&
deployment.HomeNodeID != g.nodePeerID {
if g.proxyCrossNode(w, r, deployment) {
return
}
}
handler(w, r)
}
}