volcano.sh/volcano@v1.9.0/pkg/webhooks/config/config.go (about)

     1  /*
     2  Copyright 2021 The Volcano 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 config
    18  
    19  import (
    20  	"os"
    21  	"path/filepath"
    22  	"sync"
    23  
    24  	"github.com/fsnotify/fsnotify"
    25  	"gopkg.in/yaml.v2"
    26  	v1 "k8s.io/api/core/v1"
    27  	"k8s.io/klog/v2"
    28  
    29  	"volcano.sh/volcano/pkg/filewatcher"
    30  )
    31  
    32  // Object the key data for resource group kind
    33  type Object struct {
    34  	Key   string   `yaml:"key"`
    35  	Value []string `yaml:"value"`
    36  }
    37  
    38  // ResGroupConfig defines the configuration of admission.
    39  type ResGroupConfig struct {
    40  	ResourceGroup string            `yaml:"resourceGroup"`
    41  	Object        Object            `yaml:"object"`
    42  	SchedulerName string            `yaml:"schedulerName"`
    43  	Tolerations   []v1.Toleration   `yaml:"tolerations"`
    44  	Labels        map[string]string `yaml:"labels"`
    45  	Affinity      string            `yaml:"affinity"`
    46  }
    47  
    48  // AdmissionConfiguration defines the configuration of admission.
    49  type AdmissionConfiguration struct {
    50  	sync.Mutex
    51  	ResGroupsConfig []ResGroupConfig `yaml:"resourceGroups"`
    52  }
    53  
    54  var admissionConf AdmissionConfiguration
    55  
    56  // LoadAdmissionConf parse the configuration from config path
    57  func LoadAdmissionConf(confPath string) *AdmissionConfiguration {
    58  	if confPath == "" {
    59  		return nil
    60  	}
    61  
    62  	configBytes, err := os.ReadFile(confPath)
    63  	if err != nil {
    64  		klog.Errorf("read admission file failed, err=%v", err)
    65  		return nil
    66  	}
    67  
    68  	data := AdmissionConfiguration{}
    69  	if err := yaml.Unmarshal(configBytes, &data); err != nil {
    70  		klog.Errorf("Unmarshal admission file failed, err=%v", err)
    71  		return nil
    72  	}
    73  
    74  	admissionConf.Lock()
    75  	admissionConf.ResGroupsConfig = data.ResGroupsConfig
    76  	admissionConf.Unlock()
    77  	return &admissionConf
    78  }
    79  
    80  // WatchAdmissionConf listen the changes of the configuration file
    81  func WatchAdmissionConf(path string, stopCh chan os.Signal) {
    82  	dirPath := filepath.Dir(path)
    83  	fileWatcher, err := filewatcher.NewFileWatcher(dirPath)
    84  	if err != nil {
    85  		klog.Errorf("failed to create filewatcher for %s: %v", path, err)
    86  		return
    87  	}
    88  
    89  	eventCh := fileWatcher.Events()
    90  	errCh := fileWatcher.Errors()
    91  	for {
    92  		select {
    93  		case event, ok := <-eventCh:
    94  			if !ok {
    95  				return
    96  			}
    97  			klog.V(4).Infof("watch %s event: %v", dirPath, event)
    98  			if event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Create == fsnotify.Create {
    99  				LoadAdmissionConf(path)
   100  			}
   101  		case err, ok := <-errCh:
   102  			if !ok {
   103  				return
   104  			}
   105  			klog.Infof("watch %s error: %v", path, err)
   106  		case <-stopCh:
   107  			return
   108  		}
   109  	}
   110  }