archive_unix.go 1.8 KB

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