Repository: istio/istio
File: pilot/pkg/bootstrap/configcontroller.go (Go)

Code before:
}

// checkAndRunNonRevisionLeaderElectionIfRequired checks the ConfigMap for leader election and runs non-revision leader election
// to figure out when the older leader has released the lock.
// Once the lock is acquired, it will close the activateCh channel to signal the per-revision leader to start writing status.
func (s *Server) checkAndRunNonRevisionLeaderElectionIfRequired(args *PilotArgs, activateCh chan struct{}) {
	cm, err := s.kubeClient.Kube().CoreV1().ConfigMaps(args.Namespace).Get(context.Background(), leaderelection.GatewayStatusController, v1.GetOptions{})
	if err != nil {
		// ConfigMap does not exist, so per-revision leader election should be active
		close(activateCh)
		return
	}
	leaderAnn, ok := cm.Annotations[k8sresourcelock.LeaderElectionRecordAnnotationKey]
	if ok {
		var leaderInfo struct {
			HolderIdentity string `json:"holderIdentity"`
		}
		if err := json.Unmarshal([]byte(leaderAnn), &leaderInfo); err == nil {
			if leaderInfo.HolderIdentity != "" {
				// Non-revision leader election should run, per-revision should be waiting for activation
				s.addTerminatingStartFunc("gateway status", func(stop <-chan struct{}) error {
					leaderelection.
						NewLeaderElection(args.Namespace, args.PodName, leaderelection.GatewayStatusController, args.Revision, s.kubeClient).
						AddRunFunction(func(leaderStop <-chan struct{}) {
							// now that we have the leader lock, we can activate the per-revision status writer
							close(activateCh)
							log.Infof("Activating gateway status writer")
							// <-leaderStop
						}).
						Run(stop)
					return nil
				})
				return
			}
		}
	}
	// If annotation missing or holderIdentity is blank, per-revision leader election should be active
	close(activateCh)
}


Review comment (suggestion):
Testing this out I got

```
panic: close of closed channel

goroutine 1294 [running]:
istio.io/istio/pilot/pkg/bootstrap.(*Server).checkAndRunNonRevisionLeaderElectionIfRequired.func1.1(0xc00169fa90?)
        istio.io/istio/pilot/pkg/bootstrap/configcontroller.go:516 +0x17
created by istio.io/istio/pilot/pkg/leaderelection.(*LeaderElection).create.func1 in goroutine 1385
        istio.io/istio/pilot/pkg/leaderelection/leaderelection.go:146 +0xa5
```

Code after:
	return kube.ExtractRoot(secret.Data)
}

// checkAndRunNonRevisionLeaderElectionIfRequired checks the ConfigMap for leader election and runs non-revision leader election
// to figure out when the older leader has released the lock.
// Once the lock is acquired, it will close the activateCh channel to signal the per-revision leader to start writing status.
func (s *Server) checkAndRunNonRevisionLeaderElectionIfRequired(args *PilotArgs, activateCh chan struct{}) {
	cm, err := s.kubeClient.Kube().CoreV1().ConfigMaps(args.Namespace).Get(context.Background(), leaderelection.GatewayStatusController, v1.GetOptions{})

	if errors.IsNotFound(err) {
		// ConfigMap does not exist, so per-revision leader election should be active
		close(activateCh)
		return
	}
	leaderAnn, ok := cm.Annotations[k8sresourcelock.LeaderElectionRecordAnnotationKey]
	if ok {
		var leaderInfo struct {
			HolderIdentity string `json:"holderIdentity"`
		}
		if err := json.Unmarshal([]byte(leaderAnn), &leaderInfo); err == nil {
			if leaderInfo.HolderIdentity != "" {
				// Non-revision leader election should run, per-revision should be waiting for activation
				s.addTerminatingStartFunc("gateway status", func(stop <-chan struct{}) error {
					secondStop := make(chan struct{})
					// if stop closes, ensure secondStop closes too
					go func() {
						<-stop
						select {
						case <-secondStop:
						default:
							close(secondStop)
						}
					}()
					leaderelection.
						NewLeaderElection(args.Namespace, args.PodName, leaderelection.GatewayStatusController, args.Revision, s.kubeClient).
						AddRunFunction(func(leaderStop <-chan struct{}) {
							// now that we have the leader lock, we can activate the per-revision status writer
							// first close the activateCh channel if it is not already closed
							log.Infof("Activating gateway status writer")
							select {
							case <-activateCh:
								// Channel already closed, do nothing
							default:
								close(activateCh)
							}
							// now end this lease itself
							select {
							case <-secondStop:
							default:
								close(secondStop)
							}