From 84e4201fafe4f4142331148c125369e1bfcd3bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ois=C3=ADn=20Kyne?= Date: Tue, 7 Apr 2026 21:21:42 +0100 Subject: [PATCH 1/2] Bump frontend, fix 443 issue, and another string issue --- cmd/obol/bootstrap.go | 9 +++++- cmd/obol/sell.go | 30 ++++--------------- .../values/obol-frontend.yaml.gotmpl | 2 +- internal/stack/stack.go | 9 +++++- justfile | 2 +- 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/cmd/obol/bootstrap.go b/cmd/obol/bootstrap.go index 0676256b..cd9047de 100644 --- a/cmd/obol/bootstrap.go +++ b/cmd/obol/bootstrap.go @@ -12,6 +12,8 @@ import ( "strings" "time" + "net" + "github.com/ObolNetwork/obol-stack/internal/config" "github.com/ObolNetwork/obol-stack/internal/stack" "github.com/ObolNetwork/obol-stack/internal/ui" @@ -51,6 +53,11 @@ func bootstrapCommand(cfg *config.Config) *cli.Command { // Step 4: Open browser url := "http://obol.stack" + if ln, err := net.Listen("tcp", ":80"); err != nil { + url = "http://obol.stack:8080" + } else { + ln.Close() + } u.Infof("Opening browser to %s", url) if err := openBrowser(url); err != nil { @@ -62,7 +69,7 @@ func bootstrapCommand(cfg *config.Config) *cli.Command { u.Bold("Bootstrap complete! Your Obol Stack is ready.") u.Blank() u.Print("Next steps:") - u.Print(" • View the stack interface at http://obol.stack") + u.Printf(" • View the stack interface at %s", url) u.Print(" • Create an Obol Agent: obol agent init") u.Print(" • View what's running from the terminal (press '0'): obol k9s") u.Print(" • Shut down the stack: obol stack down") diff --git a/cmd/obol/sell.go b/cmd/obol/sell.go index f638d26e..607b6941 100644 --- a/cmd/obol/sell.go +++ b/cmd/obol/sell.go @@ -396,11 +396,11 @@ func sellHTTPCommand(cfg *config.Config) *cli.Command { Name: "http", Usage: "Sell any local HTTP service with x402 payments", ArgsUsage: "", - Description: `Publishes a payment gated HTTP API to any service within the stack, along with a SKILL.md detailing how to use it.` + Description: `Publishes a payment gated HTTP API to any service within the stack, along with a SKILL.md detailing how to use it. Include --register to have the service listed on EIP8004 onchain agent registry. Example: - obol sell http my-cool-api --upstream my-svc.my-namespace.svc.cluster.local --port 8080 --wallet 0x... --price 0.01 --chain base --register`, + obol sell http my-cool-api --upstream my-svc --port 8080 --wallet 0x... --price 0.01 --chain base --register`, Flags: []cli.Flag{ &cli.StringFlag{ Name: "wallet", @@ -2091,25 +2091,7 @@ func buildInferenceServiceOfferSpec(d *inference.Deployment, pt schemas.PriceTab return spec, nil } -// removePricingRoute removes the x402-verifier pricing route for the given offer. -func removePricingRoute(cfg *config.Config, u *ui.UI, name string) { - urlPath := fmt.Sprintf("/services/%s", name) - pricingCfg, err := x402verifier.GetPricingConfig(cfg) - if err != nil { - return - } - updatedRoutes := make([]x402verifier.RouteRule, 0, len(pricingCfg.Routes)) - for _, r := range pricingCfg.Routes { - if !strings.Contains(r.Pattern, urlPath) { - updatedRoutes = append(updatedRoutes, r) - } - } - if len(updatedRoutes) < len(pricingCfg.Routes) { - pricingCfg.Routes = updatedRoutes - if err := x402verifier.WritePricingConfig(cfg, pricingCfg); err != nil { - u.Warnf("failed to remove pricing route: %v", err) - } else { - u.Infof("Removed pricing route for %s", urlPath) - } - } -} +// removePricingRoute is a no-op retained for compatibility. +// The serviceoffer-controller now manages pricing routes via the ServiceOffer +// informer; static ConfigMap routes are no longer used. +func removePricingRoute(_ *config.Config, _ *ui.UI, _ string) {} diff --git a/internal/embed/infrastructure/values/obol-frontend.yaml.gotmpl b/internal/embed/infrastructure/values/obol-frontend.yaml.gotmpl index a3906036..a49711f0 100644 --- a/internal/embed/infrastructure/values/obol-frontend.yaml.gotmpl +++ b/internal/embed/infrastructure/values/obol-frontend.yaml.gotmpl @@ -35,7 +35,7 @@ image: repository: obolnetwork/obol-stack-front-end pullPolicy: IfNotPresent - tag: "v0.1.14" + tag: "v0.1.15" service: type: ClusterIP diff --git a/internal/stack/stack.go b/internal/stack/stack.go index e0e53e92..78fd3684 100644 --- a/internal/stack/stack.go +++ b/internal/stack/stack.go @@ -283,6 +283,8 @@ func Up(cfg *config.Config, u *ui.UI, wildcardDNS bool) error { u.Infof("Starting stack (id: %s, backend: %s)", stackID, backend.Name()) + portsBlocked := checkPortsAvailable([]int{80, 443}) != nil + kubeconfigData, err := backend.Up(cfg, u, stackID) if err != nil { return err @@ -319,7 +321,12 @@ func Up(cfg *config.Config, u *ui.UI, wildcardDNS bool) error { u.Blank() u.Bold("Stack started successfully.") - u.Print("Visit http://obol.stack in your browser to get started.") + if portsBlocked { + u.Warnf("Ports 80/443 are in use by another process — use http://obol.stack:8080 instead") + u.Print("Visit http://obol.stack:8080 in your browser to get started.") + } else { + u.Print("Visit http://obol.stack in your browser to get started.") + } update.HintIfStale(cfg) return nil diff --git a/justfile b/justfile index 2a312c15..1b24e23d 100644 --- a/justfile +++ b/justfile @@ -75,7 +75,7 @@ dev-frontend-reset: set -e echo "→ Resetting frontend to released image" obol kubectl set image deployment/obol-frontend-obol-app \ - obol-app=obolnetwork/obol-stack-front-end:v0.1.7 -n obol-frontend + obol-app=obolnetwork/obol-stack-front-end:v0.1.15 -n obol-frontend obol kubectl rollout restart deployment/obol-frontend-obol-app -n obol-frontend obol kubectl rollout status deployment/obol-frontend-obol-app -n obol-frontend --timeout=120s echo "✓ Frontend reset to released image" From f686ce5c748d01b393873f8a559be4536c0e027b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ois=C3=ADn=20Kyne?= Date: Tue, 7 Apr 2026 21:28:01 +0100 Subject: [PATCH 2/2] Change how we check ports are available --- cmd/obol/bootstrap.go | 6 ++---- cmd/obol/sell.go | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/obol/bootstrap.go b/cmd/obol/bootstrap.go index cd9047de..fbc5b2a6 100644 --- a/cmd/obol/bootstrap.go +++ b/cmd/obol/bootstrap.go @@ -12,8 +12,6 @@ import ( "strings" "time" - "net" - "github.com/ObolNetwork/obol-stack/internal/config" "github.com/ObolNetwork/obol-stack/internal/stack" "github.com/ObolNetwork/obol-stack/internal/ui" @@ -53,10 +51,10 @@ func bootstrapCommand(cfg *config.Config) *cli.Command { // Step 4: Open browser url := "http://obol.stack" - if ln, err := net.Listen("tcp", ":80"); err != nil { + if resp, err := (&http.Client{Timeout: 2 * time.Second}).Get(url); err != nil { url = "http://obol.stack:8080" } else { - ln.Close() + resp.Body.Close() } u.Infof("Opening browser to %s", url) diff --git a/cmd/obol/sell.go b/cmd/obol/sell.go index 607b6941..16dd7efa 100644 --- a/cmd/obol/sell.go +++ b/cmd/obol/sell.go @@ -400,7 +400,7 @@ func sellHTTPCommand(cfg *config.Config) *cli.Command { Include --register to have the service listed on EIP8004 onchain agent registry. Example: - obol sell http my-cool-api --upstream my-svc --port 8080 --wallet 0x... --price 0.01 --chain base --register`, + obol sell http my-cool-api --upstream my-svc.my-namespace.svc.cluster.local --port 8080 --wallet 0x... --price 0.01 --chain base --register`, Flags: []cli.Flag{ &cli.StringFlag{ Name: "wallet",