github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/clusterfile/pre_process.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 clusterfile
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"io"
    21  	"os"
    22  
    23  	"github.com/alibaba/sealer/logger"
    24  	runtime2 "k8s.io/apimachinery/pkg/runtime"
    25  	"k8s.io/apimachinery/pkg/util/yaml"
    26  
    27  	"github.com/alibaba/sealer/common"
    28  	"github.com/alibaba/sealer/pkg/config"
    29  	"github.com/alibaba/sealer/pkg/env"
    30  	"github.com/alibaba/sealer/pkg/runtime"
    31  	v1 "github.com/alibaba/sealer/types/api/v1"
    32  	"github.com/alibaba/sealer/utils"
    33  )
    34  
    35  type PreProcessor interface {
    36  	Process() error
    37  }
    38  
    39  func NewPreProcessor(path string) PreProcessor {
    40  	return &ClusterFile{path: path}
    41  }
    42  
    43  func (c *ClusterFile) GetPipeLine() ([]func() error, error) {
    44  	var todoList []func() error
    45  	todoList = append(todoList,
    46  		c.PrePareCluster,
    47  		c.PrePareEnv,
    48  		c.PrePareConfigs,
    49  	)
    50  	return todoList, nil
    51  }
    52  
    53  func (c *ClusterFile) Process() error {
    54  	pipeLine, err := c.GetPipeLine()
    55  	if err != nil {
    56  		return err
    57  	}
    58  	for _, f := range pipeLine {
    59  		if err := f(); err != nil {
    60  			return err
    61  		}
    62  	}
    63  	return nil
    64  }
    65  
    66  func (c *ClusterFile) PrePareEnv() error {
    67  	clusterFileData, err := env.NewEnvProcessor(&c.Cluster).Process(c.path)
    68  	if err != nil {
    69  		return err
    70  	}
    71  	err = c.DecodePlugins(clusterFileData)
    72  	if err != nil && err != ErrTypeNotFound {
    73  		return err
    74  	}
    75  	err = c.DecodeConfigs(clusterFileData)
    76  	if err != nil && err != ErrTypeNotFound {
    77  		return err
    78  	}
    79  	err = c.DecodeKubeadmConfig(clusterFileData)
    80  	if err != nil && err != ErrTypeNotFound {
    81  		return err
    82  	}
    83  	return nil
    84  }
    85  
    86  func (c *ClusterFile) PrePareConfigs() error {
    87  	var configs []v1.Config
    88  	for _, c := range c.GetConfigs() {
    89  		cfg := c
    90  		err := config.NewProcessorsAndRun(&cfg)
    91  		if err != nil {
    92  			return err
    93  		}
    94  		configs = append(configs, cfg)
    95  	}
    96  	c.Configs = configs
    97  	return nil
    98  }
    99  
   100  func (c *ClusterFile) PrePareCluster() error {
   101  	f, err := os.Open(c.path)
   102  	if err != nil {
   103  		return err
   104  	}
   105  	defer func() {
   106  		if err := f.Close(); err != nil {
   107  			logger.Fatal("failed to close file")
   108  		}
   109  	}()
   110  	d := yaml.NewYAMLOrJSONDecoder(f, 4096)
   111  	for {
   112  		ext := runtime2.RawExtension{}
   113  		if err = d.Decode(&ext); err != nil {
   114  			if err == io.EOF {
   115  				break
   116  			}
   117  			continue
   118  		}
   119  		ext.Raw = bytes.TrimSpace(ext.Raw)
   120  		if len(ext.Raw) == 0 || bytes.Equal(ext.Raw, []byte("null")) {
   121  			continue
   122  		}
   123  		err = c.DecodeCluster(ext.Raw)
   124  		if err == nil {
   125  			return nil
   126  		}
   127  	}
   128  	return fmt.Errorf("failed to decode cluster from %s, %v", c.path, err)
   129  }
   130  
   131  func (c *ClusterFile) DecodeCluster(data []byte) error {
   132  	cluster, err := GetClusterFromDataCompatV1(data)
   133  	if err != nil {
   134  		return err
   135  	}
   136  	c.Cluster = *cluster
   137  	return nil
   138  }
   139  
   140  func (c *ClusterFile) DecodeConfigs(data []byte) error {
   141  	configs, err := utils.DecodeV1CRDFromReader(bytes.NewReader(data), common.Config)
   142  	if err != nil {
   143  		return err
   144  	}
   145  	if configs == nil {
   146  		return ErrTypeNotFound
   147  	}
   148  	cfgs := configs.([]v1.Config)
   149  	c.Configs = cfgs
   150  	return nil
   151  }
   152  
   153  func (c *ClusterFile) DecodePlugins(data []byte) error {
   154  	plugs, err := utils.DecodeV1CRDFromReader(bytes.NewReader(data), common.Plugin)
   155  	if err != nil {
   156  		return err
   157  	}
   158  	if plugs == nil {
   159  		return ErrTypeNotFound
   160  	}
   161  	plugins := plugs.([]v1.Plugin)
   162  	c.Plugins = plugins
   163  	return nil
   164  }
   165  
   166  func (c *ClusterFile) DecodeKubeadmConfig(data []byte) error {
   167  	kubeadmConfig, err := runtime.LoadKubeadmConfigs(string(data), runtime.DecodeCRDFromString)
   168  	if err != nil {
   169  		return err
   170  	}
   171  	if kubeadmConfig == nil {
   172  		return ErrTypeNotFound
   173  	}
   174  	c.KubeConfig = kubeadmConfig
   175  	return nil
   176  }