diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 7dbc593f9c..bc6b334c4a 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -36,6 +36,33 @@ jobs: - name: Cross build check run: make crossbuild + build-stringlabels: + runs-on: ubuntu-latest + name: Go build with -tags=stringlabels + env: + GOBIN: /tmp/.bin + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.22.x + + - uses: actions/cache@v4 + with: + path: | + ~/.cache/go-build + ~/.cache/golangci-lint + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Cross build check + run: go build -tags=stringlabels ./cmd/thanos + lint: runs-on: ubuntu-latest name: Linters (Static Analysis) for Go diff --git a/cmd/thanos/config.go b/cmd/thanos/config.go index a6abd7c3c9..3ce069c1b2 100644 --- a/cmd/thanos/config.go +++ b/cmd/thanos/config.go @@ -8,7 +8,6 @@ package main import ( "net/url" - "sort" "strconv" "strings" "time" @@ -266,23 +265,23 @@ func (ac *alertMgrConfig) registerFlag(cmd extflag.FlagClause) *alertMgrConfig { } func parseFlagLabels(s []string) (labels.Labels, error) { - var lset labels.Labels + var lset labels.ScratchBuilder for _, l := range s { parts := strings.SplitN(l, "=", 2) if len(parts) != 2 { - return nil, errors.Errorf("unrecognized label %q", l) + return labels.EmptyLabels(), errors.Errorf("unrecognized label %q", l) } if !model.LabelName.IsValid(model.LabelName(parts[0])) { - return nil, errors.Errorf("unsupported format for label %s", l) + return labels.EmptyLabels(), errors.Errorf("unsupported format for label %s", l) } val, err := strconv.Unquote(parts[1]) if err != nil { - return nil, errors.Wrap(err, "unquote label value") + return labels.EmptyLabels(), errors.Wrap(err, "unquote label value") } - lset = append(lset, labels.Label{Name: parts[0], Value: val}) + lset.Add(parts[0], val) } - sort.Sort(lset) - return lset, nil + lset.Sort() + return lset.Labels(), nil } type goMemLimitConfig struct { diff --git a/cmd/thanos/receive.go b/cmd/thanos/receive.go index 758a0141e8..f10b5be3a3 100644 --- a/cmd/thanos/receive.go +++ b/cmd/thanos/receive.go @@ -70,7 +70,7 @@ func registerReceive(app *extkingpin.App) { if !model.LabelName.IsValid(model.LabelName(conf.tenantLabelName)) { return errors.Errorf("unsupported format for tenant label name, got %s", conf.tenantLabelName) } - if len(lset) == 0 { + if lset.Len() == 0 { return errors.New("no external labels configured for receive, uniquely identifying external labels must be configured (ideally with `receive_` prefix); see https://thanos.io/tip/thanos/storage.md#external-labels for details.") } diff --git a/cmd/thanos/rule.go b/cmd/thanos/rule.go index da27751345..3fcc452ac6 100644 --- a/cmd/thanos/rule.go +++ b/cmd/thanos/rule.go @@ -887,13 +887,7 @@ func removeLockfileIfAny(logger log.Logger, dataDir string) error { } func labelsTSDBToProm(lset labels.Labels) (res labels.Labels) { - for _, l := range lset { - res = append(res, labels.Label{ - Name: l.Name, - Value: l.Value, - }) - } - return res + return lset.Copy() } func queryFuncCreator( diff --git a/cmd/thanos/sidecar.go b/cmd/thanos/sidecar.go index 2d51063980..91f7feee54 100644 --- a/cmd/thanos/sidecar.go +++ b/cmd/thanos/sidecar.go @@ -253,7 +253,7 @@ func runSidecar( return errors.Wrap(err, "initial external labels query") } - if len(m.Labels()) == 0 { + if m.Labels().Len() == 0 { return errors.New("no external labels configured on Prometheus server, uniquely identifying external labels must be configured; see https://thanos.io/tip/thanos/storage.md#external-labels for details.") } promUp.Set(1) @@ -393,7 +393,7 @@ func runSidecar( defer cancel() if err := runutil.Retry(2*time.Second, extLabelsCtx.Done(), func() error { - if len(m.Labels()) == 0 { + if m.Labels().Len() == 0 { return errors.New("not uploading as no external labels are configured yet - is Prometheus healthy/reachable?") } return nil diff --git a/cmd/thanos/tools_bucket.go b/cmd/thanos/tools_bucket.go index 326e4b09eb..7e711168cf 100644 --- a/cmd/thanos/tools_bucket.go +++ b/cmd/thanos/tools_bucket.go @@ -1013,12 +1013,12 @@ func getKeysAlphabetically(labels map[string]string) []string { // matchesSelector checks if blockMeta contains every label from // the selector with the correct value. func matchesSelector(blockMeta *metadata.Meta, selectorLabels labels.Labels) bool { - for _, l := range selectorLabels { - if v, ok := blockMeta.Thanos.Labels[l.Name]; !ok || v != l.Value { - return false - } - } - return true + matches := true + selectorLabels.Range(func(l labels.Label) { + val, ok := blockMeta.Thanos.Labels[l.Name] + matches = matches && ok && val == l.Value + }) + return matches } // getIndex calculates the index of s in strs. diff --git a/pkg/query/endpointset.go b/pkg/query/endpointset.go index b1faff425b..bf608c74f3 100644 --- a/pkg/query/endpointset.go +++ b/pkg/query/endpointset.go @@ -797,11 +797,7 @@ func (er *endpointRef) labelSets() []labels.Labels { labelSet := make([]labels.Labels, 0, len(er.metadata.LabelSets)) for _, ls := range labelpb.ZLabelSetsToPromLabelSets(er.metadata.LabelSets...) { - if len(ls) == 0 { - continue - } - // Compatibility label for Queriers pre 0.8.1. Filter it out now. - if ls[0].Name == store.CompatibilityTypeLabelName { + if ls.Len() == 0 { continue } labelSet = append(labelSet, ls.Copy()) diff --git a/pkg/query/endpointset_test.go b/pkg/query/endpointset_test.go index f9955d3412..99db0828a8 100644 --- a/pkg/query/endpointset_test.go +++ b/pkg/query/endpointset_test.go @@ -26,7 +26,6 @@ import ( "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/info/infopb" - "github.com/thanos-io/thanos/pkg/store" "github.com/thanos-io/thanos/pkg/store/labelpb" "github.com/thanos-io/thanos/pkg/store/storepb" ) @@ -954,11 +953,6 @@ func TestEndpointSetUpdate_AvailabilityScenarios(t *testing.T) { {Name: "l3", Value: "v4"}, }, }, - { - Labels: []labelpb.ZLabel{ - {Name: store.CompatibilityTypeLabelName, Value: "store"}, - }, - }, } }, }, @@ -978,11 +972,6 @@ func TestEndpointSetUpdate_AvailabilityScenarios(t *testing.T) { {Name: "l3", Value: "v4"}, }, }, - { - Labels: []labelpb.ZLabel{ - {Name: store.CompatibilityTypeLabelName, Value: "store"}, - }, - }, } }, },