Merge branch 'main' of github.com:ratulbasak/helm into list-all-releases

pull/32388/head
ratulbasak 3 months ago
commit 016c17a518

@ -74,9 +74,9 @@ linters:
errorlint:
# Check for plain type assertions and type switches.
asserts: false
asserts: true
# Check for plain error comparisons.
comparison: false
comparison: true
exhaustive:
default-signifies-exhaustive: true

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main // import "helm.sh/helm/v4/cmd/helm"
package main
import (
"errors"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package lint // import "helm.sh/helm/v4/internal/chart/v3/lint"
package lint
import (
"path/filepath"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules"
package rules
import (
"errors"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules"
package rules
import (
"fmt"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules"
package rules
import (
"fmt"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/internal/chart/v3/lint/rules"
package rules
import (
"testing"
@ -29,14 +29,12 @@ func TestValidateNoDeprecations(t *testing.T) {
Kind: "Deployment",
}
err := validateNoDeprecations(deprecated, nil)
var depErr deprecatedAPIError
require.Error(t, err, "Expected deprecated extension to be flagged")
var depErr deprecatedAPIError
require.ErrorAs(t, err, &depErr, "Expected error to be of type deprecatedAPIError")
require.NotEmpty(t, depErr.Message, "Expected error message to be non-blank: %v", err)
err = validateNoDeprecations(&k8sYamlStruct{
assert.NoError(t, validateNoDeprecations(&k8sYamlStruct{
APIVersion: "v1",
Kind: "Pod",
}, nil)
assert.NoError(t, err, "Expected a v1 Pod to not be deprecated")
}, nil), "Expected a v1 Pod to not be deprecated")
}

@ -20,4 +20,4 @@ Package support contains tools for linting charts.
Linting is the process of testing charts for errors or warnings regarding
formatting, compilation, or standards compliance.
*/
package support // import "helm.sh/helm/v4/internal/chart/v3/lint/support"
package support

@ -14,7 +14,7 @@ limitations under the License.
*/
// Package cache provides a key generator for vcs urls.
package cache // import "helm.sh/helm/v4/internal/plugin/cache"
package cache
import (
"net/url"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"path/filepath"

@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"testing"

@ -14,4 +14,4 @@ limitations under the License.
*/
// Package installer provides an interface for installing Helm plugins.
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"archive/tar"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"bytes"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"archive/tar"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"bytes"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"archive/tar"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"archive/tar"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"errors"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package installer // import "helm.sh/helm/v4/internal/plugin/installer"
package installer
import (
"fmt"

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package plugin // import "helm.sh/helm/v4/internal/plugin"
package plugin
import (
"context"

@ -18,6 +18,7 @@ package plugin
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"log/slog"
@ -152,7 +153,8 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error {
slog.Debug("executing plugin hook command", slog.String("pluginName", r.metadata.Name), slog.String("command", cmd.String()))
if err := cmd.Run(); err != nil {
if eerr, ok := err.(*exec.ExitError); ok {
var eerr *exec.ExitError
if errors.As(err, &eerr) {
os.Stderr.Write(eerr.Stderr)
return fmt.Errorf("plugin %s hook for %q exited with error", event, r.metadata.Name)
}
@ -166,7 +168,8 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error {
// then replace the other three with a call to this func
func executeCmd(prog *exec.Cmd, pluginName string) error {
if err := prog.Run(); err != nil {
if eerr, ok := err.(*exec.ExitError); ok {
var eerr *exec.ExitError
if errors.As(err, &eerr) {
slog.Debug(
"plugin execution failed",
slog.String("pluginName", pluginName),

@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package plugin // import "helm.sh/helm/v4/internal/plugin"
package plugin
// Types of hooks
const (

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
v2 "helm.sh/helm/v4/internal/release/v2"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"sort"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"bytes"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"fmt"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"fmt"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"sort"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/internal/release/v2/util"
package util
import (
"testing"

@ -21,6 +21,7 @@ limitations under the License.
package sympath
import (
"errors"
"fmt"
"log/slog"
"os"
@ -40,7 +41,7 @@ func Walk(root string, walkFn filepath.WalkFunc) error {
} else {
err = symwalk(root, info, walkFn)
}
if err == filepath.SkipDir {
if errors.Is(err, filepath.SkipDir) {
return nil
}
return err
@ -75,7 +76,7 @@ func symwalk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
if info, err = os.Lstat(resolved); err != nil {
return err
}
if err := symwalk(path, info, walkFn); err != nil && err != filepath.SkipDir {
if err := symwalk(path, info, walkFn); err != nil && !errors.Is(err, filepath.SkipDir) {
return err
}
return nil
@ -98,13 +99,13 @@ func symwalk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
filename := filepath.Join(path, name)
fileInfo, err := os.Lstat(filename)
if err != nil {
if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
if err := walkFn(filename, fileInfo, err); err != nil && !errors.Is(err, filepath.SkipDir) {
return err
}
} else {
err = symwalk(filename, fileInfo, walkFn)
if err != nil {
if (!fileInfo.IsDir() && !IsSymlink(fileInfo)) || err != filepath.SkipDir {
if (!fileInfo.IsDir() && !IsSymlink(fileInfo)) || !errors.Is(err, filepath.SkipDir) {
return err
}
}

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package lint // import "helm.sh/helm/v4/pkg/chart/v2/lint"
package lint
import (
"path/filepath"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules"
package rules
import (
"errors"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules"
package rules
import (
"fmt"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules"
package rules
import (
"fmt"

@ -14,9 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package rules // import "helm.sh/helm/v4/pkg/chart/v2/lint/rules"
package rules
import "testing"
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestValidateNoDeprecations(t *testing.T) {
deprecated := &k8sYamlStruct{
@ -27,10 +31,9 @@ func TestValidateNoDeprecations(t *testing.T) {
if err == nil {
t.Fatal("Expected deprecated extension to be flagged")
}
depErr := err.(deprecatedAPIError)
if depErr.Message == "" {
t.Fatalf("Expected error message to be non-blank: %v", err)
}
var depErr deprecatedAPIError
require.ErrorAs(t, err, &depErr)
require.NotEmptyf(t, depErr.Message, "Expected error message to be non-blank")
if err := validateNoDeprecations(&k8sYamlStruct{
APIVersion: "v1",

@ -24,6 +24,9 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"helm.sh/helm/v4/pkg/chart/common"
chart "helm.sh/helm/v4/pkg/chart/v2"
"helm.sh/helm/v4/pkg/chart/v2/lint/support"
@ -235,10 +238,9 @@ func TestDeprecatedAPIFails(t *testing.T) {
t.Fatalf("Expected 1 lint error, got %d", l)
}
err := linter.Messages[0].Err.(deprecatedAPIError)
if err.Deprecated != "apps/v1beta1 Deployment" {
t.Errorf("Surprised to learn that %q is deprecated", err.Deprecated)
}
var depErr deprecatedAPIError
require.ErrorAs(t, linter.Messages[0].Err, &depErr)
assert.Equalf(t, "apps/v1beta1 Deployment", depErr.Deprecated, "Surprised to learn that %q is deprecated", depErr.Deprecated)
}
const manifest = `apiVersion: v1

@ -20,4 +20,4 @@ Package support contains tools for linting charts.
Linting is the process of testing charts for errors or warnings regarding
formatting, compilation, or standards compliance.
*/
package support // import "helm.sh/helm/v4/pkg/chart/v2/lint/support"
package support

@ -21,6 +21,8 @@ import (
"strconv"
"testing"
"github.com/stretchr/testify/require"
"helm.sh/helm/v4/pkg/chart/common"
chart "helm.sh/helm/v4/pkg/chart/v2"
"helm.sh/helm/v4/pkg/chart/v2/loader"
@ -251,12 +253,8 @@ func TestProcessDependencyImportValues(t *testing.T) {
if err == nil {
t.Error("expect nil value not found but found it")
}
switch xerr := err.(type) {
case common.ErrNoValue:
// We found what we expected
default:
t.Errorf("expected an ErrNoValue but got %q instead", xerr)
}
var xerr common.ErrNoValue
require.ErrorAs(t, err, &xerr, "expected an ErrNoValue")
c = loadChart(t, "testdata/subpop")
if err := processDependencyImportValues(c, true); err != nil {

@ -65,6 +65,26 @@ func AddWaitFlag(cmd *cobra.Command, wait *kube.WaitStrategy) {
cmd.Flags().Lookup("wait").NoOptDefVal = string(kube.StatusWatcherStrategy)
}
// cliDefaultStatusComputeWorkers is the number of concurrent status-compute
// workers the Helm CLI enables by default. This prevents the informer
// notification pipeline from being blocked by slow API calls (e.g. LIST
// ReplicaSets/Pods for Deployments) when many resources are updated
// simultaneously. See https://github.com/fluxcd/cli-utils/pull/20.
//
// SDK consumers (e.g. helm-controller) inherit the zero value and can opt in
// via kube.WithStatusComputeWorkers when they want the same behavior.
const cliDefaultStatusComputeWorkers = 8
// defaultCLIWaitOptions returns the set of WaitOptions the Helm CLI applies
// by default to every wait-enabled command. Keeping these in one place keeps
// behavior consistent across install/upgrade/rollback/uninstall and makes the
// CLI-vs-SDK default asymmetry explicit.
func defaultCLIWaitOptions() []kube.WaitOption {
return []kube.WaitOption{
kube.WithStatusComputeWorkers(cliDefaultStatusComputeWorkers),
}
}
type waitValue kube.WaitStrategy
func newWaitValue(defaultValue kube.WaitStrategy, ws *kube.WaitStrategy) *waitValue {

@ -131,6 +131,7 @@ charts in a repository, use 'helm search'.
func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewInstall(cfg)
client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...)
valueOpts := &values.Options{}
var outfmt output.Format

@ -144,16 +144,10 @@ func TestLoadCLIPlugins(t *testing.T) {
// tests until this is fixed
if runtime.GOOS != "windows" {
if err := pluginCmd.RunE(pluginCmd, tt.args); err != nil {
if tt.code > 0 {
cerr, ok := err.(CommandError)
if !ok {
t.Errorf("Expected %s to return pluginError: got %v(%T)", tt.use, err, err)
}
if cerr.ExitCode != tt.code {
t.Errorf("Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode)
}
} else {
t.Errorf("Error running %s: %+v", tt.use, err)
if assert.Positive(t, tt.code, "Error running %s: %+v", tt.use, err) {
var cerr CommandError
require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError: got %v(%T)", tt.use, err, err)
assert.Equalf(t, tt.code, cerr.ExitCode, "Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode)
}
}
assert.Equal(t, tt.expect, out.String(), "expected output for %q", tt.use)
@ -218,16 +212,10 @@ func TestLoadPluginsWithSpace(t *testing.T) {
// tests until this is fixed
if runtime.GOOS != "windows" {
if err := pp.RunE(pp, tt.args); err != nil {
if tt.code > 0 {
cerr, ok := err.(CommandError)
if !ok {
t.Errorf("Expected %s to return pluginError: got %v(%T)", tt.use, err, err)
}
if cerr.ExitCode != tt.code {
t.Errorf("Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode)
}
} else {
t.Errorf("Error running %s: %+v", tt.use, err)
if assert.Positive(t, tt.code, "Error running %s: %+v", tt.use, err) {
var cerr CommandError
require.ErrorAs(t, err, &cerr, "Expected %s to return pluginError: got %v(%T)", tt.use, err, err)
assert.Equalf(t, tt.code, cerr.ExitCode, "Expected %s to return %d: got %d", tt.use, tt.code, cerr.ExitCode)
}
}
assert.Equal(t, tt.expect, out.String(), "expected output for %s", tt.use)

@ -40,6 +40,7 @@ The tests to be run are defined in the chart that was installed.
func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewReleaseTesting(cfg)
client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...)
outfmt := output.Table
var outputLogs bool
var filter []string

@ -40,6 +40,7 @@ To see revision numbers, run 'helm history RELEASE'.
func newRollbackCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewRollback(cfg)
client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...)
cmd := &cobra.Command{
Use: "rollback <RELEASE> [REVISION]",

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd // import "helm.sh/helm/v4/pkg/cmd"
package cmd
import (
"context"

@ -42,6 +42,7 @@ are fully deleted before the command returns.
func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewUninstall(cfg)
client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...)
cmd := &cobra.Command{
Use: "uninstall RELEASE_NAME [...]",

@ -84,6 +84,7 @@ which can contain sensitive values. To hide Kubernetes Secrets use the
func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewUpgrade(cfg)
client.WaitOptions = append(client.WaitOptions, defaultCLIWaitOptions()...)
valueOpts := &values.Options{}
var outfmt output.Format
var createNamespace bool
@ -139,6 +140,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
instClient.SkipCRDs = client.SkipCRDs
instClient.Timeout = client.Timeout
instClient.WaitStrategy = client.WaitStrategy
instClient.WaitOptions = client.WaitOptions
instClient.WaitForJobs = client.WaitForJobs
instClient.Devel = client.Devel
instClient.Namespace = client.Namespace

@ -21,4 +21,4 @@ When Helm renders templates it does so with additional functions and different
modes (e.g., strict, lint mode). This package handles the helm specific
implementation.
*/
package engine // import "helm.sh/helm/v4/pkg/engine"
package engine

@ -65,4 +65,4 @@ Notable differences from .gitignore:
- The evaluation of escape sequences has not been tested for compatibility
- There is no support for '\!' as a special leading sequence.
*/
package ignore // import "helm.sh/helm/v4/pkg/ignore"
package ignore

@ -167,14 +167,15 @@ func (c *Client) newStatusWatcher(opts ...WaitOption) (*statusWaiter, error) {
waitContext = c.WaitContext
}
sw := &statusWaiter{
restMapper: restMapper,
client: dynamicClient,
ctx: waitContext,
watchUntilReadyCtx: o.watchUntilReadyCtx,
waitCtx: o.waitCtx,
waitWithJobsCtx: o.waitWithJobsCtx,
waitForDeleteCtx: o.waitForDeleteCtx,
readers: o.statusReaders,
restMapper: restMapper,
client: dynamicClient,
ctx: waitContext,
watchUntilReadyCtx: o.watchUntilReadyCtx,
waitCtx: o.waitCtx,
waitWithJobsCtx: o.waitWithJobsCtx,
waitForDeleteCtx: o.waitForDeleteCtx,
readers: o.statusReaders,
statusComputeWorkers: o.statusComputeWorkers,
}
sw.SetLogger(c.Logger().Handler())
return sw, nil
@ -249,7 +250,7 @@ func (c *Client) getKubeClient() (kubernetes.Interface, error) {
// IsReachable tests connectivity to the cluster.
func (c *Client) IsReachable() error {
client, err := c.getKubeClient()
if err == genericclioptions.ErrEmptyConfig {
if errors.Is(err, genericclioptions.ErrEmptyConfig) {
// re-replace kubernetes ErrEmptyConfig error with a friendly error
// moar workarounds for Kubernetes API breaking.
return errors.New("kubernetes cluster unreachable")
@ -949,11 +950,12 @@ func (c *Client) Delete(resources ResourceList, policy metav1.DeletionPropagatio
func isIncompatibleServerError(err error) bool {
// 415: Unsupported media type means we're talking to a server which doesn't
// support server-side apply.
if _, ok := err.(*apierrors.StatusError); !ok {
var sErr *apierrors.StatusError
if !errors.As(err, &sErr) {
// Non-StatusError means the error isn't because the server is incompatible.
return false
}
return err.(*apierrors.StatusError).Status().Code == http.StatusUnsupportedMediaType
return sErr.Status().Code == http.StatusUnsupportedMediaType
}
// isServerSideRetryable checks if an error encountered during server-side apply

@ -72,11 +72,34 @@ func WithKStatusReaders(readers ...engine.StatusReader) WaitOption {
}
}
// WithStatusComputeWorkers sets the number of concurrent goroutines used to
// compute object status per informer. This prevents the informer notification
// pipeline from being blocked by slow API calls (e.g., LIST ReplicaSets/Pods
// for Deployments) when many resources are updated simultaneously.
//
// A value of 0 (the default) keeps the underlying cli-utils behavior, where
// status is computed synchronously on the informer goroutine. Negative values
// are clamped to 0 so callers cannot propagate invalid counts to the
// underlying watcher. SDK consumers (for example helm-controller) inherit
// this conservative default and can opt in explicitly. The Helm CLI passes
// a non-zero value so that `helm install/upgrade/rollback` users get the
// fix for multi-minute waits out of the box.
// See https://github.com/fluxcd/cli-utils/pull/20.
func WithStatusComputeWorkers(n int) WaitOption {
return func(wo *waitOptions) {
if n < 0 {
n = 0
}
wo.statusComputeWorkers = n
}
}
type waitOptions struct {
ctx context.Context
watchUntilReadyCtx context.Context
waitCtx context.Context
waitWithJobsCtx context.Context
waitForDeleteCtx context.Context
statusReaders []engine.StatusReader
ctx context.Context
watchUntilReadyCtx context.Context
waitCtx context.Context
waitWithJobsCtx context.Context
waitForDeleteCtx context.Context
statusReaders []engine.StatusReader
statusComputeWorkers int
}

@ -43,14 +43,15 @@ import (
)
type statusWaiter struct {
client dynamic.Interface
restMapper meta.RESTMapper
ctx context.Context
watchUntilReadyCtx context.Context
waitCtx context.Context
waitWithJobsCtx context.Context
waitForDeleteCtx context.Context
readers []engine.StatusReader
client dynamic.Interface
restMapper meta.RESTMapper
ctx context.Context
watchUntilReadyCtx context.Context
waitCtx context.Context
waitWithJobsCtx context.Context
waitForDeleteCtx context.Context
readers []engine.StatusReader
statusComputeWorkers int
logging.LogHolder
}
@ -82,6 +83,7 @@ func (w *statusWaiter) WatchUntilReady(resourceList ResourceList, timeout time.D
defer cancel()
w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout)
sw := getStatusWatcher(w.client, w.restMapper)
sw.StatusComputeWorkers = w.statusComputeWorkers
jobSR := helmStatusReaders.NewCustomJobStatusReader(w.restMapper)
podSR := helmStatusReaders.NewCustomPodStatusReader(w.restMapper)
// We don't want to wait on any other resources as watchUntilReady is only for Helm hooks.
@ -104,6 +106,7 @@ func (w *statusWaiter) Wait(resourceList ResourceList, timeout time.Duration) er
defer cancel()
w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout)
sw := getStatusWatcher(w.client, w.restMapper)
sw.StatusComputeWorkers = w.statusComputeWorkers
sw.StatusReader = statusreaders.NewStatusReader(w.restMapper, w.readers...)
return w.wait(ctx, resourceList, sw)
}
@ -116,6 +119,7 @@ func (w *statusWaiter) WaitWithJobs(resourceList ResourceList, timeout time.Dura
defer cancel()
w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout)
sw := getStatusWatcher(w.client, w.restMapper)
sw.StatusComputeWorkers = w.statusComputeWorkers
newCustomJobStatusReader := helmStatusReaders.NewCustomJobStatusReader(w.restMapper)
readers := append([]engine.StatusReader(nil), w.readers...)
readers = append(readers, newCustomJobStatusReader)

@ -1293,6 +1293,28 @@ func TestWaitOptionFunctions(t *testing.T) {
WithWaitForDeleteMethodContext(ctx)(opts)
assert.Equal(t, ctx, opts.waitForDeleteCtx)
})
t.Run("WithStatusComputeWorkers sets statusComputeWorkers", func(t *testing.T) {
t.Parallel()
opts := &waitOptions{}
WithStatusComputeWorkers(8)(opts)
assert.Equal(t, 8, opts.statusComputeWorkers)
})
t.Run("WithStatusComputeWorkers clamps negative values to zero", func(t *testing.T) {
t.Parallel()
opts := &waitOptions{}
WithStatusComputeWorkers(-1)(opts)
assert.Equal(t, 0, opts.statusComputeWorkers,
"negative worker counts must not propagate to the underlying watcher")
})
t.Run("waitOptions.statusComputeWorkers defaults to zero", func(t *testing.T) {
t.Parallel()
opts := &waitOptions{}
assert.Equal(t, 0, opts.statusComputeWorkers,
"SDK consumers must opt in to concurrent status computation")
})
}
func TestMethodSpecificContextCancellation(t *testing.T) {

@ -35,4 +35,4 @@ and using `gpg --verify`, `keybase pgp verify`, or similar:
gpg: Signature made Mon Jul 25 17:23:44 2016 MDT using RSA key ID 1FC18762
gpg: Good signature from "Helm Testing (This key should only be used for testing. DO NOT TRUST.) <helm-testing@helm.sh>" [ultimate]
*/
package provenance // import "helm.sh/helm/v4/pkg/provenance"
package provenance

@ -385,11 +385,9 @@ func TestVerify(t *testing.T) {
_, err = signer.Verify(archiveData, tamperedSigData, filepath.Base(testChartfile))
require.Errorf(t, err, "Expected %s to fail.", testTamperedSigBlock)
switch err.(type) {
case pgperrors.SignatureError:
t.Logf("Tampered sig block error: %s (%T)", err, err)
default:
t.Errorf("Expected invalid signature error, got %q (%T)", err, err)
var sErr pgperrors.SignatureError
if assert.ErrorAs(t, err, &sErr, "Expected invalid signature error, got %q (%T)", err, err) {
t.Logf("Tampered sig block error: %s (%T)", sErr, sErr)
}
}

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package registry // import "helm.sh/helm/v4/pkg/registry"
package registry
import (
"bytes"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package registry // import "helm.sh/helm/v4/pkg/registry"
package registry
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package registry // import "helm.sh/helm/v4/pkg/registry"
package registry
import (
"context"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package registry // import "helm.sh/helm/v4/pkg/registry"
package registry
const (
// OCIScheme is the URL scheme for OCI-based requests

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package registry // import "helm.sh/helm/v4/pkg/registry"
package registry
import (
"fmt"

@ -18,6 +18,7 @@ package registry
import (
"bytes"
"errors"
"fmt"
"io"
"log/slog"
@ -126,7 +127,7 @@ func logResponseBody(resp *http.Response) string {
Closer: body,
}
// read the body up to limit+1 to check if the body exceeds the limit
if _, err := io.CopyN(buf, body, payloadSizeLimit+1); err != nil && err != io.EOF {
if _, err := io.CopyN(buf, body, payloadSizeLimit+1); err != nil && !errors.Is(err, io.EOF) {
return fmt.Sprintf(" Error reading response body: %v", err)
}

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/pkg/release/v1/util"
package util
import (
"helm.sh/helm/v4/pkg/release/common"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/pkg/release/v1/util"
package util
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/pkg/release/v1/util"
package util
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/pkg/release/v1/util"
package util
import (
"sort"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package util // import "helm.sh/helm/v4/pkg/release/v1/util"
package util
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package repo // import "helm.sh/helm/v4/pkg/repo/v1"
package repo
import (
"bytes"

@ -421,8 +421,8 @@ func jsonOrYamlUnmarshal(b []byte, i any) error {
// And repository indexes may be generated by older/non-compliant software, which doesn't
// conform to all validations.
func ignoreSkippableChartValidationError(err error) error {
verr, ok := err.(chart.ValidationError)
if !ok {
var verr chart.ValidationError
if !errors.As(err, &verr) {
return err
}

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package repo // import "helm.sh/helm/v4/pkg/repo/v1"
package repo
import (
"fmt"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"context"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"errors"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"testing"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"context"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"sort"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"reflect"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"context"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"fmt"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package driver // import "helm.sh/helm/v4/pkg/storage/driver"
package driver
import (
"bytes"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package storage // import "helm.sh/helm/v4/pkg/storage"
package storage
import (
"errors"

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package storage // import "helm.sh/helm/v4/pkg/storage"
package storage
import (
"context"

@ -238,16 +238,16 @@ func (t *parser) key(data map[string]any, nestedNameLevel int) (reterr error) {
// End of key. Consume =, Get value.
// FIXME: Get value list first
vl, e := t.valList()
switch e {
case nil:
switch {
case e == nil:
set(data, string(k), vl)
return nil
case io.EOF:
case errors.Is(e, io.EOF):
set(data, string(k), "")
return e
case ErrNotList:
case errors.Is(e, ErrNotList):
rs, e := t.val()
if e != nil && e != io.EOF {
if e != nil && !errors.Is(e, io.EOF) {
return e
}
v, e := t.reader(rs)
@ -370,14 +370,14 @@ func (t *parser) listItem(list []any, i, nestedNameLevel int) ([]any, error) {
return list, err
}
vl, e := t.valList()
switch e {
case nil:
switch {
case e == nil:
return setIndex(list, i, vl)
case io.EOF:
case errors.Is(e, io.EOF):
return setIndex(list, i, "")
case ErrNotList:
case errors.Is(e, ErrNotList):
rs, e := t.val()
if e != nil && e != io.EOF {
if e != nil && !errors.Is(e, io.EOF) {
return list, e
}
v, e := t.reader(rs)
@ -476,7 +476,7 @@ func (t *parser) valList() ([]any, error) {
for {
switch rs, last, err := runesUntil(t.sc, stop); {
case err != nil:
if err == io.EOF {
if errors.Is(err, io.EOF) {
err = errors.New("list must terminate with '}'")
}
return list, err

Loading…
Cancel
Save