func initializeS2i()

in pkg/controller/catalog/initialize.go [175:398]


func initializeS2i(ctx context.Context, c client.Client, ip *v1.IntegrationPlatform, catalog *v1.CamelCatalog) (*v1.CamelCatalog, error) {
	target := catalog.DeepCopy()
	// No registry in s2i
	imageName := fmt.Sprintf(
		"camel-k-runtime-%s-builder",
		catalog.Spec.Runtime.Provider,
	)
	imageTag := strings.ToLower(catalog.Spec.Runtime.Version)

	uidStr := getS2iUserID(ctx, c, ip, catalog)

	// Dockerfile
	dockerfile := `
		FROM ` + catalog.Spec.GetQuarkusToolingImage() + `
		USER ` + uidStr + `:0
		ADD --chown=` + uidStr + `:0 /usr/local/bin/kamel /usr/local/bin/kamel
		ADD --chown=` + uidStr + `:0 /usr/share/maven/mvnw/ /usr/share/maven/mvnw/
	`
	if imageSnapshot(imageName + ":" + imageTag) {
		dockerfile = dockerfile + `
		ADD --chown=` + uidStr + `:0 ` + defaults.LocalRepository + ` ` + defaults.LocalRepository + `
	`
	}

	owner := catalogReference(catalog)

	// BuildConfig
	bc := &buildv1.BuildConfig{
		TypeMeta: metav1.TypeMeta{
			APIVersion: buildv1.GroupVersion.String(),
			Kind:       "BuildConfig",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      imageName,
			Namespace: ip.Namespace,
			Labels: map[string]string{
				kubernetes.CamelCreatorLabelKind:      v1.CamelCatalogKind,
				kubernetes.CamelCreatorLabelName:      catalog.Name,
				kubernetes.CamelCreatorLabelNamespace: catalog.Namespace,
				kubernetes.CamelCreatorLabelVersion:   catalog.ResourceVersion,
				"camel.apache.org/runtime.version":    catalog.Spec.Runtime.Version,
				"camel.apache.org/runtime.provider":   string(catalog.Spec.Runtime.Provider),
			},
		},
		Spec: buildv1.BuildConfigSpec{
			CommonSpec: buildv1.CommonSpec{
				Source: buildv1.BuildSource{
					Type:       buildv1.BuildSourceBinary,
					Dockerfile: &dockerfile,
				},
				Strategy: buildv1.BuildStrategy{
					DockerStrategy: &buildv1.DockerBuildStrategy{},
				},
				Output: buildv1.BuildOutput{
					To: &corev1.ObjectReference{
						Kind: "ImageStreamTag",
						Name: imageName + ":" + imageTag,
					},
				},
			},
		},
	}

	// ImageStream
	is := &imagev1.ImageStream{
		TypeMeta: metav1.TypeMeta{
			APIVersion: imagev1.GroupVersion.String(),
			Kind:       "ImageStream",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      bc.Name,
			Namespace: bc.Namespace,
			Labels: map[string]string{
				kubernetes.CamelCreatorLabelKind:      v1.CamelCatalogKind,
				kubernetes.CamelCreatorLabelName:      catalog.Name,
				kubernetes.CamelCreatorLabelNamespace: catalog.Namespace,
				kubernetes.CamelCreatorLabelVersion:   catalog.ResourceVersion,
				"camel.apache.org/runtime.provider":   string(catalog.Spec.Runtime.Provider),
			},
		},
		Spec: imagev1.ImageStreamSpec{
			LookupPolicy: imagev1.ImageLookupPolicy{
				Local: true,
			},
		},
	}

	if !imageSnapshot(imageName+":"+imageTag) && imageExistsS2i(ctx, c, is) {
		target.Status.Phase = v1.CamelCatalogPhaseReady
		target.Status.SetCondition(
			v1.CamelCatalogConditionReady,
			corev1.ConditionTrue,
			"Builder Image",
			"Container image exists on registry (later)",
		)
		target.Status.Image = imageName
		return target, nil
	}

	err := s2i.BuildConfig(ctx, c, bc, owner)
	if err != nil {
		target.Status.Phase = v1.CamelCatalogPhaseError
		target.Status.SetErrorCondition(
			v1.CamelCatalogConditionReady,
			"Builder Image",
			err,
		)
		return target, err
	}

	err = s2i.ImageStream(ctx, c, is, owner)
	if err != nil {
		target.Status.Phase = v1.CamelCatalogPhaseError
		target.Status.SetErrorCondition(
			v1.CamelCatalogConditionReady,
			"Builder Image",
			err,
		)
		return target, err
	}

	err = util.WithTempDir(imageName+"-s2i-", func(tmpDir string) error {
		archive := filepath.Join(tmpDir, "archive.tar.gz")

		archiveFile, err := os.Create(archive)
		if err != nil {
			return fmt.Errorf("cannot create tar archive: %w", err)
		}

		directories := []string{
			"/usr/local/bin/kamel:/usr/local/bin/kamel",
			"/usr/share/maven/mvnw/:/usr/share/maven/mvnw/",
		}
		if imageSnapshot(imageName + ":" + imageTag) {
			directories = append(directories, defaults.LocalRepository+":"+defaults.LocalRepository)
		}

		err = tarEntries(archiveFile, directories...)
		if err != nil {
			return fmt.Errorf("cannot tar path entry: %w", err)
		}

		f, err := util.Open(archive)
		if err != nil {
			return err
		}

		restClient, err := apiutil.RESTClientForGVK(
			schema.GroupVersionKind{Group: "build.openshift.io", Version: "v1"}, false,
			c.GetConfig(), serializer.NewCodecFactory(c.GetScheme()))
		if err != nil {
			return err
		}

		r := restClient.Post().
			Namespace(bc.Namespace).
			Body(bufio.NewReader(f)).
			Resource("buildconfigs").
			Name(bc.Name).
			SubResource("instantiatebinary").
			Do(ctx)

		if r.Error() != nil {
			return fmt.Errorf("cannot instantiate binary: %w", err)
		}

		data, err := r.Raw()
		if err != nil {
			return fmt.Errorf("no raw data retrieved: %w", err)
		}

		s2iBuild := buildv1.Build{}
		err = json.Unmarshal(data, &s2iBuild)
		if err != nil {
			return fmt.Errorf("cannot unmarshal instantiated binary response: %w", err)
		}

		err = s2i.WaitForS2iBuildCompletion(ctx, c, &s2iBuild)
		if err != nil {
			if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
				//nolint: contextcheck
				if err := s2i.CancelBuild(context.Background(), c, &s2iBuild); err != nil {
					return fmt.Errorf("cannot cancel s2i Build: %s/%s", s2iBuild.Namespace, s2iBuild.Name)
				}
			}
			return err
		}
		if s2iBuild.Status.Output.To != nil {
			Log.Infof("Camel K builder container image %s:%s@%s created", imageName, imageTag, s2iBuild.Status.Output.To.ImageDigest)
		}

		err = c.Get(ctx, ctrl.ObjectKeyFromObject(is), is)
		if err != nil {
			return err
		}

		if is.Status.DockerImageRepository == "" {
			return errors.New("dockerImageRepository not available in ImageStream")
		}

		target.Status.Phase = v1.CamelCatalogPhaseReady
		target.Status.SetCondition(
			v1.CamelCatalogConditionReady,
			corev1.ConditionTrue,
			"Builder Image",
			"Container image successfully built",
		)
		target.Status.Image = is.Status.DockerImageRepository + ":" + imageTag

		return f.Close()
	})

	if err != nil {
		target.Status.Phase = v1.CamelCatalogPhaseError
		target.Status.SetErrorCondition(
			v1.CamelCatalogConditionReady,
			"Builder Image",
			err,
		)
		return target, err
	}

	return target, nil
}