github.com/csfrancis/docker@v1.8.0-rc2/builder/internals_linux.go (about)

     1  // +build linux
     2  
     3  package builder
     4  
     5  import (
     6  	"os"
     7  	"path/filepath"
     8  )
     9  
    10  func fixPermissions(source, destination string, uid, gid int, destExisted bool) error {
    11  	// If the destination didn't already exist, or the destination isn't a
    12  	// directory, then we should Lchown the destination. Otherwise, we shouldn't
    13  	// Lchown the destination.
    14  	destStat, err := os.Stat(destination)
    15  	if err != nil {
    16  		// This should *never* be reached, because the destination must've already
    17  		// been created while untar-ing the context.
    18  		return err
    19  	}
    20  	doChownDestination := !destExisted || !destStat.IsDir()
    21  
    22  	// We Walk on the source rather than on the destination because we don't
    23  	// want to change permissions on things we haven't created or modified.
    24  	return filepath.Walk(source, func(fullpath string, info os.FileInfo, err error) error {
    25  		// Do not alter the walk root iff. it existed before, as it doesn't fall under
    26  		// the domain of "things we should chown".
    27  		if !doChownDestination && (source == fullpath) {
    28  			return nil
    29  		}
    30  
    31  		// Path is prefixed by source: substitute with destination instead.
    32  		cleaned, err := filepath.Rel(source, fullpath)
    33  		if err != nil {
    34  			return err
    35  		}
    36  
    37  		fullpath = filepath.Join(destination, cleaned)
    38  		return os.Lchown(fullpath, uid, gid)
    39  	})
    40  }