github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/backend/union/policy/epall.go (about) 1 package policy 2 3 import ( 4 "context" 5 "path" 6 "sync" 7 8 "github.com/rclone/rclone/backend/union/upstream" 9 "github.com/rclone/rclone/fs" 10 ) 11 12 func init() { 13 registerPolicy("epall", &EpAll{}) 14 } 15 16 // EpAll stands for existing path, all 17 // Action category: apply to all found. 18 // Create category: apply to all found. 19 // Search category: same as epff. 20 type EpAll struct { 21 EpFF 22 } 23 24 func (p *EpAll) epall(ctx context.Context, upstreams []*upstream.Fs, filePath string) ([]*upstream.Fs, error) { 25 var wg sync.WaitGroup 26 ufs := make([]*upstream.Fs, len(upstreams)) 27 for i, u := range upstreams { 28 wg.Add(1) 29 i, u := i, u // Closure 30 go func() { 31 rfs := u.RootFs 32 remote := path.Join(u.RootPath, filePath) 33 if findEntry(ctx, rfs, remote) != nil { 34 ufs[i] = u 35 } 36 wg.Done() 37 }() 38 } 39 wg.Wait() 40 var results []*upstream.Fs 41 for _, f := range ufs { 42 if f != nil { 43 results = append(results, f) 44 } 45 } 46 if len(results) == 0 { 47 return nil, fs.ErrorObjectNotFound 48 } 49 return results, nil 50 } 51 52 // Action category policy, governing the modification of files and directories 53 func (p *EpAll) Action(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) { 54 if len(upstreams) == 0 { 55 return nil, fs.ErrorObjectNotFound 56 } 57 upstreams = filterRO(upstreams) 58 if len(upstreams) == 0 { 59 return nil, fs.ErrorPermissionDenied 60 } 61 return p.epall(ctx, upstreams, path) 62 } 63 64 // ActionEntries is ACTION category policy but receiving a set of candidate entries 65 func (p *EpAll) ActionEntries(entries ...upstream.Entry) ([]upstream.Entry, error) { 66 if len(entries) == 0 { 67 return nil, fs.ErrorObjectNotFound 68 } 69 entries = filterROEntries(entries) 70 if len(entries) == 0 { 71 return nil, fs.ErrorPermissionDenied 72 } 73 return entries, nil 74 } 75 76 // Create category policy, governing the creation of files and directories 77 func (p *EpAll) Create(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) { 78 if len(upstreams) == 0 { 79 return nil, fs.ErrorObjectNotFound 80 } 81 upstreams = filterNC(upstreams) 82 if len(upstreams) == 0 { 83 return nil, fs.ErrorPermissionDenied 84 } 85 upstreams, err := p.epall(ctx, upstreams, path+"/..") 86 return upstreams, err 87 } 88 89 // CreateEntries is CREATE category policy but receiving a set of candidate entries 90 func (p *EpAll) CreateEntries(entries ...upstream.Entry) ([]upstream.Entry, error) { 91 if len(entries) == 0 { 92 return nil, fs.ErrorObjectNotFound 93 } 94 entries = filterNCEntries(entries) 95 if len(entries) == 0 { 96 return nil, fs.ErrorPermissionDenied 97 } 98 return entries, nil 99 }