github.com/pachyderm/pachyderm@v1.13.4/src/server/worker/driver/driver_windows.go (about) 1 // +build windows 2 3 package driver 4 5 import ( 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "syscall" 10 11 "github.com/pachyderm/pachyderm/src/client" 12 "github.com/pachyderm/pachyderm/src/client/pkg/errors" 13 "github.com/pachyderm/pachyderm/src/server/worker/common" 14 ) 15 16 // Note: these are stubs only meant for tests - the worker does not run on windows 17 18 func makeCmdCredentials(uid uint32, gid uint32) *syscall.SysProcAttr { 19 return nil 20 } 21 22 // Note: this function only exists for tests, the real system uses a fifo for 23 // this (which does not exist in the normal filesystem on Windows) 24 func createSpoutFifo(path string) error { 25 file, err := os.Create(path) 26 if err != nil { 27 return err 28 } 29 return file.Close() 30 } 31 32 // WithActiveData is implemented differently in unix vs windows because of how 33 // symlinks work on windows. Here, we move inputs into place before the 34 // callback, then move them back to the scratch space before returning. 35 func (d *driver) WithActiveData(inputs []*common.Input, dir string, cb func() error) (retErr error) { 36 d.activeDataMutex.Lock() 37 defer d.activeDataMutex.Unlock() 38 39 if err := d.moveData(inputs, dir); err != nil { 40 return errors.Wrap(err, "error when linking active data directory") 41 } 42 defer func() { 43 if err := d.unmoveData(inputs, dir); err != nil && retErr == nil { 44 retErr = errors.Wrap(err, "error when unlinking active data directory") 45 } 46 }() 47 48 return cb() 49 } 50 51 // os.Symlink requires additional privileges on windows, so just move the files instead 52 func (d *driver) moveData(inputs []*common.Input, dir string) error { 53 // Make sure that the previous outputs are removed. 54 if err := d.unlinkData(inputs); err != nil { 55 return err 56 } 57 58 // sometimes for group inputs, this part may get run multiple times for the same file 59 seen := make(map[string]bool) 60 for _, input := range inputs { 61 if input.S3 { 62 continue 63 } 64 if _, ok := seen[input.Name]; !ok { 65 seen[input.Name] = true 66 src := filepath.Join(dir, input.Name) 67 dst := filepath.Join(d.InputDir(), input.Name) 68 if err := os.Rename(src, dst); err != nil { 69 return err 70 } 71 } 72 } 73 74 if d.PipelineInfo().Spout != nil && d.PipelineInfo().Spout.Marker != "" { 75 src := filepath.Join(dir, d.PipelineInfo().Spout.Marker) 76 dst := filepath.Join(d.InputDir(), d.PipelineInfo().Spout.Marker) 77 if err := os.Rename(src, dst); err != nil { 78 return err 79 } 80 } 81 82 return os.Rename(filepath.Join(dir, "out"), filepath.Join(d.InputDir(), "out")) 83 } 84 85 func (d *driver) unmoveData(inputs []*common.Input, dir string) error { 86 entries, err := ioutil.ReadDir(d.InputDir()) 87 if err != nil { 88 return errors.Wrap(err, "ioutil.ReadDir") 89 } 90 for _, entry := range entries { 91 if entry.Name() == client.PPSScratchSpace { 92 continue // don't delete scratch space 93 } 94 if err := os.Rename(filepath.Join(d.InputDir(), entry.Name()), filepath.Join(dir, entry.Name())); err != nil { 95 return err 96 } 97 } 98 return nil 99 }