driver.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. Copyright The containerd 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 driver
  14. import (
  15. "fmt"
  16. "io"
  17. "os"
  18. )
  19. var ErrNotSupported = fmt.Errorf("not supported")
  20. // Driver provides all of the system-level functions in a common interface.
  21. // The context should call these with full paths and should never use the `os`
  22. // package or any other package to access resources on the filesystem. This
  23. // mechanism let's us carefully control access to the context and maintain
  24. // path and resource integrity. It also gives us an interface to reason about
  25. // direct resource access.
  26. //
  27. // Implementations don't need to do much other than meet the interface. For
  28. // example, it is not required to wrap os.FileInfo to return correct paths for
  29. // the call to Name().
  30. type Driver interface {
  31. // Note that Open() returns a File interface instead of *os.File. This
  32. // is because os.File is a struct, so if Open was to return *os.File,
  33. // the only way to fulfill the interface would be to call os.Open()
  34. Open(path string) (File, error)
  35. OpenFile(path string, flag int, perm os.FileMode) (File, error)
  36. Stat(path string) (os.FileInfo, error)
  37. Lstat(path string) (os.FileInfo, error)
  38. Readlink(p string) (string, error)
  39. Mkdir(path string, mode os.FileMode) error
  40. Remove(path string) error
  41. Link(oldname, newname string) error
  42. Lchmod(path string, mode os.FileMode) error
  43. Lchown(path string, uid, gid int64) error
  44. Symlink(oldname, newname string) error
  45. MkdirAll(path string, perm os.FileMode) error
  46. RemoveAll(path string) error
  47. // TODO(aaronl): These methods might move outside the main Driver
  48. // interface in the future as more platforms are added.
  49. Mknod(path string, mode os.FileMode, major int, minor int) error
  50. Mkfifo(path string, mode os.FileMode) error
  51. }
  52. // File is the interface for interacting with files returned by continuity's Open
  53. // This is needed since os.File is a struct, instead of an interface, so it can't
  54. // be used.
  55. type File interface {
  56. io.ReadWriteCloser
  57. io.Seeker
  58. Readdir(n int) ([]os.FileInfo, error)
  59. }
  60. func NewSystemDriver() (Driver, error) {
  61. // TODO(stevvooe): Consider having this take a "hint" path argument, which
  62. // would be the context root. The hint could be used to resolve required
  63. // filesystem support when assembling the driver to use.
  64. return &driver{}, nil
  65. }
  66. // XAttrDriver should be implemented on operation systems and filesystems that
  67. // have xattr support for regular files and directories.
  68. type XAttrDriver interface {
  69. // Getxattr returns all of the extended attributes for the file at path.
  70. // Typically, this takes a syscall call to Listxattr and Getxattr.
  71. Getxattr(path string) (map[string][]byte, error)
  72. // Setxattr sets all of the extended attributes on file at path, following
  73. // any symbolic links, if necessary. All attributes on the target are
  74. // replaced by the values from attr. If the operation fails to set any
  75. // attribute, those already applied will not be rolled back.
  76. Setxattr(path string, attr map[string][]byte) error
  77. }
  78. // LXAttrDriver should be implemented by drivers on operating systems and
  79. // filesystems that support setting and getting extended attributes on
  80. // symbolic links. If this is not implemented, extended attributes will be
  81. // ignored on symbolic links.
  82. type LXAttrDriver interface {
  83. // LGetxattr returns all of the extended attributes for the file at path
  84. // and does not follow symlinks. Typically, this takes a syscall call to
  85. // Llistxattr and Lgetxattr.
  86. LGetxattr(path string) (map[string][]byte, error)
  87. // LSetxattr sets all of the extended attributes on file at path, without
  88. // following symbolic links. All attributes on the target are replaced by
  89. // the values from attr. If the operation fails to set any attribute,
  90. // those already applied will not be rolled back.
  91. LSetxattr(path string, attr map[string][]byte) error
  92. }
  93. type DeviceInfoDriver interface {
  94. DeviceInfo(fi os.FileInfo) (maj uint64, min uint64, err error)
  95. }
  96. // driver is a simple default implementation that sends calls out to the "os"
  97. // package. Extend the "driver" type in system-specific files to add support,
  98. // such as xattrs, which can add support at compile time.
  99. type driver struct{}
  100. var _ File = &os.File{}
  101. // LocalDriver is the exported Driver struct for convenience.
  102. var LocalDriver Driver = &driver{}
  103. func (d *driver) Open(p string) (File, error) {
  104. return os.Open(p)
  105. }
  106. func (d *driver) OpenFile(path string, flag int, perm os.FileMode) (File, error) {
  107. return os.OpenFile(path, flag, perm)
  108. }
  109. func (d *driver) Stat(p string) (os.FileInfo, error) {
  110. return os.Stat(p)
  111. }
  112. func (d *driver) Lstat(p string) (os.FileInfo, error) {
  113. return os.Lstat(p)
  114. }
  115. func (d *driver) Readlink(p string) (string, error) {
  116. return os.Readlink(p)
  117. }
  118. func (d *driver) Mkdir(p string, mode os.FileMode) error {
  119. return os.Mkdir(p, mode)
  120. }
  121. // Remove is used to unlink files and remove directories.
  122. // This is following the golang os package api which
  123. // combines the operations into a higher level Remove
  124. // function. If explicit unlinking or directory removal
  125. // to mirror system call is required, they should be
  126. // split up at that time.
  127. func (d *driver) Remove(path string) error {
  128. return os.Remove(path)
  129. }
  130. func (d *driver) Link(oldname, newname string) error {
  131. return os.Link(oldname, newname)
  132. }
  133. func (d *driver) Lchown(name string, uid, gid int64) error {
  134. // TODO: error out if uid excesses int bit width?
  135. return os.Lchown(name, int(uid), int(gid))
  136. }
  137. func (d *driver) Symlink(oldname, newname string) error {
  138. return os.Symlink(oldname, newname)
  139. }
  140. func (d *driver) MkdirAll(path string, perm os.FileMode) error {
  141. return os.MkdirAll(path, perm)
  142. }
  143. func (d *driver) RemoveAll(path string) error {
  144. return os.RemoveAll(path)
  145. }