...

Source file src/github.com/containerd/continuity/driver/driver.go

Documentation: github.com/containerd/continuity/driver

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

View as plain text