From 4b449743dd9f39c264616069829268eb89878d5d Mon Sep 17 00:00:00 2001 From: Ron Federman <73110295+RonFed@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:23:49 +0200 Subject: [PATCH] use Load and Run function in director (#1941) This PR contains a temporary fix for the director to handle the new instrumentation API which split the Run function to Load and Run. Once we fully move to the new instrumentation manager, this code (and the entire director) will be removed. --- odiglet/pkg/ebpf/director.go | 47 +++++++++++++++++-------------- odiglet/pkg/ebpf/director_test.go | 7 +++-- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/odiglet/pkg/ebpf/director.go b/odiglet/pkg/ebpf/director.go index 625c5b0c4..a51303843 100644 --- a/odiglet/pkg/ebpf/director.go +++ b/odiglet/pkg/ebpf/director.go @@ -28,7 +28,10 @@ import ( // This interface should be implemented by all ebpf sdks // for example, the go auto instrumentation sdk implements it +// Deprecated: this will be removed once we fully move to the generic instrumentation manager type OtelEbpfSdk interface { + // this is temporary until we move to the generic instrumentation manager + Load(ctx context.Context) error // Run starts the eBPF instrumentation. // It should block until the instrumentation is stopped or the context is canceled or an error occurs. Run(ctx context.Context) error @@ -42,6 +45,7 @@ type ConfigurableOtelEbpfSdk interface { } // users can use different eBPF otel SDKs by returning them from this function +// Deprecated: this will be removed once we fully move to the generic instrumentation manager type InstrumentationFactory[T OtelEbpfSdk] interface { CreateEbpfInstrumentation(ctx context.Context, pid int, serviceName string, podWorkload *workload.PodWorkload, containerName string, podName string, loadedIndicator chan struct{}) (T, error) } @@ -301,46 +305,47 @@ func (d *EbpfDirector[T]) Instrument(ctx context.Context, pid int, pod types.Nam d.workloadToPods[*podWorkload][pod] = struct{}{} ip.runOnce.Do(func() { - loadedIndicator := make(chan struct{}) - loadedCtx, loadedObserverCancel := context.WithCancel(ctx) - // launch an observer for successful loading of the eBPF probes go func() { - select { - case <-loadedCtx.Done(): - return - case <-loadedIndicator: + inst, err := d.instrumentationFactory.CreateEbpfInstrumentation(ctx, pid, appName, podWorkload, containerName, pod.Name, nil) + if err != nil { d.instrumentationStatusChan <- instrumentationStatus{ - Healthy: true, - Message: "Successfully loaded eBPF probes to pod: " + pod.String(), + Healthy: false, + Message: err.Error(), Workload: *podWorkload, - Reason: LoadedSuccessfully, + Reason: FailedToInitialize, PodName: pod, ContainerName: containerName, Pid: pid, } + return } - }() - go func() { - // once the instrumentation finished running (either by error or successful exit), we can cancel the 'loaded' observer for this instrumentation - defer loadedObserverCancel() - inst, err := d.instrumentationFactory.CreateEbpfInstrumentation(ctx, pid, appName, podWorkload, containerName, pod.Name, loadedIndicator) + if ip.closed.Load() { + log.Logger.Info("Instrumentation already closed before running, stopping instrumentation", "pid", pid) + return + } + + err = inst.Load(ctx) if err != nil { d.instrumentationStatusChan <- instrumentationStatus{ Healthy: false, Message: err.Error(), Workload: *podWorkload, - Reason: FailedToInitialize, + Reason: FailedToLoad, PodName: pod, ContainerName: containerName, Pid: pid, } return } - - if ip.closed.Load() { - log.Logger.Info("Instrumentation already closed before running, stopping instrumentation", "pid", pid) - return + d.instrumentationStatusChan <- instrumentationStatus{ + Healthy: true, + Message: "Successfully loaded eBPF probes to pod: " + pod.String(), + Workload: *podWorkload, + Reason: LoadedSuccessfully, + PodName: pod, + ContainerName: containerName, + Pid: pid, } ip.inst = inst @@ -352,7 +357,7 @@ func (d *EbpfDirector[T]) Instrument(ctx context.Context, pid int, pod types.Nam Healthy: false, Message: err.Error(), Workload: *podWorkload, - Reason: FailedToLoad, + Reason: FailedToRun, PodName: pod, ContainerName: containerName, Pid: pid, diff --git a/odiglet/pkg/ebpf/director_test.go b/odiglet/pkg/ebpf/director_test.go index 18baed701..a02f1b9f3 100644 --- a/odiglet/pkg/ebpf/director_test.go +++ b/odiglet/pkg/ebpf/director_test.go @@ -21,7 +21,6 @@ import ( ) type FakeEbpfSdk struct { - loadedIndicator chan struct{} running bool pid int @@ -47,10 +46,13 @@ func (f *FakeEbpfSdk) Close(_ context.Context) error { return nil } +func (f *FakeEbpfSdk) Load(ctx context.Context) error { + return nil +} + func (f *FakeEbpfSdk) Run(ctx context.Context) error { // To simulate a real instrumentation, Run is blocking until the context is cancelled f.running = true - close(f.loadedIndicator) cancelCtx, cancel := context.WithCancel(ctx) f.cancel = cancel @@ -76,7 +78,6 @@ func NewFakeInstrumentationFactory(kubeclient client.Client, setupDuration time. func (f *FakeInstrumentationFactory) CreateEbpfInstrumentation(ctx context.Context, pid int, serviceName string, podWorkload *workload.PodWorkload, containerName string, podName string, loadedIndicator chan struct{}) (*FakeEbpfSdk, error) { <-time.After(f.timeToSetup) return &FakeEbpfSdk{ - loadedIndicator: loadedIndicator, pid: pid, }, nil }