From 67d395dfd428ce8eb16727ce47ff943676f69a06 Mon Sep 17 00:00:00 2001 From: Sergio Cazzolato Date: Tue, 9 Jun 2026 14:32:04 -0300 Subject: [PATCH 1/5] Autodetect if it is possible to ssh to the openstack vm The idea is to bypass the proxy configuratio when it is not needed, so we don't need to duplicate the backends configuration --- spread/openstack.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spread/openstack.go b/spread/openstack.go index c30470f..41a0211 100644 --- a/spread/openstack.go +++ b/spread/openstack.go @@ -574,6 +574,29 @@ func (p *openstackProvider) waitProvision(ctx context.Context, s *openstackServe var openstackServerBootTimeout = 5 * time.Minute var openstackServerBootRetry = 5 * time.Second +var openstackDirectSSHProbeTimeout = 3 * time.Second + +func canReachDirectSSH(ctx context.Context, address string, timeout time.Duration) bool { + if net.ParseIP(address) == nil { + return false + } + + dialCtx := ctx + if _, hasDeadline := ctx.Deadline(); !hasDeadline { + var cancel context.CancelFunc + dialCtx, cancel = context.WithTimeout(ctx, timeout) + defer cancel() + } + + dialer := net.Dialer{Timeout: timeout} + conn, err := dialer.DialContext(dialCtx, "tcp", net.JoinHostPort(address, "22")) + if err != nil { + debugf("Direct SSH probe to %s failed: %v", address, err) + return false + } + _ = conn.Close() + return true +} func countIPsBetween(initialIp net.IP, finalIp net.IP) (uint32, error) { ip1Int := binary.BigEndian.Uint32(initialIp.To4()) @@ -594,6 +617,11 @@ func (p *openstackProvider) updateAddressIfProxyDefined(ctx context.Context, s * return nil } + if canReachDirectSSH(ctx, s.address, openstackDirectSSHProbeTimeout) { + printf("Server reachable directly via SSH at %s; skipping proxy address mapping", s.address) + return nil + } + for _, rel := range s.p.backend.CIDRPortRel { parts := strings.SplitN(rel, ":", 2) if len(parts) != 2 { From 2efd1a7c9e801bae0a17b203b17be279f93583e6 Mon Sep 17 00:00:00 2001 From: Sergio Cazzolato Date: Tue, 9 Jun 2026 14:55:34 -0300 Subject: [PATCH 2/5] revert removal of proxy --- smoke/spread.yaml | 4 ++++ spread.yaml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/smoke/spread.yaml b/smoke/spread.yaml index 72c3b1b..d0d92f6 100644 --- a/smoke/spread.yaml +++ b/smoke/spread.yaml @@ -23,6 +23,8 @@ backends: halt-timeout: 2h wait-timeout: 5m groups: [default] + proxy: ingress-haproxy.ps7.canonical.com + cidr-port-rel: [10.151.54.0/24:4000] environment: HTTP_PROXY: 'http://egress.ps7.internal:3128' HTTPS_PROXY: 'http://egress.ps7.internal:3128' @@ -83,6 +85,8 @@ backends: halt-timeout: 2h wait-timeout: 5m groups: [default] + proxy: ingress-haproxy.ps7.canonical.com + cidr-port-rel: [10.151.89.0/24:8000] environment: HTTP_PROXY: 'http://egress.ps7.internal:3128' HTTPS_PROXY: 'http://egress.ps7.internal:3128' diff --git a/spread.yaml b/spread.yaml index ec8334e..ecaaad2 100644 --- a/spread.yaml +++ b/spread.yaml @@ -28,6 +28,8 @@ backends: plan: shared.small halt-timeout: 2h wait-timeout: 10m + proxy: ingress-haproxy.ps7.canonical.com + cidr-port-rel: [10.151.54.0/24:4000] groups: [default] environment: &openstack-env HTTP_PROXY: 'http://egress.ps7.internal:3128' From 54f96b5c6dbc61a96f0f13739f1460b29565ab74 Mon Sep 17 00:00:00 2001 From: Sergio Cazzolato Date: Tue, 9 Jun 2026 15:08:31 -0300 Subject: [PATCH 3/5] improving user message --- spread/openstack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spread/openstack.go b/spread/openstack.go index 41a0211..b436f37 100644 --- a/spread/openstack.go +++ b/spread/openstack.go @@ -618,7 +618,7 @@ func (p *openstackProvider) updateAddressIfProxyDefined(ctx context.Context, s * } if canReachDirectSSH(ctx, s.address, openstackDirectSSHProbeTimeout) { - printf("Server reachable directly via SSH at %s; skipping proxy address mapping", s.address) + printf("Server reachable directly via SSH, skipping proxy mapping (%s)", s) return nil } From d78fe18ef7a4d1f83ee93b2817b714d67c23ee9e Mon Sep 17 00:00:00 2001 From: Sergio Cazzolato Date: Tue, 9 Jun 2026 15:20:17 -0300 Subject: [PATCH 4/5] Print the name in the message --- spread/openstack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spread/openstack.go b/spread/openstack.go index b436f37..bc474c5 100644 --- a/spread/openstack.go +++ b/spread/openstack.go @@ -618,7 +618,7 @@ func (p *openstackProvider) updateAddressIfProxyDefined(ctx context.Context, s * } if canReachDirectSSH(ctx, s.address, openstackDirectSSHProbeTimeout) { - printf("Server reachable directly via SSH, skipping proxy mapping (%s)", s) + printf("Server reachable directly via SSH, skipping proxy mapping (%s)", s.d.Name) return nil } From b88bde7719ba257239d1fdf511cf6e844df1d78e Mon Sep 17 00:00:00 2001 From: Sergio Cazzolato Date: Wed, 10 Jun 2026 08:50:14 -0300 Subject: [PATCH 5/5] update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2cd0613..e0eb900 100644 --- a/README.md +++ b/README.md @@ -1198,6 +1198,8 @@ When access to the VM must go through a proxy, the proxy configuration should be To configure the IP-port mapping, use the cidr-port-rel key. This requires a list of entries in the format "CIDR:initial-port". Based on this list, the system will assign a port by matching the allocated IP with the corresponding CIDR and applying the specified initial port. +In order to allow reusing a backend definitions, the proxy configuration is not used by spread when it can ssh directly to the destination IP address. + ## Linode backend