github.phpd.cn/cilium/cilium@v1.6.12/pkg/workloads/config.go (about)

     1  // Copyright 2016-2018 Authors of Cilium
     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 workloads
    16  
    17  import (
    18  	"fmt"
    19  	"net"
    20  	"sync"
    21  
    22  	"github.com/cilium/cilium/api/v1/models"
    23  )
    24  
    25  // setOpts validates the specified options against the selected workload runtime
    26  // and then modifies the configuration
    27  func setOpts(opts map[string]string, supportedOpts workloadRuntimeOpts) error {
    28  	errors := 0
    29  
    30  	for key, val := range opts {
    31  		opt, ok := supportedOpts[key]
    32  		if !ok {
    33  			errors++
    34  			log.Errorf("unknown workload runtime configuration key %q", key)
    35  			continue
    36  		}
    37  
    38  		if opt.validate != nil {
    39  			if err := opt.validate(val); err != nil {
    40  				log.Errorf("invalid value for key %s: %s", key, err)
    41  				errors++
    42  			}
    43  		}
    44  
    45  	}
    46  
    47  	// if errors have occurred, print the supported configuration keys to
    48  	// the log
    49  	if errors > 0 {
    50  		log.Error("Supported configuration keys:")
    51  		for key, val := range supportedOpts {
    52  			log.Errorf("  %-12s %s", key, val.description)
    53  		}
    54  
    55  		return fmt.Errorf("invalid workload runtime configuration, see log for details")
    56  	}
    57  
    58  	// modify the configuration atomically after verification
    59  	for key, val := range opts {
    60  		supportedOpts[key].value = val
    61  	}
    62  
    63  	return nil
    64  }
    65  
    66  func getOpts(opts workloadRuntimeOpts) map[string]string {
    67  	result := map[string]string{}
    68  
    69  	for key, opt := range opts {
    70  		result[key] = opt.value
    71  	}
    72  
    73  	return result
    74  }
    75  
    76  var (
    77  	setupOnce sync.Once
    78  	allocator allocatorInterface
    79  )
    80  
    81  func setupWorkload(workloadRuntime WorkloadRuntimeType, opts map[string]string) error {
    82  	workloadMod := getWorkload(workloadRuntime)
    83  	if workloadMod == nil {
    84  		return fmt.Errorf("unknown workloadRuntime runtime type %s", workloadRuntime)
    85  	}
    86  
    87  	if err := workloadMod.setConfig(opts); err != nil {
    88  		return err
    89  	}
    90  
    91  	return initClient(workloadMod)
    92  }
    93  
    94  type allocatorInterface interface {
    95  	BlacklistIP(ip net.IP, owner string)
    96  }
    97  
    98  // Setup sets up the workload runtime specified in workloadRuntime and configures it
    99  // with the options provided in opts
   100  func Setup(a allocatorInterface, workloadRuntimes []string, opts map[WorkloadRuntimeType]map[string]string) error {
   101  	return setup(a, workloadRuntimes, opts, false)
   102  }
   103  
   104  func setup(a allocatorInterface, workloadRuntimes []string, opts map[WorkloadRuntimeType]map[string]string, bypassStatusCheck bool) error {
   105  	var (
   106  		st  *models.Status
   107  		err error
   108  	)
   109  
   110  	if bypassStatusCheck {
   111  		st = &models.Status{State: models.StatusStateOk}
   112  	}
   113  
   114  	setupOnce.Do(
   115  		func() {
   116  			allocator = a
   117  
   118  			var crt WorkloadRuntimeType
   119  			for _, runtime := range workloadRuntimes {
   120  				crt, err = parseRuntimeType(runtime)
   121  				if err != nil {
   122  					return
   123  				}
   124  				switch crt {
   125  				case None:
   126  					unregisterWorkloads()
   127  					err = nil
   128  					return
   129  				}
   130  			}
   131  
   132  			for _, runtime := range workloadRuntimes {
   133  				crt, err = parseRuntimeType(runtime)
   134  				if err != nil {
   135  					err = nil
   136  				}
   137  				switch crt {
   138  				case Auto:
   139  					var setupErr error
   140  					for _, rt := range []WorkloadRuntimeType{Docker, ContainerD, CRIO} {
   141  						setupErr = setupWorkload(rt, opts[rt])
   142  						if !bypassStatusCheck {
   143  							st = Status()
   144  						}
   145  						if setupErr == nil && st.State == models.StatusStateOk {
   146  							return
   147  						}
   148  					}
   149  					err = setupErr
   150  					return
   151  				default:
   152  					err = setupWorkload(crt, opts[crt])
   153  					return
   154  				}
   155  			}
   156  
   157  		})
   158  
   159  	return err
   160  }