mirror of
https://github.com/luxfi/kms.git
synced 2026-11-03 08:42:32 +00:00
ghcr.io/luxfi/kms-operator has had no new image since v1.12.3. The Build KMS
Operator workflow failed on every tag since (v1.12.4 … v1.12.7) while its
sibling Build KMS succeeded on the same tag, so the tags looked published.
Dockerfile.operator:27 builds with -mod=vendor, and vendor/ had drifted from
go.mod in both directions:
- go.opentelemetry.io/otel/{metric,trace}: in vendor/modules.txt, not in go.mod
- github.com/luxfi/{crypto,geth,ids,keys,zap,address,age,cache,constants,
container,formatting,math,go-bip32,go-bip39}: in go.mod, not marked explicit
`go mod vendor` alone could not fix it — it aborted first on go.sum entries
missing for the k8s packages cmd/kms-operator imports (k8s.io/api/core/v1,
k8s.io/apimachinery/..., k8s.io/client-go/{dynamic,kubernetes,rest}). So:
go mod tidy (adds them, drops now-unused indirects) then go mod vendor.
Verified by stash control:
operator, -mod=vendor: rc=1 -> rc=0 ("inconsistent vendoring" 1 -> 0)
server, -mod=vendor: rc=1 -> rc=1 (unchanged)
The server's vendor build was already broken and stays broken, for an unrelated
reason: blst.h has never been vendored (confirmed absent from HEAD's tree, so it
could not have worked before either) — go mod vendor does not copy cgo headers
that live outside the package dir. It is not a regression and does not affect
CI: the server's Dockerfile builds with GOFLAGS=-mod=mod after `rm -f go.sum &&
go mod download`, i.e. from the module cache, never from vendor/. The operator
is the only -mod=vendor consumer, which is exactly why it was the only failure.
Co-authored-by: Hanzo Dev <[email protected]>
146 lines
3.9 KiB
Go
146 lines
3.9 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package propagation // import "go.opentelemetry.io/otel/propagation"
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"go.opentelemetry.io/otel/baggage"
|
|
"go.opentelemetry.io/otel/internal/errorhandler"
|
|
)
|
|
|
|
const (
|
|
baggageHeader = "baggage"
|
|
|
|
maxParseErrors = 5
|
|
|
|
// W3C Baggage specification limits.
|
|
// https://www.w3.org/TR/baggage/#limits
|
|
maxMembers = 64
|
|
maxBytesPerBaggageString = 8192
|
|
)
|
|
|
|
// handleExtractErrOnce limits error reporting for attacker-controlled baggage headers
|
|
// to one process-wide emission, preventing repeated extraction from flooding logs.
|
|
var handleExtractErrOnce sync.Once
|
|
|
|
// Baggage is a propagator that supports the W3C Baggage format.
|
|
//
|
|
// This propagates user-defined baggage associated with a trace. The complete
|
|
// specification is defined at https://www.w3.org/TR/baggage/.
|
|
type Baggage struct{}
|
|
|
|
var _ TextMapPropagator = Baggage{}
|
|
|
|
// Inject sets baggage key-values from ctx into the carrier.
|
|
func (Baggage) Inject(ctx context.Context, carrier TextMapCarrier) {
|
|
bStr := baggage.FromContext(ctx).String()
|
|
if bStr != "" {
|
|
carrier.Set(baggageHeader, bStr)
|
|
}
|
|
}
|
|
|
|
// Extract returns a copy of parent with the baggage from the carrier added.
|
|
// If carrier implements [ValuesGetter] (e.g. [HeaderCarrier]), Values is invoked
|
|
// for multiple values extraction. Otherwise, Get is called.
|
|
func (Baggage) Extract(parent context.Context, carrier TextMapCarrier) context.Context {
|
|
if multiCarrier, ok := carrier.(ValuesGetter); ok {
|
|
return extractMultiBaggage(parent, multiCarrier)
|
|
}
|
|
return extractSingleBaggage(parent, carrier)
|
|
}
|
|
|
|
// Fields returns the keys who's values are set with Inject.
|
|
func (Baggage) Fields() []string {
|
|
return []string{baggageHeader}
|
|
}
|
|
|
|
func extractSingleBaggage(parent context.Context, carrier TextMapCarrier) context.Context {
|
|
bStr := carrier.Get(baggageHeader)
|
|
if bStr == "" {
|
|
return parent
|
|
}
|
|
|
|
bag, err := baggage.Parse(bStr)
|
|
if err != nil {
|
|
handleExtractErrOnce.Do(func() {
|
|
errorhandler.GetErrorHandler().Handle(err)
|
|
})
|
|
}
|
|
if bag.Len() == 0 {
|
|
return parent
|
|
}
|
|
return baggage.ContextWithBaggage(parent, bag)
|
|
}
|
|
|
|
func extractMultiBaggage(parent context.Context, carrier ValuesGetter) context.Context {
|
|
bVals := carrier.Values(baggageHeader)
|
|
if len(bVals) == 0 {
|
|
return parent
|
|
}
|
|
|
|
var members []baggage.Member
|
|
var totalBytes int
|
|
var parseErrors int
|
|
var truncateErr error
|
|
for i, bStr := range bVals {
|
|
if i > 0 {
|
|
totalBytes++ // comma separator between combined header values
|
|
}
|
|
totalBytes += len(bStr)
|
|
if totalBytes > maxBytesPerBaggageString {
|
|
// Per the W3C Baggage spec, the byte limit applies to the
|
|
// combination of all baggage headers, not each header
|
|
// individually. Mirror the single-header behavior of
|
|
// reporting the error and returning the parent context
|
|
// with no baggage attached.
|
|
handleExtractErrOnce.Do(func() {
|
|
errorhandler.GetErrorHandler().Handle(fmt.Errorf(
|
|
"baggage: aggregate header size %d exceeds %d byte limit",
|
|
totalBytes,
|
|
maxBytesPerBaggageString,
|
|
))
|
|
})
|
|
return parent
|
|
}
|
|
|
|
// If members exceed the limit, stop parsing baggage.
|
|
if len(members) <= maxMembers {
|
|
currBag, err := baggage.Parse(bStr)
|
|
if err != nil {
|
|
parseErrors++
|
|
if parseErrors <= maxParseErrors {
|
|
truncateErr = errors.Join(truncateErr, err)
|
|
}
|
|
}
|
|
if currBag.Len() == 0 {
|
|
continue
|
|
}
|
|
members = append(members, currBag.Members()...)
|
|
}
|
|
}
|
|
|
|
if dropped := parseErrors - maxParseErrors; dropped > 0 {
|
|
truncateErr = errors.Join(truncateErr, fmt.Errorf("and %d more error(s)", dropped))
|
|
}
|
|
|
|
b, err := baggage.New(members...)
|
|
if err != nil {
|
|
truncateErr = errors.Join(truncateErr, err)
|
|
}
|
|
if truncateErr != nil {
|
|
handleExtractErrOnce.Do(func() {
|
|
errorhandler.GetErrorHandler().Handle(truncateErr)
|
|
})
|
|
}
|
|
|
|
if b.Len() == 0 {
|
|
return parent
|
|
}
|
|
return baggage.ContextWithBaggage(parent, b)
|
|
}
|