github.com/boynux/docker@v1.11.0-rc4/daemon/archive_unix.go (about)

     1  // +build !windows
     2  
     3  package daemon
     4  
     5  import (
     6  	"github.com/docker/docker/container"
     7  	"os"
     8  	"path/filepath"
     9  )
    10  
    11  // checkIfPathIsInAVolume checks if the path is in a volume. If it is, it
    12  // cannot be in a read-only volume. If it  is not in a volume, the container
    13  // cannot be configured with a read-only rootfs.
    14  func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) {
    15  	var toVolume bool
    16  	for _, mnt := range container.MountPoints {
    17  		if toVolume = mnt.HasResource(absPath); toVolume {
    18  			if mnt.RW {
    19  				break
    20  			}
    21  			return false, ErrVolumeReadonly
    22  		}
    23  	}
    24  	return toVolume, nil
    25  }
    26  
    27  func fixPermissions(source, destination string, uid, gid int, destExisted bool) error {
    28  	// If the destination didn't already exist, or the destination isn't a
    29  	// directory, then we should Lchown the destination. Otherwise, we shouldn't
    30  	// Lchown the destination.
    31  	destStat, err := os.Stat(destination)
    32  	if err != nil {
    33  		// This should *never* be reached, because the destination must've already
    34  		// been created while untar-ing the context.
    35  		return err
    36  	}
    37  	doChownDestination := !destExisted || !destStat.IsDir()
    38  
    39  	// We Walk on the source rather than on the destination because we don't
    40  	// want to change permissions on things we haven't created or modified.
    41  	return filepath.Walk(source, func(fullpath string, info os.FileInfo, err error) error {
    42  		// Do not alter the walk root iff. it existed before, as it doesn't fall under
    43  		// the domain of "things we should chown".
    44  		if !doChownDestination && (source == fullpath) {
    45  			return nil
    46  		}
    47  
    48  		// Path is prefixed by source: substitute with destination instead.
    49  		cleaned, err := filepath.Rel(source, fullpath)
    50  		if err != nil {
    51  			return err
    52  		}
    53  
    54  		fullpath = filepath.Join(destination, cleaned)
    55  		return os.Lchown(fullpath, uid, gid)
    56  	})
    57  }