in command-runner/pkg/runner/container_command_executor.go [39:147]
func newContainerCommandExecutor(ctx context.Context, params *newContainerCommandExecutorParams) (commandExecutor, error) {
containerName := fmt.Sprintf("codecatalyst-%s", regexp.MustCompile(`[^a-zA-Z0-9_.-]`).ReplaceAllString(params.ID, "_"))
containerName = strings.ToLower(containerName)
var imagePrep common.Executor
var image string
platform := ""
if i, found := strings.CutPrefix(params.Image, "docker://"); found {
// pull image from registry
image = i
} else {
// local docker build
dockerfilePath := params.Image
if !filepath.IsAbs(dockerfilePath) {
dockerfilePath = filepath.Join(params.WorkingDir, params.Image)
}
_, err := os.Stat(dockerfilePath)
if err != nil {
return nil, err
}
image = fmt.Sprintf("%s:%s", containerName, "latest")
exists, err := params.ContainerService.ImageExistsLocally(ctx, image, platform)
log.Ctx(ctx).Debug().Msgf("%s exists? %v", image, exists)
if err != nil {
log.Ctx(ctx).Error().Err(err).Msg("unable to check for local image")
}
if params.Reuse && exists {
imagePrep = func(ctx context.Context) error { return nil }
} else {
imagePrep = params.ContainerService.BuildImage(types.BuildImageInput{
ContextDir: filepath.Dir(dockerfilePath),
Dockerfile: filepath.Base(dockerfilePath),
ImageTag: image,
Platform: platform,
}).TraceRegion("image-build")
}
}
env, containerDefaultDir, err := setupEnvironmentVariables(params.Env)
if err != nil {
return nil, err
}
mceDir, err := setupMceDir(env, containerDefaultDir)
if err != nil {
return nil, err
}
binds := []string{
fmt.Sprintf("%s:%s", "/var/run/docker.sock", "/var/run/docker.sock"),
fmt.Sprintf("%s:%s", mceDir, "/tmp/mce"),
}
for _, filemap := range params.FileMaps {
srcPath := resolvePath(filemap.SourcePath, params.WorkingDir)
targetPath := resolvePath(filemap.TargetPath, containerSourceDir)
if filemap.Type == FileMapTypeBind {
binds = append(binds,
fmt.Sprintf(
"%s:%s%s",
srcPath,
targetPath,
bindModifiers(),
),
)
}
}
log.Ctx(ctx).Debug().Msgf("Container binds: %#v", binds)
log.Ctx(ctx).Debug().Msgf("Container env: %#v", env)
actionContainer := params.ContainerService.NewContainer(types.NewContainerInput{
Image: image,
Name: containerName,
Stdout: params.Stdout,
Stderr: params.Stderr,
Env: env,
WorkingDir: containerDefaultDir,
Binds: binds,
Entrypoint: params.Entrypoint,
})
copyExecutors, closeExecutors, err := setupCopyAndCloseExecutors(actionContainer, params.WorkingDir, params.FileMaps)
if err != nil {
return nil, err
}
if imagePrep == nil {
imagePrep = actionContainer.Pull(true).TraceRegion("image-pull")
}
if err := common.NewPipelineExecutor(
imagePrep,
actionContainer.Remove().IfBool(!params.Reuse),
actionContainer.Create(nil, nil).TraceRegion("container-create"),
common.NewPipelineExecutor(copyExecutors...).TraceRegion("container-copy"),
actionContainer.Start(false).TraceRegion("container-start"),
)(ctx); err != nil {
return nil, fmt.Errorf("unable to create container executor: %w", err)
}
return &containerCommandExecutor{
Container: actionContainer,
ReuseContainers: params.Reuse,
CloseExecutors: closeExecutors,
mceDir: mceDir,
ctx: ctx,
}, nil
}