go-hep.org/x/hep@v0.38.1/xrootd/filesystem.go (about)

     1  // Copyright ©2018 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package xrootd // import "go-hep.org/x/hep/xrootd"
     6  
     7  import (
     8  	"context"
     9  	stdpath "path"
    10  
    11  	"go-hep.org/x/hep/xrootd/xrdfs"
    12  	"go-hep.org/x/hep/xrootd/xrdproto/chmod"
    13  	"go-hep.org/x/hep/xrootd/xrdproto/dirlist"
    14  	"go-hep.org/x/hep/xrootd/xrdproto/mkdir"
    15  	"go-hep.org/x/hep/xrootd/xrdproto/mv"
    16  	"go-hep.org/x/hep/xrootd/xrdproto/open"
    17  	"go-hep.org/x/hep/xrootd/xrdproto/rm"
    18  	"go-hep.org/x/hep/xrootd/xrdproto/rmdir"
    19  	"go-hep.org/x/hep/xrootd/xrdproto/stat"
    20  	"go-hep.org/x/hep/xrootd/xrdproto/statx"
    21  	"go-hep.org/x/hep/xrootd/xrdproto/truncate"
    22  )
    23  
    24  // FS returns a xrdfs.FileSystem which uses this client to make requests.
    25  func (cli *Client) FS() xrdfs.FileSystem {
    26  	return &fileSystem{cli}
    27  }
    28  
    29  // fileSystem contains filesystem-related methods of the XRootD protocol.
    30  type fileSystem struct {
    31  	c *Client
    32  }
    33  
    34  // Dirlist returns the contents of a directory together with the stat information.
    35  func (fs *fileSystem) Dirlist(ctx context.Context, path string) ([]xrdfs.EntryStat, error) {
    36  	var resp dirlist.Response
    37  	_, err := fs.c.Send(ctx, &resp, dirlist.NewRequest(path))
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	return resp.Entries, err
    42  }
    43  
    44  // Open returns the file handle for a file together with the compression and the stat info.
    45  func (fs *fileSystem) Open(ctx context.Context, path string, mode xrdfs.OpenMode, options xrdfs.OpenOptions) (xrdfs.File, error) {
    46  	var resp open.Response
    47  	server, err := fs.c.Send(ctx, &resp, open.NewRequest(path, mode, options))
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	return &file{fs: fs, handle: resp.FileHandle, compression: resp.Compression, info: resp.Stat, sessionID: server}, nil
    52  }
    53  
    54  // RemoveFile removes a file.
    55  func (fs *fileSystem) RemoveFile(ctx context.Context, path string) error {
    56  	_, err := fs.c.Send(ctx, nil, &rm.Request{Path: path})
    57  	return err
    58  }
    59  
    60  // Truncate changes the size of the named file.
    61  func (fs *fileSystem) Truncate(ctx context.Context, path string, size int64) error {
    62  	_, err := fs.c.Send(ctx, nil, &truncate.Request{Path: path, Size: size})
    63  	return err
    64  }
    65  
    66  // Stat returns the entry stat info for the given path.
    67  func (fs *fileSystem) Stat(ctx context.Context, path string) (xrdfs.EntryStat, error) {
    68  	var resp stat.DefaultResponse
    69  	_, err := fs.c.Send(ctx, &resp, &stat.Request{Path: path})
    70  	if err != nil {
    71  		return xrdfs.EntryStat{}, err
    72  	}
    73  	return resp.EntryStat, nil
    74  }
    75  
    76  // VirtualStat returns the virtual filesystem stat info for the given path.
    77  // Note that path needs not to be an existing filesystem object, it is used as a path prefix in order to
    78  // filter out servers and partitions that could not be used to hold objects whose path starts
    79  // with the specified path prefix.
    80  func (fs *fileSystem) VirtualStat(ctx context.Context, path string) (xrdfs.VirtualFSStat, error) {
    81  	var resp stat.VirtualFSResponse
    82  	_, err := fs.c.Send(ctx, &resp, &stat.Request{Path: path, Options: stat.OptionsVFS})
    83  	if err != nil {
    84  		return xrdfs.VirtualFSStat{}, err
    85  	}
    86  	return resp.VirtualFSStat, nil
    87  }
    88  
    89  // Mkdir creates a new directory with the specified name and permission bits.
    90  func (fs *fileSystem) Mkdir(ctx context.Context, path string, perm xrdfs.OpenMode) error {
    91  	_, err := fs.c.Send(ctx, nil, &mkdir.Request{Path: path, Mode: perm})
    92  	return err
    93  }
    94  
    95  // MkdirAll creates a directory named path, along with any necessary parents,
    96  // and returns nil, or else returns an error.
    97  // The permission bits perm are used for all directories that MkdirAll creates.
    98  func (fs *fileSystem) MkdirAll(ctx context.Context, path string, perm xrdfs.OpenMode) error {
    99  	_, err := fs.c.Send(ctx, nil, &mkdir.Request{Path: path, Mode: perm, Options: mkdir.OptionsMakePath})
   100  	return err
   101  }
   102  
   103  // RemoveDir removes a directory.
   104  // The directory to be removed must be empty.
   105  func (fs *fileSystem) RemoveDir(ctx context.Context, path string) error {
   106  	_, err := fs.c.Send(ctx, nil, &rmdir.Request{Path: path})
   107  	return err
   108  }
   109  
   110  // RemoveAll removes path and any children it contains.
   111  // It removes everything it can but returns the first error it encounters.
   112  // If the path does not exist, RemoveAll returns nil (no error.)
   113  func (fs *fileSystem) RemoveAll(ctx context.Context, path string) error {
   114  	st, err := fs.Stat(ctx, path)
   115  	if err != nil {
   116  		return err
   117  	}
   118  	switch {
   119  	case st.IsDir():
   120  		entries, err := fs.Dirlist(ctx, path)
   121  		if err != nil {
   122  			return err
   123  		}
   124  		for _, e := range entries {
   125  			name := stdpath.Join(path, e.Name())
   126  			err := fs.RemoveAll(ctx, name)
   127  			if err != nil {
   128  				return err
   129  			}
   130  		}
   131  		return fs.RemoveDir(ctx, path)
   132  	default:
   133  		return fs.RemoveFile(ctx, path)
   134  	}
   135  }
   136  
   137  // Rename renames (moves) oldpath to newpath.
   138  func (fs *fileSystem) Rename(ctx context.Context, oldpath, newpath string) error {
   139  	_, err := fs.c.Send(ctx, nil, &mv.Request{OldPath: oldpath, NewPath: newpath})
   140  	return err
   141  }
   142  
   143  // Chmod changes the permissions of the named file to perm.
   144  func (fs *fileSystem) Chmod(ctx context.Context, path string, perm xrdfs.OpenMode) error {
   145  	_, err := fs.c.Send(ctx, nil, &chmod.Request{Path: path, Mode: perm})
   146  	return err
   147  }
   148  
   149  // Statx obtains type information for one or more paths.
   150  // Only a limited number of flags is meaningful such as StatIsExecutable, StatIsDir, StatIsOther, StatIsOffline.
   151  func (fs *fileSystem) Statx(ctx context.Context, paths []string) ([]xrdfs.StatFlags, error) {
   152  	var resp statx.Response
   153  	_, err := fs.c.Send(ctx, &resp, statx.NewRequest(paths))
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  	return resp.StatFlags, nil
   158  }
   159  
   160  var (
   161  	_ xrdfs.FileSystem = (*fileSystem)(nil)
   162  )