// filterExisting returns a slice of all existing items, or an error if no // items exist at all. func filterExisting(items []string) (result []string, err error) { for _, item := range items { _, err := fs.Lstat(item) if err != nil && os.IsNotExist(errors.Cause(err)) { continue } result = append(result, item) } if len(result) == 0 { return nil, errors.Fatal("all target directories/files do not exist") } return }
// gatherDevices returns the set of unique device ids of the files and/or // directory paths listed in "items". func gatherDevices(items []string) (deviceMap map[uint64]struct{}, err error) { deviceMap = make(map[uint64]struct{}) for _, item := range items { fi, err := fs.Lstat(item) if err != nil { return nil, err } id, err := fs.DeviceID(fi) if err != nil { return nil, err } deviceMap[id] = struct{}{} } if len(deviceMap) == 0 { return nil, errors.New("zero allowed devices") } return deviceMap, nil }
// Create creates all the necessary files and directories for a new local // backend at dir. Afterwards a new config blob should be created. func Create(dir string) (*Local, error) { // test if config file already exists _, err := fs.Lstat(filepath.Join(dir, backend.Paths.Config)) if err == nil { return nil, errors.New("config file already exists") } // create paths for data, refs and temp for _, d := range paths(dir) { err := fs.MkdirAll(d, backend.Modes.Dir) if err != nil { return nil, errors.Wrap(err, "MkdirAll") } } // open backend return Open(dir) }
func walk(basedir, dir string, selectFunc SelectFunc, done <-chan struct{}, jobs chan<- Job, res chan<- Result) (excluded bool) { debug.Log("start on %q, basedir %q", dir, basedir) relpath, err := filepath.Rel(basedir, dir) if err != nil { panic(err) } info, err := fs.Lstat(dir) if err != nil { err = errors.Wrap(err, "Lstat") debug.Log("error for %v: %v, res %p", dir, err, res) select { case jobs <- Dir{basedir: basedir, path: relpath, info: info, error: err, result: res}: case <-done: } return } if !selectFunc(dir, info) { debug.Log("file %v excluded by filter, res %p", dir, res) excluded = true return } if !info.IsDir() { debug.Log("sending file job for %v, res %p", dir, res) select { case jobs <- Entry{info: info, basedir: basedir, path: relpath, result: res}: case <-done: } return } debug.RunHook("pipe.readdirnames", dir) names, err := readDirNames(dir) if err != nil { debug.Log("Readdirnames(%v) returned error: %v, res %p", dir, err, res) select { case <-done: case jobs <- Dir{basedir: basedir, path: relpath, info: info, error: err, result: res}: } return } // Insert breakpoint to allow testing behaviour with vanishing files // between Readdir() and lstat() debug.RunHook("pipe.walk1", relpath) entries := make([]<-chan Result, 0, len(names)) for _, name := range names { subpath := filepath.Join(dir, name) fi, statErr := fs.Lstat(subpath) if !selectFunc(subpath, fi) { debug.Log("file %v excluded by filter", subpath) continue } ch := make(chan Result, 1) entries = append(entries, ch) if statErr != nil { statErr = errors.Wrap(statErr, "Lstat") debug.Log("sending file job for %v, err %v, res %p", subpath, err, res) select { case jobs <- Entry{info: fi, error: statErr, basedir: basedir, path: filepath.Join(relpath, name), result: ch}: case <-done: return } continue } // Insert breakpoint to allow testing behaviour with vanishing files // between walk and open debug.RunHook("pipe.walk2", filepath.Join(relpath, name)) walk(basedir, subpath, selectFunc, done, jobs, ch) } debug.Log("sending dirjob for %q, basedir %q, res %p", dir, basedir, res) select { case jobs <- Dir{basedir: basedir, path: relpath, info: info, Entries: entries, result: res}: case <-done: } return }