...

Source file src/k8s.io/kubernetes/pkg/util/filesystem/defaultfs.go

Documentation: k8s.io/kubernetes/pkg/util/filesystem

     1  /*
     2  Copyright 2017 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  
    17  package filesystem
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  	"runtime"
    24  	"strings"
    25  	"time"
    26  )
    27  
    28  // DefaultFs implements Filesystem using same-named functions from "os" and "io"
    29  type DefaultFs struct {
    30  	root string
    31  }
    32  
    33  var _ Filesystem = &DefaultFs{}
    34  
    35  // NewTempFs returns a fake Filesystem in temporary directory, useful for unit tests
    36  func NewTempFs() Filesystem {
    37  	path, _ := os.MkdirTemp("", "tmpfs")
    38  	return &DefaultFs{
    39  		root: path,
    40  	}
    41  }
    42  
    43  func (fs *DefaultFs) prefix(path string) string {
    44  	if len(fs.root) == 0 {
    45  		return path
    46  	}
    47  	return filepath.Join(fs.root, path)
    48  }
    49  
    50  // Stat via os.Stat
    51  func (fs *DefaultFs) Stat(name string) (os.FileInfo, error) {
    52  	return os.Stat(fs.prefix(name))
    53  }
    54  
    55  // Create via os.Create
    56  func (fs *DefaultFs) Create(name string) (File, error) {
    57  	file, err := os.Create(fs.prefix(name))
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	return &defaultFile{file}, nil
    62  }
    63  
    64  // Rename via os.Rename
    65  func (fs *DefaultFs) Rename(oldpath, newpath string) error {
    66  	if !strings.HasPrefix(oldpath, fs.root) {
    67  		oldpath = fs.prefix(oldpath)
    68  	}
    69  	if !strings.HasPrefix(newpath, fs.root) {
    70  		newpath = fs.prefix(newpath)
    71  	}
    72  	return os.Rename(oldpath, newpath)
    73  }
    74  
    75  // MkdirAll via os.MkdirAll
    76  func (fs *DefaultFs) MkdirAll(path string, perm os.FileMode) error {
    77  	return os.MkdirAll(fs.prefix(path), perm)
    78  }
    79  
    80  // MkdirAllWithPathCheck checks if path exists already. If not, it creates a directory
    81  // named path, along with any necessary parents, and returns nil, or else returns an error.
    82  // Permission bits perm (before umask) are used for all directories that
    83  // MkdirAllWithPathCheck creates.
    84  // If path is already a directory, MkdirAllWithPathCheck does nothing and returns nil.
    85  // NOTE: In case of Windows NTFS, mount points are implemented as reparse-point
    86  // (similar to symlink) and do not represent actual directory. Hence Directory existence
    87  // check for windows NTFS will NOT check for dir, but for symlink presence.
    88  func MkdirAllWithPathCheck(path string, perm os.FileMode) error {
    89  	if dir, err := os.Lstat(path); err == nil {
    90  		// If the path exists already,
    91  		// 1. for Unix/Linux OS, check if the path is directory.
    92  		// 2. for windows NTFS, check if the path is symlink instead of directory.
    93  		if dir.IsDir() ||
    94  			(runtime.GOOS == "windows" && (dir.Mode()&os.ModeSymlink != 0)) {
    95  			return nil
    96  		}
    97  		return fmt.Errorf("path %v exists but is not a directory", path)
    98  	}
    99  	// If existence of path not known, attempt to create it.
   100  	if err := os.MkdirAll(path, perm); err != nil {
   101  		return err
   102  	}
   103  	return nil
   104  }
   105  
   106  // Chtimes via os.Chtimes
   107  func (fs *DefaultFs) Chtimes(name string, atime time.Time, mtime time.Time) error {
   108  	return os.Chtimes(fs.prefix(name), atime, mtime)
   109  }
   110  
   111  // RemoveAll via os.RemoveAll
   112  func (fs *DefaultFs) RemoveAll(path string) error {
   113  	return os.RemoveAll(fs.prefix(path))
   114  }
   115  
   116  // Remove via os.Remove
   117  func (fs *DefaultFs) Remove(name string) error {
   118  	return os.Remove(fs.prefix(name))
   119  }
   120  
   121  // ReadFile via os.ReadFile
   122  func (fs *DefaultFs) ReadFile(filename string) ([]byte, error) {
   123  	return os.ReadFile(fs.prefix(filename))
   124  }
   125  
   126  // TempDir via os.MkdirTemp
   127  func (fs *DefaultFs) TempDir(dir, prefix string) (string, error) {
   128  	return os.MkdirTemp(fs.prefix(dir), prefix)
   129  }
   130  
   131  // TempFile via os.CreateTemp
   132  func (fs *DefaultFs) TempFile(dir, prefix string) (File, error) {
   133  	file, err := os.CreateTemp(fs.prefix(dir), prefix)
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  	return &defaultFile{file}, nil
   138  }
   139  
   140  // ReadDir via os.ReadDir
   141  func (fs *DefaultFs) ReadDir(dirname string) ([]os.DirEntry, error) {
   142  	return os.ReadDir(fs.prefix(dirname))
   143  }
   144  
   145  // Walk via filepath.Walk
   146  func (fs *DefaultFs) Walk(root string, walkFn filepath.WalkFunc) error {
   147  	return filepath.Walk(fs.prefix(root), walkFn)
   148  }
   149  
   150  // defaultFile implements File using same-named functions from "os"
   151  type defaultFile struct {
   152  	file *os.File
   153  }
   154  
   155  // Name via os.File.Name
   156  func (file *defaultFile) Name() string {
   157  	return file.file.Name()
   158  }
   159  
   160  // Write via os.File.Write
   161  func (file *defaultFile) Write(b []byte) (n int, err error) {
   162  	return file.file.Write(b)
   163  }
   164  
   165  // Sync via os.File.Sync
   166  func (file *defaultFile) Sync() error {
   167  	return file.file.Sync()
   168  }
   169  
   170  // Close via os.File.Close
   171  func (file *defaultFile) Close() error {
   172  	return file.file.Close()
   173  }
   174  

View as plain text