//go:build !windows

package daemon // import "github.com/docker/docker/daemon"

import (
	"context"
	"io"
	"os"
	"path/filepath"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/events"
	"github.com/docker/docker/container"
	"github.com/docker/docker/errdefs"
	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/ioutils"
	volumemounts "github.com/docker/docker/volume/mounts"
	"github.com/pkg/errors"
)

// containerStatPath stats the filesystem resource at the specified path in this
// container. Returns stat info about the resource.
func (daemon *Daemon) containerStatPath(container *container.Container, path string) (stat *types.ContainerPathStat, err error) {
	container.Lock()
	defer container.Unlock()

	cfs, err := daemon.openContainerFS(container)
	if err != nil {
		return nil, err
	}
	defer cfs.Close()

	return cfs.Stat(context.TODO(), path)
}

// containerArchivePath creates an archive of the filesystem resource at the specified
// path in this container. Returns a tar archive of the resource and stat info
// about the resource.
func (daemon *Daemon) containerArchivePath(container *container.Container, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
	container.Lock()

	defer func() {
		if err != nil {
			// Wait to unlock the container until the archive is fully read
			// (see the ReadCloseWrapper func below) or if there is an error
			// before that occurs.
			container.Unlock()
		}
	}()

	cfs, err := daemon.openContainerFS(container)
	if err != nil {
		return nil, nil, err
	}

	defer func() {
		if err != nil {
			cfs.Close()
		}
	}()

	absPath := archive.PreserveTrailingDotOrSeparator(filepath.Join("/", path), path)

	stat, err = cfs.Stat(context.TODO(), absPath)
	if err != nil {
		return nil, nil, err
	}

	sourceDir, sourceBase := absPath, "."
	if stat.Mode&os.ModeDir == 0 { // not dir
		sourceDir, sourceBase = filepath.Split(absPath)
	}
	opts := archive.TarResourceRebaseOpts(sourceBase, filepath.Base(absPath))

	tb, err := archive.NewTarballer(sourceDir, opts)
	if err != nil {
		return nil, nil, err
	}

	cfs.GoInFS(context.TODO(), tb.Do)
	data := tb.Reader()
	content = ioutils.NewReadCloserWrapper(data, func() error {
		err := data.Close()
		_ = cfs.Close()
		container.Unlock()
		return err
	})

	daemon.LogContainerEvent(container, events.ActionArchivePath)

	return content, stat, nil
}

// containerExtractToDir extracts the given tar archive to the specified location in the
// filesystem of this container. The given path must be of a directory in the
// container. If it is not, the error will be an errdefs.InvalidParameter. If
// noOverwriteDirNonDir is true then it will be an error if unpacking the
// given content would cause an existing directory to be replaced with a non-
// directory and vice versa.
func (daemon *Daemon) containerExtractToDir(container *container.Container, path string, copyUIDGID, noOverwriteDirNonDir bool, content io.Reader) (err error) {
	container.Lock()
	defer container.Unlock()

	cfs, err := daemon.openContainerFS(container)
	if err != nil {
		return err
	}
	defer cfs.Close()

	err = cfs.RunInFS(context.TODO(), func() error {
		// The destination path needs to be resolved with all symbolic links
		// followed. Note that we need to also evaluate the last path element if
		// it is a symlink. This is so that you can extract an archive to a
		// symlink that points to a directory.
		absPath, err := filepath.EvalSymlinks(filepath.Join("/", path))
		if err != nil {
			return err
		}
		absPath = archive.PreserveTrailingDotOrSeparator(absPath, path)

		stat, err := os.Lstat(absPath)
		if err != nil {
			return err
		}
		if !stat.IsDir() {
			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 {
			return err
		}

		if !toVolume && container.HostConfig.ReadonlyRootfs {
			return errdefs.InvalidParameter(errors.New("container rootfs is marked read-only"))
		}

		options := daemon.defaultTarCopyOptions(noOverwriteDirNonDir)

		if copyUIDGID {
			var err error
			// tarCopyOptions will appropriately pull in the right uid/gid for the
			// user/group and will set the options.
			options, err = daemon.tarCopyOptions(container, noOverwriteDirNonDir)
			if err != nil {
				return err
			}
		}

		return archive.Untar(content, absPath, options)
	})
	if err != nil {
		return err
	}

	daemon.LogContainerEvent(container, events.ActionExtractToDir)

	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
	parser := volumemounts.NewParser()
	for _, mnt := range container.MountPoints {
		if toVolume = parser.HasResource(mnt, absPath); toVolume {
			if mnt.RW {
				break
			}
			return false, errdefs.InvalidParameter(errors.New("mounted volume is marked read-only"))
		}
	}
	return toVolume, nil
}
