Skip to content

Commit 395f185

Browse files
authored
Merge pull request #4035 from telepresenceio/thallgren/injector-race
Fix race condition between agent injector and service watcher
2 parents 6b97353 + 44d93c2 commit 395f185

File tree

5 files changed

+43
-10
lines changed

5 files changed

+43
-10
lines changed

cmd/traffic/cmd/manager/mutator/agent_injector.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,19 @@ func (a *agentInjector) Inject(ctx context.Context, req *admission.AdmissionRequ
146146
// Not an error. It just means that the pod is not eligible for intercepts.
147147
return nil, nil
148148
}
149-
sc = a.agentConfigs.Get(wl.GetName(), wl.GetNamespace())
150-
switch {
151-
case sc == nil:
152-
clog.Tracef(ctx, "Skipping %s (no agent config)", wl)
153-
return nil, nil
154-
case sc.Manual:
149+
if ia == "enabled" {
150+
sc, err = a.agentConfigs.GetOrGenerate(ctx, wl)
151+
if err != nil {
152+
return nil, fmt.Errorf("unable to get or generate agent config for workload %s.%s: %w", wl.GetNamespace(), wl.GetName(), err)
153+
}
154+
} else {
155+
sc = a.agentConfigs.Get(wl.GetName(), wl.GetNamespace())
156+
if sc == nil {
157+
clog.Tracef(ctx, "Skipping %s (no agent config)", wl)
158+
return nil, nil
159+
}
160+
}
161+
if sc.Manual {
155162
clog.Tracef(ctx, "Skipping webhook where agent is manually injected %s", wl.GetNamespace())
156163
return nil, nil
157164
}

cmd/traffic/cmd/manager/mutator/watcher.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929

3030
type Map interface {
3131
Get(string, string) *agentconfig.Sidecar
32+
GetOrGenerate(context.Context, k8sapi.Workload) (*agentconfig.Sidecar, error)
3233
Store(*agentconfig.Sidecar)
3334
Start(context.Context)
3435
StartWatchers(context.Context) error
@@ -340,6 +341,27 @@ func (c *configWatcher) Get(key, ns string) (ac *agentconfig.Sidecar) {
340341
return ac
341342
}
342343

344+
// GetOrGenerate returns the Sidecar configuration for the given workload. If no configuration is found, it blocks the entry from access while
345+
// it generates a new one using the given generator.
346+
func (c *configWatcher) GetOrGenerate(ctx context.Context, wl k8sapi.Workload) (ac *agentconfig.Sidecar, err error) {
347+
c.agentConfigs.Compute(wl.GetNamespace(), func(scMap map[string]*agentconfig.Sidecar, loaded bool) (map[string]*agentconfig.Sidecar, xsync.ComputeOp) {
348+
if loaded {
349+
ac = scMap[wl.GetName()]
350+
} else {
351+
var gc *agentmap.GeneratorConfig
352+
gc, err = managerutil.GetEnv(ctx).GeneratorConfig(managerutil.GetAgentImage(ctx))
353+
if err == nil {
354+
ac, err = gc.Generate(ctx, wl, nil)
355+
if err == nil {
356+
scMap[wl.GetName()] = ac
357+
}
358+
}
359+
}
360+
return nil, xsync.CancelOp
361+
})
362+
return ac, err
363+
}
364+
343365
func whereWeWatch(ns string) string {
344366
if ns == "" {
345367
return "cluster wide"

integration_test/cidr_conflict_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (s *cidrConflictSuite) SetupSuite() {
6969
ctx := s.Context()
7070
s.TelepresenceConnect(ctx)
7171
st := itest.TelepresenceStatusOk(ctx)
72-
itest.TelepresenceQuitOk(ctx)
72+
itest.TelepresenceQuit(ctx)
7373
s.subnets = st.RootDaemon.Subnets
7474
if len(s.subnets) < 2 {
7575
s.T().Skip("Test cannot run unless client maps at least two subnets")
@@ -94,7 +94,7 @@ func (s *cidrConflictSuite) Test_AutoConflictResolution() {
9494
ctx := s.Context()
9595
s.TelepresenceConnect(ctx)
9696
st := itest.TelepresenceStatusOk(ctx)
97-
defer itest.TelepresenceQuitOk(ctx)
97+
defer itest.TelepresenceQuit(ctx)
9898
sns := st.RootDaemon.Subnets
9999
rq := s.Require()
100100
rq.Less(len(sns), len(s.subnets), "pod and service subnets should be combined into one virtual subnet")

integration_test/itest/status.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/stretchr/testify/require"
99

1010
"github.com/telepresenceio/clog"
11+
"github.com/telepresenceio/telepresence/v2/pkg/client"
1112
"github.com/telepresenceio/telepresence/v2/pkg/client/cli/cmd"
1213
)
1314

@@ -41,6 +42,9 @@ func TelepresenceStatus(ctx context.Context, args ...string) (*StatusResponse, e
4142
return nil, jErr
4243
}
4344
if cd := status.ContainerizedDaemon; cd != nil {
45+
if cd.RoutingSnake == nil {
46+
cd.RoutingSnake = &client.RoutingSnake{}
47+
}
4448
status.UserDaemon = cd.UserDaemonStatus
4549
status.RootDaemon = &cmd.RootDaemonStatus{
4650
Running: cd.Running,
@@ -51,7 +55,7 @@ func TelepresenceStatus(ctx context.Context, args ...string) (*StatusResponse, e
5155
PortMappings: cd.PortMappings,
5256
}
5357
} else if status.RootDaemon == nil {
54-
status.RootDaemon = &cmd.RootDaemonStatus{}
58+
status.RootDaemon = &cmd.RootDaemonStatus{RoutingSnake: &client.RoutingSnake{}}
5559
}
5660
return &status, nil
5761
}

pkg/client/cli/connect/connector.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func quitHostConnector(ctx context.Context) {
9393
var errs error
9494
rootWillContinue := false
9595
if err != nil {
96-
if !errors.Is(err, fs.ErrNotExist) {
96+
if !(errors.Is(err, fs.ErrNotExist) || errors.Is(err, daemon.ErrNoUserDaemon)) {
9797
errs = errors.Join(errs, err)
9898
}
9999
} else {

0 commit comments

Comments
 (0)