Allow fallback across default ports
When no port is specified, allow falling back from 443 to 80 when http is specified along with a TLS configuration. Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
parent
d4148d94cc
commit
02b6c6939f
@ -30,11 +30,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/core/remotes/docker"
|
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/pelletier/go-toml/v2"
|
"github.com/pelletier/go-toml/v2"
|
||||||
tomlu "github.com/pelletier/go-toml/v2/unstable"
|
tomlu "github.com/pelletier/go-toml/v2/unstable"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/v2/core/remotes/docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdateClientFunc is a function that lets you to amend http Client behavior used by registry clients.
|
// UpdateClientFunc is a function that lets you to amend http Client behavior used by registry clients.
|
||||||
@ -250,7 +251,7 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
|
|||||||
// the request twice or consuming the request body.
|
// the request twice or consuming the request body.
|
||||||
if host.scheme == "http" && explicitTLS {
|
if host.scheme == "http" && explicitTLS {
|
||||||
_, port, _ := net.SplitHostPort(host.host)
|
_, port, _ := net.SplitHostPort(host.host)
|
||||||
if port != "" && port != "80" {
|
if port != "80" {
|
||||||
log.G(ctx).WithField("host", host.host).Info("host will try HTTPS first since it is configured for HTTP with a TLS configuration, consider changing host to HTTPS or removing unused TLS configuration")
|
log.G(ctx).WithField("host", host.host).Info("host will try HTTPS first since it is configured for HTTP with a TLS configuration, consider changing host to HTTPS or removing unused TLS configuration")
|
||||||
host.scheme = "https"
|
host.scheme = "https"
|
||||||
rhosts[i].Client.Transport = docker.NewHTTPFallback(rhosts[i].Client.Transport)
|
rhosts[i].Client.Transport = docker.NewHTTPFallback(rhosts[i].Client.Transport)
|
||||||
|
@ -26,8 +26,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/core/remotes/docker"
|
|
||||||
"github.com/containerd/log/logtest"
|
"github.com/containerd/log/logtest"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/v2/core/remotes/docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
const allCaps = docker.HostCapabilityPull | docker.HostCapabilityResolve | docker.HostCapabilityPush
|
const allCaps = docker.HostCapabilityPull | docker.HostCapabilityResolve | docker.HostCapabilityPush
|
||||||
@ -361,8 +362,8 @@ func TestHTTPFallback(t *testing.T) {
|
|||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedScheme: "http",
|
expectedScheme: "https",
|
||||||
usesFallback: false,
|
usesFallback: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
@ -402,8 +403,8 @@ func TestHTTPFallback(t *testing.T) {
|
|||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedScheme: "http",
|
expectedScheme: "https",
|
||||||
usesFallback: false,
|
usesFallback: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: "example.com:5000",
|
host: "example.com:5000",
|
||||||
|
@ -25,8 +25,15 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/containerd/errdefs"
|
||||||
|
"github.com/containerd/log"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/core/images"
|
"github.com/containerd/containerd/v2/core/images"
|
||||||
"github.com/containerd/containerd/v2/core/remotes"
|
"github.com/containerd/containerd/v2/core/remotes"
|
||||||
@ -35,10 +42,6 @@ import (
|
|||||||
"github.com/containerd/containerd/v2/pkg/reference"
|
"github.com/containerd/containerd/v2/pkg/reference"
|
||||||
"github.com/containerd/containerd/v2/pkg/tracing"
|
"github.com/containerd/containerd/v2/pkg/tracing"
|
||||||
"github.com/containerd/containerd/v2/version"
|
"github.com/containerd/containerd/v2/version"
|
||||||
"github.com/containerd/errdefs"
|
|
||||||
"github.com/containerd/log"
|
|
||||||
"github.com/opencontainers/go-digest"
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -732,7 +735,7 @@ func (f *httpFallback) RoundTrip(r *http.Request) (*http.Response, error) {
|
|||||||
// only fall back if the same host had previously fell back
|
// only fall back if the same host had previously fell back
|
||||||
if f.host != r.URL.Host {
|
if f.host != r.URL.Host {
|
||||||
resp, err := f.super.RoundTrip(r)
|
resp, err := f.super.RoundTrip(r)
|
||||||
if !isTLSError(err) {
|
if !isTLSError(err) && !isPortError(err, r.URL.Host) {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -773,3 +776,15 @@ func isTLSError(err error) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isPortError(err error, host string) bool {
|
||||||
|
if errors.Is(err, syscall.ECONNREFUSED) || os.IsTimeout(err) {
|
||||||
|
if _, port, _ := net.SplitHostPort(host); port != "" {
|
||||||
|
// Port is specified, will not retry on different port with scheme change
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -33,13 +33,14 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/v2/core/remotes"
|
|
||||||
"github.com/containerd/containerd/v2/core/remotes/docker/auth"
|
|
||||||
remoteerrors "github.com/containerd/containerd/v2/core/remotes/errors"
|
|
||||||
"github.com/containerd/errdefs"
|
"github.com/containerd/errdefs"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
specs "github.com/opencontainers/image-spec/specs-go"
|
specs "github.com/opencontainers/image-spec/specs-go"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/v2/core/remotes"
|
||||||
|
"github.com/containerd/containerd/v2/core/remotes/docker/auth"
|
||||||
|
remoteerrors "github.com/containerd/containerd/v2/core/remotes/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHTTPResolver(t *testing.T) {
|
func TestHTTPResolver(t *testing.T) {
|
||||||
@ -481,6 +482,34 @@ func TestHTTPFallbackTimeoutResolver(t *testing.T) {
|
|||||||
runBasicTest(t, "testname", sf)
|
runBasicTest(t, "testname", sf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHTTPFallbackPortError(t *testing.T) {
|
||||||
|
// This test only checks the isPortError since testing the whole http fallback would
|
||||||
|
// require listening on 80 and making sure nothing is listening on 443.
|
||||||
|
|
||||||
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
host := l.Addr().String()
|
||||||
|
err = l.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = net.Dial("tcp", host)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Dial should fail after close")
|
||||||
|
}
|
||||||
|
|
||||||
|
if isPortError(err, host) {
|
||||||
|
t.Fatalf("Expected no port error for %s with %v", host, err)
|
||||||
|
}
|
||||||
|
if !isPortError(err, "127.0.0.1") {
|
||||||
|
t.Fatalf("Expected port error for 127.0.0.1 with %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestResolveProxy(t *testing.T) {
|
func TestResolveProxy(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
ctx = context.Background()
|
ctx = context.Background()
|
||||||
|
Loading…
Reference in New Issue
Block a user