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  }