Skip to content

Commit

Permalink
Handle prefixes when listing blocks from S3
Browse files Browse the repository at this point in the history
  • Loading branch information
bpfoster committed Mar 5, 2024
1 parent 8079874 commit 5fd578a
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* [BUGFIX] Fix metrics query results when filtering and rating on the same attribute [#3428](https://github.com/grafana/tempo/issues/3428) (@mdisibio)
* [BUGFIX] Fix metrics query results when series contain empty strings or nil values [#3429](https://github.com/grafana/tempo/issues/3429) (@mdisibio)
* [BUGFIX] Return unfiltered results when a bad TraceQL query is provided in autocomplete. [#3426](https://github.com/grafana/tempo/pull/3426) (@mapno)
* [BUGFIX] Fix compaction/retention in AWS S3 when a prefix is configured (@bpfoster)

## v2.4.0

Expand Down
2 changes: 1 addition & 1 deletion tempodb/backend/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ func (rw *readerWriter) ListBlocks(

for _, c := range res.Contents {
// i.e: <tenantID/<blockID>/meta
parts := strings.Split(c.Key, "/")
parts := strings.Split(strings.TrimPrefix(c.Key, rw.cfg.Prefix), "/")
if len(parts) != 3 {
continue
}
Expand Down
213 changes: 213 additions & 0 deletions tempodb/backend/s3/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,219 @@ func TestObjectWithPrefix(t *testing.T) {
}
}

func TestListBlocksWithPrefix(t *testing.T) {
tests := []struct {
name string
prefix string
objectName string
keyPath backend.KeyPath
httpHandler func(t *testing.T) http.HandlerFunc
}{
{
name: "with prefix",
prefix: "a/b/c/",
objectName: "object",
keyPath: backend.KeyPath{"test"},
httpHandler: func(t *testing.T) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == getMethod {
//assert.Equal(t, r.URL.Query().Get("prefix"), "a/b/c/")

_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult>
<Name>blerg</Name>
<Prefix>a/b/c</Prefix>
<ContinuationToken></ContinuationToken>
<KeyCount>9</KeyCount>
<MaxKeys>100</MaxKeys>
<EncodingType>url</EncodingType>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000000/bloom-0</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<Size>1024</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000000/data.parquet</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;387d0a7670dcf52fa9a4d94cd36815e1-1&quot;</ETag>
<Size>3216226</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000000/index</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;532adc8eccdaa77d02748f6aa550323d&quot;</ETag>
<Size>42</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000000/meta.json</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;d42a22ddd183f61924c661b1c026c1ef&quot;</ETag>
<Size>398</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000001/bloom-0</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<Size>1024</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000001/data.parquet</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;387d0a7670dcf52fa9a4d94cd36815e1-1&quot;</ETag>
<Size>3216226</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000001/index</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;532adc8eccdaa77d02748f6aa550323d&quot;</ETag>
<Size>42</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>a/b/c/single-tenant/00000000-0000-0000-0000-000000000001/meta.compacted.json</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;d42a22ddd183f61924c661b1c026c1ef&quot;</ETag>
<Size>398</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>tempo_cluster_seed.json</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;00000000000000000000000000000000&quot;</ETag>
<ChecksumAlgorithm>CRC32C</ChecksumAlgorithm>
<Size>214</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
</ListBucketResult>`))
return
}

assert.Equal(t, "/blerg/test_storage/test/object", r.URL.String())
}
},
},
{
name: "without prefix",
prefix: "",
objectName: "object",
keyPath: backend.KeyPath{"test"},
httpHandler: func(t *testing.T) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == getMethod {
//assert.Equal(t, r.URL.Query().Get("prefix"), "")

_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult>
<Name>blerg</Name>
<Prefix></Prefix>
<ContinuationToken></ContinuationToken>
<KeyCount>9</KeyCount>
<MaxKeys>100</MaxKeys>
<EncodingType>url</EncodingType>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000000/bloom-0</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<Size>1024</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000000/data.parquet</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;387d0a7670dcf52fa9a4d94cd36815e1-1&quot;</ETag>
<Size>3216226</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000000/index</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;532adc8eccdaa77d02748f6aa550323d&quot;</ETag>
<Size>42</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000000/meta.json</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;d42a22ddd183f61924c661b1c026c1ef&quot;</ETag>
<Size>398</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000001/bloom-0</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<Size>1024</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000001/data.parquet</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;387d0a7670dcf52fa9a4d94cd36815e1-1&quot;</ETag>
<Size>3216226</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000001/index</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;532adc8eccdaa77d02748f6aa550323d&quot;</ETag>
<Size>42</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>single-tenant/00000000-0000-0000-0000-000000000001/meta.compacted.json</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;d42a22ddd183f61924c661b1c026c1ef&quot;</ETag>
<Size>398</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>tempo_cluster_seed.json</Key>
<LastModified>2024-03-01T00:00:00.000Z</LastModified>
<ETag>&quot;00000000000000000000000000000000&quot;</ETag>
<ChecksumAlgorithm>CRC32C</ChecksumAlgorithm>
<Size>214</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
</ListBucketResult>`))
return
}

assert.Equal(t, "/blerg/test/object", r.URL.String())
}
},
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
server := testServer(t, tc.httpHandler(t))
r, _, _, err := New(&Config{
Region: "blerg",
AccessKey: "test",
SecretKey: flagext.SecretWithValue("test"),
Bucket: "blerg",
Prefix: tc.prefix,
Insecure: true,
Endpoint: server.URL[7:],
ListBlocksConcurrency: 1,
})
require.NoError(t, err)

ctx := context.Background()
blockIDs, compactedBlockIDs, err2 := r.ListBlocks(ctx, "single-tenant")
assert.Equal(t, 1, len(blockIDs))
assert.Equal(t, 1, len(compactedBlockIDs))
assert.NoError(t, err2)

})
}
}

func TestObjectStorageClass(t *testing.T) {
tests := []struct {
name string
Expand Down

0 comments on commit 5fd578a

Please sign in to comment.