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"
if deployUpdate {
endpoint = "/v1/deployments/static/update"
endpoint = "/v1/deployments/static/update?name=" + deployName
}
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"
if deployUpdate {
endpoint = "/v1/deployments/nextjs/update"
endpoint = "/v1/deployments/nextjs/update?name=" + deployName
}
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"
if deployUpdate {
endpoint = "/v1/deployments/go/update"
endpoint = "/v1/deployments/go/update?name=" + deployName
}
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"
if deployUpdate {
endpoint = "/v1/deployments/nodejs/update"
endpoint = "/v1/deployments/nodejs/update?name=" + deployName
}
resp, err := uploadDeployment(endpoint, tarball, map[string]string{

View File

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

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"os"
"time"
"github.com/DeBrosOfficial/network/pkg/deployments"
@ -236,6 +237,9 @@ func (h *RollbackHandler) rollbackDynamic(ctx context.Context, current *deployme
stagingPath := deployPath + ".rollback"
// 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 {
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
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 {
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
httpClient := &http.Client{
Timeout: 30 * time.Second,
Timeout: 120 * time.Second,
}
resp, err := httpClient.Do(proxyReq)

View File

@ -2,6 +2,8 @@ package gateway
import (
"net/http"
"github.com/DeBrosOfficial/network/pkg/gateway/ctxkeys"
)
// 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 {
// Static deployments
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
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
if g.goHandler != nil {
mux.HandleFunc("/v1/deployments/go/upload", g.goHandler.HandleUpload)
mux.HandleFunc("/v1/deployments/go/update", g.withHomeNodeProxy(g.updateHandler.HandleUpdate))
}
// Node.js backend deployments
if g.nodejsHandler != nil {
mux.HandleFunc("/v1/deployments/nodejs/upload", g.nodejsHandler.HandleUpload)
mux.HandleFunc("/v1/deployments/nodejs/update", g.withHomeNodeProxy(g.updateHandler.HandleUpdate))
}
// Deployment management
mux.HandleFunc("/v1/deployments/list", g.listHandler.HandleList)
mux.HandleFunc("/v1/deployments/get", g.listHandler.HandleGet)
mux.HandleFunc("/v1/deployments/delete", g.listHandler.HandleDelete)
mux.HandleFunc("/v1/deployments/rollback", g.rollbackHandler.HandleRollback)
mux.HandleFunc("/v1/deployments/delete", g.withHomeNodeProxy(g.listHandler.HandleDelete))
mux.HandleFunc("/v1/deployments/rollback", g.withHomeNodeProxy(g.rollbackHandler.HandleRollback))
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)
// Custom domains
@ -136,3 +140,38 @@ func (g *Gateway) Routes() http.Handler {
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)
}
}