From 197e466b9a72be8999436ca756deab16452f752a Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Thu, 25 Aug 2016 09:06:14 -0600 Subject: [PATCH 1/2] ref(*): return resource update errors Resolves #1058 --- cmd/helm/upgrade.go | 2 +- cmd/tiller/release_server.go | 2 +- pkg/kube/client.go | 16 +++++++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 3b7de8ec8..10251dadd 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -125,7 +125,7 @@ func (u *upgradeCmd) run() error { _, err = u.client.UpdateRelease(u.release, chartPath, helm.UpdateValueOverrides(rawVals), helm.UpgradeDryRun(u.dryRun), helm.UpgradeDisableHooks(u.disableHooks)) if err != nil { - return prettyError(err) + return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err)) } success := u.release + " has been upgraded. Happy Helming!\n" diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go index 5c103e90d..cd3de35f6 100644 --- a/cmd/tiller/release_server.go +++ b/cmd/tiller/release_server.go @@ -224,7 +224,7 @@ func (s *releaseServer) performUpdate(originalRelease, updatedRelease *release.R original := bytes.NewBufferString(originalRelease.Manifest) modified := bytes.NewBufferString(updatedRelease.Manifest) if err := kubeCli.Update(updatedRelease.Namespace, original, modified); err != nil { - return nil, fmt.Errorf("Update of %s failed: %s", updatedRelease.Name, err) + return nil, err } // post-upgrade hooks diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 6e5e74e30..529d2b4c4 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -22,6 +22,7 @@ import ( "io" "log" "reflect" + "strings" "time" "k8s.io/kubernetes/pkg/api" @@ -157,8 +158,9 @@ func (c *Client) Update(namespace string, currentReader, modifiedReader io.Reade } modifiedInfos := []*resource.Info{} + updateErrors := []string{} - modified.Visit(func(info *resource.Info, err error) error { + err = modified.Visit(func(info *resource.Info, err error) error { modifiedInfos = append(modifiedInfos, info) if err != nil { return err @@ -188,15 +190,23 @@ func (c *Client) Update(namespace string, currentReader, modifiedReader io.Reade if err := updateResource(info, currentObj); err != nil { log.Printf("error updating the resource %s:\n\t %v", resourceName, err) - return err + updateErrors = append(updateErrors, err.Error()) } - return err + return nil }) deleteUnwantedResources(currentInfos, modifiedInfos) + if err != nil { + return err + } else if len(updateErrors) != 0 { + return fmt.Errorf(strings.Join(updateErrors, " && ")) + + } + return nil + } // Delete deletes kubernetes resources from an io.reader From c7bec344541eebc0b270c2482c6172ad112baad4 Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Thu, 25 Aug 2016 09:32:16 -0600 Subject: [PATCH 2/2] chore(kube): make update logic more generic --- pkg/kube/client.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 529d2b4c4..1dd949663 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -129,13 +129,13 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) { return buf.String(), err } -// Update reads in the current configuration and a modified configuration from io.reader +// Update reads in the current configuration and a target configuration from io.reader // and creates resources that don't already exists, updates resources that have been modified -// and deletes resources from the current configuration that are not present in the -// modified configuration +// in the target configuration and deletes resources from the current configuration that are +// not present in the target configuration // // Namespace will set the namespaces -func (c *Client) Update(namespace string, currentReader, modifiedReader io.Reader) error { +func (c *Client) Update(namespace string, currentReader, targetReader io.Reader) error { current := c.NewBuilder(includeThirdPartyAPIs). ContinueOnError(). NamespaceParam(namespace). @@ -144,11 +144,11 @@ func (c *Client) Update(namespace string, currentReader, modifiedReader io.Reade Flatten(). Do() - modified := c.NewBuilder(includeThirdPartyAPIs). + target := c.NewBuilder(includeThirdPartyAPIs). ContinueOnError(). NamespaceParam(namespace). DefaultNamespace(). - Stream(modifiedReader, ""). + Stream(targetReader, ""). Flatten(). Do() @@ -157,11 +157,11 @@ func (c *Client) Update(namespace string, currentReader, modifiedReader io.Reade return err } - modifiedInfos := []*resource.Info{} + targetInfos := []*resource.Info{} updateErrors := []string{} - err = modified.Visit(func(info *resource.Info, err error) error { - modifiedInfos = append(modifiedInfos, info) + err = target.Visit(func(info *resource.Info, err error) error { + targetInfos = append(targetInfos, info) if err != nil { return err } @@ -196,7 +196,7 @@ func (c *Client) Update(namespace string, currentReader, modifiedReader io.Reade return nil }) - deleteUnwantedResources(currentInfos, modifiedInfos) + deleteUnwantedResources(currentInfos, targetInfos) if err != nil { return err @@ -292,7 +292,7 @@ func deleteResource(info *resource.Info) error { return resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name) } -func updateResource(modified *resource.Info, currentObj runtime.Object) error { +func updateResource(target *resource.Info, currentObj runtime.Object) error { encoder := api.Codecs.LegacyCodec(registered.EnabledVersions()...) originalSerialization, err := runtime.Encode(encoder, currentObj) @@ -300,7 +300,7 @@ func updateResource(modified *resource.Info, currentObj runtime.Object) error { return err } - editedSerialization, err := runtime.Encode(encoder, modified.Object) + editedSerialization, err := runtime.Encode(encoder, target.Object) if err != nil { return err } @@ -316,7 +316,7 @@ func updateResource(modified *resource.Info, currentObj runtime.Object) error { } if reflect.DeepEqual(originalJS, editedJS) { - return fmt.Errorf("Looks like there are no changes for %s", modified.Name) + return fmt.Errorf("Looks like there are no changes for %s", target.Name) } patch, err := strategicpatch.CreateStrategicMergePatch(originalJS, editedJS, currentObj) @@ -325,8 +325,8 @@ func updateResource(modified *resource.Info, currentObj runtime.Object) error { } // send patch to server - helper := resource.NewHelper(modified.Client, modified.Mapping) - if _, err = helper.Patch(modified.Namespace, modified.Name, api.StrategicMergePatchType, patch); err != nil { + helper := resource.NewHelper(target.Client, target.Mapping) + if _, err = helper.Patch(target.Namespace, target.Name, api.StrategicMergePatchType, patch); err != nil { return err } @@ -411,10 +411,10 @@ func (c *Client) ensureNamespace(namespace string) error { return nil } -func deleteUnwantedResources(currentInfos, modifiedInfos []*resource.Info) { +func deleteUnwantedResources(currentInfos, targetInfos []*resource.Info) { for _, cInfo := range currentInfos { found := false - for _, m := range modifiedInfos { + for _, m := range targetInfos { if m.Name == cInfo.Name { found = true }