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
}