func()

in builder/builder.go [48:195]


func (b *Builder) RunTask(ctx context.Context, task *graph.Task) error {
	for _, network := range task.Networks {
		if network.SkipCreation {
			log.Printf("Skip creating network: %s\n", network.Name)
			continue
		}
		log.Printf("Creating Docker network: %s, driver: '%s'\n", network.Name, network.Driver)
		if msg, err := network.Create(ctx, b.procManager); err != nil {
			return fmt.Errorf("failed to create network: %s, err: %v, msg: %s", network.Name, err, msg)
		}
		log.Printf("Successfully set up Docker network: %s\n", network.Name)
	}

	log.Println("Setting up Docker configuration...")
	timeout := time.Duration(configTimeoutInSec) * time.Second
	configCtx, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()
	if err := b.setupConfig(configCtx); err != nil {
		return err
	}
	log.Println("Successfully set up Docker configuration")
	if task.UsingRegistryCreds() {
		timeout := time.Duration(loginTimeoutInSec) * time.Second
		for registry, cred := range task.RegistryLoginCredentials {
			loginCtx, cancel := context.WithTimeout(ctx, timeout)
			defer cancel()
			log.Printf("Logging in to registry: %s\n", registry)
			if err := b.dockerLoginWithRetries(loginCtx, registry, cred.Username.ResolvedValue, cred.Password.ResolvedValue, 0); err != nil {
				return err
			}
			log.Printf("Successfully logged into %s\n", registry)
		}
	}

	var completedChans []chan bool
	errorChan := make(chan error)
	for _, node := range task.Dag.Nodes {
		completedChans = append(completedChans, node.Value.CompletedChan)
	}

	if task.InitBuildkitContainer {
		log.Println("Task will use build cache, initializing buildkitd container")
		// --workdir = /workspace
		args := b.getDockerRunArgs(
			make(map[string]string),
			b.workspaceDir,
			"",
			false,
			true,
			true,
			[]string{},
			[]string{},
			[]string{},
			false,
			"",
			"",
			"",
			"",
			"",
			buildkitdContainerName,
			buildxImg+" create --use",
		)
		if b.debug {
			log.Printf("buildkitd container args: %v\n", strings.Join(args, ", "))
		}

		timeout := time.Duration(buildkitdContainerRunTimeoutInSeconds) * time.Second
		buildkitCtx, cancel := context.WithTimeout(ctx, timeout)
		defer cancel()

		err := b.procManager.RunRepeatWithRetries(
			buildkitCtx,
			args,
			nil,
			os.Stdout,
			os.Stderr,
			"",
			buildkitdContainerInitRetries,
			nil,
			buildkitdContainerInitRetryDelay,
			buildkitdContainerName,
			buildkitdContainerInitRepeat)
		if err != nil {
			log.Printf("buildx create --use failed with error: '%v'", err)
		}
	}

	for _, volMount := range task.Volumes {
		// create and populate volume for specified source
		if err := b.prepareVolumeSource(ctx, volMount); err != nil {
			return err
		}
	}

	for _, child := range task.Dag.Root.Children() {
		go b.processVertex(ctx, task, task.Dag.Root, child, errorChan)
	}

	// Block until either:
	// - The global context expires
	// - A step has an error
	// - All steps have been processed
	for _, ch := range completedChans {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ch:
			continue
		case err := <-errorChan:
			return err
		}
	}

	var deps []*image.Dependencies
	for _, step := range task.Steps {
		log.Printf("Step ID: %v marked as %v (elapsed time in seconds: %f)\n", step.ID, step.StepStatus, step.EndTime.Sub(step.StartTime).Seconds())

		if len(step.ImageDependencies) > 0 {
			log.Printf("Populating digests for step ID: %s...\n", step.ID)
			timeout := time.Duration(digestsTimeoutInSec) * time.Second
			digestCtx, cancel := context.WithTimeout(ctx, timeout)
			defer cancel()

			usingBuildkit := false
			if (step.UseBuildCacheForBuildStep() && runtime.GOOS == util.LinuxOS) || step.UsesBuildkit {
				log.Printf("Image was built using buildkit, fetching Digest from remote...")
				usingBuildkit = true
			}

			if err := b.getPopulateDigests(digestCtx, step.ImageDependencies, usingBuildkit, task.RegistryLoginCredentials); err != nil {
				return err
			}
			log.Printf("Successfully populated digests for step ID: %s\n", step.ID)
			deps = append(deps, step.ImageDependencies...)
		}
	}

	if len(deps) > 0 {
		depBytes, err := json.Marshal(deps)
		if err != nil {
			return errors.Wrap(err, "failed to unmarshal image dependencies")
		}
		log.Println("The following dependencies were found:")
		log.Println("\n" + string(depBytes))
	}

	return nil
}