Merge remote-tracking branch 'origin/main' into refactor-wait

pull/13604/head
Austin Abro 8 months ago
commit 916aecf1f1
No known key found for this signature in database
GPG Key ID: 92EB5159E403F9D6

@ -20,7 +20,7 @@ jobs:
- name: Checkout source code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
- name: Setup Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # pin@5.2.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.23'
check-latest: true

@ -16,11 +16,11 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
- name: Setup Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # pin@5.2.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.23'
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 #pin@6.1.1
uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae #pin@6.2.0
with:
version: v1.62

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Setup Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # pin@5.2.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.23'
check-latest: true

@ -25,7 +25,7 @@ jobs:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # pin@5.2.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.23'
@ -81,7 +81,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
- name: Setup Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # pin@5.2.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.23'
check-latest: true

@ -55,7 +55,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: SARIF file
path: results.sarif

@ -9,7 +9,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.'

@ -177,22 +177,15 @@ func formatAppVersion(c *chart.Chart) string {
return c.AppVersion()
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
func compListRevisions(_ string, cfg *action.Configuration, releaseName string) ([]string, cobra.ShellCompDirective) {
client := action.NewHistory(cfg)
var revisions []string
if hist, err := client.Run(releaseName); err == nil {
for _, release := range hist {
appVersion := fmt.Sprintf("App: %s", release.Chart.Metadata.AppVersion)
chartDesc := fmt.Sprintf("Chart: %s-%s", release.Chart.Metadata.Name, release.Chart.Metadata.Version)
revisions = append(revisions, fmt.Sprintf("%s\t%s, %s", strconv.Itoa(release.Version), appVersion, chartDesc))
for _, version := range hist {
appVersion := fmt.Sprintf("App: %s", version.Chart.Metadata.AppVersion)
chartDesc := fmt.Sprintf("Chart: %s-%s", version.Chart.Metadata.Name, version.Chart.Metadata.Version)
revisions = append(revisions, fmt.Sprintf("%s\t%s, %s", strconv.Itoa(version.Version), appVersion, chartDesc))
}
return revisions, cobra.ShellCompDirectiveNoFileComp
}

@ -59,9 +59,6 @@ type repoAddOptions struct {
repoFile string
repoCache string
// Deprecated, but cannot be removed until Helm 4
deprecatedNoUpdate bool
}
func newRepoAddCmd(out io.Writer) *cobra.Command {
@ -92,7 +89,6 @@ func newRepoAddCmd(out io.Writer) *cobra.Command {
f.StringVar(&o.password, "password", "", "chart repository password")
f.BoolVarP(&o.passwordFromStdinOpt, "password-stdin", "", false, "read chart repository password from stdin")
f.BoolVar(&o.forceUpdate, "force-update", false, "replace (overwrite) the repo if it already exists")
f.BoolVar(&o.deprecatedNoUpdate, "no-update", false, "Ignored. Formerly, it would disabled forced updates. It is deprecated by force-update.")
f.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&o.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")

@ -93,11 +93,10 @@ func TestRepoAdd(t *testing.T) {
const testRepoName = "test-name"
o := &repoAddOptions{
name: testRepoName,
url: ts.URL(),
forceUpdate: false,
deprecatedNoUpdate: true,
repoFile: repoFile,
name: testRepoName,
url: ts.URL(),
forceUpdate: false,
repoFile: repoFile,
}
os.Setenv(xdg.CacheHomeEnvVar, rootDir)
@ -148,11 +147,10 @@ func TestRepoAddCheckLegalName(t *testing.T) {
repoFile := filepath.Join(t.TempDir(), "repositories.yaml")
o := &repoAddOptions{
name: testRepoName,
url: ts.URL(),
forceUpdate: false,
deprecatedNoUpdate: true,
repoFile: repoFile,
name: testRepoName,
url: ts.URL(),
forceUpdate: false,
repoFile: repoFile,
}
os.Setenv(xdg.CacheHomeEnvVar, rootDir)
@ -204,11 +202,10 @@ func repoAddConcurrent(t *testing.T, testName, repoFile string) {
go func(name string) {
defer wg.Done()
o := &repoAddOptions{
name: name,
url: ts.URL(),
deprecatedNoUpdate: true,
forceUpdate: false,
repoFile: repoFile,
name: name,
url: ts.URL(),
forceUpdate: false,
repoFile: repoFile,
}
if err := o.run(io.Discard); err != nil {
t.Error(err)

@ -162,9 +162,9 @@ func TestRepoIndexCmd(t *testing.T) {
}
}
func linkOrCopy(old, new string) error {
if err := os.Link(old, new); err != nil {
return copyFile(old, new)
func linkOrCopy(source, target string) error {
if err := os.Link(source, target); err != nil {
return copyFile(source, target)
}
return nil

@ -19,6 +19,7 @@ package main
import (
"fmt"
"io"
"slices"
"sync"
"github.com/pkg/errors"
@ -158,10 +159,5 @@ func checkRequestedRepos(requestedRepos []string, validRepos []*repo.Entry) erro
}
func isRepoRequested(repoName string, requestedRepos []string) bool {
for _, requestedRepo := range requestedRepos {
if repoName == requestedRepo {
return true
}
}
return false
return slices.Contains(requestedRepos, repoName)
}

@ -57,7 +57,7 @@ of the CustomResourceDefinition files
`
func newShowCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewShowWithConfig(action.ShowAll, cfg)
client := action.NewShow(action.ShowAll, cfg)
showCommand := &cobra.Command{
Use: "show",

@ -24,6 +24,7 @@ import (
"path"
"path/filepath"
"regexp"
"slices"
"sort"
"strings"
@ -206,12 +207,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
func isTestHook(h *release.Hook) bool {
for _, e := range h.Events {
if e == release.HookTest {
return true
}
}
return false
return slices.Contains(h.Events, release.HookTest)
}
// The following functions (writeToFile, createOrOpenFile, and ensureDirectoryForFile)
@ -219,7 +215,7 @@ func isTestHook(h *release.Hook) bool {
// bug introduced by #8156. As part of the todo to refactor renderResources
// this duplicate code should be removed. It is added here so that the API
// surface area is as minimally impacted as possible in fixing the issue.
func writeToFile(outputDir string, name string, data string, append bool) error {
func writeToFile(outputDir string, name string, data string, appendData bool) error {
outfileName := strings.Join([]string{outputDir, name}, string(filepath.Separator))
err := ensureDirectoryForFile(outfileName)
@ -227,7 +223,7 @@ func writeToFile(outputDir string, name string, data string, append bool) error
return err
}
f, err := createOrOpenFile(outfileName, append)
f, err := createOrOpenFile(outfileName, appendData)
if err != nil {
return err
}
@ -244,8 +240,8 @@ func writeToFile(outputDir string, name string, data string, append bool) error
return nil
}
func createOrOpenFile(filename string, append bool) (*os.File, error) {
if append {
func createOrOpenFile(filename string, appendData bool) (*os.File, error) {
if appendData {
return os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0600)
}
return os.Create(filename)

@ -22,6 +22,18 @@ import (
"testing"
)
func TestTemplateCmdWithToml(t *testing.T) {
tests := []cmdTestCase{
{
name: "check toToml function rendering",
cmd: fmt.Sprintf("template '%s'", "testdata/testcharts/issue-totoml"),
golden: "output/issue-totoml.txt",
},
}
runTestCmd(t, tests)
}
var chartPath = "testdata/testcharts/subchart"
func TestTemplateCmd(t *testing.T) {

@ -0,0 +1,8 @@
---
# Source: issue-totoml/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: issue-totoml
data: |
key = 13

@ -0,0 +1,3 @@
apiVersion: v2
name: issue-totoml
version: 0.1.0

@ -0,0 +1,6 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: issue-totoml
data: |
{{ .Values.global | toToml }}

@ -11,8 +11,8 @@ require (
github.com/Masterminds/squirrel v1.5.4
github.com/Masterminds/vcs v1.13.3
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
github.com/containerd/containerd v1.7.24
github.com/cyphar/filepath-securejoin v0.3.6
github.com/containerd/containerd v1.7.25
github.com/cyphar/filepath-securejoin v0.4.0
github.com/distribution/distribution/v3 v3.0.0-rc.2
github.com/evanphx/json-patch v5.9.0+incompatible
github.com/foxcpp/go-mockdns v1.1.0
@ -37,14 +37,14 @@ require (
golang.org/x/crypto v0.32.0
golang.org/x/term v0.28.0
golang.org/x/text v0.21.0
k8s.io/api v0.32.0
k8s.io/apiextensions-apiserver v0.32.0
k8s.io/apimachinery v0.32.0
k8s.io/apiserver v0.32.0
k8s.io/cli-runtime v0.32.0
k8s.io/client-go v0.32.0
k8s.io/api v0.32.1
k8s.io/apiextensions-apiserver v0.32.1
k8s.io/apimachinery v0.32.1
k8s.io/apiserver v0.32.1
k8s.io/cli-runtime v0.32.1
k8s.io/client-go v0.32.1
k8s.io/klog/v2 v2.130.1
k8s.io/kubectl v0.32.0
k8s.io/kubectl v0.32.1
oras.land/oras-go v1.2.6
sigs.k8s.io/cli-utils v0.37.2
sigs.k8s.io/controller-runtime v0.18.4
@ -178,12 +178,12 @@ require (
google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect
google.golang.org/grpc v1.68.0 // indirect
google.golang.org/protobuf v1.35.1 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.32.0 // indirect
k8s.io/component-base v0.32.1 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect

@ -54,10 +54,10 @@ github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNS
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/containerd v1.7.24 h1:zxszGrGjrra1yYJW/6rhm9cJ1ZQ8rkKBR48brqsa7nA=
github.com/containerd/containerd v1.7.24/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/containerd v1.7.25 h1:khEQOAXOEJalRO228yzVsuASLH42vT7DIo9Ss+9SMFQ=
github.com/containerd/containerd v1.7.25/go.mod h1:tWfHzVI0azhw4CT2vaIjsb2CoV4LJ9PrMPaULAr21Ok=
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
@ -71,8 +71,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/cyphar/filepath-securejoin v0.4.0 h1:PioTG9TBRSApBpYGnDU8HC+miIsX8vitBH9LGNNMoLQ=
github.com/cyphar/filepath-securejoin v0.4.0/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@ -541,8 +541,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
@ -559,26 +559,26 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0=
k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw=
k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs=
k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag=
k8s.io/cli-runtime v0.32.0 h1:dP+OZqs7zHPpGQMCGAhectbHU2SNCuZtIimRKTv2T1c=
k8s.io/cli-runtime v0.32.0/go.mod h1:Mai8ht2+esoDRK5hr861KRy6z0zHsSTYttNVJXgP3YQ=
k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8=
k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8=
k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU=
k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM=
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apiserver v0.32.1 h1:oo0OozRos66WFq87Zc5tclUX2r0mymoVHRq8JmR7Aak=
k8s.io/apiserver v0.32.1/go.mod h1:UcB9tWjBY7aryeI5zAgzVJB/6k7E97bkr1RgqDz0jPw=
k8s.io/cli-runtime v0.32.1 h1:19nwZPlYGJPUDbhAxDIS2/oydCikvKMHsxroKNGA2mM=
k8s.io/cli-runtime v0.32.1/go.mod h1:NJPbeadVFnV2E7B7vF+FvU09mpwYlZCu8PqjzfuOnkY=
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
k8s.io/component-base v0.32.1 h1:/5IfJ0dHIKBWysGV0yKTFfacZ5yNV1sulPh3ilJjRZk=
k8s.io/component-base v0.32.1/go.mod h1:j1iMMHi/sqAHeG5z+O9BFNCF698a1u0186zkjMZQ28w=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
k8s.io/kubectl v0.32.0 h1:rpxl+ng9qeG79YA4Em9tLSfX0G8W0vfaiPVrc/WR7Xw=
k8s.io/kubectl v0.32.0/go.mod h1:qIjSX+QgPQUgdy8ps6eKsYNF+YmFOAO3WygfucIqFiE=
k8s.io/kubectl v0.32.1 h1:/btLtXLQUU1rWx8AEvX9jrb9LaI6yeezt3sFALhB8M8=
k8s.io/kubectl v0.32.1/go.mod h1:sezNuyWi1STk4ZNPVRIFfgjqMI6XMf+oCVLjZen/pFQ=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk=

@ -108,12 +108,12 @@ func checkMarks(t *testing.T, report bool) {
}
// Assumes that each node name is unique. Good enough for a test.
// If clear is true, any incoming error is cleared before return. The errors
// are always accumulated, though.
func mark(info os.FileInfo, err error, errors *[]error, clear bool) error {
// If clearIncomingError is true, any incoming error is cleared before
// return. The errors are always accumulated, though.
func mark(info os.FileInfo, err error, errors *[]error, clearIncomingError bool) error {
if err != nil {
*errors = append(*errors, err)
if clear {
if clearIncomingError {
return nil
}
return err
@ -130,9 +130,8 @@ func mark(info os.FileInfo, err error, errors *[]error, clear bool) error {
func TestWalk(t *testing.T) {
makeTree(t)
errors := make([]error, 0, 10)
clear := true
markFn := func(_ string, info os.FileInfo, err error) error {
return mark(info, err, &errors, clear)
return mark(info, err, &errors, true)
}
// Expect no errors.
err := Walk(tree.name, markFn)

@ -233,21 +233,25 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
// Check reachability of cluster unless in client-only mode (e.g. `helm template` without `--validate`)
if !i.ClientOnly {
if err := i.cfg.KubeClient.IsReachable(); err != nil {
return nil, err
i.cfg.Log(fmt.Sprintf("ERROR: Cluster reachability check failed: %v", err))
return nil, errors.Wrap(err, "cluster reachability check failed")
}
}
// HideSecret must be used with dry run. Otherwise, return an error.
if !i.isDryRun() && i.HideSecret {
i.cfg.Log("ERROR: Hiding Kubernetes secrets requires a dry-run mode")
return nil, errors.New("Hiding Kubernetes secrets requires a dry-run mode")
}
if err := i.availableName(); err != nil {
return nil, err
i.cfg.Log(fmt.Sprintf("ERROR: Release name check failed: %v", err))
return nil, errors.Wrap(err, "release name check failed")
}
if err := chartutil.ProcessDependencies(chrt, vals); err != nil {
return nil, err
i.cfg.Log(fmt.Sprintf("ERROR: Processing chart dependencies failed: %v", err))
return nil, errors.Wrap(err, "chart dependencies processing failed")
}
var interactWithRemote bool
@ -598,8 +602,8 @@ func (i *Install) replaceRelease(rel *release.Release) error {
return i.recordRelease(last)
}
// write the <data> to <output-dir>/<name>. <append> controls if the file is created or content will be appended
func writeToFile(outputDir string, name string, data string, append bool) error {
// write the <data> to <output-dir>/<name>. <appendData> controls if the file is created or content will be appended
func writeToFile(outputDir string, name string, data string, appendData bool) error {
outfileName := strings.Join([]string{outputDir, name}, string(filepath.Separator))
err := ensureDirectoryForFile(outfileName)
@ -607,7 +611,7 @@ func writeToFile(outputDir string, name string, data string, append bool) error
return err
}
f, err := createOrOpenFile(outfileName, append)
f, err := createOrOpenFile(outfileName, appendData)
if err != nil {
return err
}
@ -624,8 +628,8 @@ func writeToFile(outputDir string, name string, data string, append bool) error
return nil
}
func createOrOpenFile(filename string, append bool) (*os.File, error) {
if append {
func createOrOpenFile(filename string, appendData bool) (*os.File, error) {
if appendData {
return os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0600)
}
return os.Create(filename)

@ -65,16 +65,7 @@ type Show struct {
}
// NewShow creates a new Show object with the given configuration.
// Deprecated: Use NewShowWithConfig
// TODO Helm 4: Fold NewShowWithConfig back into NewShow
func NewShow(output ShowOutputFormat) *Show {
return &Show{
OutputFormat: output,
}
}
// NewShowWithConfig creates a new Show object with the given configuration.
func NewShowWithConfig(output ShowOutputFormat, cfg *Configuration) *Show {
func NewShow(output ShowOutputFormat, cfg *Configuration) *Show {
sh := &Show{
OutputFormat: output,
}

@ -24,7 +24,7 @@ import (
func TestShow(t *testing.T) {
config := actionConfigFixture(t)
client := NewShowWithConfig(ShowAll, config)
client := NewShow(ShowAll, config)
client.chart = &chart.Chart{
Metadata: &chart.Metadata{Name: "alpine"},
Files: []*chart.File{
@ -65,7 +65,8 @@ bar
}
func TestShowNoValues(t *testing.T) {
client := NewShow(ShowAll)
config := actionConfigFixture(t)
client := NewShow(ShowAll, config)
client.chart = new(chart.Chart)
// Regression tests for missing values. See issue #1024.
@ -81,7 +82,8 @@ func TestShowNoValues(t *testing.T) {
}
func TestShowValuesByJsonPathFormat(t *testing.T) {
client := NewShow(ShowValues)
config := actionConfigFixture(t)
client := NewShow(ShowValues, config)
client.JSONPathTemplate = "{$.nestedKey.simpleKey}"
client.chart = buildChart(withSampleValues())
output, err := client.Run("")
@ -95,7 +97,8 @@ func TestShowValuesByJsonPathFormat(t *testing.T) {
}
func TestShowCRDs(t *testing.T) {
client := NewShow(ShowCRDs)
config := actionConfigFixture(t)
client := NewShow(ShowCRDs, config)
client.chart = &chart.Chart{
Metadata: &chart.Metadata{Name: "alpine"},
Files: []*chart.File{
@ -123,7 +126,8 @@ bar
}
func TestShowNoReadme(t *testing.T) {
client := NewShow(ShowAll)
config := actionConfigFixture(t)
client := NewShow(ShowAll, config)
client.chart = &chart.Chart{
Metadata: &chart.Metadata{Name: "alpine"},
Files: []*chart.File{

@ -104,7 +104,7 @@ type Upgrade struct {
// Description is the description of this operation
Description string
Labels map[string]string
// PostRender is an optional post-renderer
// PostRenderer is an optional post-renderer
//
// If this is non-nil, then after templates are rendered, they will be sent to the
// post renderer before sending to the Kubernetes API server.

@ -18,6 +18,7 @@ package loader
import (
"bytes"
"encoding/json"
"log"
"os"
"path/filepath"
@ -104,7 +105,10 @@ func LoadFiles(files []*BufferedFile) (*chart.Chart, error) {
}
case f.Name == "values.yaml":
c.Values = make(map[string]interface{})
if err := yaml.Unmarshal(f.Data, &c.Values); err != nil {
if err := yaml.Unmarshal(f.Data, &c.Values, func(d *json.Decoder) *json.Decoder {
d.UseNumber()
return d
}); err != nil {
return c, errors.Wrap(err, "cannot load values.yaml")
}
case f.Name == "values.schema.json":

@ -237,6 +237,9 @@ func coalesceValues(printf printFn, c *chart.Chart, v map[string]interface{}, pr
printf("warning: skipped value for %s.%s: Not a table.", subPrefix, key)
}
} else {
// If the key is a child chart, coalesce tables with Merge set to true
merge := childChartMergeTrue(c, key, merge)
// Because v has higher precedence than nv, dest values override src
// values.
coalesceTablesFullKey(printf, dest, src, concatPrefix(subPrefix, key), merge)
@ -249,6 +252,15 @@ func coalesceValues(printf printFn, c *chart.Chart, v map[string]interface{}, pr
}
}
func childChartMergeTrue(chrt *chart.Chart, key string, merge bool) bool {
for _, subchart := range chrt.Dependencies() {
if subchart.Name() == key {
return true
}
}
return merge
}
// CoalesceTables merges a source map into a destination map.
//
// dest is considered authoritative.

@ -44,18 +44,21 @@ global:
boat: true
pequod:
boat: null
global:
name: Stinky
harpooner: Tashtego
nested:
boat: false
sail: true
foo2: null
ahab:
scope: whale
boat: null
nested:
foo: true
bar: null
boat: null
object: null
`)
func withDeps(c *chart.Chart, deps ...*chart.Chart) *chart.Chart {
@ -82,6 +85,13 @@ func TestCoalesceValues(t *testing.T) {
"global": map[string]interface{}{
"nested2": map[string]interface{}{"l0": "moby"},
},
"pequod": map[string]interface{}{
"boat": "maybe",
"ahab": map[string]interface{}{
"boat": "maybe",
"nested": map[string]interface{}{"boat": "maybe"},
},
},
},
},
withDeps(&chart.Chart{
@ -92,19 +102,25 @@ func TestCoalesceValues(t *testing.T) {
"global": map[string]interface{}{
"nested2": map[string]interface{}{"l1": "pequod"},
},
"boat": false,
"ahab": map[string]interface{}{
"boat": false,
"nested": map[string]interface{}{"boat": false},
},
},
},
&chart.Chart{
Metadata: &chart.Metadata{Name: "ahab"},
Values: map[string]interface{}{
"global": map[string]interface{}{
"nested": map[string]interface{}{"foo": "bar"},
"nested": map[string]interface{}{"foo": "bar", "foo2": "bar2"},
"nested2": map[string]interface{}{"l2": "ahab"},
},
"scope": "ahab",
"name": "ahab",
"boat": true,
"nested": map[string]interface{}{"foo": false, "bar": true},
"nested": map[string]interface{}{"foo": false, "boat": true},
"object": map[string]interface{}{"foo": "bar"},
},
},
),
@ -155,6 +171,7 @@ func TestCoalesceValues(t *testing.T) {
{"{{.pequod.ahab.nested.foo}}", "true"},
{"{{.pequod.ahab.global.name}}", "Ishmael"},
{"{{.pequod.ahab.global.nested.foo}}", "bar"},
{"{{.pequod.ahab.global.nested.foo2}}", "<no value>"},
{"{{.pequod.ahab.global.subject}}", "Queequeg"},
{"{{.pequod.ahab.global.harpooner}}", "Tashtego"},
{"{{.pequod.global.name}}", "Ishmael"},
@ -200,13 +217,22 @@ func TestCoalesceValues(t *testing.T) {
t.Error("Expected nested boat key to be removed, still present")
}
subchart := v["pequod"].(map[string]interface{})["ahab"].(map[string]interface{})
subchart := v["pequod"].(map[string]interface{})
if _, ok := subchart["boat"]; ok {
t.Error("Expected subchart boat key to be removed, still present")
}
if _, ok := subchart["nested"].(map[string]interface{})["bar"]; ok {
t.Error("Expected subchart nested bar key to be removed, still present")
subsubchart := subchart["ahab"].(map[string]interface{})
if _, ok := subsubchart["boat"]; ok {
t.Error("Expected sub-subchart ahab boat key to be removed, still present")
}
if _, ok := subsubchart["nested"].(map[string]interface{})["boat"]; ok {
t.Error("Expected sub-subchart nested boat key to be removed, still present")
}
if _, ok := subsubchart["object"]; ok {
t.Error("Expected sub-subchart object map to be removed, still present")
}
// CoalesceValues should not mutate the passed arguments

@ -15,6 +15,7 @@ limitations under the License.
package chartutil
import (
"encoding/json"
"os"
"path/filepath"
"sort"
@ -237,6 +238,20 @@ func TestProcessDependencyImportValues(t *testing.T) {
if b := strconv.FormatBool(pv); b != vv {
t.Errorf("failed to match imported bool value %v with expected %v for key %q", b, vv, kk)
}
case json.Number:
if fv, err := pv.Float64(); err == nil {
if sfv := strconv.FormatFloat(fv, 'f', -1, 64); sfv != vv {
t.Errorf("failed to match imported float value %v with expected %v for key %q", sfv, vv, kk)
}
}
if iv, err := pv.Int64(); err == nil {
if siv := strconv.FormatInt(iv, 10); siv != vv {
t.Errorf("failed to match imported int value %v with expected %v for key %q", siv, vv, kk)
}
}
if pv.String() != vv {
t.Errorf("failed to match imported string value %q with expected %q for key %q", pv, vv, kk)
}
default:
if pv != vv {
t.Errorf("failed to match imported string value %q with expected %q for key %q", pv, vv, kk)
@ -309,6 +324,10 @@ func TestProcessDependencyImportValuesMultiLevelPrecedence(t *testing.T) {
if s := strconv.FormatFloat(pv, 'f', -1, 64); s != vv {
t.Errorf("failed to match imported float value %v with expected %v", s, vv)
}
case json.Number:
if pv.String() != vv {
t.Errorf("failed to match imported string value %q with expected %q", pv, vv)
}
default:
if pv != vv {
t.Errorf("failed to match imported string value %q with expected %q", pv, vv)

@ -52,6 +52,9 @@ func Expand(dir string, r io.Reader) error {
}
// Find the base directory
// The directory needs to be cleaned prior to passing to SecureJoin or the location may end up
// being wrong or returning an error. This was introduced in v0.4.0.
dir = filepath.Clean(dir)
chartdir, err := securejoin.SecureJoin(dir, chartName)
if err != nil {
return err

@ -17,6 +17,7 @@ limitations under the License.
package chartutil
import (
"encoding/json"
"fmt"
"io"
"os"
@ -105,7 +106,10 @@ func tableLookup(v Values, simple string) (Values, error) {
// ReadValues will parse YAML byte data into a Values.
func ReadValues(data []byte) (vals Values, err error) {
err = yaml.Unmarshal(data, &vals)
err = yaml.Unmarshal(data, &vals, func(d *json.Decoder) *json.Decoder {
d.UseNumber()
return d
})
if len(vals) == 0 {
vals = Values{}
}

@ -81,5 +81,5 @@ func (r ResourceList) Intersect(rs ResourceList) ResourceList {
// isMatchingInfo returns true if infos match on Name and GroupVersionKind.
func isMatchingInfo(a, b *resource.Info) bool {
return a.Name == b.Name && a.Namespace == b.Namespace && a.Mapping.GroupVersionKind.Kind == b.Mapping.GroupVersionKind.Kind
return a.Name == b.Name && a.Namespace == b.Namespace && a.Mapping.GroupVersionKind.Kind == b.Mapping.GroupVersionKind.Kind && a.Mapping.GroupVersionKind.Group == b.Mapping.GroupVersionKind.Group
}

@ -73,16 +73,16 @@ func validateNoDeprecations(resource *K8sYamlStruct, kubeVersion *chartutil.Kube
return err
}
maj, err := strconv.Atoi(majorVersion)
major, err := strconv.Atoi(majorVersion)
if err != nil {
return err
}
min, err := strconv.Atoi(minorVersion)
minor, err := strconv.Atoi(minorVersion)
if err != nil {
return err
}
if !deprecation.IsDeprecated(runtimeObject, maj, min) {
if !deprecation.IsDeprecated(runtimeObject, major, minor) {
return nil
}
gvk := fmt.Sprintf("%s %s", resource.APIVersion, resource.Kind)

@ -206,6 +206,9 @@ func cleanJoin(root, dest string) (string, error) {
}
// SecureJoin will do some cleaning, as well as some rudimentary checking of symlinks.
// The directory needs to be cleaned prior to passing to SecureJoin or the location may end up
// being wrong or returning an error. This was introduced in v0.4.0.
root = filepath.Clean(root)
newpath, err := securejoin.SecureJoin(root, dest)
if err != nil {
return "", err

@ -163,7 +163,7 @@ annotations:
return ociAnnotations
}
// getChartOCIAnnotations will generate OCI annotations from the provided chart
// generateChartOCIAnnotations will generate OCI annotations from the provided chart
func generateChartOCIAnnotations(meta *chart.Metadata, creationTime string) map[string]string {
chartOCIAnnotations := map[string]string{}

@ -80,7 +80,7 @@ func tsFixtureMemory(t *testing.T) *Memory {
return mem
}
// newTestFixture initializes a MockConfigMapsInterface.
// newTestFixtureCfgMaps initializes a MockConfigMapsInterface.
// ConfigMaps are created for each release provided.
func newTestFixtureCfgMaps(t *testing.T, releases ...*rspb.Release) *ConfigMaps {
var mock MockConfigMapsInterface

@ -161,15 +161,15 @@ func (s *Storage) History(name string) ([]*rspb.Release, error) {
//
// We allow max to be set explicitly so that calling functions can "make space"
// for the new records they are going to write.
func (s *Storage) removeLeastRecent(name string, max int) error {
if max < 0 {
func (s *Storage) removeLeastRecent(name string, maximum int) error {
if maximum < 0 {
return nil
}
h, err := s.History(name)
if err != nil {
return err
}
if len(h) <= max {
if len(h) <= maximum {
return nil
}
@ -183,8 +183,8 @@ func (s *Storage) removeLeastRecent(name string, max int) error {
var toDelete []*rspb.Release
for _, rel := range h {
// once we have enough releases to delete to reach the max, stop
if len(h)-len(toDelete) == max {
// once we have enough releases to delete to reach the maximum, stop
if len(h)-len(toDelete) == maximum {
break
}
if lastDeployed != nil {

@ -30,7 +30,7 @@ import (
var emptyString = `""`
// Time is a convenience wrapper around stdlib time, but with different
// marshalling and unmarshaling for zero values
// marshalling and unmarshalling for zero values
type Time struct {
time.Time
}
@ -70,8 +70,8 @@ func ParseInLocation(layout, value string, loc *time.Location) (Time, error) {
return Time{Time: t}, err
}
func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Time {
return Time{Time: time.Date(year, month, day, hour, min, sec, nsec, loc)}
func Date(year int, month time.Month, day, hour, minute, second, nanoSecond int, loc *time.Location) Time {
return Time{Time: time.Date(year, month, day, hour, minute, second, nanoSecond, loc)}
}
func Unix(sec int64, nsec int64) Time { return Time{Time: time.Unix(sec, nsec)} }

Loading…
Cancel
Save