From df6af0bd659a1c9c8cc493739eea093997cf4778 Mon Sep 17 00:00:00 2001 From: Alan Protasio Date: Tue, 15 Nov 2022 16:33:51 -0800 Subject: [PATCH 1/4] Release Preparation (#4969) Signed-off-by: Alan Protasio Signed-off-by: Alan Protasio --- CHANGELOG.md | 20 ++++++++++---------- VERSION | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c126b1fc0b5..dc0080dbf8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,16 +47,6 @@ * [CHANGE] Enable PromQL `@` modifier, negative offset always. #4927 * [CHANGE] Store-gateway: Add user label to `cortex_bucket_store_blocks_loaded` metric. #4918 * [CHANGE] AlertManager: include `status` label in `cortex_alertmanager_alerts_received_total`. #4907 -* [ENHANCEMENT] AlertManager: Retrying AlertManager Get Requests (Get Alertmanager status, Get Alertmanager Receivers) on next replica on error #4840 -* [ENHANCEMENT] Querier/Ruler: Retry store-gateway in case of unexpected failure, instead of failing the query. #4532 #4839 -* [ENHANCEMENT] Ring: DoBatch prioritize 4xx errors when failing. #4783 -* [ENHANCEMENT] Cortex now built with Go 1.18. #4829 -* [ENHANCEMENT] Ingester: Prevent ingesters to become unhealthy during wall replay. #4847 -* [ENHANCEMENT] Compactor: Introduced visit marker file for blocks so blocks are under compaction will not be picked up by another compactor. #4805 -* [ENHANCEMENT] Distributor: Add label name to labelValueTooLongError. #4855 -* [ENHANCEMENT] Enhance traces with hostname information. #4898 -* [ENHANCEMENT] Improve the documentation around limits. #4905 -* [ENHANCEMENT] Distributor: cache user overrides to reduce lock contention. #4904 * [FEATURE] Compactor: Added `-compactor.block-files-concurrency` allowing to configure number of go routines for download/upload block files during compaction. #4784 * [FEATURE] Compactor: Added `-compactor.blocks-fetch-concurrency` allowing to configure number of go routines for blocks during compaction. #4787 * [FEATURE] Compactor: Added configurations for Azure MSI in blocks-storage, ruler-storage and alertmanager-storage. #4818 @@ -70,6 +60,16 @@ * [FEATURE] Querier: Added a new limit `-querier.max-fetched-data-bytes-per-query` allowing to limit the maximum size of all data in bytes that a query can fetch from each ingester and storage. #4854 * [FEATURE] Added 2 flags `-alertmanager.alertmanager-client.grpc-compression` and `-querier.store-gateway-client.grpc-compression` to configure compression methods for grpc clients. #4889 * [BUGFIX] Storage/Bucket: Enable AWS SDK for go authentication for s3 to fix IMDSv1 authentication. #4897 +* [ENHANCEMENT] AlertManager: Retrying AlertManager Get Requests (Get Alertmanager status, Get Alertmanager Receivers) on next replica on error #4840 +* [ENHANCEMENT] Querier/Ruler: Retry store-gateway in case of unexpected failure, instead of failing the query. #4532 #4839 +* [ENHANCEMENT] Ring: DoBatch prioritize 4xx errors when failing. #4783 +* [ENHANCEMENT] Cortex now built with Go 1.18. #4829 +* [ENHANCEMENT] Ingester: Prevent ingesters to become unhealthy during wall replay. #4847 +* [ENHANCEMENT] Compactor: Introduced visit marker file for blocks so blocks are under compaction will not be picked up by another compactor. #4805 +* [ENHANCEMENT] Distributor: Add label name to labelValueTooLongError. #4855 +* [ENHANCEMENT] Enhance traces with hostname information. #4898 +* [ENHANCEMENT] Improve the documentation around limits. #4905 +* [ENHANCEMENT] Distributor: cache user overrides to reduce lock contention. #4904 * [BUGFIX] Memberlist: Add join with no retrying when starting service. #4804 * [BUGFIX] Ruler: Fix /ruler/rule_groups returns YAML with extra fields. #4767 * [BUGFIX] Respecting `-tracing.otel.sample-ratio` configuration when enabling OpenTelemetry tracing with X-ray. #4862 diff --git a/VERSION b/VERSION index feaae22bac7..1de41da348f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.13.0 +1.14.0-rc.0 From 626ce6e91a30821d063363db7d88f71f09d6e4ed Mon Sep 17 00:00:00 2001 From: Ben Ye Date: Fri, 18 Nov 2022 10:39:07 -0800 Subject: [PATCH 2/4] fix response error to be ungzipped when status code is not 2xx (#4975) * fix response to be gzipped when status code is not 2xx Signed-off-by: Ben Ye * adding tests Signed-off-by: Alan Protasio * lint Signed-off-by: Alan Protasio * changelog Signed-off-by: Alan Protasio Signed-off-by: Ben Ye Signed-off-by: Alan Protasio Co-authored-by: Alan Protasio --- CHANGELOG.md | 1 + .../tripperware/instantquery/instant_query.go | 9 ++- .../instantquery/instant_query_test.go | 58 +++++++++++++++++++ .../tripperware/queryrange/query_range.go | 7 +-- .../queryrange/query_range_test.go | 58 +++++++++++++++++++ 5 files changed, 124 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc0080dbf8d..c31527300ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ * [BUGFIX] Ingester: fixed incorrect logging at the start of ingester block shipping logic. #4934 * [BUGFIX] Storage/Bucket: fixed global mark missing on deletion. #4949 * [BUGFIX] QueryFrontend/Querier: fixed regression added by #4863 where we stopped compressing the response between querier and query frontend. #4960 +* [BUGFIX] QueryFrontend/Querier: fixed fix response error to be ungzipped when status code is not 2xx. #4975 ## 1.13.0 2022-07-14 diff --git a/pkg/querier/tripperware/instantquery/instant_query.go b/pkg/querier/tripperware/instantquery/instant_query.go index a50b2f81eeb..f925f41cc19 100644 --- a/pkg/querier/tripperware/instantquery/instant_query.go +++ b/pkg/querier/tripperware/instantquery/instant_query.go @@ -152,11 +152,6 @@ func (c instantQueryCodec) DecodeRequest(_ context.Context, r *http.Request, for } func (instantQueryCodec) DecodeResponse(ctx context.Context, r *http.Response, _ tripperware.Request) (tripperware.Response, error) { - if r.StatusCode/100 != 2 { - body, _ := io.ReadAll(r.Body) - return nil, httpgrpc.Errorf(r.StatusCode, string(body)) - } - log, ctx := spanlogger.New(ctx, "PrometheusInstantQueryResponse") //nolint:ineffassign,staticcheck defer log.Finish() @@ -165,6 +160,10 @@ func (instantQueryCodec) DecodeResponse(ctx context.Context, r *http.Response, _ log.Error(err) return nil, err } + if r.StatusCode/100 != 2 { + return nil, httpgrpc.Errorf(r.StatusCode, string(buf)) + } + var resp PrometheusInstantQueryResponse if err := json.Unmarshal(buf, &resp); err != nil { return nil, httpgrpc.Errorf(http.StatusInternalServerError, "error decoding response: %v", err) diff --git a/pkg/querier/tripperware/instantquery/instant_query_test.go b/pkg/querier/tripperware/instantquery/instant_query_test.go index fd1ca8e87a0..a0013a5ab0a 100644 --- a/pkg/querier/tripperware/instantquery/instant_query_test.go +++ b/pkg/querier/tripperware/instantquery/instant_query_test.go @@ -2,6 +2,7 @@ package instantquery import ( "bytes" + "compress/gzip" "context" "fmt" "io" @@ -12,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/weaveworks/common/httpgrpc" "github.com/weaveworks/common/user" "github.com/cortexproject/cortex/pkg/querier/tripperware" @@ -93,6 +95,62 @@ func TestRequest(t *testing.T) { } } +func TestGzippedResponse(t *testing.T) { + for _, tc := range []struct { + body string + status int + err error + }{ + { + body: `{"status":"success","data":{"resultType":"string","result":[1,"foo"]}}`, + status: 200, + }, + { + body: `error generic 400`, + status: 400, + err: httpgrpc.Errorf(400, "error generic 400"), + }, + { + status: 400, + err: httpgrpc.Errorf(400, ""), + }, + } { + for _, c := range []bool{true, false} { + t.Run(fmt.Sprintf("compressed %t [%s]", c, tc.body), func(t *testing.T) { + h := http.Header{ + "Content-Type": []string{"application/json"}, + } + + responseBody := bytes.NewBuffer([]byte(tc.body)) + if c { + h.Set("Content-Encoding", "gzip") + var buf bytes.Buffer + w := gzip.NewWriter(&buf) + _, err := w.Write([]byte(tc.body)) + require.NoError(t, err) + w.Close() + responseBody = &buf + } + + response := &http.Response{ + StatusCode: tc.status, + Header: h, + Body: io.NopCloser(responseBody), + } + r, err := InstantQueryCodec.DecodeResponse(context.Background(), response, nil) + require.Equal(t, tc.err, err) + + if err == nil { + resp, err := json.Marshal(r) + require.NoError(t, err) + + require.Equal(t, tc.body, string(resp)) + } + }) + } + } +} + func TestResponse(t *testing.T) { for i, tc := range []struct { body string diff --git a/pkg/querier/tripperware/queryrange/query_range.go b/pkg/querier/tripperware/queryrange/query_range.go index 5fc5886d9a1..c3ad1839c19 100644 --- a/pkg/querier/tripperware/queryrange/query_range.go +++ b/pkg/querier/tripperware/queryrange/query_range.go @@ -258,10 +258,6 @@ func (prometheusCodec) EncodeRequest(ctx context.Context, r tripperware.Request) } func (prometheusCodec) DecodeResponse(ctx context.Context, r *http.Response, _ tripperware.Request) (tripperware.Response, error) { - if r.StatusCode/100 != 2 { - body, _ := io.ReadAll(r.Body) - return nil, httpgrpc.Errorf(r.StatusCode, string(body)) - } log, ctx := spanlogger.New(ctx, "ParseQueryRangeResponse") //nolint:ineffassign,staticcheck defer log.Finish() @@ -270,6 +266,9 @@ func (prometheusCodec) DecodeResponse(ctx context.Context, r *http.Response, _ t log.Error(err) return nil, err } + if r.StatusCode/100 != 2 { + return nil, httpgrpc.Errorf(r.StatusCode, string(buf)) + } log.LogFields(otlog.Int("bytes", len(buf))) var resp PrometheusResponse diff --git a/pkg/querier/tripperware/queryrange/query_range_test.go b/pkg/querier/tripperware/queryrange/query_range_test.go index 3df851b3e28..cfad6e8f999 100644 --- a/pkg/querier/tripperware/queryrange/query_range_test.go +++ b/pkg/querier/tripperware/queryrange/query_range_test.go @@ -2,7 +2,9 @@ package queryrange import ( "bytes" + "compress/gzip" "context" + "fmt" io "io" "net/http" "strconv" @@ -657,6 +659,62 @@ func TestMergeAPIResponses(t *testing.T) { } } +func TestGzippedResponse(t *testing.T) { + for _, tc := range []struct { + body string + status int + err error + }{ + { + body: `{"status":"success","data":{"resultType":"matrix","result":[{"metric":{"a":"b","c":"d"},"values":[[2,"2"],[3,"3"]]}],"stats":{"samples":{"totalQueryableSamples":20,"totalQueryableSamplesPerStep":[[2,2],[3,3]]}}}}`, + status: 200, + }, + { + body: `error generic 400`, + status: 400, + err: httpgrpc.Errorf(400, `error generic 400`), + }, + { + status: 400, + err: httpgrpc.Errorf(400, ""), + }, + } { + for _, c := range []bool{true, false} { + t.Run(fmt.Sprintf("compressed %t [%s]", c, tc.body), func(t *testing.T) { + h := http.Header{ + "Content-Type": []string{"application/json"}, + } + + responseBody := bytes.NewBuffer([]byte(tc.body)) + if c { + h.Set("Content-Encoding", "gzip") + var buf bytes.Buffer + w := gzip.NewWriter(&buf) + _, err := w.Write([]byte(tc.body)) + require.NoError(t, err) + w.Close() + responseBody = &buf + } + + response := &http.Response{ + StatusCode: tc.status, + Header: h, + Body: io.NopCloser(responseBody), + } + r, err := PrometheusCodec.DecodeResponse(context.Background(), response, nil) + require.Equal(t, tc.err, err) + + if err == nil { + resp, err := json.Marshal(r) + require.NoError(t, err) + + require.Equal(t, tc.body, string(resp)) + } + }) + } + } +} + func mustParse(t *testing.T, response string) tripperware.Response { var resp PrometheusResponse // Needed as goimports automatically add a json import otherwise. From db8b37c3a90fa3e2d3213158b0572bcfc8d02d49 Mon Sep 17 00:00:00 2001 From: Alan Protasio Date: Fri, 18 Nov 2022 18:43:33 -0800 Subject: [PATCH 3/4] Bump RC version (#4979) --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1de41da348f..027da061f34 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.14.0-rc.0 +1.14.0-rc.1 From 06d73136a372fa446dbb7ea36a4430aeeba553d8 Mon Sep 17 00:00:00 2001 From: Alan Protasio Date: Fri, 2 Dec 2022 15:16:23 -0800 Subject: [PATCH 4/4] Ready for 1.14 release (#5013) --- CHANGELOG.md | 2 +- VERSION | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c31527300ca..488c236c83f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## master / unreleased -## 1.14.0 in progress +## 1.14.0 2022-12-02 **This release removes support for chunks storage. See below for more.** * [CHANGE] Remove support for chunks storage entirely. If you are using chunks storage on a previous version, you must [migrate your data](https://github.com/cortexproject/cortex/blob/v1.11.1/docs/blocks-storage/migrate-from-chunks-to-blocks.md) on version 1.12 or earlier. Before upgrading to this release, you should also remove any deprecated chunks-related configuration, as this release will no longer accept that. The following flags are gone: diff --git a/VERSION b/VERSION index 027da061f34..850e742404b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.14.0-rc.1 +1.14.0