hostutil.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package hostutil
  14. import (
  15. "fmt"
  16. "os"
  17. "k8s.io/utils/mount"
  18. )
  19. // FileType enumerates the known set of possible file types.
  20. type FileType string
  21. const (
  22. // FileTypeBlockDev defines a constant for the block device FileType.
  23. FileTypeBlockDev FileType = "BlockDevice"
  24. // FileTypeCharDev defines a constant for the character device FileType.
  25. FileTypeCharDev FileType = "CharDevice"
  26. // FileTypeDirectory defines a constant for the directory FileType.
  27. FileTypeDirectory FileType = "Directory"
  28. // FileTypeFile defines a constant for the file FileType.
  29. FileTypeFile FileType = "File"
  30. // FileTypeSocket defines a constant for the socket FileType.
  31. FileTypeSocket FileType = "Socket"
  32. // FileTypeUnknown defines a constant for an unknown FileType.
  33. FileTypeUnknown FileType = ""
  34. )
  35. // HostUtils defines the set of methods for interacting with paths on a host.
  36. type HostUtils interface {
  37. // DeviceOpened determines if the device (e.g. /dev/sdc) is in use elsewhere
  38. // on the system, i.e. still mounted.
  39. DeviceOpened(pathname string) (bool, error)
  40. // PathIsDevice determines if a path is a device.
  41. PathIsDevice(pathname string) (bool, error)
  42. // GetDeviceNameFromMount finds the device name by checking the mount path
  43. // to get the global mount path within its plugin directory.
  44. GetDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error)
  45. // MakeRShared checks that given path is on a mount with 'rshared' mount
  46. // propagation. If not, it bind-mounts the path as rshared.
  47. MakeRShared(path string) error
  48. // GetFileType checks for file/directory/socket/block/character devices.
  49. GetFileType(pathname string) (FileType, error)
  50. // PathExists tests if the given path already exists
  51. // Error is returned on any other error than "file not found".
  52. PathExists(pathname string) (bool, error)
  53. // EvalHostSymlinks returns the path name after evaluating symlinks.
  54. EvalHostSymlinks(pathname string) (string, error)
  55. // GetOwner returns the integer ID for the user and group of the given path
  56. GetOwner(pathname string) (int64, int64, error)
  57. // GetSELinuxSupport returns true if given path is on a mount that supports
  58. // SELinux.
  59. GetSELinuxSupport(pathname string) (bool, error)
  60. // GetMode returns permissions of the path.
  61. GetMode(pathname string) (os.FileMode, error)
  62. }
  63. // Compile-time check to ensure all HostUtil implementations satisfy
  64. // the Interface.
  65. var _ HostUtils = &HostUtil{}
  66. // getFileType checks for file/directory/socket and block/character devices.
  67. func getFileType(pathname string) (FileType, error) {
  68. var pathType FileType
  69. info, err := os.Stat(pathname)
  70. if os.IsNotExist(err) {
  71. return pathType, fmt.Errorf("path %q does not exist", pathname)
  72. }
  73. // err in call to os.Stat
  74. if err != nil {
  75. return pathType, err
  76. }
  77. // checks whether the mode is the target mode.
  78. isSpecificMode := func(mode, targetMode os.FileMode) bool {
  79. return mode&targetMode == targetMode
  80. }
  81. mode := info.Mode()
  82. if mode.IsDir() {
  83. return FileTypeDirectory, nil
  84. } else if mode.IsRegular() {
  85. return FileTypeFile, nil
  86. } else if isSpecificMode(mode, os.ModeSocket) {
  87. return FileTypeSocket, nil
  88. } else if isSpecificMode(mode, os.ModeDevice) {
  89. if isSpecificMode(mode, os.ModeCharDevice) {
  90. return FileTypeCharDev, nil
  91. }
  92. return FileTypeBlockDev, nil
  93. }
  94. return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device")
  95. }