Skip to content

Commit b2b2b53

Browse files
authored
Merge pull request #8950 from thanos-io/42_3
Release 0.42.3 with a small fix
2 parents a698b52 + 728e5a3 commit b2b2b53

6 files changed

Lines changed: 91 additions & 6 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan
88

99
We use *breaking :warning:* to mark changes that are not backward compatible (relates only to v0.y.z releases.)
1010

11+
## [v0.42.3](https://github.com/thanos-io/thanos/tree/release-0.42) - 2026 07 29
12+
13+
Fixes a small bug - like before now Receive on shutdown creates a new block and uploads it.
14+
15+
### Fixed
16+
17+
- [#8948](https://github.com/thanos-io/thanos/pull/8948): receive: Preserve upload on shutdown behaviour
18+
1119
## [v0.42.2](https://github.com/thanos-io/thanos/tree/release-0.42) - 2026 07 16
1220

1321
Had to do another version release due to broken base image SHAs. No changes.

‎Dockerfile.multi-stage‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# By default we pin to amd64 sha. Use make docker to automatically adjust for arm64 versions.
22
ARG BASE_DOCKER_SHA="14d68ca3d69fceaa6224250c83d81d935c053fb13594c811038c461194599973"
3-
FROM golang:1.26.4-alpine3.20 as builder
3+
FROM golang:1.26.4-alpine3.24 as builder
44

55
WORKDIR $GOPATH/src/github.com/thanos-io/thanos
66
# Change in the docker context invalidates the cache so to leverage docker

‎VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.42.2
1+
0.42.3

‎cmd/thanos/receive.go‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,6 @@ func startTSDBAndUpload(g *run.Group,
722722
// TSDBs reload logic, listening on hashring changes.
723723
cancel := make(chan struct{})
724724
g.Add(func() error {
725-
defer close(uploadC)
726-
727725
// Before quitting, ensure the WAL is flushed and the DBs are closed.
728726
defer func() {
729727
level.Info(logger).Log("msg", "shutting down storage")
@@ -732,6 +730,11 @@ func startTSDBAndUpload(g *run.Group,
732730
} else {
733731
level.Info(logger).Log("msg", "storage is flushed successfully")
734732
}
733+
close(uploadC)
734+
// Wait for upload to finish before closing dbs.
735+
if upload {
736+
<-uploadDone
737+
}
735738
dbs.Close()
736739
level.Info(logger).Log("msg", "storage is closed")
737740
}()
@@ -812,6 +815,8 @@ func startTSDBAndUpload(g *run.Group,
812815
runutil.CloseWithLogOnErr(logger, bkt, "bucket client")
813816
}()
814817

818+
defer close(uploadDone)
819+
815820
// Before quitting, ensure all blocks are uploaded.
816821
defer func() {
817822
<-uploadC // Closed by storage routine when it's done.
@@ -827,8 +832,6 @@ func startTSDBAndUpload(g *run.Group,
827832
level.Info(logger).Log("msg", "the final cut block was uploaded", "uploaded", uploaded)
828833
}()
829834

830-
defer close(uploadDone)
831-
832835
for {
833836
select {
834837
case <-ctx.Done():

‎test/e2e/e2ethanos/services.go‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@ type ReceiveBuilder struct {
607607
nativeHistograms bool
608608
labels []string
609609
tenantSplitLabel string
610+
objStoreConfig *client.BucketConfig
610611
}
611612

612613
func NewReceiveBuilder(e e2e.Environment, name string) *ReceiveBuilder {
@@ -688,6 +689,11 @@ func (r *ReceiveBuilder) WithNativeHistograms() *ReceiveBuilder {
688689
return r
689690
}
690691

692+
func (r *ReceiveBuilder) WithObjStoreConfig(config client.BucketConfig) *ReceiveBuilder {
693+
r.objStoreConfig = &config
694+
return r
695+
}
696+
691697
// Init creates a Thanos Receive instance.
692698
// If ingestion is enabled it will be configured for ingesting samples.
693699
// If routing is configured (i.e. hashring configuration is provided) it routes samples to other receivers.
@@ -796,6 +802,14 @@ func (r *ReceiveBuilder) Init() *e2eobs.Observable {
796802
args["--tsdb.enable-native-histograms"] = ""
797803
}
798804

805+
if r.objStoreConfig != nil {
806+
bktConfigBytes, err := yaml.Marshal(r.objStoreConfig)
807+
if err != nil {
808+
return &e2eobs.Observable{Runnable: e2e.NewFailedRunnable(r.Name(), errors.Wrapf(err, "generate objstore config: %v", r.objStoreConfig))}
809+
}
810+
args["--objstore.config"] = string(bktConfigBytes)
811+
}
812+
799813
return e2eobs.AsObservable(r.f.Init(wrapWithDefaults(e2e.StartOptions{
800814
Image: r.image,
801815
Command: e2e.NewCommand("receive", e2e.BuildKingpinArgs(args)...),

‎test/e2e/receive_test.go‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ import (
3434

3535
"github.com/efficientgo/core/testutil"
3636

37+
"github.com/thanos-io/objstore"
38+
"github.com/thanos-io/objstore/client"
39+
"github.com/thanos-io/objstore/providers/s3"
40+
3741
"github.com/thanos-io/thanos/pkg/exemplars/exemplarspb"
3842
"github.com/thanos-io/thanos/pkg/promclient"
3943
"github.com/thanos-io/thanos/pkg/receive"
@@ -1390,3 +1394,59 @@ func TestReceiveWithRelabelConfigSmoke(t *testing.T) {
13901394
e2emon.WaitMissingMetrics(),
13911395
))
13921396
}
1397+
1398+
func TestReceiveUploadOnShutdown(t *testing.T) {
1399+
t.Parallel()
1400+
1401+
e, err := e2e.NewDockerEnvironment("receive-u-s")
1402+
testutil.Ok(t, err)
1403+
t.Cleanup(e2ethanos.CleanScenario(t, e))
1404+
1405+
const bucket = "receive-upload-shutdown-test"
1406+
m := e2edb.NewMinio(e, "thanos-minio", bucket, e2edb.WithMinioTLS())
1407+
testutil.Ok(t, e2e.StartAndWaitReady(m))
1408+
1409+
bktConfig := client.BucketConfig{
1410+
Type: objstore.S3,
1411+
Config: e2ethanos.NewS3Config(bucket, m.InternalEndpoint("http"), m.InternalDir()),
1412+
}
1413+
1414+
i := e2ethanos.NewReceiveBuilder(e, "ingestor").
1415+
WithIngestionEnabled().
1416+
WithObjStoreConfig(bktConfig).
1417+
Init()
1418+
testutil.Ok(t, e2e.StartAndWaitReady(i))
1419+
1420+
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
1421+
t.Cleanup(cancel)
1422+
1423+
require.NoError(t, runutil.RetryWithLog(logkit.NewLogfmtLogger(os.Stdout), 1*time.Second, ctx.Done(), func() error {
1424+
return storeWriteRequest(ctx, "http://"+i.Endpoint("remote-write")+"/api/v1/receive", &prompb.WriteRequest{
1425+
Timeseries: []prompb.TimeSeries{
1426+
{
1427+
Labels: []prompb.Label{
1428+
{Name: "__name__", Value: "upload_test_metric"},
1429+
{Name: "foo", Value: "bar"},
1430+
},
1431+
Samples: []prompb.Sample{
1432+
{Value: 1, Timestamp: time.Now().UnixMilli()},
1433+
},
1434+
},
1435+
},
1436+
})
1437+
}))
1438+
1439+
testutil.Ok(t, i.Stop())
1440+
1441+
l := logkit.NewLogfmtLogger(os.Stdout)
1442+
bkt, err := s3.NewBucketWithConfig(l,
1443+
e2ethanos.NewS3Config(bucket, m.Endpoint("http"), m.Dir()), "test-verify", nil)
1444+
testutil.Ok(t, err)
1445+
1446+
var blockCount int
1447+
testutil.Ok(t, bkt.Iter(ctx, "", func(_ string) error {
1448+
blockCount++
1449+
return nil
1450+
}))
1451+
require.Greater(t, blockCount, 0, "expected at least one block uploaded to object storage after receiver shutdown")
1452+
}

0 commit comments

Comments
 (0)