github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/edged/edged_getters.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes 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  @CHANGELOG
    17  KubeEdge Authors: To create mini-kubelet for edge deployment scenario,
    18  This file is derived from K8S Kubelet code with reduced set of methods
    19  Changes done are
    20  1. Package edged got some functions from "k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go"
    21  and made some variant
    22  */
    23  
    24  package edged
    25  
    26  import (
    27  	"fmt"
    28  	"io/ioutil"
    29  	"os"
    30  	"path"
    31  	"path/filepath"
    32  
    33  	v1 "k8s.io/api/core/v1"
    34  	"k8s.io/apimachinery/pkg/types"
    35  	"k8s.io/klog"
    36  	"k8s.io/kubernetes/pkg/kubelet/config"
    37  	"k8s.io/utils/mount"
    38  	utilfile "k8s.io/utils/path"
    39  )
    40  
    41  //constants for Kubelet
    42  const (
    43  	DefaultKubeletPluginsDirName             = "plugins"
    44  	DefaultKubeletPluginsRegistrationDirName = "plugins_registry"
    45  	DefaultKubeletVolumesDirName             = "volumes"
    46  	DefaultKubeletPodsDirName                = "pods"
    47  )
    48  
    49  // getRootDir returns the full path to the directory under which kubelet can
    50  // store data.  These functions are useful to pass interfaces to other modules
    51  // that may need to know where to write data without getting a whole kubelet
    52  // instance.
    53  func (e *edged) getRootDir() string {
    54  	return e.rootDirectory
    55  }
    56  
    57  // getPluginsDir returns the full path to the directory under which plugin
    58  // directories are created.  Plugins can use these directories for data that
    59  // they need to persist.  Plugins should create subdirectories under this named
    60  // after their own names.
    61  func (e *edged) getPluginsDir() string {
    62  	return path.Join(e.getRootDir(), DefaultKubeletPluginsDirName)
    63  }
    64  
    65  // getPluginDir returns a data directory name for a given plugin name.
    66  // Plugins can use these directories to store data that they need to persist.
    67  // For per-pod plugin data, see getPodPluginDir.
    68  func (e *edged) getPluginDir(pluginName string) string {
    69  	return path.Join(e.getPluginsDir(), pluginName)
    70  }
    71  
    72  // getPluginsRegistrationDir returns the full path to the directory under which
    73  // plugins socket should be placed to be registered.
    74  // More information is available about plugin registration in the pluginwatcher
    75  // module
    76  func (e *edged) getPluginsRegistrationDir() string {
    77  	return filepath.Join(e.getRootDir(), DefaultKubeletPluginsRegistrationDirName)
    78  }
    79  
    80  // getPodsDir returns the full path to the directory under which pod
    81  // directories are created.
    82  func (e *edged) getPodsDir() string {
    83  	return path.Join(e.getRootDir(), DefaultKubeletPodsDirName)
    84  }
    85  
    86  // getPodDir returns the full path to the per-pod directory for the pod with
    87  // the given UID.
    88  func (e *edged) getPodDir(podUID types.UID) string {
    89  	// Backwards compat.  The "old" stuff should be removed before 1.0
    90  	// release.  The thinking here is this:
    91  	//     !old && !new = use new
    92  	//     !old && new  = use new
    93  	//     old && !new  = use old
    94  	//     old && new   = use new (but warn)
    95  	oldPath := path.Join(e.getRootDir(), string(podUID))
    96  	oldExists := dirExists(oldPath)
    97  	newPath := path.Join(e.getPodsDir(), string(podUID))
    98  	newExists := dirExists(newPath)
    99  	if oldExists && !newExists {
   100  		return oldPath
   101  	}
   102  	if oldExists {
   103  		klog.Warningf("Data dir for pod %q exists in both old and new form, using new", podUID)
   104  	}
   105  	return newPath
   106  }
   107  
   108  // getPodVolumesDir returns the full path to the per-pod data directory under
   109  // which volumes are created for the specified pod.  This directory may not
   110  // exist if the pod does not exist.
   111  func (e *edged) getPodVolumesDir(podUID types.UID) string {
   112  	return path.Join(e.getPodDir(podUID), DefaultKubeletVolumesDirName)
   113  }
   114  
   115  // getPodVolumeDir returns the full path to the directory which represents the
   116  // named volume under the named plugin for specified pod.  This directory may not
   117  // exist if the pod does not exist.
   118  func (e *edged) getPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string {
   119  	return path.Join(e.getPodVolumesDir(podUID), pluginName, volumeName)
   120  }
   121  
   122  // dirExists returns true if the path exists and represents a directory.
   123  func dirExists(path string) bool {
   124  	s, err := os.Stat(path)
   125  	if err != nil {
   126  		return false
   127  	}
   128  	return s.IsDir()
   129  }
   130  
   131  // getPodPluginDir returns a data directory name for a given plugin name for a
   132  // given pod UID.  Plugins can use these directories to store data that they
   133  // need to persist.  For non-per-pod plugin data, see getPluginDir.
   134  func (e *edged) getPodPluginDir(podUID types.UID, pluginName string) string {
   135  	return path.Join(e.getPodPluginsDir(podUID), pluginName)
   136  }
   137  
   138  // getPodPluginsDir returns the full path to the per-pod data directory under
   139  // which plugins may store data for the specified pod.  This directory may not
   140  // exist if the pod does not exist.
   141  func (e *edged) getPodPluginsDir(podUID types.UID) string {
   142  	return path.Join(e.getPodDir(podUID), DefaultKubeletPluginsDirName)
   143  }
   144  
   145  // getPodVolumePathListFromDisk returns a list of the volume paths by reading the
   146  // volume directories for the given pod from the disk.
   147  func (e *edged) getPodVolumePathListFromDisk(podUID types.UID) ([]string, error) {
   148  	volumes := []string{}
   149  	podVolDir := e.getPodVolumesDir(podUID)
   150  
   151  	if pathExists, pathErr := mount.PathExists(podVolDir); pathErr != nil {
   152  		return volumes, fmt.Errorf("Error checking if path %q exists: %v", podVolDir, pathErr)
   153  	} else if !pathExists {
   154  		klog.Warningf("Path %q does not exist", podVolDir)
   155  		return volumes, nil
   156  	}
   157  
   158  	volumePluginDirs, err := ioutil.ReadDir(podVolDir)
   159  	if err != nil {
   160  		klog.Errorf("Could not read directory %s: %v", podVolDir, err)
   161  		return volumes, err
   162  	}
   163  	for _, volumePluginDir := range volumePluginDirs {
   164  		volumePluginName := volumePluginDir.Name()
   165  		volumePluginPath := filepath.Join(podVolDir, volumePluginName)
   166  		volumeDirs, err := utilfile.ReadDirNoStat(volumePluginPath)
   167  		if err != nil {
   168  			return volumes, fmt.Errorf("Could not read directory %s: %v", volumePluginPath, err)
   169  		}
   170  		for _, volumeDir := range volumeDirs {
   171  			volumes = append(volumes, filepath.Join(volumePluginPath, volumeDir))
   172  		}
   173  	}
   174  	return volumes, nil
   175  }
   176  
   177  // GetPodDir returns the full path to the per-pod data directory for the
   178  // specified pod. This directory may not exist if the pod does not exist.
   179  func (e *edged) GetPodDir(podUID types.UID) string {
   180  	return e.getPodDir(podUID)
   181  }
   182  
   183  // GetExtraSupplementalGroupsForPod returns a list of the extra
   184  // supplemental groups for the Pod. These extra supplemental groups come
   185  // from annotations on persistent volumes that the pod depends on.
   186  func (e *edged) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 {
   187  	return e.volumeManager.GetExtraSupplementalGroupsForPod(pod)
   188  }
   189  
   190  func (e *edged) getPodContainerDir(podUID types.UID, ctrName string) string {
   191  	return filepath.Join(e.getPodDir(podUID), config.DefaultKubeletContainersDirName, ctrName)
   192  }
   193  
   194  // podVolumesSubpathsDirExists returns true if the pod volume-subpaths directory for
   195  // a given pod exists
   196  func (e *edged) podVolumeSubpathsDirExists(podUID types.UID) (bool, error) {
   197  	podVolDir := e.getPodVolumeSubpathsDir(podUID)
   198  
   199  	if pathExists, pathErr := mount.PathExists(podVolDir); pathErr != nil {
   200  		return true, fmt.Errorf("Error checking if path %q exists: %v", podVolDir, pathErr)
   201  	} else if !pathExists {
   202  		return false, nil
   203  	}
   204  	return true, nil
   205  }
   206  
   207  // getPodVolumesSubpathsDir returns the full path to the per-pod subpaths directory under
   208  // which subpath volumes are created for the specified pod.  This directory may not
   209  // exist if the pod does not exist or subpaths are not specified.
   210  func (e *edged) getPodVolumeSubpathsDir(podUID types.UID) string {
   211  	return filepath.Join(e.getPodDir(podUID), config.DefaultKubeletVolumeSubpathsDirName)
   212  }