feat: kubesphere 4.0 (#6115)
* feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> * feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> --------- Signed-off-by: ci-bot <ci-bot@kubesphere.io> Co-authored-by: ks-ci-bot <ks-ci-bot@example.com> Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
committed by
GitHub
parent
b5015ec7b9
commit
447a51f08b
18
vendor/helm.sh/helm/v3/pkg/action/action.go
vendored
18
vendor/helm.sh/helm/v3/pkg/action/action.go
vendored
@@ -103,7 +103,7 @@ type Configuration struct {
|
||||
// TODO: As part of the refactor the duplicate code in cmd/helm/template.go should be removed
|
||||
//
|
||||
// This code has to do with writing files to disk.
|
||||
func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, dryRun, enableDNS bool) ([]*release.Hook, *bytes.Buffer, string, error) {
|
||||
func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, releaseName, outputDir string, subNotes, useReleaseName, includeCrds bool, pr postrender.PostRenderer, interactWithRemote, enableDNS bool) ([]*release.Hook, *bytes.Buffer, string, error) {
|
||||
hs := []*release.Hook{}
|
||||
b := bytes.NewBuffer(nil)
|
||||
|
||||
@@ -121,12 +121,10 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu
|
||||
var files map[string]string
|
||||
var err2 error
|
||||
|
||||
// A `helm template` or `helm install --dry-run` should not talk to the remote cluster.
|
||||
// It will break in interesting and exotic ways because other data (e.g. discovery)
|
||||
// is mocked. It is not up to the template author to decide when the user wants to
|
||||
// connect to the cluster. So when the user says to dry run, respect the user's
|
||||
// wishes and do not connect to the cluster.
|
||||
if !dryRun && cfg.RESTClientGetter != nil {
|
||||
// A `helm template` should not talk to the remote cluster. However, commands with the flag
|
||||
//`--dry-run` with the value of `false`, `none`, or `server` should try to interact with the cluster.
|
||||
// It may break in interesting and exotic ways because other data (e.g. discovery) is mocked.
|
||||
if interactWithRemote && cfg.RESTClientGetter != nil {
|
||||
restConfig, err := cfg.RESTClientGetter.ToRESTConfig()
|
||||
if err != nil {
|
||||
return hs, b, "", err
|
||||
@@ -189,13 +187,13 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu
|
||||
if includeCrds {
|
||||
for _, crd := range ch.CRDObjects() {
|
||||
if outputDir == "" {
|
||||
fmt.Fprintf(b, "---\n# Source: %s\n%s\n", crd.Name, string(crd.File.Data[:]))
|
||||
fmt.Fprintf(b, "---\n# Source: %s\n%s\n", crd.Filename, string(crd.File.Data[:]))
|
||||
} else {
|
||||
err = writeToFile(outputDir, crd.Filename, string(crd.File.Data[:]), fileWritten[crd.Name])
|
||||
err = writeToFile(outputDir, crd.Filename, string(crd.File.Data[:]), fileWritten[crd.Filename])
|
||||
if err != nil {
|
||||
return hs, b, "", err
|
||||
}
|
||||
fileWritten[crd.Name] = true
|
||||
fileWritten[crd.Filename] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
69
vendor/helm.sh/helm/v3/pkg/action/get_metadata.go
vendored
Normal file
69
vendor/helm.sh/helm/v3/pkg/action/get_metadata.go
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 action
|
||||
|
||||
import "time"
|
||||
|
||||
// GetMetadata is the action for checking a given release's metadata.
|
||||
//
|
||||
// It provides the implementation of 'helm get metadata'.
|
||||
type GetMetadata struct {
|
||||
cfg *Configuration
|
||||
|
||||
Version int
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Chart string `json:"chart" yaml:"chart"`
|
||||
Version string `json:"version" yaml:"version"`
|
||||
AppVersion string `json:"appVersion" yaml:"appVersion"`
|
||||
Namespace string `json:"namespace" yaml:"namespace"`
|
||||
Revision int `json:"revision" yaml:"revision"`
|
||||
Status string `json:"status" yaml:"status"`
|
||||
DeployedAt string `json:"deployedAt" yaml:"deployedAt"`
|
||||
}
|
||||
|
||||
// NewGetMetadata creates a new GetMetadata object with the given configuration.
|
||||
func NewGetMetadata(cfg *Configuration) *GetMetadata {
|
||||
return &GetMetadata{
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
// Run executes 'helm get metadata' against the given release.
|
||||
func (g *GetMetadata) Run(name string) (*Metadata, error) {
|
||||
if err := g.cfg.KubeClient.IsReachable(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rel, err := g.cfg.releaseContent(name, g.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Metadata{
|
||||
Name: rel.Name,
|
||||
Chart: rel.Chart.Metadata.Name,
|
||||
Version: rel.Chart.Metadata.Version,
|
||||
AppVersion: rel.Chart.Metadata.AppVersion,
|
||||
Namespace: rel.Namespace,
|
||||
Revision: rel.Version,
|
||||
Status: rel.Info.Status.String(),
|
||||
DeployedAt: rel.Info.LastDeployed.Format(time.RFC3339),
|
||||
}, nil
|
||||
}
|
||||
16
vendor/helm.sh/helm/v3/pkg/action/hooks.go
vendored
16
vendor/helm.sh/helm/v3/pkg/action/hooks.go
vendored
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"helm.sh/helm/v3/pkg/kube"
|
||||
"helm.sh/helm/v3/pkg/release"
|
||||
helmtime "helm.sh/helm/v3/pkg/time"
|
||||
)
|
||||
@@ -51,7 +52,7 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
|
||||
h.DeletePolicies = []release.HookDeletePolicy{release.HookBeforeHookCreation}
|
||||
}
|
||||
|
||||
if err := cfg.deleteHookByPolicy(h, release.HookBeforeHookCreation); err != nil {
|
||||
if err := cfg.deleteHookByPolicy(h, release.HookBeforeHookCreation, timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
|
||||
h.LastRun.Phase = release.HookPhaseFailed
|
||||
// If a hook is failed, check the annotation of the hook to determine whether the hook should be deleted
|
||||
// under failed condition. If so, then clear the corresponding resource object in the hook
|
||||
if err := cfg.deleteHookByPolicy(h, release.HookFailed); err != nil {
|
||||
if err := cfg.deleteHookByPolicy(h, release.HookFailed, timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
@@ -99,7 +100,7 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
|
||||
// If all hooks are successful, check the annotation of each hook to determine whether the hook should be deleted
|
||||
// under succeeded condition. If so, then clear the corresponding resource object in each hook
|
||||
for _, h := range executingHooks {
|
||||
if err := cfg.deleteHookByPolicy(h, release.HookSucceeded); err != nil {
|
||||
if err := cfg.deleteHookByPolicy(h, release.HookSucceeded, timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -120,7 +121,7 @@ func (x hookByWeight) Less(i, j int) bool {
|
||||
}
|
||||
|
||||
// deleteHookByPolicy deletes a hook if the hook policy instructs it to
|
||||
func (cfg *Configuration) deleteHookByPolicy(h *release.Hook, policy release.HookDeletePolicy) error {
|
||||
func (cfg *Configuration) deleteHookByPolicy(h *release.Hook, policy release.HookDeletePolicy, timeout time.Duration) error {
|
||||
// Never delete CustomResourceDefinitions; this could cause lots of
|
||||
// cascading garbage collection.
|
||||
if h.Kind == "CustomResourceDefinition" {
|
||||
@@ -135,6 +136,13 @@ func (cfg *Configuration) deleteHookByPolicy(h *release.Hook, policy release.Hoo
|
||||
if len(errs) > 0 {
|
||||
return errors.New(joinErrors(errs))
|
||||
}
|
||||
|
||||
//wait for resources until they are deleted to avoid conflicts
|
||||
if kubeClient, ok := cfg.KubeClient.(kube.InterfaceExt); ok {
|
||||
if err := kubeClient.WaitForDelete(resources, timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
187
vendor/helm.sh/helm/v3/pkg/action/install.go
vendored
187
vendor/helm.sh/helm/v3/pkg/action/install.go
vendored
@@ -20,7 +20,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"sigs.k8s.io/yaml"
|
||||
@@ -72,6 +73,7 @@ type Install struct {
|
||||
Force bool
|
||||
CreateNamespace bool
|
||||
DryRun bool
|
||||
DryRunOption string
|
||||
DisableHooks bool
|
||||
Replace bool
|
||||
Wait bool
|
||||
@@ -90,6 +92,7 @@ type Install struct {
|
||||
SubNotes bool
|
||||
DisableOpenAPIValidation bool
|
||||
IncludeCRDs bool
|
||||
Labels map[string]string
|
||||
// KubeVersion allows specifying a custom kubernetes version to use and
|
||||
// APIVersions allows a manual set of supported API Versions to be passed
|
||||
// (for things like templating). These are ignored if ClientOnly is false
|
||||
@@ -113,6 +116,7 @@ type ChartPathOptions struct {
|
||||
CertFile string // --cert-file
|
||||
KeyFile string // --key-file
|
||||
InsecureSkipTLSverify bool // --insecure-skip-verify
|
||||
PlainHTTP bool // --plain-http
|
||||
Keyring string // --keyring
|
||||
Password string // --password
|
||||
PassCredentialsAll bool // --pass-credentials
|
||||
@@ -136,6 +140,16 @@ func NewInstall(cfg *Configuration) *Install {
|
||||
return in
|
||||
}
|
||||
|
||||
// SetRegistryClient sets the registry client for the install action
|
||||
func (i *Install) SetRegistryClient(registryClient *registry.Client) {
|
||||
i.ChartPathOptions.registryClient = registryClient
|
||||
}
|
||||
|
||||
// GetRegistryClient get the registry client.
|
||||
func (i *Install) GetRegistryClient() *registry.Client {
|
||||
return i.ChartPathOptions.registryClient
|
||||
}
|
||||
|
||||
func (i *Install) installCRDs(crds []chart.CRD) error {
|
||||
// We do these one file at a time in the order they were read.
|
||||
totalItems := []*resource.Info{}
|
||||
@@ -159,22 +173,38 @@ func (i *Install) installCRDs(crds []chart.CRD) error {
|
||||
totalItems = append(totalItems, res...)
|
||||
}
|
||||
if len(totalItems) > 0 {
|
||||
// Invalidate the local cache, since it will not have the new CRDs
|
||||
// present.
|
||||
discoveryClient, err := i.cfg.RESTClientGetter.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.cfg.Log("Clearing discovery cache")
|
||||
discoveryClient.Invalidate()
|
||||
// Give time for the CRD to be recognized.
|
||||
|
||||
if err := i.cfg.KubeClient.Wait(totalItems, 60*time.Second); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Make sure to force a rebuild of the cache.
|
||||
discoveryClient.ServerGroups()
|
||||
// If we have already gathered the capabilities, we need to invalidate
|
||||
// the cache so that the new CRDs are recognized. This should only be
|
||||
// the case when an action configuration is reused for multiple actions,
|
||||
// as otherwise it is later loaded by ourselves when getCapabilities
|
||||
// is called later on in the installation process.
|
||||
if i.cfg.Capabilities != nil {
|
||||
discoveryClient, err := i.cfg.RESTClientGetter.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.cfg.Log("Clearing discovery cache")
|
||||
discoveryClient.Invalidate()
|
||||
|
||||
_, _ = discoveryClient.ServerGroups()
|
||||
}
|
||||
|
||||
// Invalidate the REST mapper, since it will not have the new CRDs
|
||||
// present.
|
||||
restMapper, err := i.cfg.RESTClientGetter.ToRESTMapper()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resettable, ok := restMapper.(meta.ResettableRESTMapper); ok {
|
||||
i.cfg.Log("Clearing REST mapper cache")
|
||||
resettable.Reset()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -189,6 +219,9 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
|
||||
}
|
||||
|
||||
// Run executes the installation with Context
|
||||
//
|
||||
// When the task is cancelled through ctx, the function returns and the install
|
||||
// proceeds in the background.
|
||||
func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals map[string]interface{}) (*release.Release, error) {
|
||||
// Check reachability of cluster unless in client-only mode (e.g. `helm template` without `--validate`)
|
||||
if !i.ClientOnly {
|
||||
@@ -201,15 +234,20 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := chartutil.ProcessDependencies(chrt, vals); err != nil {
|
||||
if err := chartutil.ProcessDependenciesWithMerge(chrt, vals); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var interactWithRemote bool
|
||||
if !i.isDryRun() || i.DryRunOption == "server" || i.DryRunOption == "none" || i.DryRunOption == "false" {
|
||||
interactWithRemote = true
|
||||
}
|
||||
|
||||
// Pre-install anything in the crd/ directory. We do this before Helm
|
||||
// contacts the upstream server and builds the capabilities object.
|
||||
if crds := chrt.CRDObjects(); !i.ClientOnly && !i.SkipCRDs && len(crds) > 0 {
|
||||
// On dry run, bail here
|
||||
if i.DryRun {
|
||||
if i.isDryRun() {
|
||||
i.cfg.Log("WARNING: This chart or one of its subcharts contains CRDs. Rendering may fail or contain inaccuracies.")
|
||||
} else if err := i.installCRDs(crds); err != nil {
|
||||
return nil, err
|
||||
@@ -224,7 +262,7 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
||||
i.cfg.Capabilities.KubeVersion = *i.KubeVersion
|
||||
}
|
||||
i.cfg.Capabilities.APIVersions = append(i.cfg.Capabilities.APIVersions, i.APIVersions...)
|
||||
i.cfg.KubeClient = &kubefake.PrintingKubeClient{Out: ioutil.Discard}
|
||||
i.cfg.KubeClient = &kubefake.PrintingKubeClient{Out: io.Discard}
|
||||
|
||||
mem := driver.NewMemory()
|
||||
mem.SetNamespace(i.Namespace)
|
||||
@@ -243,7 +281,7 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
||||
}
|
||||
|
||||
// special case for helm template --is-upgrade
|
||||
isUpgrade := i.IsUpgrade && i.DryRun
|
||||
isUpgrade := i.IsUpgrade && i.isDryRun()
|
||||
options := chartutil.ReleaseOptions{
|
||||
Name: i.ReleaseName,
|
||||
Namespace: i.Namespace,
|
||||
@@ -256,10 +294,14 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rel := i.createRelease(chrt, vals)
|
||||
if driver.ContainsSystemLabels(i.Labels) {
|
||||
return nil, fmt.Errorf("user suplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels())
|
||||
}
|
||||
|
||||
rel := i.createRelease(chrt, vals, i.Labels)
|
||||
|
||||
var manifestDoc *bytes.Buffer
|
||||
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, i.DryRun, i.EnableDNS)
|
||||
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.ReleaseName, i.OutputDir, i.SubNotes, i.UseReleaseName, i.IncludeCRDs, i.PostRenderer, interactWithRemote, i.EnableDNS)
|
||||
// Even for errors, attach this if available
|
||||
if manifestDoc != nil {
|
||||
rel.Manifest = manifestDoc.String()
|
||||
@@ -295,12 +337,12 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
||||
if !i.ClientOnly && !isUpgrade && len(resources) > 0 {
|
||||
toBeAdopted, err = existingResourceConflict(resources, rel.Name, rel.Namespace)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "rendered manifests contain a resource that already exists. Unable to continue with install")
|
||||
return nil, errors.Wrap(err, "Unable to continue with install")
|
||||
}
|
||||
}
|
||||
|
||||
// Bail out here if it is a dry run
|
||||
if i.DryRun {
|
||||
if i.isDryRun() {
|
||||
rel.Info.Description = "Dry run complete"
|
||||
return rel, nil
|
||||
}
|
||||
@@ -346,23 +388,48 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
|
||||
// not working.
|
||||
return rel, err
|
||||
}
|
||||
rChan := make(chan resultMessage)
|
||||
doneChan := make(chan struct{})
|
||||
defer close(doneChan)
|
||||
go i.performInstall(rChan, rel, toBeAdopted, resources)
|
||||
go i.handleContext(ctx, rChan, doneChan, rel)
|
||||
result := <-rChan
|
||||
//start preformInstall go routine
|
||||
return result.r, result.e
|
||||
|
||||
rel, err = i.performInstallCtx(ctx, rel, toBeAdopted, resources)
|
||||
if err != nil {
|
||||
rel, err = i.failRelease(rel, err)
|
||||
}
|
||||
return rel, err
|
||||
}
|
||||
|
||||
func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, toBeAdopted kube.ResourceList, resources kube.ResourceList) {
|
||||
func (i *Install) performInstallCtx(ctx context.Context, rel *release.Release, toBeAdopted kube.ResourceList, resources kube.ResourceList) (*release.Release, error) {
|
||||
type Msg struct {
|
||||
r *release.Release
|
||||
e error
|
||||
}
|
||||
resultChan := make(chan Msg, 1)
|
||||
|
||||
go func() {
|
||||
rel, err := i.performInstall(rel, toBeAdopted, resources)
|
||||
resultChan <- Msg{rel, err}
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err := ctx.Err()
|
||||
return rel, err
|
||||
case msg := <-resultChan:
|
||||
return msg.r, msg.e
|
||||
}
|
||||
}
|
||||
|
||||
// isDryRun returns true if Upgrade is set to run as a DryRun
|
||||
func (i *Install) isDryRun() bool {
|
||||
if i.DryRun || i.DryRunOption == "client" || i.DryRunOption == "server" || i.DryRunOption == "true" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *Install) performInstall(rel *release.Release, toBeAdopted kube.ResourceList, resources kube.ResourceList) (*release.Release, error) {
|
||||
var err error
|
||||
// pre-install hooks
|
||||
if !i.DisableHooks {
|
||||
if err := i.cfg.execHook(rel, release.HookPreInstall, i.Timeout); err != nil {
|
||||
i.reportToRun(c, rel, fmt.Errorf("failed pre-install: %s", err))
|
||||
return
|
||||
return rel, fmt.Errorf("failed pre-install: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,35 +437,28 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t
|
||||
// do an update, but it's not clear whether we WANT to do an update if the re-use is set
|
||||
// to true, since that is basically an upgrade operation.
|
||||
if len(toBeAdopted) == 0 && len(resources) > 0 {
|
||||
if _, err := i.cfg.KubeClient.Create(resources); err != nil {
|
||||
i.reportToRun(c, rel, err)
|
||||
return
|
||||
}
|
||||
_, err = i.cfg.KubeClient.Create(resources)
|
||||
} else if len(resources) > 0 {
|
||||
if _, err := i.cfg.KubeClient.Update(toBeAdopted, resources, i.Force); err != nil {
|
||||
i.reportToRun(c, rel, err)
|
||||
return
|
||||
}
|
||||
_, err = i.cfg.KubeClient.Update(toBeAdopted, resources, i.Force)
|
||||
}
|
||||
if err != nil {
|
||||
return rel, err
|
||||
}
|
||||
|
||||
if i.Wait {
|
||||
if i.WaitForJobs {
|
||||
if err := i.cfg.KubeClient.WaitWithJobs(resources, i.Timeout); err != nil {
|
||||
i.reportToRun(c, rel, err)
|
||||
return
|
||||
}
|
||||
err = i.cfg.KubeClient.WaitWithJobs(resources, i.Timeout)
|
||||
} else {
|
||||
if err := i.cfg.KubeClient.Wait(resources, i.Timeout); err != nil {
|
||||
i.reportToRun(c, rel, err)
|
||||
return
|
||||
}
|
||||
err = i.cfg.KubeClient.Wait(resources, i.Timeout)
|
||||
}
|
||||
if err != nil {
|
||||
return rel, err
|
||||
}
|
||||
}
|
||||
|
||||
if !i.DisableHooks {
|
||||
if err := i.cfg.execHook(rel, release.HookPostInstall, i.Timeout); err != nil {
|
||||
i.reportToRun(c, rel, fmt.Errorf("failed post-install: %s", err))
|
||||
return
|
||||
return rel, fmt.Errorf("failed post-install: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,25 +479,9 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t
|
||||
i.cfg.Log("failed to record the release: %s", err)
|
||||
}
|
||||
|
||||
i.reportToRun(c, rel, nil)
|
||||
}
|
||||
func (i *Install) handleContext(ctx context.Context, c chan<- resultMessage, done chan struct{}, rel *release.Release) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err := ctx.Err()
|
||||
i.reportToRun(c, rel, err)
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
func (i *Install) reportToRun(c chan<- resultMessage, rel *release.Release, err error) {
|
||||
i.Lock.Lock()
|
||||
if err != nil {
|
||||
rel, err = i.failRelease(rel, err)
|
||||
}
|
||||
c <- resultMessage{r: rel, e: err}
|
||||
i.Lock.Unlock()
|
||||
return rel, nil
|
||||
}
|
||||
|
||||
func (i *Install) failRelease(rel *release.Release, err error) (*release.Release, error) {
|
||||
rel.SetStatus(release.StatusFailed, fmt.Sprintf("Release %q failed: %s", i.ReleaseName, err.Error()))
|
||||
if i.Atomic {
|
||||
@@ -469,7 +513,8 @@ func (i *Install) availableName() error {
|
||||
if err := chartutil.ValidateReleaseName(start); err != nil {
|
||||
return errors.Wrapf(err, "release name %q", start)
|
||||
}
|
||||
if i.DryRun {
|
||||
// On dry run, bail here
|
||||
if i.isDryRun() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -487,7 +532,7 @@ func (i *Install) availableName() error {
|
||||
}
|
||||
|
||||
// createRelease creates a new release object
|
||||
func (i *Install) createRelease(chrt *chart.Chart, rawVals map[string]interface{}) *release.Release {
|
||||
func (i *Install) createRelease(chrt *chart.Chart, rawVals map[string]interface{}, labels map[string]string) *release.Release {
|
||||
ts := i.cfg.Now()
|
||||
return &release.Release{
|
||||
Name: i.ReleaseName,
|
||||
@@ -500,6 +545,7 @@ func (i *Install) createRelease(chrt *chart.Chart, rawVals map[string]interface{
|
||||
Status: release.StatusUnknown,
|
||||
},
|
||||
Version: 1,
|
||||
Labels: labels,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -676,8 +722,6 @@ OUTER:
|
||||
//
|
||||
// If 'verify' was set on ChartPathOptions, this will attempt to also verify the chart.
|
||||
func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (string, error) {
|
||||
// If there is no registry client and the name is in an OCI registry return
|
||||
// an error and a lookup will not occur.
|
||||
if registry.IsOCI(name) && c.registryClient == nil {
|
||||
return "", fmt.Errorf("unable to lookup chart %q, missing registry client", name)
|
||||
}
|
||||
@@ -709,6 +753,7 @@ func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (
|
||||
getter.WithPassCredentialsAll(c.PassCredentialsAll),
|
||||
getter.WithTLSClientConfig(c.CertFile, c.KeyFile, c.CaFile),
|
||||
getter.WithInsecureSkipVerifyTLS(c.InsecureSkipTLSverify),
|
||||
getter.WithPlainHTTP(c.PlainHTTP),
|
||||
},
|
||||
RepositoryConfig: settings.RepositoryConfig,
|
||||
RepositoryCache: settings.RepositoryCache,
|
||||
|
||||
12
vendor/helm.sh/helm/v3/pkg/action/lint.go
vendored
12
vendor/helm.sh/helm/v3/pkg/action/lint.go
vendored
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package action
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -37,6 +36,7 @@ type Lint struct {
|
||||
Namespace string
|
||||
WithSubcharts bool
|
||||
Quiet bool
|
||||
KubeVersion *chartutil.KubeVersion
|
||||
}
|
||||
|
||||
// LintResult is the result of Lint
|
||||
@@ -59,7 +59,7 @@ func (l *Lint) Run(paths []string, vals map[string]interface{}) *LintResult {
|
||||
}
|
||||
result := &LintResult{}
|
||||
for _, path := range paths {
|
||||
linter, err := lintChart(path, vals, l.Namespace, l.Strict)
|
||||
linter, err := lintChart(path, vals, l.Namespace, l.KubeVersion)
|
||||
if err != nil {
|
||||
result.Errors = append(result.Errors, err)
|
||||
continue
|
||||
@@ -83,15 +83,15 @@ func HasWarningsOrErrors(result *LintResult) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return len(result.Errors) > 0
|
||||
}
|
||||
|
||||
func lintChart(path string, vals map[string]interface{}, namespace string, strict bool) (support.Linter, error) {
|
||||
func lintChart(path string, vals map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) (support.Linter, error) {
|
||||
var chartPath string
|
||||
linter := support.Linter{}
|
||||
|
||||
if strings.HasSuffix(path, ".tgz") || strings.HasSuffix(path, ".tar.gz") {
|
||||
tempDir, err := ioutil.TempDir("", "helm-lint")
|
||||
tempDir, err := os.MkdirTemp("", "helm-lint")
|
||||
if err != nil {
|
||||
return linter, errors.Wrap(err, "unable to create temp dir to extract tarball")
|
||||
}
|
||||
@@ -125,5 +125,5 @@ func lintChart(path string, vals map[string]interface{}, namespace string, stric
|
||||
return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart")
|
||||
}
|
||||
|
||||
return lint.All(chartPath, vals, namespace, strict), nil
|
||||
return lint.AllWithKubeVersion(chartPath, vals, namespace, kubeVersion), nil
|
||||
}
|
||||
|
||||
5
vendor/helm.sh/helm/v3/pkg/action/package.go
vendored
5
vendor/helm.sh/helm/v3/pkg/action/package.go
vendored
@@ -19,7 +19,6 @@ package action
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
@@ -55,7 +54,7 @@ func NewPackage() *Package {
|
||||
}
|
||||
|
||||
// Run executes 'helm package' against the given chart and returns the path to the packaged chart.
|
||||
func (p *Package) Run(path string, vals map[string]interface{}) (string, error) {
|
||||
func (p *Package) Run(path string, _ map[string]interface{}) (string, error) {
|
||||
ch, err := loader.LoadDir(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -137,7 +136,7 @@ func (p *Package) Clearsign(filename string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(filename+".prov", []byte(sig), 0644)
|
||||
return os.WriteFile(filename+".prov", []byte(sig), 0644)
|
||||
}
|
||||
|
||||
// promptUser implements provenance.PassphraseFetcher
|
||||
|
||||
10
vendor/helm.sh/helm/v3/pkg/action/pull.go
vendored
10
vendor/helm.sh/helm/v3/pkg/action/pull.go
vendored
@@ -18,7 +18,6 @@ package action
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -72,6 +71,11 @@ func NewPullWithOpts(opts ...PullOpt) *Pull {
|
||||
return p
|
||||
}
|
||||
|
||||
// SetRegistryClient sets the registry client on the pull configuration object.
|
||||
func (p *Pull) SetRegistryClient(client *registry.Client) {
|
||||
p.cfg.RegistryClient = client
|
||||
}
|
||||
|
||||
// Run executes 'helm pull' against the given release.
|
||||
func (p *Pull) Run(chartRef string) (string, error) {
|
||||
var out strings.Builder
|
||||
@@ -86,6 +90,7 @@ func (p *Pull) Run(chartRef string) (string, error) {
|
||||
getter.WithPassCredentialsAll(p.PassCredentialsAll),
|
||||
getter.WithTLSClientConfig(p.CertFile, p.KeyFile, p.CaFile),
|
||||
getter.WithInsecureSkipVerifyTLS(p.InsecureSkipTLSverify),
|
||||
getter.WithPlainHTTP(p.PlainHTTP),
|
||||
},
|
||||
RegistryClient: p.cfg.RegistryClient,
|
||||
RepositoryConfig: p.Settings.RepositoryConfig,
|
||||
@@ -95,6 +100,7 @@ func (p *Pull) Run(chartRef string) (string, error) {
|
||||
if registry.IsOCI(chartRef) {
|
||||
c.Options = append(c.Options,
|
||||
getter.WithRegistryClient(p.cfg.RegistryClient))
|
||||
c.RegistryClient = p.cfg.RegistryClient
|
||||
}
|
||||
|
||||
if p.Verify {
|
||||
@@ -108,7 +114,7 @@ func (p *Pull) Run(chartRef string) (string, error) {
|
||||
dest := p.DestDir
|
||||
if p.Untar {
|
||||
var err error
|
||||
dest, err = ioutil.TempDir("", "helm-")
|
||||
dest, err = os.MkdirTemp("", "helm-")
|
||||
if err != nil {
|
||||
return out.String(), errors.Wrap(err, "failed to untar")
|
||||
}
|
||||
|
||||
48
vendor/helm.sh/helm/v3/pkg/action/push.go
vendored
48
vendor/helm.sh/helm/v3/pkg/action/push.go
vendored
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package action
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"helm.sh/helm/v3/pkg/cli"
|
||||
@@ -29,8 +30,14 @@ import (
|
||||
//
|
||||
// It provides the implementation of 'helm push'.
|
||||
type Push struct {
|
||||
Settings *cli.EnvSettings
|
||||
cfg *Configuration
|
||||
Settings *cli.EnvSettings
|
||||
cfg *Configuration
|
||||
certFile string
|
||||
keyFile string
|
||||
caFile string
|
||||
insecureSkipTLSverify bool
|
||||
plainHTTP bool
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
// PushOpt is a type of function that sets options for a push action.
|
||||
@@ -43,6 +50,36 @@ func WithPushConfig(cfg *Configuration) PushOpt {
|
||||
}
|
||||
}
|
||||
|
||||
// WithTLSClientConfig sets the certFile, keyFile, and caFile fields on the push configuration object.
|
||||
func WithTLSClientConfig(certFile, keyFile, caFile string) PushOpt {
|
||||
return func(p *Push) {
|
||||
p.certFile = certFile
|
||||
p.keyFile = keyFile
|
||||
p.caFile = caFile
|
||||
}
|
||||
}
|
||||
|
||||
// WithInsecureSkipTLSVerify determines if a TLS Certificate will be checked
|
||||
func WithInsecureSkipTLSVerify(insecureSkipTLSVerify bool) PushOpt {
|
||||
return func(p *Push) {
|
||||
p.insecureSkipTLSverify = insecureSkipTLSVerify
|
||||
}
|
||||
}
|
||||
|
||||
// WithPlainHTTP configures the use of plain HTTP connections.
|
||||
func WithPlainHTTP(plainHTTP bool) PushOpt {
|
||||
return func(p *Push) {
|
||||
p.plainHTTP = plainHTTP
|
||||
}
|
||||
}
|
||||
|
||||
// WithOptWriter sets the registryOut field on the push configuration object.
|
||||
func WithPushOptWriter(out io.Writer) PushOpt {
|
||||
return func(p *Push) {
|
||||
p.out = out
|
||||
}
|
||||
}
|
||||
|
||||
// NewPushWithOpts creates a new push, with configuration options.
|
||||
func NewPushWithOpts(opts ...PushOpt) *Push {
|
||||
p := &Push{}
|
||||
@@ -59,10 +96,15 @@ func (p *Push) Run(chartRef string, remote string) (string, error) {
|
||||
c := uploader.ChartUploader{
|
||||
Out: &out,
|
||||
Pushers: pusher.All(p.Settings),
|
||||
Options: []pusher.Option{},
|
||||
Options: []pusher.Option{
|
||||
pusher.WithTLSClientConfig(p.certFile, p.keyFile, p.caFile),
|
||||
pusher.WithInsecureSkipTLSVerify(p.insecureSkipTLSverify),
|
||||
pusher.WithPlainHTTP(p.plainHTTP),
|
||||
},
|
||||
}
|
||||
|
||||
if registry.IsOCI(remote) {
|
||||
// Don't use the default registry client if tls options are set.
|
||||
c.Options = append(c.Options, pusher.WithRegistryClient(p.cfg.RegistryClient))
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,45 @@ import (
|
||||
|
||||
// RegistryLogin performs a registry login operation.
|
||||
type RegistryLogin struct {
|
||||
cfg *Configuration
|
||||
cfg *Configuration
|
||||
certFile string
|
||||
keyFile string
|
||||
caFile string
|
||||
insecure bool
|
||||
}
|
||||
|
||||
type RegistryLoginOpt func(*RegistryLogin) error
|
||||
|
||||
// WithCertFile specifies the path to the certificate file to use for TLS.
|
||||
func WithCertFile(certFile string) RegistryLoginOpt {
|
||||
return func(r *RegistryLogin) error {
|
||||
r.certFile = certFile
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithKeyFile specifies whether to very certificates when communicating.
|
||||
func WithInsecure(insecure bool) RegistryLoginOpt {
|
||||
return func(r *RegistryLogin) error {
|
||||
r.insecure = insecure
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithKeyFile specifies the path to the key file to use for TLS.
|
||||
func WithKeyFile(keyFile string) RegistryLoginOpt {
|
||||
return func(r *RegistryLogin) error {
|
||||
r.keyFile = keyFile
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCAFile specifies the path to the CA file to use for TLS.
|
||||
func WithCAFile(caFile string) RegistryLoginOpt {
|
||||
return func(r *RegistryLogin) error {
|
||||
r.caFile = caFile
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewRegistryLogin creates a new RegistryLogin object with the given configuration.
|
||||
@@ -35,9 +73,16 @@ func NewRegistryLogin(cfg *Configuration) *RegistryLogin {
|
||||
}
|
||||
|
||||
// Run executes the registry login operation
|
||||
func (a *RegistryLogin) Run(out io.Writer, hostname string, username string, password string, insecure bool) error {
|
||||
func (a *RegistryLogin) Run(_ io.Writer, hostname string, username string, password string, opts ...RegistryLoginOpt) error {
|
||||
for _, opt := range opts {
|
||||
if err := opt(a); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return a.cfg.RegistryClient.Login(
|
||||
hostname,
|
||||
registry.LoginOptBasicAuth(username, password),
|
||||
registry.LoginOptInsecure(insecure))
|
||||
registry.LoginOptInsecure(a.insecure),
|
||||
registry.LoginOptTLSClientConfig(a.certFile, a.keyFile, a.caFile))
|
||||
}
|
||||
|
||||
@@ -33,6 +33,6 @@ func NewRegistryLogout(cfg *Configuration) *RegistryLogout {
|
||||
}
|
||||
|
||||
// Run executes the registry logout operation
|
||||
func (a *RegistryLogout) Run(out io.Writer, hostname string) error {
|
||||
func (a *RegistryLogout) Run(_ io.Writer, hostname string) error {
|
||||
return a.cfg.RegistryClient.Logout(hostname)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -29,6 +30,11 @@ import (
|
||||
"helm.sh/helm/v3/pkg/release"
|
||||
)
|
||||
|
||||
const (
|
||||
ExcludeNameFilter = "!name"
|
||||
IncludeNameFilter = "name"
|
||||
)
|
||||
|
||||
// ReleaseTesting is the action for testing a release.
|
||||
//
|
||||
// It provides the implementation of 'helm test'.
|
||||
@@ -66,9 +72,9 @@ func (r *ReleaseTesting) Run(name string) (*release.Release, error) {
|
||||
|
||||
skippedHooks := []*release.Hook{}
|
||||
executingHooks := []*release.Hook{}
|
||||
if len(r.Filters["!name"]) != 0 {
|
||||
if len(r.Filters[ExcludeNameFilter]) != 0 {
|
||||
for _, h := range rel.Hooks {
|
||||
if contains(r.Filters["!name"], h.Name) {
|
||||
if contains(r.Filters[ExcludeNameFilter], h.Name) {
|
||||
skippedHooks = append(skippedHooks, h)
|
||||
} else {
|
||||
executingHooks = append(executingHooks, h)
|
||||
@@ -76,10 +82,10 @@ func (r *ReleaseTesting) Run(name string) (*release.Release, error) {
|
||||
}
|
||||
rel.Hooks = executingHooks
|
||||
}
|
||||
if len(r.Filters["name"]) != 0 {
|
||||
if len(r.Filters[IncludeNameFilter]) != 0 {
|
||||
executingHooks = nil
|
||||
for _, h := range rel.Hooks {
|
||||
if contains(r.Filters["name"], h.Name) {
|
||||
if contains(r.Filters[IncludeNameFilter], h.Name) {
|
||||
executingHooks = append(executingHooks, h)
|
||||
} else {
|
||||
skippedHooks = append(skippedHooks, h)
|
||||
@@ -107,9 +113,17 @@ func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error {
|
||||
return errors.Wrap(err, "unable to get kubernetes client to fetch pod logs")
|
||||
}
|
||||
|
||||
for _, h := range rel.Hooks {
|
||||
hooksByWight := append([]*release.Hook{}, rel.Hooks...)
|
||||
sort.Stable(hookByWeight(hooksByWight))
|
||||
for _, h := range hooksByWight {
|
||||
for _, e := range h.Events {
|
||||
if e == release.HookTest {
|
||||
if contains(r.Filters[ExcludeNameFilter], h.Name) {
|
||||
continue
|
||||
}
|
||||
if len(r.Filters[IncludeNameFilter]) > 0 && !contains(r.Filters[IncludeNameFilter], h.Name) {
|
||||
continue
|
||||
}
|
||||
req := client.CoreV1().Pods(r.Namespace).GetLogs(h.Name, &v1.PodLogOptions{})
|
||||
logReader, err := req.Stream(context.Background())
|
||||
if err != nil {
|
||||
|
||||
19
vendor/helm.sh/helm/v3/pkg/action/rollback.go
vendored
19
vendor/helm.sh/helm/v3/pkg/action/rollback.go
vendored
@@ -110,6 +110,24 @@ func (r *Rollback) prepareRollback(name string) (*release.Release, *release.Rele
|
||||
previousVersion = currentRelease.Version - 1
|
||||
}
|
||||
|
||||
historyReleases, err := r.cfg.Releases.History(name)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Check if the history version to be rolled back exists
|
||||
previousVersionExist := false
|
||||
for _, historyRelease := range historyReleases {
|
||||
version := historyRelease.Version
|
||||
if previousVersion == version {
|
||||
previousVersionExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !previousVersionExist {
|
||||
return nil, nil, errors.Errorf("release has no %d version", previousVersion)
|
||||
}
|
||||
|
||||
r.cfg.Log("rolling back %s (current: v%d, target: v%d)", name, currentRelease.Version, previousVersion)
|
||||
|
||||
previousRelease, err := r.cfg.Releases.Get(name, previousVersion)
|
||||
@@ -133,6 +151,7 @@ func (r *Rollback) prepareRollback(name string) (*release.Release, *release.Rele
|
||||
Description: fmt.Sprintf("Rollback to %d", previousVersion),
|
||||
},
|
||||
Version: currentRelease.Version + 1,
|
||||
Labels: previousRelease.Labels,
|
||||
Manifest: previousRelease.Manifest,
|
||||
Hooks: previousRelease.Hooks,
|
||||
}
|
||||
|
||||
9
vendor/helm.sh/helm/v3/pkg/action/show.go
vendored
9
vendor/helm.sh/helm/v3/pkg/action/show.go
vendored
@@ -28,6 +28,7 @@ import (
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
"helm.sh/helm/v3/pkg/chart/loader"
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"helm.sh/helm/v3/pkg/registry"
|
||||
)
|
||||
|
||||
// ShowOutputFormat is the format of the output of `helm show`
|
||||
@@ -82,6 +83,11 @@ func NewShowWithConfig(output ShowOutputFormat, cfg *Configuration) *Show {
|
||||
return sh
|
||||
}
|
||||
|
||||
// SetRegistryClient sets the registry client to use when pulling a chart from a registry.
|
||||
func (s *Show) SetRegistryClient(client *registry.Client) {
|
||||
s.ChartPathOptions.registryClient = client
|
||||
}
|
||||
|
||||
// Run executes 'helm show' against the given release.
|
||||
func (s *Show) Run(chartpath string) (string, error) {
|
||||
if s.chart == nil {
|
||||
@@ -147,6 +153,9 @@ func (s *Show) Run(chartpath string) (string, error) {
|
||||
func findReadme(files []*chart.File) (file *chart.File) {
|
||||
for _, file := range files {
|
||||
for _, n := range readmeFileNames {
|
||||
if file == nil {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(file.Name, n) {
|
||||
return file
|
||||
}
|
||||
|
||||
37
vendor/helm.sh/helm/v3/pkg/action/uninstall.go
vendored
37
vendor/helm.sh/helm/v3/pkg/action/uninstall.go
vendored
@@ -22,6 +22,8 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"helm.sh/helm/v3/pkg/kube"
|
||||
"helm.sh/helm/v3/pkg/release"
|
||||
@@ -35,12 +37,14 @@ import (
|
||||
type Uninstall struct {
|
||||
cfg *Configuration
|
||||
|
||||
DisableHooks bool
|
||||
DryRun bool
|
||||
KeepHistory bool
|
||||
Wait bool
|
||||
Timeout time.Duration
|
||||
Description string
|
||||
DisableHooks bool
|
||||
DryRun bool
|
||||
IgnoreNotFound bool
|
||||
KeepHistory bool
|
||||
Wait bool
|
||||
DeletionPropagation string
|
||||
Timeout time.Duration
|
||||
Description string
|
||||
}
|
||||
|
||||
// NewUninstall creates a new Uninstall object with the given configuration.
|
||||
@@ -71,6 +75,9 @@ func (u *Uninstall) Run(name string) (*release.UninstallReleaseResponse, error)
|
||||
|
||||
rels, err := u.cfg.Releases.History(name)
|
||||
if err != nil {
|
||||
if u.IgnoreNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, errors.Wrapf(err, "uninstall: Release not loaded: %s", name)
|
||||
}
|
||||
if len(rels) < 1 {
|
||||
@@ -220,7 +227,25 @@ func (u *Uninstall) deleteRelease(rel *release.Release) (kube.ResourceList, stri
|
||||
return nil, "", []error{errors.Wrap(err, "unable to build kubernetes objects for delete")}
|
||||
}
|
||||
if len(resources) > 0 {
|
||||
if kubeClient, ok := u.cfg.KubeClient.(kube.InterfaceDeletionPropagation); ok {
|
||||
_, errs = kubeClient.DeleteWithPropagationPolicy(resources, parseCascadingFlag(u.cfg, u.DeletionPropagation))
|
||||
return resources, kept, errs
|
||||
}
|
||||
_, errs = u.cfg.KubeClient.Delete(resources)
|
||||
}
|
||||
return resources, kept, errs
|
||||
}
|
||||
|
||||
func parseCascadingFlag(cfg *Configuration, cascadingFlag string) v1.DeletionPropagation {
|
||||
switch cascadingFlag {
|
||||
case "orphan":
|
||||
return v1.DeletePropagationOrphan
|
||||
case "foreground":
|
||||
return v1.DeletePropagationForeground
|
||||
case "background":
|
||||
return v1.DeletePropagationBackground
|
||||
default:
|
||||
cfg.Log("uninstall: given cascade value: %s, defaulting to delete propagation background", cascadingFlag)
|
||||
return v1.DeletePropagationBackground
|
||||
}
|
||||
}
|
||||
|
||||
63
vendor/helm.sh/helm/v3/pkg/action/upgrade.go
vendored
63
vendor/helm.sh/helm/v3/pkg/action/upgrade.go
vendored
@@ -32,6 +32,7 @@ import (
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"helm.sh/helm/v3/pkg/kube"
|
||||
"helm.sh/helm/v3/pkg/postrender"
|
||||
"helm.sh/helm/v3/pkg/registry"
|
||||
"helm.sh/helm/v3/pkg/release"
|
||||
"helm.sh/helm/v3/pkg/releaseutil"
|
||||
"helm.sh/helm/v3/pkg/storage/driver"
|
||||
@@ -70,8 +71,9 @@ type Upgrade struct {
|
||||
// DisableHooks disables hook processing if set to true.
|
||||
DisableHooks bool
|
||||
// DryRun controls whether the operation is prepared, but not executed.
|
||||
// If `true`, the upgrade is prepared but not performed.
|
||||
DryRun bool
|
||||
// DryRunOption controls whether the operation is prepared, but not executed with options on whether or not to interact with the remote cluster.
|
||||
DryRunOption string
|
||||
// Force will, if set to `true`, ignore certain warnings and perform the upgrade anyway.
|
||||
//
|
||||
// This should be used with caution.
|
||||
@@ -80,6 +82,8 @@ type Upgrade struct {
|
||||
ResetValues bool
|
||||
// ReuseValues will re-use the user's last supplied values.
|
||||
ReuseValues bool
|
||||
// ResetThenReuseValues will reset the values to the chart's built-ins then merge with user's last supplied values.
|
||||
ResetThenReuseValues bool
|
||||
// Recreate will (if true) recreate pods after a rollback.
|
||||
Recreate bool
|
||||
// MaxHistory limits the maximum number of revisions saved per release
|
||||
@@ -92,6 +96,7 @@ type Upgrade struct {
|
||||
SubNotes bool
|
||||
// Description is the description of this operation
|
||||
Description string
|
||||
Labels map[string]string
|
||||
// PostRender is an optional post-renderer
|
||||
//
|
||||
// If this is non-nil, then after templates are rendered, they will be sent to the
|
||||
@@ -122,6 +127,11 @@ func NewUpgrade(cfg *Configuration) *Upgrade {
|
||||
return up
|
||||
}
|
||||
|
||||
// SetRegistryClient sets the registry client to use when fetching charts.
|
||||
func (u *Upgrade) SetRegistryClient(client *registry.Client) {
|
||||
u.ChartPathOptions.registryClient = client
|
||||
}
|
||||
|
||||
// Run executes the upgrade on the given release.
|
||||
func (u *Upgrade) Run(name string, chart *chart.Chart, vals map[string]interface{}) (*release.Release, error) {
|
||||
ctx := context.Background()
|
||||
@@ -141,6 +151,7 @@ func (u *Upgrade) RunWithContext(ctx context.Context, name string, chart *chart.
|
||||
if err := chartutil.ValidateReleaseName(name); err != nil {
|
||||
return nil, errors.Errorf("release name is invalid: %s", name)
|
||||
}
|
||||
|
||||
u.cfg.Log("preparing upgrade for %s", name)
|
||||
currentRelease, upgradedRelease, err := u.prepareUpgrade(name, chart, vals)
|
||||
if err != nil {
|
||||
@@ -155,7 +166,8 @@ func (u *Upgrade) RunWithContext(ctx context.Context, name string, chart *chart.
|
||||
return res, err
|
||||
}
|
||||
|
||||
if !u.DryRun {
|
||||
// Do not update for dry runs
|
||||
if !u.isDryRun() {
|
||||
u.cfg.Log("updating status for upgraded release for %s", name)
|
||||
if err := u.cfg.Releases.Update(upgradedRelease); err != nil {
|
||||
return res, err
|
||||
@@ -165,6 +177,14 @@ func (u *Upgrade) RunWithContext(ctx context.Context, name string, chart *chart.
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// isDryRun returns true if Upgrade is set to run as a DryRun
|
||||
func (u *Upgrade) isDryRun() bool {
|
||||
if u.DryRun || u.DryRunOption == "client" || u.DryRunOption == "server" || u.DryRunOption == "true" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// prepareUpgrade builds an upgraded release for an upgrade operation.
|
||||
func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[string]interface{}) (*release.Release, *release.Release, error) {
|
||||
if chart == nil {
|
||||
@@ -209,7 +229,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := chartutil.ProcessDependencies(chart, vals); err != nil {
|
||||
if err := chartutil.ProcessDependenciesWithMerge(chart, vals); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -233,11 +253,21 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, u.DryRun, u.EnableDNS)
|
||||
// Determine whether or not to interact with remote
|
||||
var interactWithRemote bool
|
||||
if !u.isDryRun() || u.DryRunOption == "server" || u.DryRunOption == "none" || u.DryRunOption == "false" {
|
||||
interactWithRemote = true
|
||||
}
|
||||
|
||||
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", "", u.SubNotes, false, false, u.PostRenderer, interactWithRemote, u.EnableDNS)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if driver.ContainsSystemLabels(u.Labels) {
|
||||
return nil, nil, fmt.Errorf("user suplied labels contains system reserved label name. System labels: %+v", driver.GetSystemLabels())
|
||||
}
|
||||
|
||||
// Store an upgraded release.
|
||||
upgradedRelease := &release.Release{
|
||||
Name: name,
|
||||
@@ -253,6 +283,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
|
||||
Version: revision,
|
||||
Manifest: manifestDoc.String(),
|
||||
Hooks: hooks,
|
||||
Labels: mergeCustomLabels(lastRelease.Labels, u.Labels),
|
||||
}
|
||||
|
||||
if len(notesTxt) > 0 {
|
||||
@@ -300,7 +331,7 @@ func (u *Upgrade) performUpgrade(ctx context.Context, originalRelease, upgradedR
|
||||
|
||||
toBeUpdated, err := existingResourceConflict(toBeCreated, upgradedRelease.Name, upgradedRelease.Namespace)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "rendered manifests contain a resource that already exists. Unable to continue with update")
|
||||
return nil, errors.Wrap(err, "Unable to continue with update")
|
||||
}
|
||||
|
||||
toBeUpdated.Visit(func(r *resource.Info, err error) error {
|
||||
@@ -311,7 +342,8 @@ func (u *Upgrade) performUpgrade(ctx context.Context, originalRelease, upgradedR
|
||||
return nil
|
||||
})
|
||||
|
||||
if u.DryRun {
|
||||
// Run if it is a dry run
|
||||
if u.isDryRun() {
|
||||
u.cfg.Log("dry run for %s", upgradedRelease.Name)
|
||||
if len(u.Description) > 0 {
|
||||
upgradedRelease.Info.Description = u.Description
|
||||
@@ -522,6 +554,15 @@ func (u *Upgrade) reuseValues(chart *chart.Chart, current *release.Release, newV
|
||||
return newVals, nil
|
||||
}
|
||||
|
||||
// If the ResetThenReuseValues flag is set, we use the new chart's values, but we copy the old config's values over the new config's values.
|
||||
if u.ResetThenReuseValues {
|
||||
u.cfg.Log("merging values from old release to new values")
|
||||
|
||||
newVals = chartutil.CoalesceTables(newVals, current.Config)
|
||||
|
||||
return newVals, nil
|
||||
}
|
||||
|
||||
if len(newVals) == 0 && len(current.Config) > 0 {
|
||||
u.cfg.Log("copying values from %s (v%d) to new release.", current.Name, current.Version)
|
||||
newVals = current.Config
|
||||
@@ -574,3 +615,13 @@ func objectKey(r *resource.Info) string {
|
||||
gvk := r.Object.GetObjectKind().GroupVersionKind()
|
||||
return fmt.Sprintf("%s/%s/%s/%s", gvk.GroupVersion().String(), gvk.Kind, r.Namespace, r.Name)
|
||||
}
|
||||
|
||||
func mergeCustomLabels(current, desired map[string]string) map[string]string {
|
||||
labels := mergeStrStrMaps(current, desired)
|
||||
for k, v := range labels {
|
||||
if v == "null" {
|
||||
delete(labels, k)
|
||||
}
|
||||
}
|
||||
return labels
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user