Updating the Go version

This is needed for goreleaser to create updates. Its latest release
needs it.

Updates needed for linting and to fix failed tests resulting from
Go std library changes.

Signed-off-by: Matt Farina <matt.farina@suse.com>
pull/32577/head
Matt Farina 2 weeks ago
parent 6d1f67cf6a
commit b5b498b774

@ -42,8 +42,7 @@ func main() {
} }
if err := cmd.Execute(); err != nil { if err := cmd.Execute(); err != nil {
var cerr helmcmd.CommandError if cerr, ok := errors.AsType[helmcmd.CommandError](err); ok {
if errors.As(err, &cerr) {
os.Exit(cerr.ExitCode) os.Exit(cerr.ExitCode)
} }
os.Exit(1) os.Exit(1)

@ -123,7 +123,7 @@ func LoadFiles(files []*archive.BufferedFile) (*chart.Chart, error) {
} }
fname := strings.TrimPrefix(f.Name, "charts/") fname := strings.TrimPrefix(f.Name, "charts/")
cname := strings.SplitN(fname, "/", 2)[0] cname, _, _ := strings.Cut(fname, "/")
if slices.Index(subChartsKeys, cname) == -1 { if slices.Index(subChartsKeys, cname) == -1 {
subChartsKeys = append(subChartsKeys, cname) subChartsKeys = append(subChartsKeys, cname)
} }

@ -46,7 +46,6 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
if c != "" { if c != "" {
// retrieve value // retrieve value
vv, err := cvals.PathValue(cpath + c) vv, err := cvals.PathValue(cpath + c)
var errNoValue common.ErrNoValue
if err == nil { if err == nil {
// if not bool, warn // if not bool, warn
if bv, ok := vv.(bool); ok { if bv, ok := vv.(bool); ok {
@ -54,7 +53,7 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
break break
} }
slog.Warn("returned non-bool value", "path", c, "chart", r.Name) slog.Warn("returned non-bool value", "path", c, "chart", r.Name)
} else if errors.As(err, &errNoValue) { } else if _, ok := errors.AsType[common.ErrNoValue](err); ok {
// this is a real error // this is a real error
slog.Warn("the method PathValue returned error", slog.Any("error", err)) slog.Warn("the method PathValue returned error", slog.Any("error", err))
} }

@ -42,4 +42,4 @@ into a Chart.
When creating charts in memory, use the 'helm.sh/helm/pkg/chart' When creating charts in memory, use the 'helm.sh/helm/pkg/chart'
package directly. package directly.
*/ */
package util // import "helm.sh/helm/v4/internal/chart/v3/util" package util

@ -231,13 +231,10 @@ func TestSaveDir(t *testing.T) {
} }
func TestRepeatableSave(t *testing.T) { func TestRepeatableSave(t *testing.T) {
tmp := t.TempDir()
defer os.RemoveAll(tmp)
modTime := time.Date(2021, 9, 1, 20, 34, 58, 651387237, time.UTC) modTime := time.Date(2021, 9, 1, 20, 34, 58, 651387237, time.UTC)
tests := []struct { tests := []struct {
name string name string
chart *chart.Chart chart *chart.Chart
want string
}{ }{
{ {
name: "Package 1 file", name: "Package 1 file",
@ -258,7 +255,6 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"), Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime, SchemaModTime: modTime,
}, },
want: "5bfea18cc3c8cbc265744bc32bffa9489a4dbe87d6b51b90f4255e4839d35e03",
}, },
{ {
name: "Package 2 files", name: "Package 2 files",
@ -280,20 +276,26 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"), Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime, SchemaModTime: modTime,
}, },
want: "a240365c21e0a2f4a57873132a9b686566a612d08bcb3f20c9446bfff005ccce",
}, },
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
// create package // Package the same chart twice, into separate directories so the
dest := path.Join(tmp, "newdir") // second Save does not simply overwrite the first.
where, err := Save(test.chart, dest) first, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save")
second, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save") require.NoError(t, err, "Failed to save")
// get shasum for package
result, err := sha256Sum(where) firstSum, err := sha256Sum(first)
require.NoError(t, err, "Failed to check shasum") require.NoError(t, err, "Failed to check shasum")
// assert that the package SHA is what we wanted. secondSum, err := sha256Sum(second)
assert.Equal(t, test.want, result, "FormatName() result = %v, want %v", result, test.want) require.NoError(t, err, "Failed to check shasum")
// Packaging a chart must be reproducible. The digest itself is not
// pinned here because the bytes depend on the compression
// implementation of the Go release Helm is built with.
assert.Equal(t, firstSum, secondSum, "Save() is not repeatable")
}) })
} }
} }

@ -41,7 +41,7 @@ func TestUnmarshaConfig(t *testing.T) {
ShortHelp: "short help string", ShortHelp: "short help string",
LongHelp: "long help string", LongHelp: "long help string",
IgnoreFlags: true, IgnoreFlags: true,
}, *(config.(*schema.ConfigCLIV1))) }, *config.(*schema.ConfigCLIV1))
} }
// Test unmarshalling invalid config data // Test unmarshalling invalid config data

@ -74,7 +74,7 @@ func (r *RuntimeSubprocess) CreatePlugin(pluginDir string, metadata *Metadata) (
return &SubprocessPluginRuntime{ return &SubprocessPluginRuntime{
metadata: *metadata, metadata: *metadata,
pluginDir: pluginDir, pluginDir: pluginDir,
RuntimeConfig: *(metadata.RuntimeConfig.(*RuntimeConfigSubprocess)), RuntimeConfig: *metadata.RuntimeConfig.(*RuntimeConfigSubprocess),
EnvVars: maps.Clone(r.EnvVars), EnvVars: maps.Clone(r.EnvVars),
}, nil }, nil
} }
@ -153,8 +153,7 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error {
slog.Debug("executing plugin hook command", slog.String("pluginName", r.metadata.Name), slog.String("command", cmd.String())) slog.Debug("executing plugin hook command", slog.String("pluginName", r.metadata.Name), slog.String("command", cmd.String()))
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
var eerr *exec.ExitError if eerr, ok := errors.AsType[*exec.ExitError](err); ok {
if errors.As(err, &eerr) {
os.Stderr.Write(eerr.Stderr) os.Stderr.Write(eerr.Stderr)
return fmt.Errorf("plugin %s hook for %q exited with error", event, r.metadata.Name) return fmt.Errorf("plugin %s hook for %q exited with error", event, r.metadata.Name)
} }
@ -168,8 +167,7 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error {
// then replace the other three with a call to this func // then replace the other three with a call to this func
func executeCmd(prog *exec.Cmd, pluginName string) error { func executeCmd(prog *exec.Cmd, pluginName string) error {
if err := prog.Run(); err != nil { if err := prog.Run(); err != nil {
var eerr *exec.ExitError if eerr, ok := errors.AsType[*exec.ExitError](err); ok {
if errors.As(err, &eerr) {
slog.Debug( slog.Debug(
"plugin execution failed", "plugin execution failed",
slog.String("pluginName", pluginName), slog.String("pluginName", pluginName),

@ -42,7 +42,7 @@ func getProtocolCommand(commands []SubprocessProtocolCommand, protocol string) *
// TODO can we replace a lot of this func with RuntimeSubprocess.invokeWithEnv? // TODO can we replace a lot of this func with RuntimeSubprocess.invokeWithEnv?
func (r *SubprocessPluginRuntime) runGetter(ctx context.Context, input *Input) (*Output, error) { func (r *SubprocessPluginRuntime) runGetter(ctx context.Context, input *Input) (*Output, error) {
msg, ok := (input.Message).(schema.InputMessageGetterV1) msg, ok := input.Message.(schema.InputMessageGetterV1)
if !ok { if !ok {
return nil, fmt.Errorf("expected input type schema.InputMessageGetterV1, got %T", input) return nil, fmt.Errorf("expected input type schema.InputMessageGetterV1, got %T", input)
} }

@ -136,11 +136,11 @@ func IsRollingUpdate(deployment *apps.Deployment) bool {
// MaxUnavailable returns the maximum unavailable pods a rolling deployment can take. // MaxUnavailable returns the maximum unavailable pods a rolling deployment can take.
func MaxUnavailable(deployment apps.Deployment) int32 { func MaxUnavailable(deployment apps.Deployment) int32 {
if !IsRollingUpdate(&deployment) || *(deployment.Spec.Replicas) == 0 { if !IsRollingUpdate(&deployment) || *deployment.Spec.Replicas == 0 {
return int32(0) return int32(0)
} }
// Error caught by validation // Error caught by validation
_, maxUnavailable, _ := ResolveFenceposts(deployment.Spec.Strategy.RollingUpdate.MaxSurge, deployment.Spec.Strategy.RollingUpdate.MaxUnavailable, *(deployment.Spec.Replicas)) _, maxUnavailable, _ := ResolveFenceposts(deployment.Spec.Strategy.RollingUpdate.MaxSurge, deployment.Spec.Strategy.RollingUpdate.MaxUnavailable, *deployment.Spec.Replicas)
if maxUnavailable > *deployment.Spec.Replicas { if maxUnavailable > *deployment.Spec.Replicas {
return *deployment.Spec.Replicas return *deployment.Spec.Replicas
} }

@ -17,14 +17,20 @@ limitations under the License.
package version package version
import ( import (
"strings"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestK8sClientGoModVersion(t *testing.T) { func TestK8sClientGoModVersion(t *testing.T) {
// Unfortunately, test builds don't include debug info / module info // Whether module info is embedded in a test binary depends on the Go
// So we expect "K8sIOClientGoModVersion" to return error // release: builds before Go 1.27 omit it, so the lookup fails. Accept
_, err := K8sIOClientGoModVersion() // either outcome, but require that a successful lookup returns a version.
v, err := K8sIOClientGoModVersion()
if err != nil {
require.ErrorContains(t, err, "k8s.io/client-go not found in build info") require.ErrorContains(t, err, "k8s.io/client-go not found in build info")
return
}
require.True(t, strings.HasPrefix(v, "v"), "expected a semver-like version, got %q", v)
} }

@ -153,7 +153,7 @@ func LoadFiles(files []*archive.BufferedFile) (*chart.Chart, error) {
} }
fname := strings.TrimPrefix(f.Name, "charts/") fname := strings.TrimPrefix(f.Name, "charts/")
cname := strings.SplitN(fname, "/", 2)[0] cname, _, _ := strings.Cut(fname, "/")
subcharts[cname] = append(subcharts[cname], &archive.BufferedFile{Name: fname, ModTime: f.ModTime, Data: f.Data}) subcharts[cname] = append(subcharts[cname], &archive.BufferedFile{Name: fname, ModTime: f.ModTime, Data: f.Data})
default: default:
c.Files = append(c.Files, &common.File{Name: f.Name, ModTime: f.ModTime, Data: f.Data}) c.Files = append(c.Files, &common.File{Name: f.Name, ModTime: f.ModTime, Data: f.Data})

@ -46,7 +46,6 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
if c != "" { if c != "" {
// retrieve value // retrieve value
vv, err := cvals.PathValue(cpath + c) vv, err := cvals.PathValue(cpath + c)
var errNoValue common.ErrNoValue
if err == nil { if err == nil {
// if not bool, warn // if not bool, warn
if bv, ok := vv.(bool); ok { if bv, ok := vv.(bool); ok {
@ -54,7 +53,7 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
break break
} }
slog.Warn("returned non-bool value", "path", c, "chart", r.Name) slog.Warn("returned non-bool value", "path", c, "chart", r.Name)
} else if !errors.As(err, &errNoValue) { } else if _, ok := errors.AsType[common.ErrNoValue](err); !ok {
// this is a real error // this is a real error
slog.Warn("the method PathValue returned error", slog.Any("error", err)) slog.Warn("the method PathValue returned error", slog.Any("error", err))
} }

@ -42,4 +42,4 @@ into a Chart.
When creating charts in memory, use the 'helm.sh/helm/pkg/chart' When creating charts in memory, use the 'helm.sh/helm/pkg/chart'
package directly. package directly.
*/ */
package util // import "helm.sh/helm/v4/pkg/chart/v2/util" package util

@ -298,13 +298,10 @@ func TestSaveDir(t *testing.T) {
} }
func TestRepeatableSave(t *testing.T) { func TestRepeatableSave(t *testing.T) {
tmp := t.TempDir()
defer os.RemoveAll(tmp)
modTime := time.Date(2021, 9, 1, 20, 34, 58, 651387237, time.UTC) modTime := time.Date(2021, 9, 1, 20, 34, 58, 651387237, time.UTC)
tests := []struct { tests := []struct {
name string name string
chart *chart.Chart chart *chart.Chart
want string
}{ }{
{ {
name: "Package 1 file", name: "Package 1 file",
@ -325,7 +322,6 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"), Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime, SchemaModTime: modTime,
}, },
want: "63358874b93ea095c857cd66bcf5d0a4464840cf84a07547db744d81d6c5af59",
}, },
{ {
name: "Package 2 files", name: "Package 2 files",
@ -347,20 +343,26 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"), Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime, SchemaModTime: modTime,
}, },
want: "c2a43990053da788ad4e260d3b00d52a0b103ccc67ab9f48278a7b6dcfb2a4bd",
}, },
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
// create package // Package the same chart twice, into separate directories so the
dest := path.Join(tmp, "newdir") // second Save does not simply overwrite the first.
where, err := Save(test.chart, dest) first, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save")
second, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save") require.NoError(t, err, "Failed to save")
// get shasum for package
result, err := sha256Sum(where) firstSum, err := sha256Sum(first)
require.NoError(t, err, "Failed to check shasum") require.NoError(t, err, "Failed to check shasum")
// assert that the package SHA is what we wanted. secondSum, err := sha256Sum(second)
assert.Equal(t, test.want, result, "FormatName() result = %v, want %v", result, test.want) require.NoError(t, err, "Failed to check shasum")
// Packaging a chart must be reproducible. The digest itself is not
// pinned here because the bytes depend on the compression
// implementation of the Go release Helm is built with.
assert.Equal(t, firstSum, secondSum, "Save() is not repeatable")
}) })
} }
} }

@ -83,8 +83,7 @@ func newDependencyBuildCmd(out io.Writer) *cobra.Command {
man.Verify = downloader.VerifyIfPossible man.Verify = downloader.VerifyIfPossible
} }
err = man.Build() err = man.Build()
var e downloader.ErrRepoNotFound if e, ok := errors.AsType[downloader.ErrRepoNotFound](err); ok {
if errors.As(err, &e) {
return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error()) return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error())
} }
return err return err

@ -482,8 +482,7 @@ func reformatExecErrorMsg(filename string, err error) error {
// If it can parse out details from that error message such as the line number, template it failed on, // If it can parse out details from that error message such as the line number, template it failed on,
// and error description, then it will construct a new error that displays these details in a structured way. // and error description, then it will construct a new error that displays these details in a structured way.
// If there are issues with parsing the error message, the err passed into the function should return instead. // If there are issues with parsing the error message, the err passed into the function should return instead.
var execError template.ExecError if _, ok := errors.AsType[template.ExecError](err); !ok {
if !errors.As(err, &execError) {
return err return err
} }

@ -447,7 +447,7 @@ func verifyInsecureSkipVerify(t *testing.T, g *HTTPGetter, caseName string, expe
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, returnVal, "Expected non nil value for http client") require.NotNil(t, returnVal, "Expected non nil value for http client")
transport := (returnVal.Transport).(*http.Transport) transport := returnVal.Transport.(*http.Transport)
gotValue := false gotValue := false
if transport.TLSClientConfig != nil { if transport.TLSClientConfig != nil {
gotValue = transport.TLSClientConfig.InsecureSkipVerify gotValue = transport.TLSClientConfig.InsecureSkipVerify
@ -465,7 +465,7 @@ func TestDefaultHTTPTransportReuse(t *testing.T) {
require.NotNil(t, httpClient1, "Expected non nil value for http client") require.NotNil(t, httpClient1, "Expected non nil value for http client")
transport1 := (httpClient1.Transport).(*http.Transport) transport1 := httpClient1.Transport.(*http.Transport)
httpClient2, err := g.httpClient(g.opts) httpClient2, err := g.httpClient(g.opts)
@ -473,7 +473,7 @@ func TestDefaultHTTPTransportReuse(t *testing.T) {
require.NotNil(t, httpClient2, "Expected non nil value for http client") require.NotNil(t, httpClient2, "Expected non nil value for http client")
transport2 := (httpClient2.Transport).(*http.Transport) transport2 := httpClient2.Transport.(*http.Transport)
require.Equal(t, transport2, transport1, "Expected default transport to be reused") require.Equal(t, transport2, transport1, "Expected default transport to be reused")
} }
@ -489,7 +489,7 @@ func TestHTTPTransportOption(t *testing.T) {
require.NotNil(t, httpClient1, "Expected non nil value for http client") require.NotNil(t, httpClient1, "Expected non nil value for http client")
transport1 := (httpClient1.Transport).(*http.Transport) transport1 := httpClient1.Transport.(*http.Transport)
require.Equal(t, transport, transport1, "Expected transport option to be applied") require.Equal(t, transport, transport1, "Expected transport option to be applied")
@ -499,7 +499,7 @@ func TestHTTPTransportOption(t *testing.T) {
require.NotNil(t, httpClient2, "Expected non nil value for http client") require.NotNil(t, httpClient2, "Expected non nil value for http client")
transport2 := (httpClient2.Transport).(*http.Transport) transport2 := httpClient2.Transport.(*http.Transport)
require.Equal(t, transport2, transport1, "Expected applied transport to be reused") require.Equal(t, transport2, transport1, "Expected applied transport to be reused")

@ -79,7 +79,6 @@ func newPodWithStatus(name string, status v1.PodStatus, namespace string) v1.Pod
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: name,
Namespace: ns, Namespace: ns,
SelfLink: "/api/v1/namespaces/default/pods/" + name,
}, },
Spec: v1.PodSpec{ Spec: v1.PodSpec{
Containers: []v1.Container{{ Containers: []v1.Container{{

@ -231,7 +231,7 @@ type (
// Returns true if the host contains a path component (i.e., contains a '/'). // Returns true if the host contains a path component (i.e., contains a '/').
func warnIfHostHasPath(host string) bool { func warnIfHostHasPath(host string) bool {
if strings.Contains(host, "/") { if strings.Contains(host, "/") {
registryHost := strings.Split(host, "/")[0] registryHost, _, _ := strings.Cut(host, "/")
slog.Warn("registry login currently only supports registry hostname, not a repository path", "host", host, "suggested", registryHost) slog.Warn("registry login currently only supports registry hostname, not a repository path", "host", host, "suggested", registryHost)
return true return true
} }
@ -322,6 +322,11 @@ func ensureTLSConfig(client *auth.Client, setConfig *tls.Config) (*tls.Config, e
transport.TLSClientConfig = &tls.Config{} transport.TLSClientConfig = &tls.Config{}
} }
// Idle connections were established under the previous TLS configuration.
// Drop them so the settings being applied here take effect on the next
// request instead of being bypassed by a pooled connection.
transport.CloseIdleConnections()
return transport.TLSClientConfig, nil return transport.TLSClientConfig, nil
} }

@ -216,6 +216,19 @@ func (srv *OCIServer) RunWithReturn(t *testing.T, opts ...OCIServerOpt) *OCIServ
go srv.ListenAndServe() go srv.ListenAndServe()
// NewOCIServer released the port it reserved so the registry could claim
// it, and ListenAndServe binds asynchronously. Wait for the port to accept
// connections so the login below does not race the listener coming up.
dialer := &net.Dialer{Timeout: time.Second}
require.Eventually(t, func() bool {
conn, err := dialer.DialContext(t.Context(), "tcp", srv.RegistryURL)
if err != nil {
return false
}
conn.Close()
return true
}, 30*time.Second, 20*time.Millisecond, "test registry never started listening on %s", srv.RegistryURL)
credentialsFile := filepath.Join(srv.Dir, "config.json") credentialsFile := filepath.Join(srv.Dir, "config.json")
// init test client // init test client

Loading…
Cancel
Save