func injectDotNetSDK()

in pkg/instrumentation/dotnet.go [57:150]


func injectDotNetSDK(dotNetSpec v1alpha1.DotNet, pod corev1.Pod, index int, runtime string) (corev1.Pod, error) {

	// caller checks if there is at least one container.
	container := &pod.Spec.Containers[index]

	err := validateContainerEnv(container.Env, envDotNetStartupHook, envDotNetAdditionalDeps, envDotNetSharedStore)
	if err != nil {
		return pod, err
	}

	// check if OTEL_DOTNET_AUTO_HOME env var is already set in the container
	// if it is already set, then we assume that .NET Auto-instrumentation is already configured for this container
	if getIndexOfEnv(container.Env, envDotNetOTelAutoHome) > -1 {
		return pod, errors.New("OTEL_DOTNET_AUTO_HOME environment variable is already set in the container")
	}

	// check if OTEL_DOTNET_AUTO_HOME env var is already set in the .NET instrumentation spec
	// if it is already set, then we assume that .NET Auto-instrumentation is already configured for this container
	if getIndexOfEnv(dotNetSpec.Env, envDotNetOTelAutoHome) > -1 {
		return pod, errors.New("OTEL_DOTNET_AUTO_HOME environment variable is already set in the .NET instrumentation spec")
	}

	coreClrProfilerPath := ""
	switch runtime {
	case "", dotNetRuntimeLinuxGlibc:
		coreClrProfilerPath = dotNetCoreClrProfilerGlibcPath
	case dotNetRuntimeLinuxMusl:
		coreClrProfilerPath = dotNetCoreClrProfilerMuslPath
	default:
		return pod, fmt.Errorf("provided instrumentation.opentelemetry.io/dotnet-runtime annotation value '%s' is not supported", runtime)
	}

	// inject .NET instrumentation spec env vars.
	for _, env := range dotNetSpec.Env {
		idx := getIndexOfEnv(container.Env, env.Name)
		if idx == -1 {
			container.Env = append(container.Env, env)
		}
	}

	const (
		doNotConcatEnvValues = false
		concatEnvValues      = true
	)

	setDotNetEnvVar(container, envDotNetCoreClrEnableProfiling, dotNetCoreClrEnableProfilingEnabled, doNotConcatEnvValues)
	setDotNetEnvVar(container, envDotNetCoreClrProfiler, dotNetCoreClrProfilerID, doNotConcatEnvValues)
	if isWindowsPod(pod) {
		setDotNetEnvVar(container, envDotNetCoreClrProfilerPath, dotNetCoreClrProfilerPathWindows, doNotConcatEnvValues)
		setDotNetEnvVar(container, envDotNetStartupHook, dotNetStartupHookPathWindows, concatEnvValues)
		setDotNetEnvVar(container, envDotNetAdditionalDeps, dotNetAdditionalDepsPathWindows, concatEnvValues)
		setDotNetEnvVar(container, envDotNetOTelAutoHome, dotNetOTelAutoHomePathWindows, doNotConcatEnvValues)
		setDotNetEnvVar(container, envDotNetSharedStore, dotNetSharedStorePathWindows, concatEnvValues)
	} else {
		setDotNetEnvVar(container, envDotNetCoreClrProfilerPath, coreClrProfilerPath, doNotConcatEnvValues)
		setDotNetEnvVar(container, envDotNetStartupHook, dotNetStartupHookPath, concatEnvValues)
		setDotNetEnvVar(container, envDotNetAdditionalDeps, dotNetAdditionalDepsPath, concatEnvValues)
		setDotNetEnvVar(container, envDotNetOTelAutoHome, dotNetOTelAutoHomePath, doNotConcatEnvValues)
		setDotNetEnvVar(container, envDotNetSharedStore, dotNetSharedStorePath, concatEnvValues)
	}

	container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
		Name:      dotnetVolumeName,
		MountPath: dotnetInstrMountPath,
	})

	// We just inject Volumes and init containers for the first processed container.
	if isInitContainerMissing(pod, dotnetInitContainerName) {
		pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
			Name: dotnetVolumeName,
			VolumeSource: corev1.VolumeSource{
				EmptyDir: &corev1.EmptyDirVolumeSource{
					SizeLimit: volumeSize(dotNetSpec.VolumeSizeLimit),
				},
			}})

		command := dotNetCommandLinux
		if isWindowsPod(pod) {
			command = dotNetCommandWindows
		}

		pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{
			Name:      dotnetInitContainerName,
			Image:     dotNetSpec.Image,
			Command:   command,
			Resources: dotNetSpec.Resources,
			VolumeMounts: []corev1.VolumeMount{{
				Name:      dotnetVolumeName,
				MountPath: dotnetInstrMountPath,
			}},
		})
	}
	return pod, nil
}