func()

in pkg/builder/s2i.go [61:225]


func (t *s2iTask) Do(ctx context.Context) v1.BuildStatus {
	log.Info("S2I publishing strategy is deprecated and may be removed in the future, use Jib strategy instead")
	status := initializeStatusFrom(t.build.Status, t.task.BaseImage)

	bc := &buildv1.BuildConfig{
		TypeMeta: metav1.TypeMeta{
			APIVersion: buildv1.GroupVersion.String(),
			Kind:       "BuildConfig",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      "camel-k-" + t.build.Name,
			Namespace: t.build.Namespace,
			Labels:    t.build.Labels,
		},
		Spec: buildv1.BuildConfigSpec{
			CommonSpec: buildv1.CommonSpec{
				Source: buildv1.BuildSource{
					Type: buildv1.BuildSourceBinary,
				},
				Strategy: buildv1.BuildStrategy{
					DockerStrategy: &buildv1.DockerBuildStrategy{},
				},
				Output: buildv1.BuildOutput{
					To: &corev1.ObjectReference{
						Kind: "ImageStreamTag",
						Name: "camel-k-" + t.build.Name + ":" + t.task.Tag,
					},
				},
			},
		},
	}

	// Set the build controller as owner reference
	owner := t.getControllerReference()
	if owner == nil {
		// Default to the Build if no controller reference is present
		owner = t.build
	}

	err := s2i.BuildConfig(ctx, t.c, bc, owner)
	if err != nil {
		return status.Failed(err)
	}

	is := &imagev1.ImageStream{
		TypeMeta: metav1.TypeMeta{
			APIVersion: imagev1.GroupVersion.String(),
			Kind:       "ImageStream",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      "camel-k-" + t.build.Name,
			Namespace: t.build.Namespace,
			Labels:    t.build.Labels,
		},
		Spec: imagev1.ImageStreamSpec{
			LookupPolicy: imagev1.ImageLookupPolicy{
				Local: true,
			},
		},
	}

	err = s2i.ImageStream(ctx, t.c, is, owner)
	if err != nil {
		return status.Failed(err)
	}

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

		contextDir := t.task.ContextDir
		if contextDir == "" {
			// Use the working directory.
			// This is useful when the task is executed in-container,
			// so that its WorkingDir can be used to share state and
			// coordinate with other tasks.
			pwd, err := os.Getwd()
			if err != nil {
				return err
			}
			contextDir = filepath.Join(pwd, ContextDir)
		}

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

		err = tarDir(contextDir, archiveFile)
		if err != nil {
			return fmt.Errorf("cannot tar context directory: %w", err)
		}

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

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

		r := restClient.Post().
			Namespace(t.build.Namespace).
			Body(bufio.NewReader(f)).
			Resource("buildconfigs").
			Name("camel-k-" + t.build.Name).
			SubResource("instantiatebinary").
			Do(ctx)

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

		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, t.c, &s2iBuild)
		if err != nil {
			if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
				//nolint:contextcheck
				if err := s2i.CancelBuild(context.Background(), t.c, &s2iBuild); err != nil {
					log.Errorf(err, "cannot cancel s2i Build: %s/%s", s2iBuild.Namespace, s2iBuild.Name)
				}
			}
			return err
		}
		if s2iBuild.Status.Output.To != nil {
			status.Digest = s2iBuild.Status.Output.To.ImageDigest
		}

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

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

		status.Image = is.Status.DockerImageRepository + ":" + t.task.Tag

		return f.Close()
	})

	if err != nil {
		return status.Failed(err)
	}

	return *status
}