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
}