diff --git a/daemon/archive_unix.go b/daemon/archive_unix.go index 5db36d9bde..a0ac2c68e9 100644 --- a/daemon/archive_unix.go +++ b/daemon/archive_unix.go @@ -126,18 +126,11 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path return errdefs.InvalidParameter(errors.New("extraction point is not a directory")) } - // Need to check if the path is in a volume. If it is, it cannot be in a - // read-only volume. If it is not in a volume, the container cannot be - // configured with a read-only rootfs. - toVolume, err := checkIfPathIsInAVolume(container, absPath) - if err != nil { + // Check that the destination is not a read-only filesystem. + if err := checkWritablePath(container, absPath); err != nil { return err } - if !toVolume && container.HostConfig.ReadonlyRootfs { - return errdefs.InvalidParameter(errors.New("container rootfs is marked read-only")) - } - options := daemon.defaultTarCopyOptions(noOverwriteDirNonDir) if copyUIDGID { @@ -161,19 +154,22 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path return nil } -// checkIfPathIsInAVolume checks if the path is in a volume. If it is, it -// cannot be in a read-only volume. If it is not in a volume, the container -// cannot be configured with a read-only rootfs. -func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) { - var toVolume bool +// checkWritablePath checks if the path is in a writable location inside the +// container. If the path is within a location mounted from a volume, it checks +// if the volume is mounted read-only. If it is not in a volume, it checks whether +// the container's rootfs is mounted read-only. +func checkWritablePath(ctr *container.Container, absPath string) error { parser := volumemounts.NewParser() - for _, mnt := range container.MountPoints { - if toVolume = parser.HasResource(mnt, absPath); toVolume { + for _, mnt := range ctr.MountPoints { + if isVolumePath := parser.HasResource(mnt, absPath); isVolumePath { if mnt.RW { - break + return nil } - return false, errdefs.InvalidParameter(errors.New("mounted volume is marked read-only")) + return errdefs.InvalidParameter(errors.New("mounted volume is marked read-only")) } } - return toVolume, nil + if ctr.HostConfig.ReadonlyRootfs { + return errdefs.InvalidParameter(errors.New("container rootfs is marked read-only")) + } + return nil } diff --git a/daemon/archive_windows.go b/daemon/archive_windows.go index 32f8fc9e4a..e20cfa2699 100644 --- a/daemon/archive_windows.go +++ b/daemon/archive_windows.go @@ -229,18 +229,11 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path } } - // Make it an absolute path. absPath = filepath.Join(string(filepath.Separator), baseRel) - - toVolume, err := checkIfPathIsInAVolume(container, absPath) - if err != nil { + if err := checkWritablePath(container, absPath); err != nil { return err } - if !toVolume && container.HostConfig.ReadonlyRootfs { - return errdefs.InvalidParameter(errors.New("container rootfs is marked read-only")) - } - options := daemon.defaultTarCopyOptions(noOverwriteDirNonDir) if err := chrootarchive.UntarWithRoot(content, resolvedPath, options, container.BaseFS); err != nil { return err @@ -324,14 +317,16 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str return reader, nil } -// checkIfPathIsInAVolume checks if the path is in a volume. If it is, it -// cannot be in a read-only volume. If it is not in a volume, the container -// cannot be configured with a read-only rootfs. +// checkWritablePath is a no-op on Windows, which does not support read-only +// rootFS for containers, does not support read-only volumes, or extracting +// to a mount point inside a volume. // -// This is a no-op on Windows which does not support read-only volumes, or -// extracting to a mount point inside a volume. TODO Windows: FIXME Post-TP5 -func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) { - return false, nil +// TODO(thaJeztah): add check for writable path once windows supports read-only rootFS and (read-only) volumes during copy +// +// - e5261d6e4a1e96d4c0fa4b4480042046b695eda1 added "FIXME Post-TP4 / TP5"; check whether this would be possible to implement on Windows. +// - e5261d6e4a1e96d4c0fa4b4480042046b695eda1 added "or extracting to a mount point inside a volume"; check whether this is is still true, and adjust this check accordingly +func checkWritablePath(_ *container.Container, _ string) error { + return nil } // isOnlineFSOperationPermitted returns an error if an online filesystem operation