feat: kubesphere 4.0 (#6115)

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

---------

Signed-off-by: ci-bot <ci-bot@kubesphere.io>
Co-authored-by: ks-ci-bot <ks-ci-bot@example.com>
Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
KubeSphere CI Bot
2024-09-06 11:05:52 +08:00
committed by GitHub
parent b5015ec7b9
commit 447a51f08b
8557 changed files with 546695 additions and 1146174 deletions

View File

@@ -18,14 +18,22 @@ package getter
import (
"bytes"
"fmt"
"net"
"net/http"
"strings"
"sync"
"time"
"helm.sh/helm/v3/internal/tlsutil"
"helm.sh/helm/v3/internal/urlutil"
"helm.sh/helm/v3/pkg/registry"
)
// OCIGetter is the default HTTP(/S) backend handler
type OCIGetter struct {
opts options
opts options
transport *http.Transport
once sync.Once
}
// Get performs a Get from repo.Getter and returns the body.
@@ -38,6 +46,15 @@ func (g *OCIGetter) Get(href string, options ...Option) (*bytes.Buffer, error) {
func (g *OCIGetter) get(href string) (*bytes.Buffer, error) {
client := g.opts.registryClient
// if the user has already provided a configured registry client, use it,
// this is particularly true when user has his own way of handling the client credentials.
if client == nil {
c, err := g.newRegistryClient()
if err != nil {
return nil, err
}
client = c
}
ref := strings.TrimPrefix(href, fmt.Sprintf("%s://", registry.OCIScheme))
@@ -63,18 +80,7 @@ func (g *OCIGetter) get(href string) (*bytes.Buffer, error) {
// NewOCIGetter constructs a valid http/https client as a Getter
func NewOCIGetter(ops ...Option) (Getter, error) {
registryClient, err := registry.NewClient(
registry.ClientOptEnableCache(true),
)
if err != nil {
return nil, err
}
client := OCIGetter{
opts: options{
registryClient: registryClient,
},
}
var client OCIGetter
for _, opt := range ops {
opt(&client.opts)
@@ -82,3 +88,68 @@ func NewOCIGetter(ops ...Option) (Getter, error) {
return &client, nil
}
func (g *OCIGetter) newRegistryClient() (*registry.Client, error) {
if g.opts.transport != nil {
client, err := registry.NewClient(
registry.ClientOptHTTPClient(&http.Client{
Transport: g.opts.transport,
Timeout: g.opts.timeout,
}),
)
if err != nil {
return nil, err
}
return client, nil
}
g.once.Do(func() {
g.transport = &http.Transport{
// From https://github.com/google/go-containerregistry/blob/31786c6cbb82d6ec4fb8eb79cd9387905130534e/pkg/v1/remote/options.go#L87
DisableCompression: true,
DialContext: (&net.Dialer{
// By default we wrap the transport in retries, so reduce the
// default dial timeout to 5s to avoid 5x 30s of connection
// timeouts when doing the "ping" on certain http registries.
Timeout: 5 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
})
if (g.opts.certFile != "" && g.opts.keyFile != "") || g.opts.caFile != "" || g.opts.insecureSkipVerifyTLS {
tlsConf, err := tlsutil.NewClientTLS(g.opts.certFile, g.opts.keyFile, g.opts.caFile, g.opts.insecureSkipVerifyTLS)
if err != nil {
return nil, fmt.Errorf("can't create TLS config for client: %w", err)
}
sni, err := urlutil.ExtractHostname(g.opts.url)
if err != nil {
return nil, err
}
tlsConf.ServerName = sni
g.transport.TLSClientConfig = tlsConf
}
opts := []registry.ClientOption{registry.ClientOptHTTPClient(&http.Client{
Transport: g.transport,
Timeout: g.opts.timeout,
})}
if g.opts.plainHTTP {
opts = append(opts, registry.ClientOptPlainHTTP())
}
client, err := registry.NewClient(opts...)
if err != nil {
return nil, err
}
return client, nil
}