Skip to content

Commit

Permalink
[release/v1.1] Cherry-pick bugfixes for v1.1.1 release (#959)
Browse files Browse the repository at this point in the history
* Fix panic when component ID contains `/` in `otelcomponent.MustNewType(ID)` (#858)

Signed-off-by: Weifeng Wang <[email protected]>
(cherry picked from commit 7bae89c)

* No error when http fails (#841)

* Fail if we see the port is not available

* Update changelog

* cleanup message

* Update CHANGELOG.md

Co-authored-by: Erik Baranowski <[email protected]>

---------

Co-authored-by: Erik Baranowski <[email protected]>
(cherry picked from commit 4ca3f84)

* fix panic loki source docker (#875)

(cherry picked from commit 4fb1df9)

* clustering: fix ipv6 advertise addresses (#869)

Signed-off-by: Matthew Penner <[email protected]>
(cherry picked from commit 3df2cd0)

* otelcol: decouple otel/alloy component IDs (#882)

Signed-off-by: Paschalis Tsilias <[email protected]>
(cherry picked from commit d018e6e)

* updates with latest snowflake prometheus exporter (fixes null issues) (#939)

* updates with latest snowflake prometheus exporter (fixes null issues)

* Update CHANGELOG.md

Co-authored-by: William Dumont <[email protected]>

---------

Co-authored-by: William Dumont <[email protected]>
(cherry picked from commit 551d407)

* feat(vcs): bubble up SSH key conversion error for better debugging experience (#943)

* feat(vcs): bubble up SSH key conversion error for better debugging experience

Signed-off-by: hainenber <[email protected]>

* chore: refactor code to be more succinct

Signed-off-by: hainenber <[email protected]>

---------

Signed-off-by: hainenber <[email protected]>
(cherry picked from commit 037893f)

* prepare changelog for 1.1.1 (#958)

This includes all bugfixes found in main to date except for #703, which
is a more involved change that should probably wait for a minor release.

(cherry picked from commit 3bceb1a)

---------

Co-authored-by: Weifeng Wang <[email protected]>
Co-authored-by: mattdurham <[email protected]>
Co-authored-by: William Dumont <[email protected]>
Co-authored-by: Matthew Penner <[email protected]>
Co-authored-by: Paschalis Tsilias <[email protected]>
Co-authored-by: Stefan Kurek <[email protected]>
Co-authored-by: Đỗ Trọng Hải <[email protected]>
  • Loading branch information
8 people authored May 30, 2024
1 parent 44dd220 commit f4d761b
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 50 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,30 @@ This document contains a historical list of changes between releases. Only
changes that impact end-user behavior are listed; changes to documentation or
internal API changes are not present.

v1.1.1
------

### Bugfixes

- Fix panic when component ID contains `/` in `otelcomponent.MustNewType(ID)`.(@qclaogui)

- Exit Alloy immediately if the port it runs on is not available.
This port can be configured with `--server.http.listen-addr` or using
the default listen address`127.0.0.1:12345`. (@mattdurham)

- Fix a panic in `loki.source.docker` when trying to stop a target that was never started. (@wildum)

- Fix error on boot when using IPv6 advertise addresses without explicitly
specifying a port. (@matthewpi)

- Fix an issue where having long component labels (>63 chars) on otelcol.auth
components lead to a panic. (@tpaschalis)

- Update `prometheus.exporter.snowflake` with the [latest](https://github.com/grafana/snowflake-prometheus-exporter) version of the exporter as of May 28, 2024 (@StefanKurek)
- Fixes issue where returned `NULL` values from database could cause unexpected errors.

- Bubble up SSH key conversion error to facilitate failed `import.git`. (@hainenber)

v1.1.0
------

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ require (
github.com/grafana/pyroscope/api v0.4.0
github.com/grafana/pyroscope/ebpf v0.4.7
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db
github.com/grafana/snowflake-prometheus-exporter v0.0.0-20221213150626-862cad8e9538
github.com/grafana/snowflake-prometheus-exporter v0.0.0-20240524135656-12b7c9be6cbf
github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0
github.com/grafana/vmware_exporter v0.0.5-beta
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
Expand Down Expand Up @@ -644,7 +644,7 @@ require (
github.com/xo/dburl v0.20.0 // indirect
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 // indirect
github.com/yl2chen/cidranger v1.0.2 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/etcd/api/v3 v3.5.10 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect
Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1080,8 +1080,8 @@ github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db h1:7aN5cccjIqCLTzed
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A=
github.com/grafana/smimesign v0.2.1-0.20220408144937-2a5adf3481d3 h1:UPkAxuhlAcRmJT3/qd34OMTl+ZU7BLLfOO2+NXBlJpY=
github.com/grafana/smimesign v0.2.1-0.20220408144937-2a5adf3481d3/go.mod h1:iZiiwNT4HbtGRVqCQu7uJPEZCuEE5sfSSttcnePkDl4=
github.com/grafana/snowflake-prometheus-exporter v0.0.0-20221213150626-862cad8e9538 h1:tkT0yha3JzB5S5VNjfY4lT0cJAe20pU8XGt3Nuq73rM=
github.com/grafana/snowflake-prometheus-exporter v0.0.0-20221213150626-862cad8e9538/go.mod h1:VxVydRyq8f6w1qmX/5MSYIdSbgujre8rdFRLgU6u/RI=
github.com/grafana/snowflake-prometheus-exporter v0.0.0-20240524135656-12b7c9be6cbf h1:272jCM4WJtrv4JsVTyjSlzRavZRur60rBGgaCKQOK5k=
github.com/grafana/snowflake-prometheus-exporter v0.0.0-20240524135656-12b7c9be6cbf/go.mod h1:DANNLd5vSKqHloqNX4yeS+9ZRI89dj8ySZeEWlI5UU4=
github.com/grafana/stackdriver_exporter v0.0.0-20240228143257-3a2c9acef5a2 h1:xBGGPnQyQNK0Apz269BZoKTnFxKKxYhhXzI++N2phE0=
github.com/grafana/stackdriver_exporter v0.0.0-20240228143257-3a2c9acef5a2/go.mod h1:Ce7MjYSAUzZZeFb5jBNqSUUZ45w5IMdnNEKfz3jJRos=
github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0 h1:bjh0PVYSVVFxzINqPFYJmAmJNrWPgnVjuSdYJGHmtFU=
Expand Down Expand Up @@ -2263,8 +2263,9 @@ github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryB
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY=
github.com/yl2chen/cidranger v1.0.2 h1:lbOWZVCG1tCRX4u24kuM1Tb4nHqWkDxwLdoS+SevawU=
github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 h1:tBiBTKHnIjovYoLX/TPkcf+OjqqKGQrPtGT3Foz+Pgo=
github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76/go.mod h1:SQliXeA7Dhkt//vS29v3zpbEwoa+zb2Cn5xj5uO4K5U=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
52 changes: 28 additions & 24 deletions internal/alloycli/cluster_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ func buildClusterService(opts clusterOptions) (*cluster.Service, error) {

EnableClustering: opts.EnableClustering,
NodeName: opts.NodeName,
AdvertiseAddress: opts.AdvertiseAddress,
RejoinInterval: opts.RejoinInterval,
ClusterMaxJoinPeers: opts.ClusterMaxJoinPeers,
ClusterName: opts.ClusterName,
Expand All @@ -59,28 +58,10 @@ func buildClusterService(opts clusterOptions) (*cluster.Service, error) {
config.NodeName = hostname
}

if config.AdvertiseAddress == "" {
advertiseAddress := fmt.Sprintf("%s:%d", net.ParseIP("127.0.0.1"), listenPort)
if opts.EnableClustering {
advertiseInterfaces := opts.AdvertiseInterfaces
if useAllInterfaces(advertiseInterfaces) {
advertiseInterfaces = nil
}
addr, err := advertise.FirstAddress(advertiseInterfaces)
if err != nil {
level.Warn(opts.Log).Log("msg", "could not find advertise address using network interfaces", opts.AdvertiseInterfaces,
"falling back to localhost", "err", err)
} else if addr.Is4() {
advertiseAddress = fmt.Sprintf("%s:%d", addr.String(), listenPort)
} else if addr.Is6() {
advertiseAddress = fmt.Sprintf("[%s]:%d", addr.String(), listenPort)
} else {
return nil, fmt.Errorf("type unknown for address: %s", addr.String())
}
}
config.AdvertiseAddress = advertiseAddress
} else {
config.AdvertiseAddress = appendDefaultPort(config.AdvertiseAddress, listenPort)
var err error
config.AdvertiseAddress, err = getAdvertiseAddress(opts, listenPort)
if err != nil {
return nil, err
}

switch {
Expand Down Expand Up @@ -110,6 +91,29 @@ func useAllInterfaces(interfaces []string) bool {
return len(interfaces) == 1 && interfaces[0] == "all"
}

func getAdvertiseAddress(opts clusterOptions, listenPort int) (string, error) {
if opts.AdvertiseAddress != "" {
return appendDefaultPort(opts.AdvertiseAddress, listenPort), nil
}
advertiseAddress := net.JoinHostPort("127.0.0.1", strconv.Itoa(listenPort))
if opts.EnableClustering {
advertiseInterfaces := opts.AdvertiseInterfaces
if useAllInterfaces(advertiseInterfaces) {
advertiseInterfaces = nil
}
addr, err := advertise.FirstAddress(advertiseInterfaces)
if err != nil {
level.Warn(opts.Log).Log("msg", "could not find advertise address using network interfaces", opts.AdvertiseInterfaces,
"falling back to localhost", "err", err)
} else if !addr.Is4() && !addr.Is6() {
return "", fmt.Errorf("type unknown for address: %s", addr.String())
} else {
advertiseAddress = net.JoinHostPort(addr.String(), strconv.Itoa(listenPort))
}
}
return advertiseAddress, nil
}

func findPort(addr string, defaultPort int) int {
_, portStr, err := net.SplitHostPort(addr)
if err != nil {
Expand All @@ -128,7 +132,7 @@ func appendDefaultPort(addr string, port int) string {
// No error means there was a port in the string
return addr
}
return fmt.Sprintf("%s:%d", addr, port)
return net.JoinHostPort(addr, strconv.Itoa(port))
}

type discoverFunc func() ([]string, error)
Expand Down
38 changes: 38 additions & 0 deletions internal/alloycli/cluster_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package alloycli
import (
"testing"

"github.com/go-kit/log"
"github.com/stretchr/testify/require"
)

Expand All @@ -16,3 +17,40 @@ func TestBuildClusterService(t *testing.T) {
require.Nil(t, cs)
require.EqualError(t, err, "at most one of join peers and discover peers may be set")
}

func TestGetAdvertiseAddress(t *testing.T) {
// This tests that an IPv4 advertise address is properly joined to it's port.
t.Run("IPv4", func(t *testing.T) {
opts := clusterOptions{
AdvertiseAddress: "1.1.1.1",
}

addr, err := getAdvertiseAddress(opts, 80)
require.Nil(t, err)
require.Equal(t, "1.1.1.1:80", addr)
})

// This tests that an IPv6 advertise address is properly joined to it's port.
t.Run("IPv6", func(t *testing.T) {
opts := clusterOptions{
AdvertiseAddress: "2606:4700:4700::1111",
}

addr, err := getAdvertiseAddress(opts, 80)
require.Nil(t, err)
require.Equal(t, "[2606:4700:4700::1111]:80", addr)
})

// This tests the loopback fallback.
t.Run("loopback Fallback", func(t *testing.T) {
opts := clusterOptions{
Log: log.NewNopLogger(),
EnableClustering: true,
AdvertiseInterfaces: []string{"lo"},
}

addr, err := getAdvertiseAddress(opts, 80)
require.Nil(t, err)
require.Equal(t, "127.0.0.1:80", addr)
})
}
16 changes: 16 additions & 0 deletions internal/component/loki/source/docker/docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,22 @@ func TestRestart(t *testing.T) {
}, time.Second, 20*time.Millisecond, "Expected log lines were not found within the time limit after restart.")
}

func TestTargetNeverStarted(t *testing.T) {
runningState := false
client := clientMock{
logLine: "2024-05-02T13:11:55.879889Z caller=module_service.go:114 msg=\"module stopped\" module=distributor",
running: func() bool { return runningState },
}

tailer, _ := setupTailer(t, client)
ctx, cancel := context.WithCancel(context.Background())
go tailer.Run(ctx)

time.Sleep(20 * time.Millisecond)

require.NotPanics(t, func() { cancel() })
}

func setupTailer(t *testing.T, client clientMock) (tailer *tailer, entryHandler *fake.Client) {
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,11 @@ func (t *Target) StartIfNotRunning() {

// Stop shuts down the target.
func (t *Target) Stop() {
t.cancel()
t.wg.Wait()
level.Debug(t.logger).Log("msg", "stopped Docker target", "container", t.containerName)
if t.Ready() {
t.cancel()
t.wg.Wait()
level.Debug(t.logger).Log("msg", "stopped Docker target", "container", t.containerName)
}
}

// Ready reports whether the target is running.
Expand Down
20 changes: 19 additions & 1 deletion internal/component/otelcol/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package auth

import (
"context"
"fmt"
"hash/fnv"
"os"
"strings"

Expand Down Expand Up @@ -168,7 +170,7 @@ func (a *Auth) Update(args component.Arguments) error {
components = append(components, ext)
}

cTypeStr := strings.ReplaceAll(a.opts.ID, ".", "_")
cTypeStr := NormalizeType(a.opts.ID)

// Inform listeners that our handler changed.
a.opts.OnStateChange(Exports{
Expand All @@ -187,3 +189,19 @@ func (a *Auth) Update(args component.Arguments) error {
func (a *Auth) CurrentHealth() component.Health {
return a.sched.CurrentHealth()
}

func getHash(in string) string {
fnvHash := fnv.New32()
fnvHash.Write([]byte(in))
return fmt.Sprintf("%x", fnvHash.Sum(nil))
}

func NormalizeType(in string) string {
res := strings.ReplaceAll(strings.ReplaceAll(in, ".", "_"), "/", "_")

if len(res) > 63 {
res = res[:40] + getHash(res)
}

return res
}
30 changes: 30 additions & 0 deletions internal/component/otelcol/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package auth_test

import (
"context"
"regexp"
"testing"
"time"

Expand Down Expand Up @@ -93,3 +94,32 @@ func (fa fakeAuthArgs) Extensions() map[otelcomponent.ID]otelextension.Extension
func (fa fakeAuthArgs) Exporters() map[otelcomponent.DataType]map[otelcomponent.ID]otelcomponent.Component {
return nil
}

func TestNormalizeType(t *testing.T) {
type tc struct {
input string
expected string
}
testcases := []tc{
{"foo", "foo"},
{"foo1", "foo1"},
{"fooBar", "fooBar"},

{"foo.bar", "foo_bar"},
{"foo/bar", "foo_bar"},
{"foo.bar/baz", "foo_bar_baz"},
{"foo/bar_baz", "foo_bar_baz"},

{"thisStringsConstructedSoThatItsLengthIsSetToBeAtSixtyThreeChars", "thisStringsConstructedSoThatItsLengthIsSetToBeAtSixtyThreeChars"},
{"whileThisOneHeresConstructedSoThatItsSizeIsEqualToSixtyFourChars", "whileThisOneHeresConstructedSoThatItsSiz2d7fa5d2"},
}

// https://github.com/open-telemetry/opentelemetry-collector/blob/e09b25f7d1b4090a9b7b73ef7d3c514592331554/component/config.go#L127-L131
var typeRegexp = regexp.MustCompile(`^[a-zA-Z][0-9a-zA-Z_]{0,62}$`)

for _, tt := range testcases {
actual := auth.NormalizeType(tt.input)
require.Equal(t, tt.expected, actual)
require.True(t, typeRegexp.MatchString(actual))
}
}
6 changes: 0 additions & 6 deletions internal/component/otelcol/receiver/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"os"
"regexp"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -115,12 +114,7 @@ func (c *Component) Update(newConfig component.Arguments) error {
gcInterval = 5 * time.Minute
)

cTypeStr := strings.ReplaceAll(c.opts.ID, ".", "_")

settings := otelreceiver.CreateSettings{

ID: otelcomponent.NewID(otelcomponent.MustNewType(cTypeStr)),

TelemetrySettings: otelcomponent.TelemetrySettings{
Logger: zapadapter.New(c.opts.Logger),

Expand Down
5 changes: 4 additions & 1 deletion internal/service/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net"
"net/http"
_ "net/http/pprof" // Register pprof handlers
"os"
"path"
"sort"
"strings"
Expand Down Expand Up @@ -151,7 +152,9 @@ func (s *Service) Run(ctx context.Context, host service.Host) error {

netLis, err := net.Listen("tcp", s.opts.HTTPListenAddr)
if err != nil {
return fmt.Errorf("failed to listen on %s: %w", s.opts.HTTPListenAddr, err)
// There is no recovering from failing to listen on the port.
level.Error(s.log).Log("msg", fmt.Sprintf("failed to listen on %s", s.opts.HTTPListenAddr), "err", err)
os.Exit(1)
}
if err := s.tcpLis.SetInner(netLis); err != nil {
return fmt.Errorf("failed to use listener: %w", err)
Expand Down
12 changes: 5 additions & 7 deletions internal/vcs/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,18 @@ type GitAuthConfig struct {

// Convert converts HTTPClientConfig to the native Prometheus type. If h is
// nil, the default client config is returned.
func (h *GitAuthConfig) Convert() transport.AuthMethod {
func (h *GitAuthConfig) Convert() (transport.AuthMethod, error) {
if h == nil {
return nil
return nil, nil
}

if h.BasicAuth != nil {
return h.BasicAuth.Convert()
return h.BasicAuth.Convert(), nil
}

if h.SSHKey != nil {
key, _ := h.SSHKey.Convert()
return key
return h.SSHKey.Convert()
}
return nil
return nil, nil
}

type BasicAuth struct {
Expand Down
Loading

0 comments on commit f4d761b

Please sign in to comment.