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 }