func()

in executors/kubernetes/kubernetes.go [340:419]


func (s *executor) Prepare(options common.ExecutorPrepareOptions) (err error) {
	s.AbstractExecutor.PrepareConfiguration(options)

	if err = s.prepareOverwrites(options.Build.GetAllVariables()); err != nil {
		return fmt.Errorf("couldn't prepare overwrites: %w", err)
	}

	s.prepareOptions(options.Build)

	if err = s.prepareServiceOverwrites(s.options.Services); err != nil {
		return fmt.Errorf("couldn't prepare explicit service overwrites: %w", err)
	}

	// Dynamically configure use of shared build dir allowing
	// for static build dir when isolated volume is in use.
	s.SharedBuildsDir = s.isSharedBuildsDirRequired()

	if err = s.checkDefaults(); err != nil {
		return fmt.Errorf("check defaults error: %w", err)
	}

	s.kubeConfig, err = s.getKubeConfig(s.Config.Kubernetes, s.configurationOverwrites)
	if err != nil {
		return fmt.Errorf("getting Kubernetes config: %w", err)
	}

	s.kubeClient, err = s.newKubeClient(s.kubeConfig)
	if err != nil {
		return fmt.Errorf("connecting to Kubernetes: %w", err)
	}

	s.helperImageInfo, err = s.prepareHelperImage()
	if err != nil {
		return fmt.Errorf("prepare helper image: %w", err)
	}

	// setup default executor options based on OS type
	s.setupDefaultExecutorOptions(s.helperImageInfo.OSType)

	s.featureChecker = &kubeClientFeatureChecker{s.kubeClient}

	imageName := s.options.Image.Name

	s.BuildLogger.Println("Using Kubernetes executor with image", imageName, "...")
	if !s.Build.IsFeatureFlagOn(featureflags.UseLegacyKubernetesExecutionStrategy) {
		s.BuildLogger.Println("Using attach strategy to execute scripts...")
	}

	// pull manager can be prepared once s.options.Image & s.options.Services is set up
	s.pullManager, err = s.preparePullManager()
	if err != nil {
		return err
	}

	s.BuildLogger.Debugln(fmt.Sprintf("Using helper image: %s:%s", s.helperImageInfo.Name, s.helperImageInfo.Tag))

	if err = s.AbstractExecutor.PrepareBuildAndShell(); err != nil {
		return fmt.Errorf("prepare build and shell: %w", err)
	}

	if s.BuildShell.PassFile {
		return fmt.Errorf("kubernetes doesn't support shells that require script file")
	}

	s.podWatcher = s.newPodWatcher(podWatcherConfig{
		ctx:             options.Context,
		logger:          &s.BuildLogger,
		kubeClient:      s.kubeClient,
		featureChecker:  s.featureChecker,
		namespace:       s.configurationOverwrites.namespace,
		labels:          s.buildLabels(),
		maxSyncDuration: s.Config.Kubernetes.RequestRetryBackoffMax.Get(),
		retryProvider:   s,
	})
	if err := s.podWatcher.Start(); err != nil {
		return fmt.Errorf("starting pod watcher: %w", err)
	}

	return s.waitForServices(options.Context)
}