Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API support for NoOverwriteDirNonDir #14393

Merged
merged 1 commit into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions libpod/container_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func (c *Container) AddArtifact(name string, data []byte) error {
return define.ErrCtrRemoved
}

return ioutil.WriteFile(c.getArtifactPath(name), data, 0740)
return ioutil.WriteFile(c.getArtifactPath(name), data, 0o740)
}

// GetArtifact reads the specified artifact file from the container
Expand Down Expand Up @@ -877,7 +877,7 @@ func (c *Container) ShouldRestart(ctx context.Context) bool {

// CopyFromArchive copies the contents from the specified tarStream to path
// *inside* the container.
func (c *Container) CopyFromArchive(ctx context.Context, containerPath string, chown bool, rename map[string]string, tarStream io.Reader) (func() error, error) {
func (c *Container) CopyFromArchive(_ context.Context, containerPath string, chown, noOverwriteDirNonDir bool, rename map[string]string, tarStream io.Reader) (func() error, error) {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
Expand All @@ -887,7 +887,7 @@ func (c *Container) CopyFromArchive(ctx context.Context, containerPath string, c
}
}

return c.copyFromArchive(containerPath, chown, rename, tarStream)
return c.copyFromArchive(containerPath, chown, noOverwriteDirNonDir, rename, tarStream)
}

// CopyToArchive copies the contents from the specified path *inside* the
Expand Down
13 changes: 7 additions & 6 deletions libpod/container_copy_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"golang.org/x/sys/unix"
)

func (c *Container) copyFromArchive(path string, chown bool, rename map[string]string, reader io.Reader) (func() error, error) {
func (c *Container) copyFromArchive(path string, chown, noOverwriteDirNonDir bool, rename map[string]string, reader io.Reader) (func() error, error) {
var (
mountPoint string
resolvedRoot string
Expand Down Expand Up @@ -89,11 +89,12 @@ func (c *Container) copyFromArchive(path string, chown bool, rename map[string]s
defer unmount()
defer decompressed.Close()
putOptions := buildahCopiah.PutOptions{
UIDMap: c.config.IDMappings.UIDMap,
GIDMap: c.config.IDMappings.GIDMap,
ChownDirs: idPair,
ChownFiles: idPair,
Rename: rename,
UIDMap: c.config.IDMappings.UIDMap,
GIDMap: c.config.IDMappings.GIDMap,
ChownDirs: idPair,
ChownFiles: idPair,
NoOverwriteDirNonDir: noOverwriteDirNonDir,
Rename: rename,
}

return c.joinMountAndExec(
Expand Down
40 changes: 25 additions & 15 deletions pkg/api/handlers/compat/containers_archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"net/http"
"os"
"strings"

"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
Expand Down Expand Up @@ -94,11 +95,10 @@ func handleHeadAndGet(w http.ResponseWriter, r *http.Request, decoder *schema.De

func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder, runtime *libpod.Runtime) {
query := struct {
Path string `schema:"path"`
Chown bool `schema:"copyUIDGID"`
Rename string `schema:"rename"`
// TODO handle params below
NoOverwriteDirNonDir bool `schema:"noOverwriteDirNonDir"`
Path string `schema:"path"`
Chown bool `schema:"copyUIDGID"`
Rename string `schema:"rename"`
NoOverwriteDirNonDir bool `schema:"noOverwriteDirNonDir"`
}{
Chown: utils.IsLibpodRequest(r), // backward compatibility
}
Expand All @@ -112,23 +112,33 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
var rename map[string]string
if query.Rename != "" {
if err := json.Unmarshal([]byte(query.Rename), &rename); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrap(err, "couldn't decode the query"))
utils.Error(w, http.StatusBadRequest, errors.Wrap(err, "couldn't decode the query field 'rename'"))
return
}
}

containerName := utils.GetName(r)
containerEngine := abi.ContainerEngine{Libpod: runtime}

copyOptions := entities.CopyOptions{Chown: query.Chown, Rename: rename}
copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body, copyOptions)
if errors.Cause(err) == define.ErrNoSuchCtr || os.IsNotExist(err) {
// 404 is returned for an absent container and path. The
// clients must deal with it accordingly.
utils.Error(w, http.StatusNotFound, errors.Wrap(err, "the container doesn't exists"))
return
} else if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body,
entities.CopyOptions{
Chown: query.Chown,
NoOverwriteDirNonDir: query.NoOverwriteDirNonDir,
Rename: rename,
})
if err != nil {
switch {
case errors.Cause(err) == define.ErrNoSuchCtr || os.IsNotExist(err):
// 404 is returned for an absent container and path. The
// clients must deal with it accordingly.
utils.Error(w, http.StatusNotFound, errors.Wrap(err, "the container doesn't exists"))
case strings.Contains(err.Error(), "copier: put: error creating file"):
// Not the best test but need to break this out for compatibility
// See vendor/github.com/containers/buildah/copier/copier.go:1585
utils.Error(w, http.StatusBadRequest, err)
default:
utils.Error(w, http.StatusInternalServerError, err)
}
return
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/domain/entities/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ type ContainerRunlabelOptions struct {
}

// ContainerRunlabelReport contains the results from executing container-runlabel.
type ContainerRunlabelReport struct {
}
type ContainerRunlabelReport struct{}

type WaitOptions struct {
Condition []define.ContainerStatus
Expand Down Expand Up @@ -165,6 +164,9 @@ type CopyOptions struct {
Chown bool
// Map to translate path names.
Rename map[string]string
// NoOverwriteDirNonDir when true prevents an existing directory or file from being overwritten
// by the other type
NoOverwriteDirNonDir bool
}

type CommitReport struct {
Expand Down
4 changes: 2 additions & 2 deletions pkg/domain/infra/abi/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ func (ic *ContainerEngine) ContainerCopyFromArchive(ctx context.Context, nameOrI
if err != nil {
return nil, err
}
return container.CopyFromArchive(ctx, containerPath, options.Chown, options.Rename, reader)
return container.CopyFromArchive(ctx, containerPath, options.Chown, options.NoOverwriteDirNonDir, options.Rename, reader)
}

func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID string, containerPath string, writer io.Writer) (entities.ContainerCopyFunc, error) {
func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID, containerPath string, writer io.Writer) (entities.ContainerCopyFunc, error) {
container, err := ic.Libpod.LookupContainer(nameOrID)
if err != nil {
return nil, err
Expand Down