github.com/zoumo/helm@v2.5.0+incompatible/pkg/tiller/release_uninstall.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package tiller
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	ctx "golang.org/x/net/context"
    24  
    25  	"k8s.io/helm/pkg/hooks"
    26  	"k8s.io/helm/pkg/proto/hapi/release"
    27  	"k8s.io/helm/pkg/proto/hapi/services"
    28  	relutil "k8s.io/helm/pkg/releaseutil"
    29  	"k8s.io/helm/pkg/timeconv"
    30  )
    31  
    32  // UninstallRelease deletes all of the resources associated with this release, and marks the release DELETED.
    33  func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) {
    34  	if !ValidName.MatchString(req.Name) {
    35  		s.Log("uninstall: Release not found: %s", req.Name)
    36  		return nil, errMissingRelease
    37  	}
    38  
    39  	if len(req.Name) > releaseNameMaxLen {
    40  		return nil, fmt.Errorf("release name %q exceeds max length of %d", req.Name, releaseNameMaxLen)
    41  	}
    42  
    43  	err := s.env.Releases.LockRelease(req.Name)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	defer s.env.Releases.UnlockRelease(req.Name)
    48  
    49  	rels, err := s.env.Releases.History(req.Name)
    50  	if err != nil {
    51  		s.Log("uninstall: Release not loaded: %s", req.Name)
    52  		return nil, err
    53  	}
    54  	if len(rels) < 1 {
    55  		return nil, errMissingRelease
    56  	}
    57  
    58  	relutil.SortByRevision(rels)
    59  	rel := rels[len(rels)-1]
    60  
    61  	// TODO: Are there any cases where we want to force a delete even if it's
    62  	// already marked deleted?
    63  	if rel.Info.Status.Code == release.Status_DELETED {
    64  		if req.Purge {
    65  			if err := s.purgeReleases(rels...); err != nil {
    66  				s.Log("uninstall: Failed to purge the release: %s", err)
    67  				return nil, err
    68  			}
    69  			return &services.UninstallReleaseResponse{Release: rel}, nil
    70  		}
    71  		return nil, fmt.Errorf("the release named %q is already deleted", req.Name)
    72  	}
    73  
    74  	s.Log("uninstall: Deleting %s", req.Name)
    75  	rel.Info.Status.Code = release.Status_DELETING
    76  	rel.Info.Deleted = timeconv.Now()
    77  	rel.Info.Description = "Deletion in progress (or silently failed)"
    78  	res := &services.UninstallReleaseResponse{Release: rel}
    79  
    80  	if !req.DisableHooks {
    81  		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PreDelete, req.Timeout); err != nil {
    82  			return res, err
    83  		}
    84  	} else {
    85  		s.Log("delete hooks disabled for %s", req.Name)
    86  	}
    87  
    88  	// From here on out, the release is currently considered to be in Status_DELETING
    89  	// state.
    90  	if err := s.env.Releases.Update(rel); err != nil {
    91  		s.Log("uninstall: Failed to store updated release: %s", err)
    92  	}
    93  
    94  	kept, errs := s.ReleaseModule.Delete(rel, req, s.env)
    95  	res.Info = kept
    96  
    97  	es := make([]string, 0, len(errs))
    98  	for _, e := range errs {
    99  		s.Log("error: %v", e)
   100  		es = append(es, e.Error())
   101  	}
   102  
   103  	if !req.DisableHooks {
   104  		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PostDelete, req.Timeout); err != nil {
   105  			es = append(es, err.Error())
   106  		}
   107  	}
   108  
   109  	rel.Info.Status.Code = release.Status_DELETED
   110  	rel.Info.Description = "Deletion complete"
   111  
   112  	if req.Purge {
   113  		s.Log("purge requested for %s", req.Name)
   114  		err := s.purgeReleases(rels...)
   115  		if err != nil {
   116  			s.Log("uninstall: Failed to purge the release: %s", err)
   117  		}
   118  		return res, err
   119  	}
   120  
   121  	if err := s.env.Releases.Update(rel); err != nil {
   122  		s.Log("uninstall: Failed to store updated release: %s", err)
   123  	}
   124  
   125  	if len(es) > 0 {
   126  		return res, fmt.Errorf("deletion completed with %d error(s): %s", len(es), strings.Join(es, "; "))
   127  	}
   128  	return res, nil
   129  }
   130  
   131  func (s *ReleaseServer) purgeReleases(rels ...*release.Release) error {
   132  	for _, rel := range rels {
   133  		if _, err := s.env.Releases.Delete(rel.Name, rel.Version); err != nil {
   134  			return err
   135  		}
   136  	}
   137  	return nil
   138  }