Merge branch 'main' into cache-index-file

pull/12167/head
Yarden Shoham 7 months ago
commit d9c9fd8796

@ -1,7 +1,24 @@
version: 2
updates:
- # Keep dev-v3 branch dependencies up to date, while Helm v3 is within support
package-ecosystem: "gomod"
target-branch: "dev-v3"
directory: "/"
schedule:
interval: "daily"
groups:
k8s.io:
patterns:
- "k8s.io/api"
- "k8s.io/apiextensions-apiserver"
- "k8s.io/apimachinery"
- "k8s.io/apiserver"
- "k8s.io/cli-runtime"
- "k8s.io/client-go"
- "k8s.io/kubectl"
- package-ecosystem: "gomod"
target-branch: "main"
directory: "/"
schedule:
interval: "daily"
@ -16,6 +33,7 @@ updates:
- "k8s.io/client-go"
- "k8s.io/kubectl"
- package-ecosystem: "github-actions"
target-branch: "main"
directory: "/"
schedule:
interval: "daily"

@ -3,12 +3,14 @@ on:
push:
branches:
- "main"
- "dev-v3"
- "release-**"
pull_request:
branches:
- main
- "main"
- "dev-v3"
permissions:
permissions:
contents: read
jobs:
@ -16,11 +18,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
- name: Setup Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.22.7'
go-version: '1.23'
check-latest: true
- name: Test source headers are present
run: make test-source-headers
- name: Run unit tests

@ -13,10 +13,14 @@ name: "CodeQL"
on:
push:
branches: [ main ]
branches:
- main
- dev-v3
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
branches:
- main
- dev-v3
schedule:
- cron: '29 6 * * 6'
@ -39,7 +43,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

@ -13,13 +13,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
- name: Setup Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: "1.22.7"
go-version: '1.23'
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 #pin@6.1.0
uses: golangci/golangci-lint-action@051d91933864810ecd5e2ea2cfd98f6a5bca5347 #pin@6.3.2
with:
version: v1.58
version: v1.62

@ -6,16 +6,19 @@ on:
schedule:
- cron: "0 0 * * *"
permissions: read-all
jobs:
govulncheck:
name: govulncheck
runs-on: ubuntu-latest
steps:
- name: Setup Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.22.7'
go-version: '1.23'
check-latest: true
- name: govulncheck
uses: golang/govulncheck-action@dd0578b371c987f96d1185abb54344b44352bd58 # pin@1.0.3
uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # pin@1.0.4
with:
go-package: ./...

@ -7,6 +7,8 @@ on:
branches:
- main
permissions: read-all
# Note the only differences between release and canary-release jobs are:
# - only canary passes --overwrite flag
# - the VERSION make variable passed to 'make dist checksum' is expected to
@ -15,17 +17,17 @@ on:
jobs:
release:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
runs-on: ubuntu-latest-16-cores
steps:
- name: Checkout source code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.22.7'
go-version: '1.23'
- name: Run unit tests
run: make test-coverage
@ -72,16 +74,17 @@ jobs:
connection_string: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}
canary-release:
runs-on: ubuntu-latest
runs-on: ubuntu-latest-16-cores
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout source code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
- name: Setup Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # pin@5.3.0
with:
go-version: '1.22.7'
go-version: '1.23'
check-latest: true
- name: Run unit tests
run: make test-coverage

@ -28,7 +28,7 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
@ -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@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
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@87c2b794b9b47a9bec68ae03c01aeb572ffebdb1 # v3.0.14
- 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.'

1
.gitignore vendored

@ -12,3 +12,4 @@ bin/
vendor/
# Ignores charts pulled for dependency build tests
cmd/helm/testdata/testcharts/issue-7233/charts/*
.pre-commit-config.yaml

@ -20,6 +20,26 @@ linters-settings:
gofmt:
simplify: true
goimports:
local-prefixes: helm.sh/helm/v3
local-prefixes: helm.sh/helm/v4
dupl:
threshold: 400
issues:
exclude-rules:
# Helm, and the Go source code itself, sometimes uses these names outside their built-in
# functions. As the Go source code has re-used these names it's ok for Helm to do the same.
# Linting will look for redefinition of built-in id's but we opt-in to the ones we choose to use.
- linters:
- revive
text: "redefines-builtin-id: redefinition of the built-in function append"
- linters:
- revive
text: "redefines-builtin-id: redefinition of the built-in function clear"
- linters:
- revive
text: "redefines-builtin-id: redefinition of the built-in function max"
- linters:
- revive
text: "redefines-builtin-id: redefinition of the built-in function min"
- linters:
- revive
text: "redefines-builtin-id: redefinition of the built-in function new"

@ -5,15 +5,21 @@
# Organizations Using Helm
- [IBM](https://www.ibm.com)
- [Microsoft](https://microsoft.com)
- [Octopus Deploy](https://octopus.com/)
- [New Relic](https://www.newrelic.com)
- [Qovery](https://www.qovery.com/)
- [Samsung SDS](https://www.samsungsds.com/)
- [Softonic](https://hello.softonic.com/)
- [Syself](https://syself.com)
- [Ville de Montreal](https://montreal.ca)
- [Intercept](https://Intercept.cloud)
- [IBM](https://www.ibm.com)
- [InfoCert](https://www.infocert.it/)
- [Intercept](https://Intercept.cloud)
- [Microsoft](https://microsoft.com)
- [New Relic](https://www.newrelic.com)
- [Octopus Deploy](https://octopus.com/)
- [Omnistrate](https://omnistrate.com)
- [Oracle](www.oracle.com)
- [Percona](https://www.percona.com)
- [Qovery](https://www.qovery.com/)
- [Samsung SDS](https://www.samsungsds.com/)
- [Softonic](https://hello.softonic.com/)
- [SyncTune](https://mb-consulting.dev)
- [Syself](https://syself.com)
- [Ville de Montreal](https://montreal.ca)
_This file is part of the CNCF official documentation for projects._

@ -11,6 +11,10 @@ vulnerability_, please email a report to
[cncf-helm-security@lists.cncf.io](mailto:cncf-helm-security@lists.cncf.io). This will give us a
chance to try to fix the issue before it is exploited in the wild.
## Helm v3 and v4
Helm v4 is currently under development on the `main` branch. During the development of Helm v4 and for some time after its released, Helm v3 will continue to be supported and developed on the `dev-v3` branch. Helm v3 will continue to get bug fixes and updates for new Kubernetes releases. Helm v4 is where new features and major changes will happen. For features to be backported to Helm v3, an exception will be needed. Bugs should first be fixed on Helm v4 and then backported to Helm v3.
## Sign Your Work
The sign-off is a simple line at the end of the explanation for a commit. All commits need to be
@ -274,7 +278,7 @@ Like any good open source project, we use Pull Requests (PRs) to track code chan
#### Documentation PRs
Documentation PRs should be made on the docs repo: <https://github.com/helm/helm-www>. Keeping Helm's documentation up to date is highly desirable, and it is recommend all user facing changes. Accurate and helpful documentation is critical for effectively communicating Helm's behavior to a wide audience.
Documentation PRs should be made on the docs repo: <https://github.com/helm/helm-www>. Keeping Helm's documentation up to date is highly desirable, and is recommended for all user facing changes. Accurate and helpful documentation is critical for effectively communicating Helm's behavior to a wide audience.
Small, ad-hoc changes/PRs to Helm which introduce user facing changes, which would benefit from documentation changes, should apply the `docs needed` label. Larger changes associated with a HIP should track docs via that HIP. The `docs needed` label doesn't block PRs, and maintainers/PR reviewers should apply discretion judging in whether the `docs needed` label should be applied.

21
KEYS

@ -1037,3 +1037,24 @@ nk38BkgHg3LHjCbCNEVkSK2TMT69A58iwpY9WUQlphsiz4WBpafSPbv/jSlsm7uK
TNWtbFGBRpJyEg==
=w141
-----END PGP PUBLIC KEY BLOCK-----
pub ed25519 2024-07-09 [SC]
7FEC81FACC7FFB2A010ADD13C2D40F4D8196E874
uid [ultimate] Robert Sirchia (I like turtles.) <rsirchia@outlook.com>
sig 3 C2D40F4D8196E874 2024-07-09 [self-signature]
sub cv25519 2024-07-09 [E]
sig C2D40F4D8196E874 2024-07-09 [self-signature]
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZo2C6xYJKwYBBAHaRw8BAQdA8kCWaI+FlCabcTw8EVeiMkokyWDalgl/Inbn
ACcGN1e0N1JvYmVydCBTaXJjaGlhIChJIGxpa2UgdHVydGxlcy4pIDxyc2lyY2hp
YUBvdXRsb29rLmNvbT6IkwQTFgoAOxYhBH/sgfrMf/sqAQrdE8LUD02Bluh0BQJm
jYLrAhsDBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEMLUD02Bluh0dyYA
/i7RB6m3MXNA8ei7GD8uQVpLfCRgEFsqSS/AzAOu8NGhAQCbw1kWL3AUll7KKtiQ
UE96nhCk+HnkQeVkWYS+MZ1tALg4BGaNgusSCisGAQQBl1UBBQEBB0CCA6Au4krL
YinQq9aAs29fFeRu/ye3PqQuz5jZ2r1ScAMBCAeIeAQYFgoAIBYhBH/sgfrMf/sq
AQrdE8LUD02Bluh0BQJmjYLrAhsMAAoJEMLUD02Bluh0KH4BAMSwEIGkoQl10LN3
K6V08VpFmniENmCDHshXYq0gGiTDAP9FsXl2UtmFU5xuYxH4fRKIxgmxJRAFMWI8
u3Rdu/s+DQ==
=smBO
-----END PGP PUBLIC KEY BLOCK-----

@ -44,7 +44,7 @@ BINARY_VERSION ?= ${GIT_TAG}
# Only set Version if building a tag or VERSION is set
ifneq ($(BINARY_VERSION),)
LDFLAGS += -X helm.sh/helm/v3/internal/version.version=${BINARY_VERSION}
LDFLAGS += -X helm.sh/helm/v4/internal/version.version=${BINARY_VERSION}
endif
VERSION_METADATA = unreleased
@ -53,9 +53,9 @@ ifneq ($(GIT_TAG),)
VERSION_METADATA =
endif
LDFLAGS += -X helm.sh/helm/v3/internal/version.metadata=${VERSION_METADATA}
LDFLAGS += -X helm.sh/helm/v3/internal/version.gitCommit=${GIT_COMMIT}
LDFLAGS += -X helm.sh/helm/v3/internal/version.gitTreeState=${GIT_DIRTY}
LDFLAGS += -X helm.sh/helm/v4/internal/version.metadata=${VERSION_METADATA}
LDFLAGS += -X helm.sh/helm/v4/internal/version.gitCommit=${GIT_COMMIT}
LDFLAGS += -X helm.sh/helm/v4/internal/version.gitTreeState=${GIT_DIRTY}
LDFLAGS += $(EXT_LDFLAGS)
# Define constants based on the client-go version
@ -63,10 +63,10 @@ K8S_MODULES_VER=$(subst ., ,$(subst v,,$(shell go list -f '{{.Version}}' -m k8s.
K8S_MODULES_MAJOR_VER=$(shell echo $$(($(firstword $(K8S_MODULES_VER)) + 1)))
K8S_MODULES_MINOR_VER=$(word 2,$(K8S_MODULES_VER))
LDFLAGS += -X helm.sh/helm/v3/pkg/lint/rules.k8sVersionMajor=$(K8S_MODULES_MAJOR_VER)
LDFLAGS += -X helm.sh/helm/v3/pkg/lint/rules.k8sVersionMinor=$(K8S_MODULES_MINOR_VER)
LDFLAGS += -X helm.sh/helm/v3/pkg/chartutil.k8sVersionMajor=$(K8S_MODULES_MAJOR_VER)
LDFLAGS += -X helm.sh/helm/v3/pkg/chartutil.k8sVersionMinor=$(K8S_MODULES_MINOR_VER)
LDFLAGS += -X helm.sh/helm/v4/pkg/lint/rules.k8sVersionMajor=$(K8S_MODULES_MAJOR_VER)
LDFLAGS += -X helm.sh/helm/v4/pkg/lint/rules.k8sVersionMinor=$(K8S_MODULES_MINOR_VER)
LDFLAGS += -X helm.sh/helm/v4/pkg/chartutil.k8sVersionMajor=$(K8S_MODULES_MAJOR_VER)
LDFLAGS += -X helm.sh/helm/v4/pkg/chartutil.k8sVersionMinor=$(K8S_MODULES_MINOR_VER)
.PHONY: all
all: build
@ -78,7 +78,7 @@ all: build
build: $(BINDIR)/$(BINNAME)
$(BINDIR)/$(BINNAME): $(SRC)
GO111MODULE=on CGO_ENABLED=$(CGO_ENABLED) go build $(GOFLAGS) -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o '$(BINDIR)'/$(BINNAME) ./cmd/helm
CGO_ENABLED=$(CGO_ENABLED) go build $(GOFLAGS) -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o '$(BINDIR)'/$(BINNAME) ./cmd/helm
# ------------------------------------------------------------------------------
# install
@ -104,7 +104,16 @@ test: test-unit
test-unit:
@echo
@echo "==> Running unit tests <=="
GO111MODULE=on go test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS)
go test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS)
@echo
@echo "==> Running unit test(s) with ldflags <=="
# Test to check the deprecation warnings on Kubernetes templates created by `helm create` against the current Kubernetes
# version. Note: The version details are set in var LDFLAGS. To avoid the ldflags impact on other unit tests that are
# based on older versions, this is run separately. When run without the ldflags in the unit test (above) or coverage
# test, it still passes with a false-positive result as the resources shouldnt be deprecated in the older Kubernetes
# version if it only starts failing with the latest.
go test $(GOFLAGS) -run ^TestHelmCreateChart_CheckDeprecatedWarnings$$ ./pkg/lint/ $(TESTFLAGS) -ldflags '$(LDFLAGS)'
.PHONY: test-coverage
test-coverage:
@ -142,7 +151,7 @@ coverage:
.PHONY: format
format: $(GOIMPORTS)
GO111MODULE=on go list -f '{{.Dir}}' ./... | xargs $(GOIMPORTS) -w -local helm.sh/helm
go list -f '{{.Dir}}' ./... | xargs $(GOIMPORTS) -w -local helm.sh/helm
# Generate golden files used in unit tests
.PHONY: gen-test-golden
@ -159,10 +168,10 @@ gen-test-golden: test-unit
# without a go.mod file when downloading the following dependencies
$(GOX):
(cd /; GO111MODULE=on go install github.com/mitchellh/gox@v1.0.2-0.20220701044238-9f712387e2d2)
(cd /; go install github.com/mitchellh/gox@v1.0.2-0.20220701044238-9f712387e2d2)
$(GOIMPORTS):
(cd /; GO111MODULE=on go install golang.org/x/tools/cmd/goimports@latest)
(cd /; go install golang.org/x/tools/cmd/goimports@latest)
# ------------------------------------------------------------------------------
# release
@ -170,7 +179,7 @@ $(GOIMPORTS):
.PHONY: build-cross
build-cross: LDFLAGS += -extldflags "-static"
build-cross: $(GOX)
GOFLAGS="-trimpath" GO111MODULE=on CGO_ENABLED=0 $(GOX) -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/$(BINNAME)" -osarch='$(TARGETS)' $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./cmd/helm
GOFLAGS="-trimpath" CGO_ENABLED=0 $(GOX) -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/$(BINNAME)" -osarch='$(TARGETS)' $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./cmd/helm
.PHONY: dist
dist:

@ -1,15 +1,16 @@
maintainers:
- gjenkins8
- joejulian
- jdolitsky
- marckhouzam
- mattfarina
- robertsirc
- sabre1041
- scottrigby
- technosophos
triage:
- banjoh
- yxxhero
- zonggen
- gjenkins8
- z4ce
emeritus:
- adamreese
@ -17,6 +18,7 @@ emeritus:
- fibonacci1729
- hickeyma
- jascott1
- jdolitsky
- michelleN
- migmartri
- nebril

@ -2,7 +2,7 @@
[![Build Status](https://github.com/helm/helm/workflows/release/badge.svg)](https://github.com/helm/helm/actions?workflow=release)
[![Go Report Card](https://goreportcard.com/badge/github.com/helm/helm)](https://goreportcard.com/report/github.com/helm/helm)
[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/helm.sh/helm/v3)
[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/helm.sh/helm/v4)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3131/badge)](https://bestpractices.coreinfrastructure.org/projects/3131)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/helm/helm/badge)](https://scorecard.dev/viewer/?uri=github.com/helm/helm)
@ -29,6 +29,11 @@ Think of it like apt/yum/homebrew for Kubernetes.
- Charts can be stored on disk, or fetched from remote chart repositories
(like Debian or RedHat packages)
## Helm Development and Stable Versions
Helm v4 is currently under development on the `main` branch. This is unstable and the APIs within the Go SDK and at the command line are changing.
Helm v3 (current stable) is maintained on the `dev-v3` branch. APIs there follow semantic versioning.
## Install
Binary downloads of the Helm client can be found on [the Releases page](https://github.com/helm/helm/releases/latest).
@ -39,8 +44,10 @@ If you want to use a package manager:
- [Homebrew](https://brew.sh/) users can use `brew install helm`.
- [Chocolatey](https://chocolatey.org/) users can use `choco install kubernetes-helm`.
- [Winget](https://learn.microsoft.com/en-us/windows/package-manager/) users can use `winget install Helm.Helm`.
- [Scoop](https://scoop.sh/) users can use `scoop install helm`.
- [Snapcraft](https://snapcraft.io/) users can use `snap install helm --classic`
- [Snapcraft](https://snapcraft.io/) users can use `snap install helm --classic`.
- [Flox](https://flox.dev) users can use `flox install kubernetes-helm`.
To rapidly get Helm up and running, start with the [Quick Start Guide](https://helm.sh/docs/intro/quickstart/).
@ -55,6 +62,8 @@ Get started with the [Quick Start guide](https://helm.sh/docs/intro/quickstart/)
The [Helm roadmap uses GitHub milestones](https://github.com/helm/helm/milestones) to track the progress of the project.
The development of Helm v4 is currently happening on the `main` branch while the development of Helm v3, the stable branch, is happening on the `dev-v3` branch. Changes should be made to the `main` branch prior to being added to the `dev-v3` branch so that all changes are carried along to Helm v4.
## Community, discussion, contribution, and support
You can reach the Helm community and developers via the following channels:

@ -23,7 +23,7 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v4/cmd/helm/require"
)
const completionDesc = `

@ -21,8 +21,8 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/release"
)
// Check if file completion should be performed according to parameter 'shouldBePerformed'

@ -23,10 +23,10 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/helmpath"
)
const createDesc = `

@ -22,11 +22,11 @@ import (
"path/filepath"
"testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v4/internal/test/ensure"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/chart/loader"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/helmpath"
)
func TestCreateCmd(t *testing.T) {

@ -20,9 +20,10 @@ import (
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
const dependencyDesc = `
@ -93,7 +94,7 @@ func newDependencyCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
cmd.AddCommand(newDependencyListCmd(out))
cmd.AddCommand(newDependencyUpdateCmd(cfg, out))
cmd.AddCommand(newDependencyBuildCmd(cfg, out))
cmd.AddCommand(newDependencyBuildCmd(out))
return cmd
}
@ -120,3 +121,16 @@ func newDependencyListCmd(out io.Writer) *cobra.Command {
f.UintVar(&client.ColumnWidth, "max-col-width", 80, "maximum column width for output table")
return cmd
}
func addDependencySubcommandFlags(f *pflag.FlagSet, client *action.Dependency) {
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
f.StringVar(&client.Username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&client.Password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&client.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&client.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.BoolVar(&client.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart download")
f.BoolVar(&client.PlainHTTP, "plain-http", false, "use insecure HTTP connections for the chart download")
f.StringVar(&client.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
}

@ -24,12 +24,12 @@ import (
"github.com/spf13/cobra"
"k8s.io/client-go/util/homedir"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cache"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cache"
"helm.sh/helm/v4/pkg/downloader"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/repo"
)
const dependencyBuildDesc = `
@ -43,7 +43,7 @@ If no lock file is found, 'helm dependency build' will mirror the behavior
of 'helm dependency update'.
`
func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
func newDependencyBuildCmd(out io.Writer) *cobra.Command {
client := action.NewDependency()
cmd := &cobra.Command{
@ -56,6 +56,11 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
if len(args) > 0 {
chartpath = filepath.Clean(args[0])
}
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
var c cache.Cache[*repo.IndexFile] = cache.NewConcurrentMapCache[*repo.IndexFile]()
man := &downloader.Manager{
Out: out,
@ -63,7 +68,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
Keyring: client.Keyring,
SkipUpdate: client.SkipRefresh,
Getters: getter.All(settings),
RegistryClient: cfg.RegistryClient,
RegistryClient: registryClient,
RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug,
@ -72,7 +77,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
if client.Verify {
man.Verify = downloader.VerifyIfPossible
}
err := man.Build()
err = man.Build()
if e, ok := err.(downloader.ErrRepoNotFound); ok {
return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error())
}
@ -81,9 +86,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
}
f := cmd.Flags()
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
addDependencySubcommandFlags(f, client)
return cmd
}

@ -22,10 +22,10 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/provenance"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/provenance"
"helm.sh/helm/v4/pkg/repo"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestDependencyBuildCmd(t *testing.T) {
@ -58,7 +58,7 @@ func TestDependencyBuildCmd(t *testing.T) {
createTestingChart(t, rootDir, chartname, srv.URL())
repoFile := filepath.Join(rootDir, "repositories.yaml")
cmd := fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s", filepath.Join(rootDir, chartname), repoFile, rootDir)
cmd := fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s --plain-http", filepath.Join(rootDir, chartname), repoFile, rootDir)
_, out, err := executeActionCommand(cmd)
// In the first pass, we basically want the same results as an update.
@ -117,7 +117,7 @@ func TestDependencyBuildCmd(t *testing.T) {
t.Errorf("mismatched versions. Expected %q, got %q", "0.1.0", v)
}
skipRefreshCmd := fmt.Sprintf("dependency build '%s' --skip-refresh --repository-config %s --repository-cache %s", filepath.Join(rootDir, chartname), repoFile, rootDir)
skipRefreshCmd := fmt.Sprintf("dependency build '%s' --skip-refresh --repository-config %s --repository-cache %s --plain-http", filepath.Join(rootDir, chartname), repoFile, rootDir)
_, out, err = executeActionCommand(skipRefreshCmd)
// In this pass, we check --skip-refresh option becomes effective.
@ -134,7 +134,7 @@ func TestDependencyBuildCmd(t *testing.T) {
if err := chartutil.SaveDir(c, dir()); err != nil {
t.Fatal(err)
}
cmd = fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s --registry-config %s/config.json",
cmd = fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s --registry-config %s/config.json --plain-http",
dir(ociChartName),
dir("repositories.yaml"),
dir(),

@ -16,17 +16,18 @@ limitations under the License.
package main
import (
"fmt"
"io"
"path/filepath"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cache"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cache"
"helm.sh/helm/v4/pkg/downloader"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/repo"
)
const dependencyUpDesc = `
@ -45,7 +46,7 @@ in the Chart.yaml file, but (b) at the wrong version.
`
// newDependencyUpdateCmd creates a new dependency update command.
func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
func newDependencyUpdateCmd(_ *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewDependency()
cmd := &cobra.Command{
@ -59,6 +60,11 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
if len(args) > 0 {
chartpath = filepath.Clean(args[0])
}
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
// the helm client cli is run as a short-lived process so it's ok to use a simple
// implementation for a strictly growing cache
var c cache.Cache[*repo.IndexFile] = cache.NewConcurrentMapCache[*repo.IndexFile]()
@ -68,7 +74,7 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
Keyring: client.Keyring,
SkipUpdate: client.SkipRefresh,
Getters: getter.All(settings),
RegistryClient: cfg.RegistryClient,
RegistryClient: registryClient,
RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache,
Debug: settings.Debug,
@ -82,9 +88,7 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
}
f := cmd.Flags()
f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
addDependencySubcommandFlags(f, client)
return cmd
}

@ -22,13 +22,13 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/provenance"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/internal/test/ensure"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/provenance"
"helm.sh/helm/v4/pkg/repo"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestDependencyUpdateCmd(t *testing.T) {
@ -67,7 +67,7 @@ func TestDependencyUpdateCmd(t *testing.T) {
}
_, out, err := executeActionCommand(
fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()),
fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --plain-http", dir(chartname), dir("repositories.yaml"), dir()),
)
if err != nil {
t.Logf("Output: %s", out)
@ -110,7 +110,7 @@ func TestDependencyUpdateCmd(t *testing.T) {
t.Fatal(err)
}
_, out, err = executeActionCommand(fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()))
_, out, err = executeActionCommand(fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --plain-http", dir(chartname), dir("repositories.yaml"), dir()))
if err != nil {
t.Logf("Output: %s", out)
t.Fatal(err)
@ -131,7 +131,7 @@ func TestDependencyUpdateCmd(t *testing.T) {
if err := chartutil.SaveDir(c, dir()); err != nil {
t.Fatal(err)
}
cmd := fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --registry-config %s/config.json",
cmd := fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --registry-config %s/config.json --plain-http",
dir(ociChartName),
dir("repositories.yaml"),
dir(),
@ -169,7 +169,7 @@ func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) {
}
createTestingChart(t, dir(), chartname, srv.URL())
_, output, err := executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()))
_, output, err := executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s --plain-http", dir(chartname), dir("repositories.yaml"), dir()))
if err != nil {
t.Logf("Output: %s", output)
t.Fatal(err)
@ -178,7 +178,7 @@ func TestDependencyUpdateCmd_DoNotDeleteOldChartsOnError(t *testing.T) {
// Chart repo is down
srv.Stop()
_, output, err = executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s", dir(chartname), dir("repositories.yaml"), dir()))
_, output, err = executeActionCommand(fmt.Sprintf("dependency update %s --repository-config %s --repository-cache %s --plain-http", dir(chartname), dir("repositories.yaml"), dir()))
if err == nil {
t.Logf("Output: %s", output)
t.Fatal("Expected error, got nil")

@ -28,7 +28,7 @@ import (
"golang.org/x/text/cases"
"golang.org/x/text/language"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v4/cmd/helm/require"
)
const docsDesc = `

@ -23,7 +23,7 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v4/cmd/helm/require"
)
var envHelp = `

@ -28,12 +28,12 @@ import (
"github.com/spf13/pflag"
"k8s.io/klog/v2"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/postrender"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/cli/values"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/postrender"
"helm.sh/helm/v4/pkg/repo"
)
const (

@ -20,9 +20,9 @@ import (
"fmt"
"testing"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/release"
helmtime "helm.sh/helm/v3/pkg/time"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/release"
helmtime "helm.sh/helm/v4/pkg/time"
)
func outputFlagCompletionTest(t *testing.T, cmdName string) {

@ -21,8 +21,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
var getHelp = `

@ -22,9 +22,9 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
)
var getAllHelp = `
@ -58,7 +58,12 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
return tpl(template, data, out)
}
return output.Table.Write(out, &statusPrinter{res, true, false, false, true, false})
return output.Table.Write(out, &statusPrinter{
release: res,
debug: true,
showMetadata: true,
hideNotes: false,
})
},
}
@ -70,7 +75,6 @@ func newGetAllCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}

@ -19,7 +19,7 @@ package main
import (
"testing"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestGetCmd(t *testing.T) {

@ -23,8 +23,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
const getHooksHelp = `

@ -19,7 +19,7 @@ package main
import (
"testing"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestGetHooks(t *testing.T) {

@ -23,8 +23,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
var getManifestHelp = `

@ -19,7 +19,7 @@ package main
import (
"testing"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestGetManifest(t *testing.T) {

@ -22,10 +22,11 @@ import (
"log"
"github.com/spf13/cobra"
k8sLabels "k8s.io/apimachinery/pkg/labels"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
)
type metadataWriter struct {
@ -78,10 +79,13 @@ func (w metadataWriter) WriteTable(out io.Writer) error {
_, _ = fmt.Fprintf(out, "CHART: %v\n", w.metadata.Chart)
_, _ = fmt.Fprintf(out, "VERSION: %v\n", w.metadata.Version)
_, _ = fmt.Fprintf(out, "APP_VERSION: %v\n", w.metadata.AppVersion)
_, _ = fmt.Fprintf(out, "ANNOTATIONS: %v\n", k8sLabels.Set(w.metadata.Annotations).String())
_, _ = fmt.Fprintf(out, "DEPENDENCIES: %v\n", w.metadata.FormattedDepNames())
_, _ = fmt.Fprintf(out, "NAMESPACE: %v\n", w.metadata.Namespace)
_, _ = fmt.Fprintf(out, "REVISION: %v\n", w.metadata.Revision)
_, _ = fmt.Fprintf(out, "STATUS: %v\n", w.metadata.Status)
_, _ = fmt.Fprintf(out, "DEPLOYED_AT: %v\n", w.metadata.DeployedAt)
return nil
}

@ -19,7 +19,7 @@ package main
import (
"testing"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestGetMetadataCmd(t *testing.T) {

@ -23,8 +23,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
var getNotesHelp = `

@ -19,7 +19,7 @@ package main
import (
"testing"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestGetNotesCmd(t *testing.T) {

@ -23,9 +23,9 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
)
var getValuesHelp = `

@ -19,7 +19,7 @@ package main
import (
"testing"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestGetValuesCmd(t *testing.T) {

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main // import "helm.sh/helm/v3/cmd/helm"
package main // import "helm.sh/helm/v4/cmd/helm"
import (
"fmt"
@ -30,12 +30,12 @@ import (
// Import to initialize client auth plugins.
_ "k8s.io/client-go/plugin/pkg/client/auth"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/kube"
kubefake "helm.sh/helm/v3/pkg/kube/fake"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage/driver"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli"
"helm.sh/helm/v4/pkg/kube"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
"helm.sh/helm/v4/pkg/release"
"helm.sh/helm/v4/pkg/storage/driver"
)
var settings = cli.New()

@ -28,15 +28,15 @@ import (
shellwords "github.com/mattn/go-shellwords"
"github.com/spf13/cobra"
"helm.sh/helm/v3/internal/test"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli"
kubefake "helm.sh/helm/v3/pkg/kube/fake"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage"
"helm.sh/helm/v3/pkg/storage/driver"
"helm.sh/helm/v3/pkg/time"
"helm.sh/helm/v4/internal/test"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/cli"
kubefake "helm.sh/helm/v4/pkg/kube/fake"
"helm.sh/helm/v4/pkg/release"
"helm.sh/helm/v4/pkg/storage"
"helm.sh/helm/v4/pkg/storage/driver"
"helm.sh/helm/v4/pkg/time"
)
func testTimestamper() time.Time { return time.Unix(242085845, 0).UTC() }

@ -25,13 +25,13 @@ import (
"github.com/gosuri/uitable"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/releaseutil"
helmtime "helm.sh/helm/v3/pkg/time"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/release"
"helm.sh/helm/v4/pkg/releaseutil"
helmtime "helm.sh/helm/v4/pkg/time"
)
var historyHelp = `
@ -136,7 +136,7 @@ func getHistory(client *action.History, name string) (releaseHistory, error) {
func getReleaseHistory(rls []*release.Release) (history releaseHistory) {
for i := len(rls) - 1; i >= 0; i-- {
r := rls[i]
c := formatChartname(r.Chart)
c := formatChartName(r.Chart)
s := r.Info.Status.String()
v := r.Version
d := r.Info.Description
@ -159,7 +159,7 @@ func getReleaseHistory(rls []*release.Release) (history releaseHistory) {
return history
}
func formatChartname(c *chart.Chart) string {
func formatChartName(c *chart.Chart) string {
if c == nil || c.Metadata == nil {
// This is an edge case that has happened in prod, though we don't
// know how: https://github.com/helm/helm/issues/1347
@ -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
}

@ -20,7 +20,7 @@ import (
"fmt"
"testing"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestHistoryCmd(t *testing.T) {

@ -30,15 +30,15 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/chart/loader"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/cli/values"
"helm.sh/helm/v4/pkg/downloader"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/release"
)
const installDesc = `
@ -141,7 +141,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
},
RunE: func(_ *cobra.Command, args []string) error {
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP)
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
@ -158,7 +158,12 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return errors.Wrap(err, "INSTALLATION FAILED")
}
return outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false, false, client.HideNotes})
return outfmt.Write(out, &statusPrinter{
release: rel,
debug: settings.Debug,
showMetadata: false,
hideNotes: client.HideNotes,
})
},
}
@ -184,7 +189,7 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
f.Lookup("dry-run").NoOptDefVal = "client"
f.BoolVar(&client.Force, "force", false, "force resource updates through a replacement strategy")
f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during install")
f.BoolVar(&client.Replace, "replace", false, "re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production")
f.BoolVar(&client.Replace, "replace", false, "reuse the given name, only if that name is a deleted release which remains in the history. This is unsafe in production")
f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&client.Wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.BoolVar(&client.WaitForJobs, "wait-for-jobs", false, "if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout")
@ -201,6 +206,7 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
f.StringToStringVarP(&client.Labels, "labels", "l", nil, "Labels that would be added to release metadata. Should be divided by comma.")
f.BoolVar(&client.EnableDNS, "enable-dns", false, "enable DNS lookups when rendering templates")
f.BoolVar(&client.HideNotes, "hide-notes", false, "if set, do not show notes in install output. Does not affect presence in chart metadata")
f.BoolVar(&client.TakeOwnership, "take-ownership", false, "if set, install will ignore the check for helm annotations and take ownership of the existing resources")
addValueOptionsFlags(f, valueOpts)
addChartPathOptionsFlags(f, &client.ChartPathOptions)
@ -214,7 +220,6 @@ func addInstallFlags(cmd *cobra.Command, f *pflag.FlagSet, client *action.Instal
}
return compVersionFlag(args[requiredArgs-1], toComplete)
})
if err != nil {
log.Fatal(err)
}

@ -23,7 +23,7 @@ import (
"path/filepath"
"testing"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestInstall(t *testing.T) {
@ -96,12 +96,18 @@ func TestInstall(t *testing.T) {
golden: "output/install-no-args.txt",
wantError: true,
},
// Install, re-use name
// Install, reuse name
{
name: "install and replace release",
cmd: "install aeneas testdata/testcharts/empty --replace",
golden: "output/install-and-replace.txt",
},
// Install, take ownership
{
name: "install and replace release",
cmd: "install aeneas-take-ownership testdata/testcharts/empty --take-ownership",
golden: "output/install-and-take-ownership.txt",
},
// Install, with timeout
{
name: "install with a timeout",

@ -26,11 +26,11 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/lint/support"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/cli/values"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/lint/support"
)
var longLintHelp = `

@ -25,10 +25,10 @@ import (
"github.com/gosuri/uitable"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/release"
)
var listHelp = `
@ -156,7 +156,7 @@ func newReleaseListWriter(releases []*release.Release, timeFormat string, noHead
Namespace: r.Namespace,
Revision: strconv.Itoa(r.Version),
Status: r.Info.Status.String(),
Chart: formatChartname(r.Chart),
Chart: formatChartName(r.Chart),
AppVersion: formatAppVersion(r.Chart),
}

@ -19,9 +19,9 @@ package main
import (
"testing"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/time"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/release"
"helm.sh/helm/v4/pkg/time"
)
func TestListCmd(t *testing.T) {

@ -31,7 +31,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"
"helm.sh/helm/v3/pkg/plugin"
"helm.sh/helm/v4/pkg/plugin"
)
const (
@ -286,7 +286,7 @@ func addPluginCommands(plugin *plugin.Plugin, baseCmd *cobra.Command, cmds *plug
f.BoolP(longs[i], shorts[i], false, "")
} else {
// Create a long flag with the same name as the short flag.
// Not a perfect solution, but its better than ignoring the extra short flags.
// Not a perfect solution, but it's better than ignoring the extra short flags.
f.BoolP(shorts[i], shorts[i], false, "")
}
}

@ -25,12 +25,12 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cache"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cache"
"helm.sh/helm/v4/pkg/cli/values"
"helm.sh/helm/v4/pkg/downloader"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/repo"
)
const packageDesc = `
@ -49,7 +49,7 @@ If '--keyring' is not specified, Helm usually defaults to the public keyring
unless your environment is otherwise configured.
`
func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
func newPackageCmd(out io.Writer) *cobra.Command {
client := action.NewPackage()
valueOpts := &values.Options{}
@ -77,6 +77,12 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return err
}
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
for i := 0; i < len(args); i++ {
path, err := filepath.Abs(args[i])
if err != nil {
@ -94,7 +100,7 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
Keyring: client.Keyring,
Getters: p,
Debug: settings.Debug,
RegistryClient: cfg.RegistryClient,
RegistryClient: registryClient,
RepositoryConfig: settings.RepositoryConfig,
RepositoryCache: settings.RepositoryCache,
IndexFileCache: &c,
@ -123,6 +129,13 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version")
f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.")
f.BoolVarP(&client.DependencyUpdate, "dependency-update", "u", false, `update dependencies from "Chart.yaml" to dir "charts/" before packaging`)
f.StringVar(&client.Username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&client.Password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&client.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&client.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.BoolVar(&client.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart download")
f.BoolVar(&client.PlainHTTP, "plain-http", false, "use insecure HTTP connections for the chart download")
f.StringVar(&client.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
return cmd
}

@ -23,8 +23,8 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/chart/loader"
)
func TestPackage(t *testing.T) {

@ -23,7 +23,7 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/plugin"
"helm.sh/helm/v4/pkg/plugin"
)
const pluginHelp = `
@ -47,19 +47,27 @@ func newPluginCmd(out io.Writer) *cobra.Command {
// runHook will execute a plugin hook.
func runHook(p *plugin.Plugin, event string) error {
hook := p.Metadata.Hooks[event]
if hook == "" {
plugin.SetupPluginEnv(settings, p.Metadata.Name, p.Dir)
cmds := p.Metadata.PlatformHooks[event]
expandArgs := true
if len(cmds) == 0 && len(p.Metadata.Hooks) > 0 {
cmd := p.Metadata.Hooks[event]
if len(cmd) > 0 {
cmds = []plugin.PlatformCommand{{Command: "sh", Args: []string{"-c", cmd}}}
expandArgs = false
}
}
main, argv, err := plugin.PrepareCommands(cmds, expandArgs, []string{})
if err != nil {
return nil
}
prog := exec.Command("sh", "-c", hook)
// TODO make this work on windows
// I think its ... ¯\_(ツ)_/¯
// prog := exec.Command("cmd", "/C", p.Metadata.Hooks.Install())
prog := exec.Command(main, argv...)
debug("running %s hook: %s", event, prog)
plugin.SetupPluginEnv(settings, p.Metadata.Name, p.Dir)
prog.Stdout, prog.Stderr = os.Stdout, os.Stderr
if err := prog.Run(); err != nil {
if eerr, ok := err.(*exec.ExitError); ok {

@ -22,9 +22,9 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/plugin"
"helm.sh/helm/v3/pkg/plugin/installer"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/plugin"
"helm.sh/helm/v4/pkg/plugin/installer"
)
type pluginInstallOptions struct {

@ -22,7 +22,7 @@ import (
"github.com/gosuri/uitable"
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/plugin"
"helm.sh/helm/v4/pkg/plugin"
)
func newPluginListCmd(out io.Writer) *cobra.Command {

@ -26,7 +26,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
)
func TestManuallyProcessArgs(t *testing.T) {

@ -24,7 +24,7 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/plugin"
"helm.sh/helm/v4/pkg/plugin"
)
type pluginUninstallOptions struct {
@ -78,7 +78,7 @@ func (o *pluginUninstallOptions) run(out io.Writer) error {
}
}
if len(errorPlugins) > 0 {
return errors.Errorf(strings.Join(errorPlugins, "\n"))
return errors.New(strings.Join(errorPlugins, "\n"))
}
return nil
}

@ -24,8 +24,8 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/plugin"
"helm.sh/helm/v3/pkg/plugin/installer"
"helm.sh/helm/v4/pkg/plugin"
"helm.sh/helm/v4/pkg/plugin/installer"
)
type pluginUpdateOptions struct {
@ -81,7 +81,7 @@ func (o *pluginUpdateOptions) run(out io.Writer) error {
}
}
if len(errorPlugins) > 0 {
return errors.Errorf(strings.Join(errorPlugins, "\n"))
return errors.New(strings.Join(errorPlugins, "\n"))
}
return nil
}

@ -23,8 +23,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
const pullDesc = `
@ -43,7 +43,7 @@ result in an error, and the chart will not be saved locally.
`
func newPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client := action.NewPullWithOpts(action.WithConfig(cfg))
client := action.NewPull(action.WithConfig(cfg))
cmd := &cobra.Command{
Use: "pull [chart URL | repo/chartname] [...]",
@ -65,7 +65,7 @@ func newPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP)
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}

@ -24,7 +24,7 @@ import (
"path/filepath"
"testing"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestPullCmd(t *testing.T) {
@ -183,22 +183,27 @@ func TestPullCmd(t *testing.T) {
wantError: true,
},
{
name: "Fail fetching OCI chart without version specified",
args: fmt.Sprintf("oci://%s/u/ocitestuser/oci-dependent-chart:0.1.0", ociSrv.RegistryURL),
wantErrorMsg: "Error: --version flag is explicitly required for OCI registries",
wantError: true,
name: "Fetching OCI chart without version option specified",
args: fmt.Sprintf("oci://%s/u/ocitestuser/oci-dependent-chart:0.1.0", ociSrv.RegistryURL),
expectFile: "./oci-dependent-chart-0.1.0.tgz",
},
{
name: "Fail fetching OCI chart without version specified",
args: fmt.Sprintf("oci://%s/u/ocitestuser/oci-dependent-chart:0.1.0 --version 0.1.0", ociSrv.RegistryURL),
wantError: true,
name: "Fetching OCI chart with version specified",
args: fmt.Sprintf("oci://%s/u/ocitestuser/oci-dependent-chart:0.1.0 --version 0.1.0", ociSrv.RegistryURL),
expectFile: "./oci-dependent-chart-0.1.0.tgz",
},
{
name: "Fail fetching OCI chart with version mismatch",
args: fmt.Sprintf("oci://%s/u/ocitestuser/oci-dependent-chart:0.2.0 --version 0.1.0", ociSrv.RegistryURL),
wantErrorMsg: "Error: chart reference and version mismatch: 0.2.0 is not 0.1.0",
wantError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
outdir := srv.Root()
cmd := fmt.Sprintf("fetch %s -d '%s' --repository-config %s --repository-cache %s --registry-config %s",
cmd := fmt.Sprintf("fetch %s -d '%s' --repository-config %s --repository-cache %s --registry-config %s --plain-http",
tt.args,
outdir,
filepath.Join(outdir, "repositories.yaml"),

@ -22,9 +22,9 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/pusher"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/pusher"
)
const pushDesc = `
@ -40,6 +40,8 @@ type registryPushOptions struct {
caFile string
insecureSkipTLSverify bool
plainHTTP bool
password string
username string
}
func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
@ -68,7 +70,10 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return noMoreArgsComp()
},
RunE: func(_ *cobra.Command, args []string) error {
registryClient, err := newRegistryClient(o.certFile, o.keyFile, o.caFile, o.insecureSkipTLSverify, o.plainHTTP)
registryClient, err := newRegistryClient(
o.certFile, o.keyFile, o.caFile, o.insecureSkipTLSverify, o.plainHTTP, o.username, o.password,
)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
@ -96,6 +101,8 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&o.insecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart upload")
f.BoolVar(&o.plainHTTP, "plain-http", false, "use insecure HTTP connections for the chart upload")
f.StringVar(&o.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&o.password, "password", "", "chart repository password where to locate the requested chart")
return cmd
}

@ -20,7 +20,7 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/pkg/action"
)
const registryHelp = `

@ -27,8 +27,8 @@ import (
"github.com/moby/term"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
const registryLoginDesc = `
@ -43,6 +43,7 @@ type registryLoginOptions struct {
keyFile string
caFile string
insecure bool
plainHTTP bool
}
func newRegistryLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
@ -66,7 +67,8 @@ func newRegistryLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Comman
action.WithCertFile(o.certFile),
action.WithKeyFile(o.keyFile),
action.WithCAFile(o.caFile),
action.WithInsecure(o.insecure))
action.WithInsecure(o.insecure),
action.WithPlainHTTPLogin(o.plainHTTP))
},
}
@ -78,6 +80,7 @@ func newRegistryLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Comman
f.StringVar(&o.certFile, "cert-file", "", "identify registry client using this SSL certificate file")
f.StringVar(&o.keyFile, "key-file", "", "identify registry client using this SSL key file")
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&o.plainHTTP, "plain-http", false, "use insecure HTTP connections for the chart upload")
return cmd
}

@ -21,8 +21,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
const registryLogoutDesc = `

@ -25,9 +25,9 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
)
const releaseTestHelp = `
@ -39,7 +39,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)
var outfmt = output.Table
outfmt := output.Table
var outputLogs bool
var filter []string
@ -72,7 +72,12 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
return runErr
}
if err := outfmt.Write(out, &statusPrinter{rel, settings.Debug, false, false, false, client.HideNotes}); err != nil {
if err := outfmt.Write(out, &statusPrinter{
release: rel,
debug: settings.Debug,
showMetadata: false,
hideNotes: client.HideNotes,
}); err != nil {
return err
}

@ -23,7 +23,7 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v4/cmd/helm/require"
)
var repoHelm = `

@ -31,9 +31,9 @@ import (
"golang.org/x/term"
"sigs.k8s.io/yaml"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/repo"
)
// Repositories that have been permanently deleted and no longer work
@ -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")

@ -27,10 +27,10 @@ import (
"sigs.k8s.io/yaml"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/helmpath/xdg"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/helmpath/xdg"
"helm.sh/helm/v4/pkg/repo"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestRepoAddCmd(t *testing.T) {
@ -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)

@ -24,19 +24,21 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/repo"
)
const repoIndexDesc = `
Read the current directory and generate an index file based on the charts found.
Read the current directory, generate an index file based on the charts found
and write the result to 'index.yaml' in the current directory.
This tool is used for creating an 'index.yaml' file for a chart repository. To
set an absolute URL to the charts, use '--url' flag.
To merge the generated index with an existing index file, use the '--merge'
flag. In this case, the charts found in the current directory will be merged
into the existing index, with local charts taking priority over existing charts.
into the index passed in with --merge, with local charts taking priority over
existing charts.
`
type repoIndexOptions struct {

@ -24,7 +24,7 @@ import (
"path/filepath"
"testing"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/pkg/repo"
)
func TestRepoIndexCmd(t *testing.T) {
@ -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

@ -24,9 +24,9 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/repo"
)
func newRepoListCmd(out io.Writer) *cobra.Command {

@ -25,9 +25,9 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/repo"
)
type repoRemoveOptions struct {

@ -24,9 +24,9 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/repo"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestRepoRemove(t *testing.T) {

@ -19,14 +19,15 @@ package main
import (
"fmt"
"io"
"slices"
"sync"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/repo"
)
const updateDesc = `
@ -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)
}

@ -24,10 +24,10 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/internal/test/ensure"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/repo"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestUpdateCmd(t *testing.T) {

@ -24,8 +24,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
const rollbackDesc = `

@ -21,8 +21,8 @@ import (
"reflect"
"testing"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/release"
)
func TestRollbackCmd(t *testing.T) {

@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package main // import "helm.sh/helm/v3/cmd/helm"
package main // import "helm.sh/helm/v4/cmd/helm"
import (
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
@ -29,9 +30,10 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/clientcmd"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/registry"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/internal/tlsutil"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/registry"
"helm.sh/helm/v4/pkg/repo"
)
var globalUsage = `The Kubernetes package manager
@ -153,7 +155,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
flags.ParseErrorsWhitelist.UnknownFlags = true
flags.Parse(args)
registryClient, err := newDefaultRegistryClient(false)
registryClient, err := newDefaultRegistryClient(false, "", "")
if err != nil {
return nil, err
}
@ -167,7 +169,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
newPullCmd(actionConfig, out),
newShowCmd(actionConfig, out),
newLintCmd(out),
newPackageCmd(actionConfig, out),
newPackageCmd(out),
newRepoCmd(out),
newSearchCmd(out),
newVerifyCmd(out),
@ -201,9 +203,6 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
// Find and add plugins
loadPlugins(cmd, out)
// Check permissions on critical files
checkPerms()
// Check for expired repositories
checkForExpiredRepos(settings.RepositoryConfig)
@ -230,7 +229,7 @@ func checkForExpiredRepos(repofile string) {
}
// parse repo file.
// Ignore the error because it is okay for a repo file to be unparseable at this
// Ignore the error because it is okay for a repo file to be unparsable at this
// stage. Later checks will trap the error and respond accordingly.
repoFile, err := repo.LoadFile(repofile)
if err != nil {
@ -258,27 +257,30 @@ func checkForExpiredRepos(repofile string) {
}
func newRegistryClient(certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool) (*registry.Client, error) {
func newRegistryClient(
certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool, username, password string,
) (*registry.Client, error) {
if certFile != "" && keyFile != "" || caFile != "" || insecureSkipTLSverify {
registryClient, err := newRegistryClientWithTLS(certFile, keyFile, caFile, insecureSkipTLSverify)
registryClient, err := newRegistryClientWithTLS(certFile, keyFile, caFile, insecureSkipTLSverify, username, password)
if err != nil {
return nil, err
}
return registryClient, nil
}
registryClient, err := newDefaultRegistryClient(plainHTTP)
registryClient, err := newDefaultRegistryClient(plainHTTP, username, password)
if err != nil {
return nil, err
}
return registryClient, nil
}
func newDefaultRegistryClient(plainHTTP bool) (*registry.Client, error) {
func newDefaultRegistryClient(plainHTTP bool, username, password string) (*registry.Client, error) {
opts := []registry.ClientOption{
registry.ClientOptDebug(settings.Debug),
registry.ClientOptEnableCache(true),
registry.ClientOptWriter(os.Stderr),
registry.ClientOptCredentialsFile(settings.RegistryConfig),
registry.ClientOptBasicAuth(username, password),
}
if plainHTTP {
opts = append(opts, registry.ClientOptPlainHTTP())
@ -292,10 +294,31 @@ func newDefaultRegistryClient(plainHTTP bool) (*registry.Client, error) {
return registryClient, nil
}
func newRegistryClientWithTLS(certFile, keyFile, caFile string, insecureSkipTLSverify bool) (*registry.Client, error) {
func newRegistryClientWithTLS(
certFile, keyFile, caFile string, insecureSkipTLSverify bool, username, password string,
) (*registry.Client, error) {
tlsConf, err := tlsutil.NewTLSConfig(
tlsutil.WithInsecureSkipVerify(insecureSkipTLSverify),
tlsutil.WithCertKeyPairFiles(certFile, keyFile),
tlsutil.WithCAFile(caFile),
)
if err != nil {
return nil, fmt.Errorf("can't create TLS config for client: %w", err)
}
// Create a new registry client
registryClient, err := registry.NewRegistryClientWithTLS(os.Stderr, certFile, keyFile, caFile, insecureSkipTLSverify,
settings.RegistryConfig, settings.Debug,
registryClient, err := registry.NewClient(
registry.ClientOptDebug(settings.Debug),
registry.ClientOptEnableCache(true),
registry.ClientOptWriter(os.Stderr),
registry.ClientOptCredentialsFile(settings.RegistryConfig),
registry.ClientOptHTTPClient(&http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConf,
},
}),
registry.ClientOptBasicAuth(username, password),
)
if err != nil {
return nil, err

@ -21,9 +21,9 @@ import (
"path/filepath"
"testing"
"helm.sh/helm/v3/internal/test/ensure"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/helmpath/xdg"
"helm.sh/helm/v4/internal/test/ensure"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/helmpath/xdg"
)
func TestRootCmd(t *testing.T) {

@ -1,58 +0,0 @@
//go:build !windows
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"os"
"os/user"
"path/filepath"
)
func checkPerms() {
// This function MUST NOT FAIL, as it is just a check for a common permissions problem.
// If for some reason the function hits a stopping condition, it may panic. But only if
// we can be sure that it is panicking because Helm cannot proceed.
kc := settings.KubeConfig
if kc == "" {
kc = os.Getenv("KUBECONFIG")
}
if kc == "" {
u, err := user.Current()
if err != nil {
// No idea where to find KubeConfig, so return silently. Many helm commands
// can proceed happily without a KUBECONFIG, so this is not a fatal error.
return
}
kc = filepath.Join(u.HomeDir, ".kube", "config")
}
fi, err := os.Stat(kc)
if err != nil {
// DO NOT error if no KubeConfig is found. Not all commands require one.
return
}
perm := fi.Mode().Perm()
if perm&0040 > 0 {
warning("Kubernetes configuration file is group-readable. This is insecure. Location: %s", kc)
}
if perm&0004 > 0 {
warning("Kubernetes configuration file is world-readable. This is insecure. Location: %s", kc)
}
}

@ -1,82 +0,0 @@
//go:build !windows
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bytes"
"io"
"os"
"path/filepath"
"strings"
"testing"
)
func checkPermsStderr() (string, error) {
r, w, err := os.Pipe()
if err != nil {
return "", err
}
stderr := os.Stderr
os.Stderr = w
defer func() {
os.Stderr = stderr
}()
checkPerms()
w.Close()
var text bytes.Buffer
io.Copy(&text, r)
return text.String(), nil
}
func TestCheckPerms(t *testing.T) {
tdir := t.TempDir()
tfile := filepath.Join(tdir, "testconfig")
fh, err := os.OpenFile(tfile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0440)
if err != nil {
t.Errorf("Failed to create temp file: %s", err)
}
tconfig := settings.KubeConfig
settings.KubeConfig = tfile
defer func() { settings.KubeConfig = tconfig }()
text, err := checkPermsStderr()
if err != nil {
t.Fatalf("could not read from stderr: %s", err)
}
expectPrefix := "WARNING: Kubernetes configuration file is group-readable. This is insecure. Location:"
if !strings.HasPrefix(text, expectPrefix) {
t.Errorf("Expected to get a warning for group perms. Got %q", text)
}
if err := fh.Chmod(0404); err != nil {
t.Errorf("Could not change mode on file: %s", err)
}
text, err = checkPermsStderr()
if err != nil {
t.Fatalf("could not read from stderr: %s", err)
}
expectPrefix = "WARNING: Kubernetes configuration file is world-readable. This is insecure. Location:"
if !strings.HasPrefix(text, expectPrefix) {
t.Errorf("Expected to get a warning for world perms. Got %q", text)
}
}

@ -31,7 +31,7 @@ import (
"github.com/Masterminds/semver/v3"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/pkg/repo"
)
// Result is a search result.

@ -20,8 +20,8 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/repo"
)
func TestSortScore(t *testing.T) {

@ -25,8 +25,8 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/internal/monocular"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v4/internal/monocular"
"helm.sh/helm/v4/pkg/cli/output"
)
const searchHubDesc = `

@ -30,10 +30,10 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/search"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/repo"
"helm.sh/helm/v4/cmd/helm/search"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/repo"
)
const searchRepoDesc = `
@ -139,7 +139,7 @@ func (o *searchRepoOptions) setupSearchedVersion() {
if o.devel { // search for releases and prereleases (alpha, beta, and release candidate releases).
debug("setting version to >0.0.0-0")
o.version = ">0.0.0-0"
} else { // search only for stable releases, prerelease versions will be skip
} else { // search only for stable releases, prerelease versions will be skipped
debug("setting version to >0.0.0")
o.version = ">0.0.0"
}

@ -23,8 +23,8 @@ import (
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
)
const showDesc = `
@ -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",
@ -226,7 +226,7 @@ func runShow(args []string, client *action.Show) (string, error) {
func addRegistryClient(client *action.Show) error {
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP)
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}

@ -22,7 +22,7 @@ import (
"strings"
"testing"
"helm.sh/helm/v3/pkg/repo/repotest"
"helm.sh/helm/v4/pkg/repo/repotest"
)
func TestShowPreReleaseChart(t *testing.T) {

@ -28,11 +28,11 @@ import (
"k8s.io/kubectl/pkg/cmd/get"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/release"
)
// NOTE: Keep the list of statuses up-to-date with pkg/release/status.go.
@ -43,8 +43,8 @@ The status consists of:
- k8s namespace in which the release lives
- state of the release (can be: unknown, deployed, uninstalled, superseded, failed, uninstalling, pending-install, pending-upgrade or pending-rollback)
- revision of the release
- description of the release (can be completion message or error message, need to enable --show-desc)
- list of resources that this release consists of (need to enable --show-resources)
- description of the release (can be completion message or error message)
- list of resources that this release consists of
- details on last test suite run, if applicable
- additional notes provided by the chart
`
@ -65,7 +65,6 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
return compListReleases(toComplete, args, cfg)
},
RunE: func(_ *cobra.Command, args []string) error {
// When the output format is a table the resources should be fetched
// and displayed as a table. When YAML or JSON the resources will be
// returned. This mirrors the handling in kubectl.
@ -80,7 +79,12 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
// strip chart metadata from the output
rel.Chart = nil
return outfmt.Write(out, &statusPrinter{rel, false, client.ShowDescription, client.ShowResources, false, false})
return outfmt.Write(out, &statusPrinter{
release: rel,
debug: false,
showMetadata: false,
hideNotes: false,
})
},
}
@ -94,26 +98,20 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}
bindOutputFlag(cmd, &outfmt)
f.BoolVar(&client.ShowDescription, "show-desc", false, "if set, display the description message of the named release")
f.BoolVar(&client.ShowResources, "show-resources", false, "if set, display the resources of the named release")
return cmd
}
type statusPrinter struct {
release *release.Release
debug bool
showDescription bool
showResources bool
showMetadata bool
hideNotes bool
release *release.Release
debug bool
showMetadata bool
hideNotes bool
}
func (s statusPrinter) WriteJSON(out io.Writer) error {
@ -140,11 +138,9 @@ func (s statusPrinter) WriteTable(out io.Writer) error {
_, _ = fmt.Fprintf(out, "VERSION: %s\n", s.release.Chart.Metadata.Version)
_, _ = fmt.Fprintf(out, "APP_VERSION: %s\n", s.release.Chart.Metadata.AppVersion)
}
if s.showDescription {
_, _ = fmt.Fprintf(out, "DESCRIPTION: %s\n", s.release.Info.Description)
}
_, _ = fmt.Fprintf(out, "DESCRIPTION: %s\n", s.release.Info.Description)
if s.showResources && s.release.Info.Resources != nil && len(s.release.Info.Resources) > 0 {
if len(s.release.Info.Resources) > 0 {
buf := new(bytes.Buffer)
printFlags := get.NewHumanPrintFlags()
typePrinter, _ := printFlags.ToPrinter("")

@ -20,9 +20,9 @@ import (
"testing"
"time"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/release"
helmtime "helm.sh/helm/v3/pkg/time"
"helm.sh/helm/v4/pkg/chart"
"helm.sh/helm/v4/pkg/release"
helmtime "helm.sh/helm/v4/pkg/time"
)
func TestStatusCmd(t *testing.T) {
@ -46,7 +46,7 @@ func TestStatusCmd(t *testing.T) {
}),
}, {
name: "get status of a deployed release, with desc",
cmd: "status --show-desc flummoxed-chickadee",
cmd: "status flummoxed-chickadee",
golden: "output/status-with-desc.txt",
rels: releasesMockWithStatus(&release.Info{
Status: release.StatusDeployed,
@ -70,7 +70,7 @@ func TestStatusCmd(t *testing.T) {
}),
}, {
name: "get status of a deployed release with resources",
cmd: "status --show-resources flummoxed-chickadee",
cmd: "status flummoxed-chickadee",
golden: "output/status-with-resources.txt",
rels: releasesMockWithStatus(
&release.Info{
@ -79,7 +79,7 @@ func TestStatusCmd(t *testing.T) {
),
}, {
name: "get status of a deployed release with resources in json",
cmd: "status --show-resources flummoxed-chickadee -o json",
cmd: "status flummoxed-chickadee -o json",
golden: "output/status-with-resources.json",
rels: releasesMockWithStatus(
&release.Info{

@ -24,18 +24,19 @@ import (
"path"
"path/filepath"
"regexp"
"slices"
"sort"
"strings"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v4/pkg/release"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/releaseutil"
"helm.sh/helm/v4/cmd/helm/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/chartutil"
"helm.sh/helm/v4/pkg/cli/values"
"helm.sh/helm/v4/pkg/releaseutil"
)
const templateDesc = `
@ -74,7 +75,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
client.InsecureSkipTLSverify, client.PlainHTTP)
client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
if err != nil {
return fmt.Errorf("missing registry client: %w", err)
}
@ -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) {

@ -3,6 +3,7 @@ LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
PARENT NOTES

@ -3,4 +3,5 @@ LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None

@ -1 +1 @@
{"name":"thomas-guide","chart":"foo","version":"0.1.0-beta.1","appVersion":"1.0","namespace":"default","revision":1,"status":"deployed","deployedAt":"1977-09-02T22:04:05Z"}
{"name":"thomas-guide","chart":"foo","version":"0.1.0-beta.1","appVersion":"1.0","annotations":{"category":"web-apps","supported":"true"},"dependencies":[{"name":"cool-plugin","version":"1.0.0","repository":"https://coolplugin.io/charts","condition":"coolPlugin.enabled","enabled":true},{"name":"crds","version":"2.7.1","repository":"","condition":"crds.enabled"}],"namespace":"default","revision":1,"status":"deployed","deployedAt":"1977-09-02T22:04:05Z"}

@ -2,6 +2,8 @@ NAME: thomas-guide
CHART: foo
VERSION: 0.1.0-beta.1
APP_VERSION: 1.0
ANNOTATIONS: category=web-apps,supported=true
DEPENDENCIES: cool-plugin,crds
NAMESPACE: default
REVISION: 1
STATUS: deployed

@ -1,5 +1,18 @@
annotations:
category: web-apps
supported: "true"
appVersion: "1.0"
chart: foo
dependencies:
- condition: coolPlugin.enabled
enabled: true
name: cool-plugin
repository: https://coolplugin.io/charts
version: 1.0.0
- condition: crds.enabled
name: crds
repository: ""
version: 2.7.1
deployedAt: "1977-09-02T22:04:05Z"
name: thomas-guide
namespace: default

@ -6,6 +6,7 @@ REVISION: 1
CHART: foo
VERSION: 0.1.0-beta.1
APP_VERSION: 1.0
DESCRIPTION: Release mock
TEST SUITE: None
USER-SUPPLIED VALUES:
name: value

@ -3,4 +3,5 @@ LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save