func WithCluster()

in pkg/testutils/collector/collector.go [96:219]


func WithCluster(ctx context.Context, k *k3s.K3sContainer) testcontainers.CustomizeRequestOption {

	return func(req *testcontainers.GenericContainerRequest) error {
		isolateKinds := []string{"DaemonSet", "ConfigMap", "Deployment"}
		writeTo, err := os.MkdirTemp("", "collector")
		if err != nil {
			return fmt.Errorf("failed to create temp dir: %w", err)
		}

		var img string
		if req.FromDockerfile.Context != "" {
			img = req.FromDockerfile.Repo + ":" + req.FromDockerfile.Tag
		} else {
			img = req.Image
		}

		req.LifecycleHooks = append(req.LifecycleHooks, testcontainers.ContainerLifecycleHooks{
			PreCreates: []testcontainers.ContainerRequestHook{
				func(ctx context.Context, req testcontainers.ContainerRequest) error {

					if err := k.LoadImages(ctx, img); err != nil {
						return fmt.Errorf("failed to load image: %w", err)
					}

					if err := testutils.ExtractManifests(writeTo, "build/k8s/collector.yaml", isolateKinds); err != nil {
						return fmt.Errorf("failed to extract manifests: %w", err)
					}

					manifestsPath := filepath.Join(writeTo, "manifests.yaml")
					containerPath := filepath.Join(testutils.K3sManifests, "collector-manifests.yaml")
					if err := k.CopyFileToContainer(ctx, manifestsPath, containerPath, 0644); err != nil {
						return fmt.Errorf("failed to copy file to container: %w", err)
					}

					return testutils.InstallCrds(ctx, k)
				},
			},
			PostCreates: []testcontainers.ContainerHook{
				func(ctx context.Context, c testcontainers.Container) error {
					// Deserialize our statefulset manifest and customize it to our needs
					dsPath := filepath.Join(writeTo, "DaemonSet.yaml")
					dsData, err := os.ReadFile(dsPath)
					if err != nil {
						return fmt.Errorf("failed to read file: %w", err)
					}

					var daemonset appsv1.DaemonSet
					if err := yaml.Unmarshal(dsData, &daemonset); err != nil {
						return fmt.Errorf("failed to unmarshal daemonset: %w", err)
					}
					daemonset.Spec.Template.Spec.Tolerations = nil
					daemonset.Spec.Template.Spec.Containers[0].Image = img
					daemonset.Spec.Template.Spec.Containers[0].ImagePullPolicy = corev1.PullNever

					daemonset.Spec.Template.Spec.Volumes = slices.DeleteFunc(daemonset.Spec.Template.Spec.Volumes, func(v corev1.Volume) bool {
						return v.Name == "etcmachineid"
					})
					daemonset.Spec.Template.Spec.Containers[0].VolumeMounts = slices.DeleteFunc(daemonset.Spec.Template.Spec.Containers[0].VolumeMounts, func(v corev1.VolumeMount) bool {
						return v.Name == "etcmachineid"
					})

					// Wait for our manifests to be applied
					restConfig, _, err := testutils.GetKubeConfig(ctx, k)
					if err != nil {
						return fmt.Errorf("failed to get kube config: %w", err)
					}

					clientset, err := kubernetes.NewForConfig(restConfig)
					if err != nil {
						return fmt.Errorf("failed to create clientset: %w", err)
					}

					ctrlCli, err := ctrlclient.New(restConfig, ctrlclient.Options{})
					if err != nil {
						return fmt.Errorf("failed to create controller client: %w", err)
					}

					err = kwait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Minute, true, func(ctx context.Context) (bool, error) {
						ns, err := clientset.CoreV1().Namespaces().Get(ctx, daemonset.GetNamespace(), metav1.GetOptions{})
						return ns != nil && err == nil, nil
					})
					if err != nil {
						return fmt.Errorf("failed to wait for namespace: %w", err)
					}

					collectorConfigMap := makeCollectorConfigMap()
					patchBytes, err := json.Marshal(collectorConfigMap)
					if err != nil {
						return fmt.Errorf("failed to marshal configmap: %w", err)
					}
					_, err = clientset.CoreV1().ConfigMaps(collectorConfigMap.Namespace).Patch(ctx, collectorConfigMap.Name, types.ApplyPatchType, patchBytes, metav1.PatchOptions{
						FieldManager: "testcontainers",
					})
					if err != nil {
						return fmt.Errorf("failed to patch configmap: %w", err)
					}

					patchBytes, err = json.Marshal(daemonset)
					if err != nil {
						return fmt.Errorf("failed to marshal daemonset: %w", err)
					}
					_, err = clientset.AppsV1().DaemonSets(daemonset.Namespace).Patch(ctx, daemonset.Name, types.ApplyPatchType, patchBytes, metav1.PatchOptions{
						FieldManager: "testcontainers",
					})
					if err != nil {
						return fmt.Errorf("failed to patch daemonset: %w", err)
					}

					// create new function instance since Create will modify the passed-in object
					collectorFunction := makeCollectorFunction()
					if err := ctrlCli.Get(ctx, types.NamespacedName{Namespace: collectorFunction.Namespace, Name: collectorFunction.Name}, collectorFunction); err != nil {
						if err := ctrlCli.Create(ctx, collectorFunction); err != nil {
							return fmt.Errorf("failed to create function: %w", err)
						}
					}

					return nil
				},
			},
		})

		return nil
	}
}