From 38dc71b34399e787a609602871570f1e5702ed3f Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Mon, 27 Feb 2023 16:18:08 +0100 Subject: [PATCH] Make `odo dev` fail on Podman if we detect that the application is bound to the loopback interface (on any ports supposed to be forwarded) Next step will be to provide an option for end-users to override this behavior, by either: - ignoring this error (--ignore-localhost); - or explicitly adding a redirect via a side container (--forward-localhost) More context in https://github.com/redhat-developer/odo/issues/6510#issuecomment-1439986558 --- pkg/dev/podmandev/reconcile.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/dev/podmandev/reconcile.go b/pkg/dev/podmandev/reconcile.go index 0d6511d0b7b..779b6a8b111 100644 --- a/pkg/dev/podmandev/reconcile.go +++ b/pkg/dev/podmandev/reconcile.go @@ -2,6 +2,7 @@ package podmandev import ( "context" + "errors" "fmt" "io" "path/filepath" @@ -18,6 +19,7 @@ import ( "github.com/redhat-developer/odo/pkg/libdevfile" "github.com/redhat-developer/odo/pkg/log" odocontext "github.com/redhat-developer/odo/pkg/odo/context" + "github.com/redhat-developer/odo/pkg/port" "github.com/redhat-developer/odo/pkg/watch" corev1 "k8s.io/api/core/v1" @@ -113,6 +115,29 @@ func (o *DevClient) reconcile( componentStatus.RunExecuted = true } + // By default, Podman will not forward to container applications listening on the loopback interface. + // So we are trying to detect such cases accordingly. + // See https://github.com/redhat-developer/odo/issues/6510#issuecomment-1439986558 + loopbackPorts, err := port.DetectRemotePortsBoundOnLoopback(o.execClient, pod.Name, pod.Spec.Containers[0].Name, fwPorts) + if err != nil { + return fmt.Errorf("unable to detect container ports bound on the loopback interface: %w", err) + } + klog.V(4).Infof("detected %d ports bound on the loopback interface in the pod: %v", len(loopbackPorts), loopbackPorts) + + if len(loopbackPorts) != 0 { + list := make([]string, 0, len(loopbackPorts)) + for _, p := range loopbackPorts { + list = append(list, fmt.Sprintf("%s (%d)", p.PortName, p.ContainerPort)) + } + + log.Errorf(`Detected that the following port(s) can be reached only via the container loopback interface: %s. +Port forwarding on Podman currently does not work with applications listening on the loopback interface. +Either change the application to make those port(s) reachable on all interfaces (0.0.0.0), or rerun 'odo dev' with any of the following options: +- --ignore-localhost: no error will be returned by odo, but port-forwarding on those ports might not work on Podman. +- --forward-localhost: odo will inject a dedicated side container to redirect traffic to such ports.`, strings.Join(list, ", ")) + return errors.New("cannot make port forwarding work with ports bound to the loopback interface only") + } + for _, fwPort := range fwPorts { s := fmt.Sprintf("Forwarding from %s:%d -> %d", fwPort.LocalAddress, fwPort.LocalPort, fwPort.ContainerPort) fmt.Fprintf(out, " - %s", log.SboldColor(color.FgGreen, s))