From e79e00ab1aa44ddfd9b143e5222acdc26e7a1f60 Mon Sep 17 00:00:00 2001 From: yodigos Date: Sun, 8 Sep 2024 14:45:00 +0300 Subject: [PATCH] Comment out Nginx from os repo (to test) --- odiglet/pkg/ebpf/director.go | 98 +++++++++++++++++++ .../pkg/kube/instrumentation_ebpf/shared.go | 30 ++++++ tests/e2e/cli-upgrade/odigos-ui.pid | 1 - 3 files changed, 128 insertions(+), 1 deletion(-) delete mode 100644 tests/e2e/cli-upgrade/odigos-ui.pid diff --git a/odiglet/pkg/ebpf/director.go b/odiglet/pkg/ebpf/director.go index 1561ce811..e78739058 100644 --- a/odiglet/pkg/ebpf/director.go +++ b/odiglet/pkg/ebpf/director.go @@ -1,9 +1,15 @@ package ebpf import ( + "bytes" "context" "fmt" + "github.com/odigos-io/odigos/common/consts" + "github.com/odigos-io/odigos/odiglet/pkg/env" + "os" + "strconv" "sync" + "syscall" odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" "github.com/odigos-io/odigos/common" @@ -193,6 +199,26 @@ func (d *EbpfDirector[T]) observeInstrumentations(ctx context.Context, scheme *r func (d *EbpfDirector[T]) Instrument(ctx context.Context, pid int, pod types.NamespacedName, podWorkload *workload.PodWorkload, appName string, containerName string) error { log.Logger.V(0).Info("Instrumenting process", "pid", pid, "workload", podWorkload) + if d.language == common.NginxProgrammingLanguage { + + err := modifyNginxConfFile(pid) + if err != nil { + return err + } + + err = addOtelNginxAttributeConfFile(pid, podWorkload.Name) + if err != nil { + return err + } + + err = reloadNginx(pid) + if err != nil { + return err + } + + return nil + } + d.mux.Lock() defer d.mux.Unlock() if _, exists := d.pidsAttemptedInstrumentation[pid]; exists { @@ -288,6 +314,78 @@ func (d *EbpfDirector[T]) Instrument(ctx context.Context, pid int, pod types.Nam return nil } +func addOtelNginxAttributeConfFile(pid int, deploymentName string) error { + nginx_path := "/proc/" + strconv.Itoa(pid) + "/root/etc/nginx/conf.d" + nginx_conf_file_name := "opentelemetry_module.conf" + opentelemetry_module_conf := nginx_path + "/" + nginx_conf_file_name + + otlpEndpoint := fmt.Sprintf("http://%s:%d", env.Current.NodeIP, consts.OTLPPort) + + content := "NginxModuleEnabled ON;\n" + + "NginxModuleOtelSpanExporter otlp;\n" + + "NginxModuleOtelExporterEndpoint " + otlpEndpoint + ";\n" + + "NginxModuleServiceName " + deploymentName + ";\n" + + "NginxModuleServiceNamespace NginxServiceNamespace;\n" + + "NginxModuleServiceInstanceId NginxInstanceId;\n" + + "NginxModuleResolveBackends ON;\n" + + file, err := os.Create(opentelemetry_module_conf) + if err != nil { + return err + } + defer file.Close() + + // Write content to the file + _, err = file.WriteString(content) + if err != nil { + return err + } + + // Sync to ensure the content is written to disk + err = file.Sync() + if err != nil { + return err + } + + return nil +} + +func reloadNginx(pid int) error { + + err := syscall.Kill(pid, syscall.SIGHUP) + if err != nil { + return fmt.Errorf("failed to send SIGHUP signal to nginx: %v", err) + } + + fmt.Println("NGINX reloaded successfully") + return nil +} + +func modifyNginxConfFile(pid int) error { + nginx_path := "/proc/" + strconv.Itoa(pid) + "/root/etc/nginx" + nginx_conf_file_name := "nginx.conf" + nginx_conf_full_path := nginx_path + "/" + nginx_conf_file_name + + originalContent, err := os.ReadFile(nginx_conf_full_path) + if err != nil { + return err + } + file, err := os.OpenFile(nginx_conf_full_path, os.O_TRUNC|os.O_WRONLY, 0644) + if err != nil { + return err + } + + otelLoadConf := "load_module /var/odigos/nginx/opentelemetry-webserver-sdk/WebServerModule/Nginx/1.25.5/ngx_http_opentelemetry_module.so;" + if !bytes.Contains(originalContent, []byte(otelLoadConf)) { + _, err = file.WriteString(otelLoadConf + string(originalContent)) + if err != nil { + return err + } + } + + return nil +} + func (d *EbpfDirector[T]) Language() common.ProgrammingLanguage { return d.language } diff --git a/odiglet/pkg/kube/instrumentation_ebpf/shared.go b/odiglet/pkg/kube/instrumentation_ebpf/shared.go index 1fce73c24..d19b6e21c 100644 --- a/odiglet/pkg/kube/instrumentation_ebpf/shared.go +++ b/odiglet/pkg/kube/instrumentation_ebpf/shared.go @@ -3,6 +3,9 @@ package instrumentation_ebpf import ( "context" "errors" + "github.com/odigos-io/odigos/common" + process2 "github.com/odigos-io/odigos/procdiscovery/pkg/process" + "math" odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" odgiosK8s "github.com/odigos-io/odigos/k8sutils/pkg/container" @@ -53,8 +56,15 @@ func instrumentPodWithEbpf(ctx context.Context, pod *corev1.Pod, directors ebpf. return err, instrumentedEbpf } + minProcessId := getMinimumProcessID(details, language) + var errs []error for _, d := range details { + // Hack - if NginxInstrumentation - only instrument the process with the minimum PID (it's root) + if minProcessId != -1 && d.ProcessID != minProcessId { + continue + } + podDetails := types.NamespacedName{ Namespace: pod.Namespace, Name: pod.Name, @@ -76,3 +86,23 @@ func instrumentPodWithEbpf(ctx context.Context, pod *corev1.Pod, directors ebpf. } return nil, instrumentedEbpf } + +func getMinimumProcessID(details []process2.Details, language common.ProgrammingLanguage) int { + if language != common.NginxProgrammingLanguage { + return -1 + } + + return findMinProcessID(details) +} + +func findMinProcessID(details []process2.Details) int { + minPID := math.MaxInt // Start with the maximum possible integer value + + for _, detail := range details { + if detail.ProcessID < minPID { + minPID = detail.ProcessID + } + } + + return minPID +} diff --git a/tests/e2e/cli-upgrade/odigos-ui.pid b/tests/e2e/cli-upgrade/odigos-ui.pid deleted file mode 100644 index 989dc8b87..000000000 --- a/tests/e2e/cli-upgrade/odigos-ui.pid +++ /dev/null @@ -1 +0,0 @@ -88480