github.com/wangchanggan/helm@v0.0.0-20211020154240-11b1b7d5406d/pkg/tiller/release_uninstall.go (about)

     1  /*
     2  Copyright The Helm Authors.
     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 err := validateReleaseName(req.Name); err != nil {
    35  		s.Log("uninstallRelease: Release name is invalid: %s", req.Name)
    36  		return nil, err
    37  	}
    38  
    39  	// 首先根据传递过来的参数去configmap中获取对应的Release对象,不同的是,这里获取的是一个列表,把该名称下的Release所有的历史记录都取回来
    40  	rels, err := s.env.Releases.History(req.Name)
    41  	if err != nil {
    42  		s.Log("uninstall: Release not loaded: %s", req.Name)
    43  		return nil, err
    44  	}
    45  	if len(rels) < 1 {
    46  		return nil, errMissingRelease
    47  	}
    48  
    49  	relutil.SortByRevision(rels)
    50  	rel := rels[len(rels)-1]
    51  
    52  	// TODO: Are there any cases where we want to force a delete even if it's
    53  	// already marked deleted?
    54  	// 如果上一次没有强制删除,即么这一次就有要判断是否会对已经制除过的Release进行强制副除操作
    55  	if rel.Info.Status.Code == release.Status_DELETED {
    56  		if req.Purge {
    57  			if err := s.purgeReleases(rels...); err != nil {
    58  				s.Log("uninstall: Failed to purge the release: %s", err)
    59  				return nil, err
    60  			}
    61  			return &services.UninstallReleaseResponse{Release: rel}, nil
    62  		}
    63  		return nil, fmt.Errorf("the release named %q is already deleted", req.Name)
    64  	}
    65  
    66  	s.Log("uninstall: Deleting %s", req.Name)
    67  	rel.Info.Status.Code = release.Status_DELETING
    68  	rel.Info.Deleted = timeconv.Now()
    69  	rel.Info.Description = "Deletion in progress (or silently failed)"
    70  	res := &services.UninstallReleaseResponse{Release: rel}
    71  
    72  	// 针对删除时需要执行的Hooks. 所有删除资源时需要执行的Hooks都是在这个函数下进行操作的
    73  	// 如果用户指定了不执行Hooks,那么就会直接进行到下一步
    74  	if !req.DisableHooks {
    75  		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PreDelete, req.Timeout); err != nil {
    76  			return res, err
    77  		}
    78  	} else {
    79  		s.Log("delete hooks disabled for %s", req.Name)
    80  	}
    81  
    82  	// From here on out, the release is currently considered to be in Status_DELETING
    83  	// state.
    84  	// 这里首先标记Release的状态为删除中。有时删除资源的进程会比较长,所以先将状态置为删除中
    85  	if err := s.env.Releases.Update(rel); err != nil {
    86  		s.Log("uninstall: Failed to store updated release: %s", err)
    87  	}
    88  
    89  	// 进行真正的删除操作,主要是将Chart指定的资源进行移除,类比于kubectl delete -f,但是最终会留下真正的Release信息
    90  	kept, errs := s.ReleaseModule.Delete(rel, req, s.env)
    91  	res.Info = kept
    92  
    93  	es := make([]string, 0, len(errs))
    94  	for _, e := range errs {
    95  		s.Log("error: %v", e)
    96  		es = append(es, e.Error())
    97  	}
    98  
    99  	if !req.DisableHooks {
   100  		if err := s.execHook(rel.Hooks, rel.Name, rel.Namespace, hooks.PostDelete, req.Timeout); err != nil {
   101  			es = append(es, err.Error())
   102  		}
   103  	}
   104  
   105  	rel.Info.Status.Code = release.Status_DELETED
   106  	if req.Description == "" {
   107  		rel.Info.Description = "Deletion complete"
   108  	} else {
   109  		rel.Info.Description = req.Description
   110  	}
   111  
   112  	// 如果指定了强制删除,就会将资源和Release信息一并删除
   113  	if req.Purge {
   114  		s.Log("purge requested for %s", req.Name)
   115  		err := s.purgeReleases(rels...)
   116  		if err != nil {
   117  			s.Log("uninstall: Failed to purge the release: %s", err)
   118  		}
   119  		return res, err
   120  	}
   121  
   122  	if err := s.env.Releases.Update(rel); err != nil {
   123  		s.Log("uninstall: Failed to store updated release: %s", err)
   124  	}
   125  
   126  	if len(es) > 0 {
   127  		return res, fmt.Errorf("deletion completed with %d error(s): %s", len(es), strings.Join(es, "; "))
   128  	}
   129  	return res, nil
   130  }
   131  
   132  func (s *ReleaseServer) purgeReleases(rels ...*release.Release) error {
   133  	for _, rel := range rels {
   134  		if _, err := s.env.Releases.Delete(rel.Name, rel.Version); err != nil {
   135  			return err
   136  		}
   137  	}
   138  	return nil
   139  }