mirror of
https://github.com/helm/helm.git
synced 2026-08-09 09:33:14 +00:00
fix: pass registry client to downloader.Manager in upgrade
`helm upgrade --dependency-update` built its downloader.Manager without a RegistryClient, unlike the identical literals in install, dependency update, and dependency build. Resolving an OCI chart dependency whose version is a range then dereferenced a nil *registry.Client in registry.(*Client).Tags, panicking the process. Pass the registry client already constructed for the command, matching install. Add a regression test that runs `upgrade --dependency-update` against a chart with an unresolved OCI dependency and asserts the command returns an error instead of panicking. Signed-off-by: Gates Wang <9372086+SetagGnaw@users.noreply.github.com>
This commit is contained in:
@@ -226,6 +226,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
|
||||
ContentCache: settings.ContentCache,
|
||||
Debug: settings.Debug,
|
||||
SourceDateEpoch: sourceDateEpoch,
|
||||
RegistryClient: registryClient,
|
||||
}
|
||||
if err := man.Update(); err != nil {
|
||||
return err
|
||||
|
||||
@@ -18,6 +18,8 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -193,6 +195,64 @@ func TestUpgradeCmd(t *testing.T) {
|
||||
runTestCmd(t, tests)
|
||||
}
|
||||
|
||||
// TestUpgradeDependencyUpdateOCINoPanic is a regression test for a nil-pointer
|
||||
// panic in `helm upgrade --dependency-update` when a chart declares an OCI
|
||||
// dependency. The upgrade command built its downloader.Manager without a
|
||||
// RegistryClient (unlike install, dependency update, and dependency build), so
|
||||
// resolving an OCI dependency dereferenced a nil *registry.Client. The command
|
||||
// must now return a graceful error instead of panicking.
|
||||
func TestUpgradeDependencyUpdateOCINoPanic(t *testing.T) {
|
||||
defer resetEnv()()
|
||||
|
||||
// A stub registry that answers the API-version ping but rejects the tag
|
||||
// lookup, so OCI dependency resolution fails fast and hermetically instead
|
||||
// of reaching a real registry.
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Docker-Distribution-API-Version", "registry/2.0")
|
||||
if r.URL.Path == "/v2/" {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
// A chart with an unresolved OCI dependency forces --dependency-update into
|
||||
// the tag-lookup path that previously panicked: the version is a range (an
|
||||
// explicit version would skip the lookup) and the dependency is not present
|
||||
// under charts/.
|
||||
tmp := t.TempDir()
|
||||
parent := &chart.Chart{
|
||||
Metadata: &chart.Metadata{
|
||||
APIVersion: chart.APIVersionV2,
|
||||
Name: "oci-parent",
|
||||
Version: "0.1.0",
|
||||
Dependencies: []*chart.Dependency{{
|
||||
Name: "subchart",
|
||||
Repository: fmt.Sprintf("oci://%s/charts", srv.Listener.Addr()),
|
||||
Version: "^1.0.0",
|
||||
}},
|
||||
},
|
||||
}
|
||||
if err := chartutil.SaveDir(parent, tmp); err != nil {
|
||||
t.Fatalf("Error creating chart: %v", err)
|
||||
}
|
||||
chartPath := filepath.Join(tmp, parent.Metadata.Name)
|
||||
// SaveDir writes only resolved subcharts (Chart.Dependencies()), not the
|
||||
// declared Metadata.Dependencies, so create the empty charts/ directory
|
||||
// explicitly to make the "dependency missing from charts/" state concrete.
|
||||
if err := os.MkdirAll(filepath.Join(chartPath, "charts"), 0o755); err != nil {
|
||||
t.Fatalf("Error creating charts dir: %v", err)
|
||||
}
|
||||
|
||||
// The command must return an error (registry rejects the lookup), not panic.
|
||||
_, _, err := executeActionCommandC(storageFixture(),
|
||||
fmt.Sprintf("upgrade --dependency-update --plain-http oci-parent '%s'", chartPath))
|
||||
if err == nil {
|
||||
t.Fatal("expected an error resolving the OCI dependency, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpgradeWithValue(t *testing.T) {
|
||||
releaseName := "funny-bunny-v2"
|
||||
relMock, ch, chartPath := prepareMockRelease(t, releaseName)
|
||||
|
||||
Reference in New Issue
Block a user