github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/plugin/cluster_check_plugin.go (about)

     1  // Copyright © 2021 Alibaba Group Holding Ltd.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package plugin
    16  
    17  import (
    18  	goContext "context"
    19  	"fmt"
    20  	"time"
    21  
    22  	"golang.org/x/net/context"
    23  
    24  	"github.com/alibaba/sealer/logger"
    25  	"github.com/alibaba/sealer/pkg/client/k8s"
    26  )
    27  
    28  type ClusterChecker struct {
    29  	client *k8s.Client
    30  }
    31  
    32  func NewClusterCheckerPlugin() Interface {
    33  	return &ClusterChecker{}
    34  }
    35  
    36  func init() {
    37  	Register(ClusterCheckPlugin, NewClusterCheckerPlugin())
    38  }
    39  
    40  func (c *ClusterChecker) Run(context Context, phase Phase) error {
    41  	if phase != PhasePreGuest || context.Plugin.Spec.Type != ClusterCheckPlugin {
    42  		logger.Debug("check cluster is PreGuest!")
    43  		return nil
    44  	}
    45  	if err := c.waitClusterReady(goContext.TODO()); err != nil {
    46  		return err
    47  	}
    48  	return nil
    49  }
    50  
    51  func (c *ClusterChecker) waitClusterReady(ctx goContext.Context) error {
    52  	var clusterStatusChan = make(chan string)
    53  	ctx, cancel := context.WithTimeout(ctx, 15*time.Minute)
    54  	defer cancel()
    55  	ticker := time.NewTicker(30 * time.Second)
    56  	defer ticker.Stop()
    57  	go func(t *time.Ticker) {
    58  		for {
    59  			clusterStatus := c.getClusterStatus()
    60  			clusterStatusChan <- clusterStatus
    61  			<-t.C
    62  		}
    63  	}(ticker)
    64  	for {
    65  		select {
    66  		case status := <-clusterStatusChan:
    67  			if status == ClusterNotReady {
    68  				logger.Info("wait for the cluster to ready ")
    69  			} else if status == ClusterReady {
    70  				logger.Info("cluster is ready now")
    71  				return nil
    72  			}
    73  		case <-ctx.Done():
    74  			return fmt.Errorf("cluster is not ready, please check")
    75  		}
    76  	}
    77  }
    78  
    79  func (c *ClusterChecker) getClusterStatus() string {
    80  	k8sClient, err := k8s.Newk8sClient()
    81  	c.client = k8sClient
    82  	if err != nil {
    83  		return ClusterNotReady
    84  	}
    85  
    86  	kubeSystemPodStatus, err := c.client.ListKubeSystemPodsStatus()
    87  	if !kubeSystemPodStatus || err != nil {
    88  		return ClusterNotReady
    89  	}
    90  
    91  	return ClusterReady
    92  }