func injectApacheHttpdagent()

in pkg/instrumentation/apachehttpd.go [51:179]


func injectApacheHttpdagent(_ logr.Logger, apacheSpec v1alpha1.ApacheHttpd, pod corev1.Pod, index int, otlpEndpoint string, resourceMap map[string]string) corev1.Pod {

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

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

	// First make a clone of the instrumented container to take the existing Apache configuration from
	// and create init container from it
	if isApacheInitContainerMissing(pod, apacheAgentCloneContainerName) {
		// Inject volume for original Apache configuration
		pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
			Name: apacheAgentConfigVolume,
			VolumeSource: corev1.VolumeSource{
				EmptyDir: &corev1.EmptyDirVolumeSource{
					SizeLimit: volumeSize(apacheSpec.VolumeSizeLimit),
				},
			}})

		apacheConfDir := getApacheConfDir(apacheSpec.ConfigPath)

		cloneContainer := container.DeepCopy()
		cloneContainer.Name = apacheAgentCloneContainerName
		cloneContainer.Command = []string{"/bin/sh", "-c"}
		cloneContainer.Args = []string{"cp -r " + apacheConfDir + "/* " + apacheAgentConfDirFull}
		cloneContainer.VolumeMounts = append(cloneContainer.VolumeMounts, corev1.VolumeMount{
			Name:      apacheAgentConfigVolume,
			MountPath: apacheAgentConfDirFull,
		})
		// remove resource requirements since those are then reserved for the lifetime of a pod
		// and we definitely do not need them for the init container for cp command
		cloneContainer.Resources = apacheSpec.Resources
		// remove livenessProbe, readinessProbe, and startupProbe, since not supported on init containers
		cloneContainer.LivenessProbe = nil
		cloneContainer.ReadinessProbe = nil
		cloneContainer.StartupProbe = nil

		pod.Spec.InitContainers = append(pod.Spec.InitContainers, *cloneContainer)

		// drop volume mount with volume-provided Apache config from original container
		// since it could over-write configuration provided by the injection
		idxFound := -1
		for idx, volume := range container.VolumeMounts {
			if strings.Contains(volume.MountPath, apacheConfDir) { // potentially passes config, which we want to pass to init copy only
				idxFound = idx
				break
			}
		}
		if idxFound >= 0 {
			volumeMounts := container.VolumeMounts
			volumeMounts = append(volumeMounts[:idxFound], volumeMounts[idxFound+1:]...)
			container.VolumeMounts = volumeMounts
		}

		// Inject volumes info instrumented container - Apache config dir + Apache agent
		container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
			Name:      apacheAgentVolume,
			MountPath: apacheAgentDirFull,
		})
		container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
			Name:      apacheAgentConfigVolume,
			MountPath: apacheConfDir,
		})
	}

	// Inject second init container with instrumentation image
	// Create / update config files
	// Copy OTEL module to a shared volume
	if isApacheInitContainerMissing(pod, apacheAgentInitContainerName) {
		// Inject volume for agent
		pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
			Name: apacheAgentVolume,
			VolumeSource: corev1.VolumeSource{
				EmptyDir: &corev1.EmptyDirVolumeSource{
					SizeLimit: volumeSize(apacheSpec.VolumeSizeLimit),
				},
			}})

		pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{
			Name:    apacheAgentInitContainerName,
			Image:   apacheSpec.Image,
			Command: []string{"/bin/sh", "-c"},
			Args: []string{
				// Copy agent binaries to shared volume
				"cp -r /opt/opentelemetry/* " + apacheAgentDirFull + " && " +
					// setup logging configuration from template
					"export agentLogDir=$(echo \"" + apacheAgentDirFull + "/logs\" | sed 's,/,\\\\/,g') && " +
					"cat " + apacheAgentDirFull + "/conf/appdynamics_sdk_log4cxx.xml.template | sed 's/__agent_log_dir__/'${agentLogDir}'/g'  > " + apacheAgentDirFull + "/conf/appdynamics_sdk_log4cxx.xml &&" +
					// Create agent configuration file by pasting content of env var to a file
					"echo \"$" + apacheAttributesEnvVar + "\" > " + apacheAgentConfDirFull + "/" + apacheAgentConfigFile + " && " +
					"sed -i 's/" + apacheServiceInstanceId + "/'${" + apacheServiceInstanceIdEnvVar + "}'/g' " + apacheAgentConfDirFull + "/" + apacheAgentConfigFile + " && " +
					// Include a link to include Apache agent configuration file into httpd.conf
					"echo 'Include " + getApacheConfDir(apacheSpec.ConfigPath) + "/" + apacheAgentConfigFile + "' >> " + apacheAgentConfDirFull + "/" + apacheConfigFile,
			},
			Env: []corev1.EnvVar{
				{
					Name:  apacheAttributesEnvVar,
					Value: getApacheOtelConfig(pod, apacheSpec, index, otlpEndpoint, resourceMap),
				},
				{Name: apacheServiceInstanceIdEnvVar,
					ValueFrom: &corev1.EnvVarSource{
						FieldRef: &corev1.ObjectFieldSelector{
							FieldPath: "metadata.name",
						},
					},
				},
			},
			Resources: apacheSpec.Resources,
			VolumeMounts: []corev1.VolumeMount{
				{
					Name:      apacheAgentVolume,
					MountPath: apacheAgentDirFull,
				},
				{
					Name:      apacheAgentConfigVolume,
					MountPath: apacheAgentConfDirFull,
				},
			},
		})
	}

	return pod
}