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