func addKanikoTaskToPod()

in pkg/controller/build/build_pod.go [426:552]


func addKanikoTaskToPod(ctx context.Context, c ctrl.Reader, build *v1.Build, task *v1.KanikoTask, pod *corev1.Pod) error {
	cache := false
	if task.Cache.Enabled != nil && *task.Cache.Enabled {
		cache = true
	}

	args := []string{
		"--dockerfile=Dockerfile",
		"--context=" + filepath.Join(builderDir, build.Name, builder.ContextDir),
		"--destination=" + task.Image,
		"--cache=" + strconv.FormatBool(cache),
		"--cache-dir=" + builder.KanikoCacheDir,
	}

	if task.Verbose != nil && *task.Verbose {
		args = append(args, "-v=debug")
	}

	affinity := &corev1.Affinity{}
	env := make([]corev1.EnvVar, 0)
	volumes := make([]corev1.Volume, 0)
	volumeMounts := make([]corev1.VolumeMount, 0)

	if task.Registry.Secret != "" {
		secret, err := getRegistrySecret(ctx, c, build.Namespace, task.Registry.Secret, kanikoRegistrySecrets)
		if err != nil {
			return err
		}
		addRegistrySecret(task.Registry.Secret, secret, &volumes, &volumeMounts, &env)
	}

	if task.Registry.Insecure {
		args = append(args, "--insecure")
		args = append(args, "--insecure-pull")
	}

	env = append(env, proxyFromEnvironment()...)

	if cache {
		// Co-locate with the Kaniko warmer pod for sharing the host path volume as the current
		// persistent volume claim uses the default storage class which is likely relying
		// on the host path provisioner.
		// This has to be done manually by retrieving the Kaniko warmer pod node name and using
		// node affinity as pod affinity only works for running pods and the Kaniko warmer pod
		// has already completed at that stage.

		// Locate the kaniko warmer pod
		pods := &corev1.PodList{}
		err := c.List(ctx, pods,
			ctrl.InNamespace(build.Namespace),
			ctrl.MatchingLabels{
				"camel.apache.org/component": "kaniko-warmer",
			})
		if err != nil {
			return err
		}

		if len(pods.Items) != 1 {
			return errors.New("failed to locate the Kaniko cache warmer pod")
		}

		// Use node affinity with the Kaniko warmer pod node name
		affinity = &corev1.Affinity{
			NodeAffinity: &corev1.NodeAffinity{
				RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
					NodeSelectorTerms: []corev1.NodeSelectorTerm{
						{
							MatchExpressions: []corev1.NodeSelectorRequirement{
								{
									Key:      "kubernetes.io/hostname",
									Operator: "In",
									Values:   []string{pods.Items[0].Spec.NodeName},
								},
							},
						},
					},
				},
			},
		}
		// Mount the PV used to warm the Kaniko cache into the Kaniko image build
		volumes = append(volumes, corev1.Volume{
			Name: "kaniko-cache",
			VolumeSource: corev1.VolumeSource{
				PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
					ClaimName: task.Cache.PersistentVolumeClaim,
				},
			},
		})
		volumeMounts = append(volumeMounts, corev1.VolumeMount{
			Name:      "kaniko-cache",
			MountPath: builder.KanikoCacheDir,
		})
	}

	image := task.ExecutorImage
	if image == "" {
		image = fmt.Sprintf("%s:v%s", builder.KanikoDefaultExecutorImageName, defaults.KanikoVersion)
	}

	container := corev1.Container{
		Name:            task.Name,
		Image:           image,
		ImagePullPolicy: corev1.PullIfNotPresent,
		Args:            args,
		Env:             env,
		WorkingDir:      filepath.Join(builderDir, build.Name, builder.ContextDir),
		VolumeMounts:    volumeMounts,
	}

	// We may want to handle possible conflicts
	pod.Spec.Affinity = affinity
	pod.Spec.Volumes = append(pod.Spec.Volumes, volumes...)

	// Warning: Kaniko requires root privileges to work correctly
	// As we're planning to deprecate this building strategy we're fixing in the first
	// releases of version 2
	var ugfid int64 = 0
	pod.Spec.SecurityContext = &corev1.PodSecurityContext{
		RunAsUser:  &ugfid,
		RunAsGroup: &ugfid,
		FSGroup:    &ugfid,
	}

	addContainerToPod(build, container, pod)

	return nil
}