pull/32431/merge
Dean Chen 1 day ago committed by GitHub
commit 79dcd755d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -327,6 +327,29 @@ func (i *Install) RunWithContext(ctx context.Context, ch ci.Charter, vals map[st
}
if !interactWithServer(i.DryRunStrategy) {
// Work on a local copy of the Configuration so client-only mocks
// (fake KubeClient, in-memory Releases, default Capabilities) do
// not mutate the shared *Configuration passed to NewInstall.
// Callers that reuse the same cfg for a later real install must
// still observe the original client and storage. See #11463.
//
// Copy exported fields only. Configuration has an unexported mutex and
// embeds logging.LogHolder (atomic.Pointer); both must not be copied
// by value (govet copylocks).
origCfg := i.cfg
cfgCopy := &Configuration{
RESTClientGetter: origCfg.RESTClientGetter,
Releases: origCfg.Releases,
KubeClient: origCfg.KubeClient,
RegistryClient: origCfg.RegistryClient,
Capabilities: origCfg.Capabilities,
CustomTemplateFuncs: origCfg.CustomTemplateFuncs,
HookOutputFunc: origCfg.HookOutputFunc,
}
cfgCopy.SetLogger(origCfg.Logger().Handler())
i.cfg = cfgCopy
defer func() { i.cfg = origCfg }()
// Add mock objects in here so it doesn't use Kube API server
// NOTE(bacongobbler): used for `helm template`
i.cfg.Capabilities = common.DefaultCapabilities.Copy()

@ -1253,3 +1253,39 @@ func TestInstallRelease_WaitOptionsPassedDownstream(t *testing.T) {
// Verify that WaitOptions were passed to GetWaiter
is.NotEmpty(failer.RecordedWaitOptions, "WaitOptions should be passed to GetWaiter")
}
// TestInstallDryRunClientDoesNotMutateSharedConfiguration ensures that a
// client-only install does not permanently replace the shared Configuration's
// KubeClient, Releases, or Capabilities (issue #11463).
func TestInstallDryRunClientDoesNotMutateSharedConfiguration(t *testing.T) {
req := require.New(t)
config := actionConfigFixture(t)
originalKubeClient := config.KubeClient
originalCapabilities := config.Capabilities
originalReleases := config.Releases
clientOnly := NewInstall(config)
clientOnly.DryRunStrategy = DryRunClient
clientOnly.ReleaseName = "test-client-only"
clientOnly.Namespace = "spaced"
_, err := clientOnly.Run(buildChart(), nil)
req.NoError(err)
req.Same(originalKubeClient, config.KubeClient, "KubeClient must not be replaced by client-only install")
req.Same(originalCapabilities, config.Capabilities, "Capabilities must not be replaced by client-only install")
req.Same(originalReleases, config.Releases, "Releases must not be replaced by client-only install")
// A subsequent real install sharing the same Configuration must still work.
realInstall := NewInstall(config)
realInstall.DryRunStrategy = DryRunNone
realInstall.ReleaseName = "test-real-install"
realInstall.Namespace = "spaced"
_, err = realInstall.Run(buildChart(), nil)
req.NoError(err)
req.Same(originalKubeClient, config.KubeClient, "KubeClient must still be original after real install")
req.Same(originalReleases, config.Releases, "Releases must still be original after real install")
}

Loading…
Cancel
Save