mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
Changes to accommodate client-go changes and kube vendor update
to v1.18.0 Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
committed by
mergify[bot]
parent
4c96ad3c85
commit
34fc1d847e
225
vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go
generated
vendored
225
vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go
generated
vendored
@ -24,7 +24,10 @@ import (
|
||||
|
||||
"os"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -36,60 +39,192 @@ const (
|
||||
// SetVolumeOwnership modifies the given volume to be owned by
|
||||
// fsGroup, and sets SetGid so that newly created files are owned by
|
||||
// fsGroup. If fsGroup is nil nothing is done.
|
||||
func SetVolumeOwnership(mounter Mounter, fsGroup *int64) error {
|
||||
|
||||
func SetVolumeOwnership(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy) error {
|
||||
if fsGroup == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
fsGroupPolicyEnabled := utilfeature.DefaultFeatureGate.Enabled(features.ConfigurableFSGroupPolicy)
|
||||
|
||||
klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", mounter.GetPath())
|
||||
|
||||
// This code exists for legacy purposes, so as old behaviour is entirely preserved when feature gate is disabled
|
||||
// TODO: remove this when ConfigurableFSGroupPolicy turns GA.
|
||||
if !fsGroupPolicyEnabled {
|
||||
return legacyOwnershipChange(mounter, fsGroup)
|
||||
}
|
||||
|
||||
if skipPermissionChange(mounter, fsGroup, fsGroupChangePolicy) {
|
||||
klog.V(3).Infof("skipping permission and ownership change for volume %s", mounter.GetPath())
|
||||
return nil
|
||||
}
|
||||
|
||||
return walkDeep(mounter.GetPath(), func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return changeFilePermission(path, fsGroup, mounter.GetAttributes().ReadOnly, info)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func legacyOwnershipChange(mounter Mounter, fsGroup *int64) error {
|
||||
return filepath.Walk(mounter.GetPath(), func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// chown and chmod pass through to the underlying file for symlinks.
|
||||
// Symlinks have a mode of 777 but this really doesn't mean anything.
|
||||
// The permissions of the underlying file are what matter.
|
||||
// However, if one reads the mode of a symlink then chmods the symlink
|
||||
// with that mode, it changes the mode of the underlying file, overridden
|
||||
// the defaultMode and permissions initialized by the volume plugin, which
|
||||
// is not what we want; thus, we skip chown/chmod for symlinks.
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
stat, ok := info.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
if stat == nil {
|
||||
klog.Errorf("Got nil stat_t for path %v while setting ownership of volume", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
err = os.Chown(path, int(stat.Uid), int(*fsGroup))
|
||||
if err != nil {
|
||||
klog.Errorf("Chown failed on %v: %v", path, err)
|
||||
}
|
||||
|
||||
mask := rwMask
|
||||
if mounter.GetAttributes().ReadOnly {
|
||||
mask = roMask
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
mask |= os.ModeSetgid
|
||||
mask |= execMask
|
||||
}
|
||||
|
||||
err = os.Chmod(path, info.Mode()|mask)
|
||||
if err != nil {
|
||||
klog.Errorf("Chmod failed on %v: %v", path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return changeFilePermission(path, fsGroup, mounter.GetAttributes().ReadOnly, info)
|
||||
})
|
||||
}
|
||||
|
||||
func changeFilePermission(filename string, fsGroup *int64, readonly bool, info os.FileInfo) error {
|
||||
// chown and chmod pass through to the underlying file for symlinks.
|
||||
// Symlinks have a mode of 777 but this really doesn't mean anything.
|
||||
// The permissions of the underlying file are what matter.
|
||||
// However, if one reads the mode of a symlink then chmods the symlink
|
||||
// with that mode, it changes the mode of the underlying file, overridden
|
||||
// the defaultMode and permissions initialized by the volume plugin, which
|
||||
// is not what we want; thus, we skip chown/chmod for symlinks.
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
stat, ok := info.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
if stat == nil {
|
||||
klog.Errorf("Got nil stat_t for path %v while setting ownership of volume", filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
err := os.Chown(filename, int(stat.Uid), int(*fsGroup))
|
||||
if err != nil {
|
||||
klog.Errorf("Chown failed on %v: %v", filename, err)
|
||||
}
|
||||
|
||||
mask := rwMask
|
||||
if readonly {
|
||||
mask = roMask
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
mask |= os.ModeSetgid
|
||||
mask |= execMask
|
||||
}
|
||||
|
||||
err = os.Chmod(filename, info.Mode()|mask)
|
||||
if err != nil {
|
||||
klog.Errorf("Chmod failed on %v: %v", filename, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func skipPermissionChange(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy) bool {
|
||||
dir := mounter.GetPath()
|
||||
|
||||
if fsGroupChangePolicy == nil || *fsGroupChangePolicy != v1.FSGroupChangeOnRootMismatch {
|
||||
klog.V(4).Infof("perform recursive ownership change for %s", dir)
|
||||
return false
|
||||
}
|
||||
return !requiresPermissionChange(mounter.GetPath(), fsGroup, mounter.GetAttributes().ReadOnly)
|
||||
}
|
||||
|
||||
func requiresPermissionChange(rootDir string, fsGroup *int64, readonly bool) bool {
|
||||
fsInfo, err := os.Stat(rootDir)
|
||||
if err != nil {
|
||||
klog.Errorf("performing recursive ownership change on %s because reading permissions of root volume failed: %v", rootDir, err)
|
||||
return true
|
||||
}
|
||||
stat, ok := fsInfo.Sys().(*syscall.Stat_t)
|
||||
if !ok || stat == nil {
|
||||
klog.Errorf("performing recursive ownership change on %s because reading permissions of root volume failed", rootDir)
|
||||
return true
|
||||
}
|
||||
|
||||
if int(stat.Gid) != int(*fsGroup) {
|
||||
klog.V(4).Infof("expected group ownership of volume %s did not match with: %d", rootDir, stat.Gid)
|
||||
return true
|
||||
}
|
||||
unixPerms := rwMask
|
||||
|
||||
if readonly {
|
||||
unixPerms = roMask
|
||||
}
|
||||
|
||||
// if rootDir is not a directory then we should apply permission change anyways
|
||||
if !fsInfo.IsDir() {
|
||||
return true
|
||||
}
|
||||
unixPerms |= execMask
|
||||
filePerm := fsInfo.Mode().Perm()
|
||||
|
||||
// We need to check if actual permissions of root directory is a superset of permissions required by unixPerms.
|
||||
// This is done by checking if permission bits expected in unixPerms is set in actual permissions of the directory.
|
||||
// We use bitwise AND operation to check set bits. For example:
|
||||
// unixPerms: 770, filePerms: 775 : 770&775 = 770 (perms on directory is a superset)
|
||||
// unixPerms: 770, filePerms: 770 : 770&770 = 770 (perms on directory is a superset)
|
||||
// unixPerms: 770, filePerms: 750 : 770&750 = 750 (perms on directory is NOT a superset)
|
||||
// We also need to check if setgid bits are set in permissions of the directory.
|
||||
if (unixPerms&filePerm != unixPerms) || (fsInfo.Mode()&os.ModeSetgid == 0) {
|
||||
klog.V(4).Infof("performing recursive ownership change on %s because of mismatching mode", rootDir)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// readDirNames reads the directory named by dirname and returns
|
||||
// a list of directory entries.
|
||||
// We are not using filepath.readDirNames because we do not want to sort files found in a directory before changing
|
||||
// permissions for performance reasons.
|
||||
func readDirNames(dirname string) ([]string, error) {
|
||||
f, err := os.Open(dirname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names, err := f.Readdirnames(-1)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
// walkDeep can be used to traverse directories and has two minor differences
|
||||
// from filepath.Walk:
|
||||
// - List of files/dirs is not sorted for performance reasons
|
||||
// - callback walkFunc is invoked on root directory after visiting children dirs and files
|
||||
func walkDeep(root string, walkFunc filepath.WalkFunc) error {
|
||||
info, err := os.Lstat(root)
|
||||
if err != nil {
|
||||
return walkFunc(root, nil, err)
|
||||
}
|
||||
return walk(root, info, walkFunc)
|
||||
}
|
||||
|
||||
func walk(path string, info os.FileInfo, walkFunc filepath.WalkFunc) error {
|
||||
if !info.IsDir() {
|
||||
return walkFunc(path, info, nil)
|
||||
}
|
||||
names, err := readDirNames(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, name := range names {
|
||||
filename := filepath.Join(path, name)
|
||||
fileInfo, err := os.Lstat(filename)
|
||||
if err != nil {
|
||||
if err := walkFunc(filename, fileInfo, err); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err = walk(filename, fileInfo, walkFunc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return walkFunc(path, info, nil)
|
||||
}
|
||||
|
Reference in New Issue
Block a user