feat(tiller): Adds more logging

This builds on previous work and adds more logging to follow
the full process of installing, updating, deleting, and rolling back.
This also standardizes capitalization of logs and small formatting
fixes
pull/2513/head
Taylor Thomas 8 years ago
parent f250fce921
commit 119fa6537c

@ -22,7 +22,6 @@ import (
goerrors "errors" goerrors "errors"
"fmt" "fmt"
"io" "io"
"log"
"strings" "strings"
"time" "time"
@ -86,10 +85,12 @@ func (c *Client) Create(namespace string, reader io.Reader, timeout int64, shoul
if err := ensureNamespace(client, namespace); err != nil { if err := ensureNamespace(client, namespace); err != nil {
return err return err
} }
c.Log("building resources from manifest")
infos, buildErr := c.BuildUnstructured(namespace, reader) infos, buildErr := c.BuildUnstructured(namespace, reader)
if buildErr != nil { if buildErr != nil {
return buildErr return buildErr
} }
c.Log("creating %d resource(s)", len(infos))
if err := perform(infos, createResource); err != nil { if err := perform(infos, createResource); err != nil {
return err return err
} }
@ -217,6 +218,7 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
return fmt.Errorf("failed decoding reader into objects: %s", err) return fmt.Errorf("failed decoding reader into objects: %s", err)
} }
c.Log("building resources from updated manifest")
target, err := c.BuildUnstructured(namespace, targetReader) target, err := c.BuildUnstructured(namespace, targetReader)
if err != nil { if err != nil {
return fmt.Errorf("failed decoding reader into objects: %s", err) return fmt.Errorf("failed decoding reader into objects: %s", err)
@ -224,6 +226,7 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
updateErrors := []string{} updateErrors := []string{}
c.Log("checking %d resources for changes", len(target))
err = target.Visit(func(info *resource.Info, err error) error { err = target.Visit(func(info *resource.Info, err error) error {
if err != nil { if err != nil {
return err return err
@ -232,7 +235,7 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader
helper := resource.NewHelper(info.Client, info.Mapping) helper := resource.NewHelper(info.Client, info.Mapping)
if _, err := helper.Get(info.Namespace, info.Name, info.Export); err != nil { if _, err := helper.Get(info.Namespace, info.Name, info.Export); err != nil {
if !errors.IsNotFound(err) { if !errors.IsNotFound(err) {
return fmt.Errorf("Could not get information about the resource: err: %s", err) return fmt.Errorf("Could not get information about the resource: %s", err)
} }
// Since the resource does not exist, create it. // Since the resource does not exist, create it.
@ -386,7 +389,6 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b
case err != nil: case err != nil:
return nil, types.StrategicMergePatchType, fmt.Errorf("failed to get versionedObject: %s", err) return nil, types.StrategicMergePatchType, fmt.Errorf("failed to get versionedObject: %s", err)
default: default:
log.Printf("generating strategic merge patch for %T", target)
patch, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, versionedObject) patch, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, versionedObject)
return patch, types.StrategicMergePatchType, err return patch, types.StrategicMergePatchType, err
} }

@ -17,7 +17,6 @@ limitations under the License.
package kube // import "k8s.io/helm/pkg/kube" package kube // import "k8s.io/helm/pkg/kube"
import ( import (
"log"
"time" "time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -44,7 +43,7 @@ type deployment struct {
// waitForResources polls to get the current status of all pods, PVCs, and Services // waitForResources polls to get the current status of all pods, PVCs, and Services
// until all are ready or a timeout is reached // until all are ready or a timeout is reached
func (c *Client) waitForResources(timeout time.Duration, created Result) error { func (c *Client) waitForResources(timeout time.Duration, created Result) error {
log.Printf("beginning wait for resources with timeout of %v", timeout) c.Log("beginning wait for %d resources with timeout of %v", len(created), timeout)
cs, err := c.ClientSet() cs, err := c.ClientSet()
if err != nil { if err != nil {
@ -121,7 +120,9 @@ func (c *Client) waitForResources(timeout time.Duration, created Result) error {
services = append(services, *svc) services = append(services, *svc)
} }
} }
return podsReady(pods) && servicesReady(services) && volumesReady(pvc) && deploymentsReady(deployments), nil isReady := podsReady(pods) && servicesReady(services) && volumesReady(pvc) && deploymentsReady(deployments)
c.Log("resources ready: %v", isReady)
return isReady, nil
}) })
} }

@ -41,7 +41,7 @@ type Storage struct {
// if the storage driver failed to fetch the release, or the // if the storage driver failed to fetch the release, or the
// release identified by the key, version pair does not exist. // release identified by the key, version pair does not exist.
func (s *Storage) Get(name string, version int32) (*rspb.Release, error) { func (s *Storage) Get(name string, version int32) (*rspb.Release, error) {
s.Log("Getting release %q", makeKey(name, version)) s.Log("getting release %q", makeKey(name, version))
return s.Driver.Get(makeKey(name, version)) return s.Driver.Get(makeKey(name, version))
} }
@ -49,7 +49,7 @@ func (s *Storage) Get(name string, version int32) (*rspb.Release, error) {
// error is returned if the storage driver failed to store the // error is returned if the storage driver failed to store the
// release, or a release with identical an key already exists. // release, or a release with identical an key already exists.
func (s *Storage) Create(rls *rspb.Release) error { func (s *Storage) Create(rls *rspb.Release) error {
s.Log("Creating release %q", makeKey(rls.Name, rls.Version)) s.Log("creating release %q", makeKey(rls.Name, rls.Version))
return s.Driver.Create(makeKey(rls.Name, rls.Version), rls) return s.Driver.Create(makeKey(rls.Name, rls.Version), rls)
} }
@ -57,7 +57,7 @@ func (s *Storage) Create(rls *rspb.Release) error {
// storage backend fails to update the release or if the release // storage backend fails to update the release or if the release
// does not exist. // does not exist.
func (s *Storage) Update(rls *rspb.Release) error { func (s *Storage) Update(rls *rspb.Release) error {
s.Log("Updating release %q", makeKey(rls.Name, rls.Version)) s.Log("updating release %q", makeKey(rls.Name, rls.Version))
return s.Driver.Update(makeKey(rls.Name, rls.Version), rls) return s.Driver.Update(makeKey(rls.Name, rls.Version), rls)
} }
@ -65,21 +65,21 @@ func (s *Storage) Update(rls *rspb.Release) error {
// the storage backend fails to delete the release or if the release // the storage backend fails to delete the release or if the release
// does not exist. // does not exist.
func (s *Storage) Delete(name string, version int32) (*rspb.Release, error) { func (s *Storage) Delete(name string, version int32) (*rspb.Release, error) {
s.Log("Deleting release %q", makeKey(name, version)) s.Log("deleting release %q", makeKey(name, version))
return s.Driver.Delete(makeKey(name, version)) return s.Driver.Delete(makeKey(name, version))
} }
// ListReleases returns all releases from storage. An error is returned if the // ListReleases returns all releases from storage. An error is returned if the
// storage backend fails to retrieve the releases. // storage backend fails to retrieve the releases.
func (s *Storage) ListReleases() ([]*rspb.Release, error) { func (s *Storage) ListReleases() ([]*rspb.Release, error) {
s.Log("Listing all releases in storage") s.Log("listing all releases in storage")
return s.Driver.List(func(_ *rspb.Release) bool { return true }) return s.Driver.List(func(_ *rspb.Release) bool { return true })
} }
// ListDeleted returns all releases with Status == DELETED. An error is returned // ListDeleted returns all releases with Status == DELETED. An error is returned
// if the storage backend fails to retrieve the releases. // if the storage backend fails to retrieve the releases.
func (s *Storage) ListDeleted() ([]*rspb.Release, error) { func (s *Storage) ListDeleted() ([]*rspb.Release, error) {
s.Log("Listing deleted releases in storage") s.Log("listing deleted releases in storage")
return s.Driver.List(func(rls *rspb.Release) bool { return s.Driver.List(func(rls *rspb.Release) bool {
return relutil.StatusFilter(rspb.Status_DELETED).Check(rls) return relutil.StatusFilter(rspb.Status_DELETED).Check(rls)
}) })
@ -88,7 +88,7 @@ func (s *Storage) ListDeleted() ([]*rspb.Release, error) {
// ListDeployed returns all releases with Status == DEPLOYED. An error is returned // ListDeployed returns all releases with Status == DEPLOYED. An error is returned
// if the storage backend fails to retrieve the releases. // if the storage backend fails to retrieve the releases.
func (s *Storage) ListDeployed() ([]*rspb.Release, error) { func (s *Storage) ListDeployed() ([]*rspb.Release, error) {
s.Log("Listing all deployed releases in storage") s.Log("listing all deployed releases in storage")
return s.Driver.List(func(rls *rspb.Release) bool { return s.Driver.List(func(rls *rspb.Release) bool {
return relutil.StatusFilter(rspb.Status_DEPLOYED).Check(rls) return relutil.StatusFilter(rspb.Status_DEPLOYED).Check(rls)
}) })
@ -98,7 +98,7 @@ func (s *Storage) ListDeployed() ([]*rspb.Release, error) {
// (filter0 && filter1 && ... && filterN), i.e. a Release is included in the results // (filter0 && filter1 && ... && filterN), i.e. a Release is included in the results
// if and only if all filters return true. // if and only if all filters return true.
func (s *Storage) ListFilterAll(fns ...relutil.FilterFunc) ([]*rspb.Release, error) { func (s *Storage) ListFilterAll(fns ...relutil.FilterFunc) ([]*rspb.Release, error) {
s.Log("Listing all releases with filter") s.Log("listing all releases with filter")
return s.Driver.List(func(rls *rspb.Release) bool { return s.Driver.List(func(rls *rspb.Release) bool {
return relutil.All(fns...).Check(rls) return relutil.All(fns...).Check(rls)
}) })
@ -108,7 +108,7 @@ func (s *Storage) ListFilterAll(fns ...relutil.FilterFunc) ([]*rspb.Release, err
// (filter0 || filter1 || ... || filterN), i.e. a Release is included in the results // (filter0 || filter1 || ... || filterN), i.e. a Release is included in the results
// if at least one of the filters returns true. // if at least one of the filters returns true.
func (s *Storage) ListFilterAny(fns ...relutil.FilterFunc) ([]*rspb.Release, error) { func (s *Storage) ListFilterAny(fns ...relutil.FilterFunc) ([]*rspb.Release, error) {
s.Log("Listing any releases with filter") s.Log("listing any releases with filter")
return s.Driver.List(func(rls *rspb.Release) bool { return s.Driver.List(func(rls *rspb.Release) bool {
return relutil.Any(fns...).Check(rls) return relutil.Any(fns...).Check(rls)
}) })
@ -117,7 +117,7 @@ func (s *Storage) ListFilterAny(fns ...relutil.FilterFunc) ([]*rspb.Release, err
// Deployed returns the deployed release with the provided release name, or // Deployed returns the deployed release with the provided release name, or
// returns ErrReleaseNotFound if not found. // returns ErrReleaseNotFound if not found.
func (s *Storage) Deployed(name string) (*rspb.Release, error) { func (s *Storage) Deployed(name string) (*rspb.Release, error) {
s.Log("Getting deployed release from %q history", name) s.Log("getting deployed release from %q history", name)
ls, err := s.Driver.Query(map[string]string{ ls, err := s.Driver.Query(map[string]string{
"NAME": name, "NAME": name,
@ -137,14 +137,14 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) {
// History returns the revision history for the release with the provided name, or // History returns the revision history for the release with the provided name, or
// returns ErrReleaseNotFound if no such release name exists. // returns ErrReleaseNotFound if no such release name exists.
func (s *Storage) History(name string) ([]*rspb.Release, error) { func (s *Storage) History(name string) ([]*rspb.Release, error) {
s.Log("Getting release history for %q", name) s.Log("getting release history for %q", name)
return s.Driver.Query(map[string]string{"NAME": name, "OWNER": "TILLER"}) return s.Driver.Query(map[string]string{"NAME": name, "OWNER": "TILLER"})
} }
// Last fetches the last revision of the named release. // Last fetches the last revision of the named release.
func (s *Storage) Last(name string) (*rspb.Release, error) { func (s *Storage) Last(name string) (*rspb.Release, error) {
s.Log("Getting last revision of %q", name) s.Log("getting last revision of %q", name)
h, err := s.History(name) h, err := s.History(name)
if err != nil { if err != nil {
return nil, err return nil, err
@ -159,6 +159,7 @@ func (s *Storage) Last(name string) (*rspb.Release, error) {
// LockRelease gains a mutually exclusive access to a release via a mutex. // LockRelease gains a mutually exclusive access to a release via a mutex.
func (s *Storage) LockRelease(name string) error { func (s *Storage) LockRelease(name string) error {
s.Log("locking release %s", name)
s.releaseLocksLock.Lock() s.releaseLocksLock.Lock()
defer s.releaseLocksLock.Unlock() defer s.releaseLocksLock.Unlock()
@ -191,6 +192,7 @@ func (s *Storage) LockRelease(name string) error {
// UnlockRelease releases a mutually exclusive access to a release. // UnlockRelease releases a mutually exclusive access to a release.
// If release doesn't exist or wasn't previously locked - the unlock will pass // If release doesn't exist or wasn't previously locked - the unlock will pass
func (s *Storage) UnlockRelease(name string) { func (s *Storage) UnlockRelease(name string) {
s.Log("unlocking release %s", name)
s.releaseLocksLock.Lock() s.releaseLocksLock.Lock()
defer s.releaseLocksLock.Unlock() defer s.releaseLocksLock.Unlock()

@ -25,6 +25,7 @@ import (
// GetHistory gets the history for a given release. // GetHistory gets the history for a given release.
func (s *ReleaseServer) GetHistory(ctx context.Context, req *tpb.GetHistoryRequest) (*tpb.GetHistoryResponse, error) { func (s *ReleaseServer) GetHistory(ctx context.Context, req *tpb.GetHistoryRequest) (*tpb.GetHistoryResponse, error) {
s.Log("getting history for release %s", req.Name)
h, err := s.env.Releases.History(req.Name) h, err := s.env.Releases.History(req.Name)
if err != nil { if err != nil {
return nil, err return nil, err

@ -18,6 +18,8 @@ package tiller
import ( import (
"fmt" "fmt"
"strings"
ctx "golang.org/x/net/context" ctx "golang.org/x/net/context"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/hooks" "k8s.io/helm/pkg/hooks"
@ -25,14 +27,14 @@ import (
"k8s.io/helm/pkg/proto/hapi/services" "k8s.io/helm/pkg/proto/hapi/services"
relutil "k8s.io/helm/pkg/releaseutil" relutil "k8s.io/helm/pkg/releaseutil"
"k8s.io/helm/pkg/timeconv" "k8s.io/helm/pkg/timeconv"
"strings"
) )
// InstallRelease installs a release and stores the release record. // InstallRelease installs a release and stores the release record.
func (s *ReleaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) { func (s *ReleaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
s.Log("preparing install for %s", req.Name)
rel, err := s.prepareRelease(req) rel, err := s.prepareRelease(req)
if err != nil { if err != nil {
s.Log("Failed install prepare step: %s", err) s.Log("failed install prepare step: %s", err)
res := &services.InstallReleaseResponse{Release: rel} res := &services.InstallReleaseResponse{Release: rel}
// On dry run, append the manifest contents to a failed release. This is // On dry run, append the manifest contents to a failed release. This is
@ -43,9 +45,10 @@ func (s *ReleaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea
return res, err return res, err
} }
s.Log("performing install for %s", req.Name)
res, err := s.performRelease(rel, req) res, err := s.performRelease(rel, req)
if err != nil { if err != nil {
s.Log("Failed install perform step: %s", err) s.Log("failed install perform step: %s", err)
} }
return res, err return res, err
} }
@ -132,7 +135,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
res := &services.InstallReleaseResponse{Release: r} res := &services.InstallReleaseResponse{Release: r}
if req.DryRun { if req.DryRun {
s.Log("Dry run for %s", r.Name) s.Log("dry run for %s", r.Name)
res.Release.Info.Description = "Dry run complete" res.Release.Info.Description = "Dry run complete"
return res, nil return res, nil
} }
@ -142,11 +145,14 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PreInstall, req.Timeout); err != nil { if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PreInstall, req.Timeout); err != nil {
return res, err return res, err
} }
} else {
s.Log("install hooks disabled for %s", req.Name)
} }
switch h, err := s.env.Releases.History(req.Name); { switch h, err := s.env.Releases.History(req.Name); {
// if this is a replace operation, append to the release history // if this is a replace operation, append to the release history
case req.ReuseName && err == nil && len(h) >= 1: case req.ReuseName && err == nil && len(h) >= 1:
s.Log("name reuse for %s requested, replacing release", req.Name)
// get latest release revision // get latest release revision
relutil.Reverse(h, relutil.SortByRevision) relutil.Reverse(h, relutil.SortByRevision)

@ -18,6 +18,7 @@ package tiller
import ( import (
"fmt" "fmt"
ctx "golang.org/x/net/context" ctx "golang.org/x/net/context"
"k8s.io/helm/pkg/hooks" "k8s.io/helm/pkg/hooks"
"k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/release"
@ -33,17 +34,20 @@ func (s *ReleaseServer) RollbackRelease(c ctx.Context, req *services.RollbackRel
} }
defer s.env.Releases.UnlockRelease(req.Name) defer s.env.Releases.UnlockRelease(req.Name)
s.Log("preparing rollback of %s", req.Name)
currentRelease, targetRelease, err := s.prepareRollback(req) currentRelease, targetRelease, err := s.prepareRollback(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
s.Log("performing rollback of %s", req.Name)
res, err := s.performRollback(currentRelease, targetRelease, req) res, err := s.performRollback(currentRelease, targetRelease, req)
if err != nil { if err != nil {
return res, err return res, err
} }
if !req.DryRun { if !req.DryRun {
s.Log("creating rolled back release %s", req.Name)
if err := s.env.Releases.Create(targetRelease); err != nil { if err := s.env.Releases.Create(targetRelease); err != nil {
return res, err return res, err
} }
@ -53,7 +57,7 @@ func (s *ReleaseServer) RollbackRelease(c ctx.Context, req *services.RollbackRel
} }
// prepareRollback finds the previous release and prepares a new release object with // prepareRollback finds the previous release and prepares a new release object with
// the previous release's configuration // the previous release's configuration
func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) { func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) {
switch { switch {
case !ValidName.MatchString(req.Name): case !ValidName.MatchString(req.Name):
@ -108,7 +112,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
res := &services.RollbackReleaseResponse{Release: targetRelease} res := &services.RollbackReleaseResponse{Release: targetRelease}
if req.DryRun { if req.DryRun {
s.Log("Dry run for %s", targetRelease.Name) s.Log("dry run for %s", targetRelease.Name)
return res, nil return res, nil
} }
@ -117,6 +121,8 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, hooks.PreRollback, req.Timeout); err != nil { if err := s.execHook(targetRelease.Hooks, targetRelease.Name, targetRelease.Namespace, hooks.PreRollback, req.Timeout); err != nil {
return res, err return res, err
} }
} else {
s.Log("rollback hooks disabled for %s", req.Name)
} }
if err := s.ReleaseModule.Rollback(currentRelease, targetRelease, req, s.env); err != nil { if err := s.ReleaseModule.Rollback(currentRelease, targetRelease, req, s.env); err != nil {

@ -113,13 +113,13 @@ func NewReleaseServer(env *environment.Environment, clientset internalclientset.
func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current *release.Release) error { func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current *release.Release) error {
if req.ResetValues { if req.ResetValues {
// If ResetValues is set, we comletely ignore current.Config. // If ResetValues is set, we comletely ignore current.Config.
s.Log("Reset values to the chart's original version.") s.Log("resetting values to the chart's original version")
return nil return nil
} }
// If the ReuseValues flag is set, we always copy the old values over the new config's values. // If the ReuseValues flag is set, we always copy the old values over the new config's values.
if req.ReuseValues { if req.ReuseValues {
s.Log("Reusing the old release's values") s.Log("reusing the old release's values")
// We have to regenerate the old coalesced values: // We have to regenerate the old coalesced values:
oldVals, err := chartutil.CoalesceValues(current.Chart, current.Config) oldVals, err := chartutil.CoalesceValues(current.Chart, current.Config)
@ -142,7 +142,7 @@ func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current
current.Config != nil && current.Config != nil &&
current.Config.Raw != "" && current.Config.Raw != "" &&
current.Config.Raw != "{}\n" { current.Config.Raw != "{}\n" {
s.Log("Copying values from %s (v%d) to new release.", current.Name, current.Version) s.Log("copying values from %s (v%d) to new release.", current.Name, current.Version)
req.Values = current.Config req.Values = current.Config
} }
return nil return nil
@ -168,13 +168,13 @@ func (s *ReleaseServer) uniqName(start string, reuse bool) (string, error) {
if st := rel.Info.Status.Code; reuse && (st == release.Status_DELETED || st == release.Status_FAILED) { if st := rel.Info.Status.Code; reuse && (st == release.Status_DELETED || st == release.Status_FAILED) {
// Allowe re-use of names if the previous release is marked deleted. // Allowe re-use of names if the previous release is marked deleted.
s.Log("reusing name %q", start) s.Log("name %s exists but is not in use, reusing name", start)
return start, nil return start, nil
} else if reuse { } else if reuse {
return "", errors.New("cannot re-use a name that is still in use") return "", errors.New("cannot re-use a name that is still in use")
} }
return "", fmt.Errorf("a release named %q already exists.\nPlease run: helm ls --all %q; helm del --help", start, start) return "", fmt.Errorf("a release named %s already exists.\nRun: helm ls --all %s; to check the status of the release\nOr run: helm del --purge %s; to delete it", start, start, start)
} }
maxTries := 5 maxTries := 5
@ -187,7 +187,7 @@ func (s *ReleaseServer) uniqName(start string, reuse bool) (string, error) {
if _, err := s.env.Releases.Get(name, 1); strings.Contains(err.Error(), "not found") { if _, err := s.env.Releases.Get(name, 1); strings.Contains(err.Error(), "not found") {
return name, nil return name, nil
} }
s.Log("info: Name %q is taken. Searching again.", name) s.Log("info: generated name %s is taken. Searching again.", name)
} }
s.Log("warning: No available release names found after %d tries", maxTries) s.Log("warning: No available release names found after %d tries", maxTries)
return "ERROR", errors.New("no available release name found") return "ERROR", errors.New("no available release name found")
@ -249,6 +249,7 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values
return nil, nil, "", fmt.Errorf("Chart incompatible with Tiller %s", sver) return nil, nil, "", fmt.Errorf("Chart incompatible with Tiller %s", sver)
} }
s.Log("rendering %s chart using values", ch.GetMetadata().Name)
renderer := s.engine(ch) renderer := s.engine(ch)
files, err := renderer.Render(ch, values) files, err := renderer.Render(ch, values)
if err != nil { if err != nil {
@ -306,10 +307,10 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values
func (s *ReleaseServer) recordRelease(r *release.Release, reuse bool) { func (s *ReleaseServer) recordRelease(r *release.Release, reuse bool) {
if reuse { if reuse {
if err := s.env.Releases.Update(r); err != nil { if err := s.env.Releases.Update(r); err != nil {
s.Log("warning: Failed to update release %q: %s", r.Name, err) s.Log("warning: Failed to update release %s: %s", r.Name, err)
} }
} else if err := s.env.Releases.Create(r); err != nil { } else if err := s.env.Releases.Create(r); err != nil {
s.Log("warning: Failed to record release %q: %s", r.Name, err) s.Log("warning: Failed to record release %s: %s", r.Name, err)
} }
} }
@ -317,10 +318,10 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin
kubeCli := s.env.KubeClient kubeCli := s.env.KubeClient
code, ok := events[hook] code, ok := events[hook]
if !ok { if !ok {
return fmt.Errorf("unknown hook %q", hook) return fmt.Errorf("unknown hook %s", hook)
} }
s.Log("Executing %s hooks for %s", hook, name) s.Log("executing %d %s hooks for %s", len(hs), hook, name)
executingHooks := []*release.Hook{} executingHooks := []*release.Hook{}
for _, h := range hs { for _, h := range hs {
for _, e := range h.Events { for _, e := range h.Events {
@ -336,20 +337,20 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin
b := bytes.NewBufferString(h.Manifest) b := bytes.NewBufferString(h.Manifest)
if err := kubeCli.Create(namespace, b, timeout, false); err != nil { if err := kubeCli.Create(namespace, b, timeout, false); err != nil {
s.Log("warning: Release %q %s %s failed: %s", name, hook, h.Path, err) s.Log("warning: Release %s %s %s failed: %s", name, hook, h.Path, err)
return err return err
} }
// No way to rewind a bytes.Buffer()? // No way to rewind a bytes.Buffer()?
b.Reset() b.Reset()
b.WriteString(h.Manifest) b.WriteString(h.Manifest)
if err := kubeCli.WatchUntilReady(namespace, b, timeout, false); err != nil { if err := kubeCli.WatchUntilReady(namespace, b, timeout, false); err != nil {
s.Log("warning: Release %q %s %s could not complete: %s", name, hook, h.Path, err) s.Log("warning: Release %s %s %s could not complete: %s", name, hook, h.Path, err)
return err return err
} }
h.LastRun = timeconv.Now() h.LastRun = timeconv.Now()
} }
s.Log("Hooks complete for %s %s", hook, name) s.Log("hooks complete for %s %s", hook, name)
return nil return nil
} }

@ -41,15 +41,15 @@ func (s *ReleaseServer) RunReleaseTest(req *services.TestReleaseRequest, stream
Timeout: req.Timeout, Timeout: req.Timeout,
Stream: stream, Stream: stream,
} }
s.Log("running tests for release %s", rel.Name)
tSuite, err := reltesting.NewTestSuite(rel) tSuite, err := reltesting.NewTestSuite(rel)
if err != nil { if err != nil {
s.Log("Error creating test suite for %s", rel.Name) s.Log("error creating test suite for %s: %s", rel.Name, err)
return err return err
} }
if err := tSuite.Run(testEnv); err != nil { if err := tSuite.Run(testEnv); err != nil {
s.Log("Error running test suite for %s", rel.Name) s.Log("error running test suite for %s: %s", rel.Name, err)
return err return err
} }

@ -18,13 +18,14 @@ package tiller
import ( import (
"fmt" "fmt"
"strings"
ctx "golang.org/x/net/context" ctx "golang.org/x/net/context"
"k8s.io/helm/pkg/hooks" "k8s.io/helm/pkg/hooks"
"k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/proto/hapi/services" "k8s.io/helm/pkg/proto/hapi/services"
relutil "k8s.io/helm/pkg/releaseutil" relutil "k8s.io/helm/pkg/releaseutil"
"k8s.io/helm/pkg/timeconv" "k8s.io/helm/pkg/timeconv"
"strings"
) )
// UninstallRelease deletes all of the resources associated with this release, and marks the release DELETED. // UninstallRelease deletes all of the resources associated with this release, and marks the release DELETED.
@ -79,6 +80,8 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR
if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PreDelete, req.Timeout); err != nil { if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PreDelete, req.Timeout); err != nil {
return res, err return res, err
} }
} else {
s.Log("delete hooks disabled for %s", req.Name)
} }
// From here on out, the release is currently considered to be in Status_DELETING // From here on out, the release is currently considered to be in Status_DELETING
@ -106,6 +109,7 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR
rel.Info.Description = "Deletion complete" rel.Info.Description = "Deletion complete"
if req.Purge { if req.Purge {
s.Log("purge requested for %s", req.Name)
err := s.purgeReleases(rels...) err := s.purgeReleases(rels...)
if err != nil { if err != nil {
s.Log("uninstall: Failed to purge the release: %s", err) s.Log("uninstall: Failed to purge the release: %s", err)

@ -18,6 +18,7 @@ package tiller
import ( import (
"fmt" "fmt"
ctx "golang.org/x/net/context" ctx "golang.org/x/net/context"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/hooks" "k8s.io/helm/pkg/hooks"
@ -34,17 +35,20 @@ func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
} }
defer s.env.Releases.UnlockRelease(req.Name) defer s.env.Releases.UnlockRelease(req.Name)
s.Log("preparing update for %s", req.Name)
currentRelease, updatedRelease, err := s.prepareUpdate(req) currentRelease, updatedRelease, err := s.prepareUpdate(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
s.Log("performing update for %s", req.Name)
res, err := s.performUpdate(currentRelease, updatedRelease, req) res, err := s.performUpdate(currentRelease, updatedRelease, req)
if err != nil { if err != nil {
return res, err return res, err
} }
if !req.DryRun { if !req.DryRun {
s.Log("creating updated release for %s", req.Name)
if err := s.env.Releases.Create(updatedRelease); err != nil { if err := s.env.Releases.Create(updatedRelease); err != nil {
return res, err return res, err
} }
@ -129,7 +133,7 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R
res := &services.UpdateReleaseResponse{Release: updatedRelease} res := &services.UpdateReleaseResponse{Release: updatedRelease}
if req.DryRun { if req.DryRun {
s.Log("Dry run for %s", updatedRelease.Name) s.Log("dry run for %s", updatedRelease.Name)
res.Release.Info.Description = "Dry run complete" res.Release.Info.Description = "Dry run complete"
return res, nil return res, nil
} }
@ -139,6 +143,8 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R
if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, hooks.PreUpgrade, req.Timeout); err != nil { if err := s.execHook(updatedRelease.Hooks, updatedRelease.Name, updatedRelease.Namespace, hooks.PreUpgrade, req.Timeout); err != nil {
return res, err return res, err
} }
} else {
s.Log("update hooks disabled for %s", req.Name)
} }
if err := s.ReleaseModule.Update(originalRelease, updatedRelease, req, s.env); err != nil { if err := s.ReleaseModule.Update(originalRelease, updatedRelease, req, s.env); err != nil {
msg := fmt.Sprintf("Upgrade %q failed: %s", updatedRelease.Name, err) msg := fmt.Sprintf("Upgrade %q failed: %s", updatedRelease.Name, err)

Loading…
Cancel
Save