forked from TrueCloudLab/distribution
Ignore self reference object on empty prefix
When a given prefix is empty and we attempt to list its content AWS returns that the prefix contains one object with key defined as the prefix with an extra "/" at the end. e.g. If we call ListObjects() passing to it an existing but empty prefix, say "my/empty/prefix", AWS will return that "my/empty/prefix/" is an object inside "my/empty/prefix" (ListObjectsOutput.Contents). This extra "/" causes the upload purging process to panic. On normal circunstances we never find empty prefixes on S3 but users may touch it. Signed-off-by: Ricardo Maraschini <rmarasch@redhat.com>
This commit is contained in:
parent
551158e600
commit
87cbd09fa7
2 changed files with 39 additions and 0 deletions
|
@ -986,6 +986,11 @@ func (d *driver) doWalk(parentCtx context.Context, objectCount *int64, path, pre
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range objects.Contents {
|
for _, file := range objects.Contents {
|
||||||
|
// empty prefixes are listed as objects inside its own prefix.
|
||||||
|
// https://docs.aws.amazon.com/AmazonS3/latest/user-guide/using-folders.html
|
||||||
|
if strings.HasSuffix(*file.Key, "/") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
walkInfos = append(walkInfos, walkInfoContainer{
|
walkInfos = append(walkInfos, walkInfoContainer{
|
||||||
FileInfoFields: storagedriver.FileInfoFields{
|
FileInfoFields: storagedriver.FileInfoFields{
|
||||||
IsDir: false,
|
IsDir: false,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -164,6 +165,39 @@ func TestEmptyRootList(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestWalkEmptySubDirectory assures we list an empty sub directory only once when walking
|
||||||
|
// through its parent directory.
|
||||||
|
func TestWalkEmptySubDirectory(t *testing.T) {
|
||||||
|
if skipS3() != "" {
|
||||||
|
t.Skip(skipS3())
|
||||||
|
}
|
||||||
|
|
||||||
|
drv, err := s3DriverConstructor("", s3.StorageClassStandard)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error creating rooted driver: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an empty sub directory.
|
||||||
|
s3driver := drv.StorageDriver.(*driver)
|
||||||
|
if _, err := s3driver.S3.PutObject(&s3.PutObjectInput{
|
||||||
|
Bucket: aws.String(os.Getenv("S3_BUCKET")),
|
||||||
|
Key: aws.String("/testdir/emptydir/"),
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("error creating empty directory: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bucketFiles := []string{}
|
||||||
|
s3driver.Walk(context.Background(), "/testdir", func(fileInfo storagedriver.FileInfo) error {
|
||||||
|
bucketFiles = append(bucketFiles, fileInfo.Path())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
expected := []string{"/testdir/emptydir"}
|
||||||
|
if !reflect.DeepEqual(bucketFiles, expected) {
|
||||||
|
t.Errorf("expecting files %+v, found %+v instead", expected, bucketFiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStorageClass(t *testing.T) {
|
func TestStorageClass(t *testing.T) {
|
||||||
if skipS3() != "" {
|
if skipS3() != "" {
|
||||||
t.Skip(skipS3())
|
t.Skip(skipS3())
|
||||||
|
|
Loading…
Reference in a new issue