diff --git a/pkg/instrumentation/javaagent.go b/pkg/instrumentation/javaagent.go index f68f5213a..6f1d2b4c5 100644 --- a/pkg/instrumentation/javaagent.go +++ b/pkg/instrumentation/javaagent.go @@ -10,11 +10,17 @@ import ( ) const ( - envJavaToolsOptions = "JAVA_TOOL_OPTIONS" - javaJVMArgument = " -javaagent:/otel-auto-instrumentation-java/javaagent.jar" - javaInitContainerName = initContainerName + "-java" - javaVolumeName = volumeName + "-java" - javaInstrMountPath = "/otel-auto-instrumentation-java" + envJavaToolsOptions = "JAVA_TOOL_OPTIONS" + javaJVMArgument = " -javaagent:/otel-auto-instrumentation-java/javaagent.jar" + javaInitContainerName = initContainerName + "-java" + javaVolumeName = volumeName + "-java" + javaInstrMountPath = "/otel-auto-instrumentation-java" + javaInstrMountPathWindows = "\\otel-auto-instrumentation-java" +) + +var ( + commandLinux = []string{"cp", "/javaagent.jar", javaInstrMountPath + "/javaagent.jar"} + commandWindows = []string{"CMD", "/c", "copy", "javaagent.jar", javaInstrMountPathWindows} ) func injectJavaagent(javaSpec v1alpha1.Java, pod corev1.Pod, index int) (corev1.Pod, error) { @@ -59,10 +65,15 @@ func injectJavaagent(javaSpec v1alpha1.Java, pod corev1.Pod, index int) (corev1. }, }}) + command := commandLinux + if pod.Spec.NodeSelector["kubernetes.io/os"] == "windows" { + command = commandWindows + } + pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{ Name: javaInitContainerName, Image: javaSpec.Image, - Command: []string{"cp", "/javaagent.jar", javaInstrMountPath + "/javaagent.jar"}, + Command: command, Resources: javaSpec.Resources, VolumeMounts: []corev1.VolumeMount{{ Name: javaVolumeName, diff --git a/pkg/instrumentation/javaagent_test.go b/pkg/instrumentation/javaagent_test.go index c8f8256b2..840d837ca 100644 --- a/pkg/instrumentation/javaagent_test.go +++ b/pkg/instrumentation/javaagent_test.go @@ -178,3 +178,175 @@ func TestInjectJavaagent(t *testing.T) { }) } } + +func TestInjectJavaagentWindows(t *testing.T) { + tests := []struct { + name string + v1alpha1.Java + pod corev1.Pod + expected corev1.Pod + err error + }{ + { + name: "JAVA_TOOL_OPTIONS not defined", + Java: v1alpha1.Java{Image: "foo/bar:1"}, + pod: corev1.Pod{ + Spec: corev1.PodSpec{ + NodeSelector: map[string]string{ + "kubernetes.io/os": "windows", + }, + Containers: []corev1.Container{ + {}, + }, + }, + }, + expected: corev1.Pod{ + Spec: corev1.PodSpec{ + NodeSelector: map[string]string{ + "kubernetes.io/os": "windows", + }, + Volumes: []corev1.Volume{ + { + Name: "opentelemetry-auto-instrumentation-java", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + SizeLimit: &defaultVolumeLimitSize, + }, + }, + }, + }, + InitContainers: []corev1.Container{ + { + Name: "opentelemetry-auto-instrumentation-java", + Image: "foo/bar:1", + Command: []string{"CMD", "/c", "copy", "javaagent.jar", "\\otel-auto-instrumentation-java"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "opentelemetry-auto-instrumentation-java", + MountPath: "/otel-auto-instrumentation-java", + }}, + }, + }, + Containers: []corev1.Container{ + { + VolumeMounts: []corev1.VolumeMount{ + { + Name: "opentelemetry-auto-instrumentation-java", + MountPath: "/otel-auto-instrumentation-java", + }, + }, + Env: []corev1.EnvVar{ + { + Name: "JAVA_TOOL_OPTIONS", + Value: javaJVMArgument, + }, + }, + }, + }, + }, + }, + err: nil, + }, + { + name: "JAVA_TOOL_OPTIONS defined", + Java: v1alpha1.Java{Image: "foo/bar:1", Resources: testResourceRequirements}, + pod: corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Env: []corev1.EnvVar{ + { + Name: "JAVA_TOOL_OPTIONS", + Value: "-Dbaz=bar", + }, + }, + }, + }, + }, + }, + expected: corev1.Pod{ + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "opentelemetry-auto-instrumentation-java", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + SizeLimit: &defaultVolumeLimitSize, + }, + }, + }, + }, + InitContainers: []corev1.Container{ + { + Name: "opentelemetry-auto-instrumentation-java", + Image: "foo/bar:1", + Command: []string{"cp", "/javaagent.jar", "/otel-auto-instrumentation-java/javaagent.jar"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "opentelemetry-auto-instrumentation-java", + MountPath: "/otel-auto-instrumentation-java", + }}, + Resources: testResourceRequirements, + }, + }, + Containers: []corev1.Container{ + { + VolumeMounts: []corev1.VolumeMount{ + { + Name: "opentelemetry-auto-instrumentation-java", + MountPath: "/otel-auto-instrumentation-java", + }, + }, + Env: []corev1.EnvVar{ + { + Name: "JAVA_TOOL_OPTIONS", + Value: "-Dbaz=bar" + javaJVMArgument, + }, + }, + }, + }, + }, + }, + err: nil, + }, + { + name: "JAVA_TOOL_OPTIONS defined as ValueFrom", + Java: v1alpha1.Java{Image: "foo/bar:1"}, + pod: corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Env: []corev1.EnvVar{ + { + Name: "JAVA_TOOL_OPTIONS", + ValueFrom: &corev1.EnvVarSource{}, + }, + }, + }, + }, + }, + }, + expected: corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Env: []corev1.EnvVar{ + { + Name: "JAVA_TOOL_OPTIONS", + ValueFrom: &corev1.EnvVarSource{}, + }, + }, + }, + }, + }, + }, + err: fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", envJavaToolsOptions), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + pod, err := injectJavaagent(test.Java, test.pod, 0) + assert.Equal(t, test.expected, pod) + assert.Equal(t, test.err, err) + }) + } +}