Add API support for NoOverwriteDirNonDir

Update method signatures and structs to pass option to buildah code

```release-note
NONE
```

[NO NEW TESTS NEEDED]

Signed-off-by: Jhon Honce <jhonce@redhat.com>
This commit is contained in:
Jhon Honce
2022-05-26 16:24:10 -07:00
parent 1736f2fe60
commit 8efdbf5c4c
5 changed files with 41 additions and 28 deletions

View File

@ -446,7 +446,7 @@ func (c *Container) AddArtifact(name string, data []byte) error {
return define.ErrCtrRemoved 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 // GetArtifact reads the specified artifact file from the container
@ -877,7 +877,7 @@ func (c *Container) ShouldRestart(ctx context.Context) bool {
// CopyFromArchive copies the contents from the specified tarStream to path // CopyFromArchive copies the contents from the specified tarStream to path
// *inside* the container. // *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 { if !c.batched {
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock() defer c.lock.Unlock()
@ -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 // CopyToArchive copies the contents from the specified path *inside* the

View File

@ -23,7 +23,7 @@ import (
"golang.org/x/sys/unix" "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 ( var (
mountPoint string mountPoint string
resolvedRoot string resolvedRoot string
@ -89,11 +89,12 @@ func (c *Container) copyFromArchive(path string, chown bool, rename map[string]s
defer unmount() defer unmount()
defer decompressed.Close() defer decompressed.Close()
putOptions := buildahCopiah.PutOptions{ putOptions := buildahCopiah.PutOptions{
UIDMap: c.config.IDMappings.UIDMap, UIDMap: c.config.IDMappings.UIDMap,
GIDMap: c.config.IDMappings.GIDMap, GIDMap: c.config.IDMappings.GIDMap,
ChownDirs: idPair, ChownDirs: idPair,
ChownFiles: idPair, ChownFiles: idPair,
Rename: rename, NoOverwriteDirNonDir: noOverwriteDirNonDir,
Rename: rename,
} }
return c.joinMountAndExec( return c.joinMountAndExec(

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"os" "os"
"strings"
"github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
@ -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) { func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder, runtime *libpod.Runtime) {
query := struct { query := struct {
Path string `schema:"path"` Path string `schema:"path"`
Chown bool `schema:"copyUIDGID"` Chown bool `schema:"copyUIDGID"`
Rename string `schema:"rename"` Rename string `schema:"rename"`
// TODO handle params below NoOverwriteDirNonDir bool `schema:"noOverwriteDirNonDir"`
NoOverwriteDirNonDir bool `schema:"noOverwriteDirNonDir"`
}{ }{
Chown: utils.IsLibpodRequest(r), // backward compatibility Chown: utils.IsLibpodRequest(r), // backward compatibility
} }
@ -112,7 +112,7 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
var rename map[string]string var rename map[string]string
if query.Rename != "" { if query.Rename != "" {
if err := json.Unmarshal([]byte(query.Rename), &rename); err != nil { 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 return
} }
} }
@ -120,15 +120,25 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
containerName := utils.GetName(r) containerName := utils.GetName(r)
containerEngine := abi.ContainerEngine{Libpod: runtime} containerEngine := abi.ContainerEngine{Libpod: runtime}
copyOptions := entities.CopyOptions{Chown: query.Chown, Rename: rename} copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body,
copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body, copyOptions) entities.CopyOptions{
if errors.Cause(err) == define.ErrNoSuchCtr || os.IsNotExist(err) { Chown: query.Chown,
// 404 is returned for an absent container and path. The NoOverwriteDirNonDir: query.NoOverwriteDirNonDir,
// clients must deal with it accordingly. Rename: rename,
utils.Error(w, http.StatusNotFound, errors.Wrap(err, "the container doesn't exists")) })
return if err != nil {
} else if err != nil { switch {
utils.Error(w, http.StatusInternalServerError, err) 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 return
} }

View File

@ -47,8 +47,7 @@ type ContainerRunlabelOptions struct {
} }
// ContainerRunlabelReport contains the results from executing container-runlabel. // ContainerRunlabelReport contains the results from executing container-runlabel.
type ContainerRunlabelReport struct { type ContainerRunlabelReport struct{}
}
type WaitOptions struct { type WaitOptions struct {
Condition []define.ContainerStatus Condition []define.ContainerStatus
@ -165,6 +164,9 @@ type CopyOptions struct {
Chown bool Chown bool
// Map to translate path names. // Map to translate path names.
Rename map[string]string 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 { type CommitReport struct {

View File

@ -12,10 +12,10 @@ func (ic *ContainerEngine) ContainerCopyFromArchive(ctx context.Context, nameOrI
if err != nil { if err != nil {
return nil, err 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) container, err := ic.Libpod.LookupContainer(nameOrID)
if err != nil { if err != nil {
return nil, err return nil, err