Skip to content

Commit 56787a6

Browse files
authored
Fix/panic with composable renderer (#823)
* Fix a panic with wg passed to the composable object In the code to retrieve the variables from the configuration files we need to pass a execution callback, this callback will be called in a goroutine. This callback can be executed multiple time until the composable renderer is stopped. There were a problem in the code that made the callback called multiple time and it made the waitgroup internal counter to do to a negative values. This commit change the behavior, it start the composable renderer give it a callback when the callback receives the variables it will stop the composable's Run method using the context. This ensure that the callback will be called a single time and that the variables are correctly retrieved. Fixes: #806
1 parent 448b218 commit 56787a6

2 files changed

Lines changed: 23 additions & 5 deletions

File tree

CHANGELOG.next.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
- Allow the / char in variable names in eql and transpiler. {issue}715[715] {pull}718[718]
113113
- Fix data duplication for standalone agent on Kubernetes using the default manifest {issue-beats}31512[31512] {pull}742[742]
114114
- Agent updates will clean up unneeded artifacts. {issue}693[693] {issue}694[694] {pull}752[752]
115+
- Fix a panic caused by a race condition when installing the Elastic Agent. {issues}806[806]
115116

116117
==== New features
117118

internal/pkg/agent/install/uninstall.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"runtime"
1414
"strings"
1515
"sync"
16+
"time"
1617

1718
"github.com/kardianos/service"
1819

@@ -233,19 +234,35 @@ func applyDynamics(ctx context.Context, log *logger.Logger, cfg *config.Config)
233234
inputs, ok := transpiler.Lookup(ast, "inputs")
234235
if ok {
235236
varsArray := make([]*transpiler.Vars, 0)
236-
var wg sync.WaitGroup
237-
wg.Add(1)
237+
238+
// Give some time for the providers to replace the variables
239+
const timeout = 15 * time.Second
240+
var doOnce sync.Once
241+
ctx, cancel := context.WithTimeout(ctx, timeout)
242+
defer cancel()
243+
244+
// The composable system will continuously run, we are only interested in the first run on of the
245+
// renderer to collect the variables we should stop the execution.
238246
varsCallback := func(vv []*transpiler.Vars) {
239-
varsArray = vv
240-
wg.Done()
247+
doOnce.Do(func() {
248+
varsArray = vv
249+
cancel()
250+
})
241251
}
242252

243253
ctrl, err := composable.New(log, cfg)
244254
if err != nil {
245255
return nil, err
246256
}
247257
_ = ctrl.Run(ctx, varsCallback)
248-
wg.Wait()
258+
259+
// Wait for the first callback to retrieve the variables from the providers.
260+
<-ctx.Done()
261+
262+
// Bail out if callback was not executed in time.
263+
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
264+
return nil, errors.New("failed to get transpiler vars", err)
265+
}
249266

250267
renderedInputs, err := transpiler.RenderInputs(inputs, varsArray)
251268
if err != nil {

0 commit comments

Comments
 (0)