Commit b18e12d8 authored by Yann Hodique's avatar Yann Hodique Committed by GitHub

feat(kurtosis-devnet): deduplicate all builds (#13705)

Avoid rebuilding the same artifacts, as long as the inputs are the
same. This enables us to be as careless as we want on the template
definition side, and still build everything only once.
parent 83187273
......@@ -96,13 +96,8 @@ func (m *Main) localContractArtifactsOption(dir string) tmpl.TemplateContextOpti
return tmpl.WithFunction("localContractArtifacts", func(layer string) (string, error) {
bundlePath := contractsBundlePath(layer)
// we're in a temp dir, so we can skip the build if the file already
// exists: it'll be the same file! In particular, since we're ignoring
// layer for now, skip the 2nd build.
if _, err := os.Stat(bundlePath); err != nil {
if err := contractBuilder.Build(layer, bundlePath); err != nil {
return "", err
}
if err := contractBuilder.Build(layer, bundlePath); err != nil {
return "", err
}
log.Printf("%s: contract artifacts available at: %s\n", layer, contractsURL)
......
......@@ -17,6 +17,8 @@ type ContractBuilder struct {
// Dry run mode
dryRun bool
builtContracts map[string]interface{}
}
const (
......@@ -52,9 +54,10 @@ func WithContractDryRun(dryRun bool) ContractBuilderOptions {
// NewContractBuilder creates a new ContractBuilder instance
func NewContractBuilder(opts ...ContractBuilderOptions) *ContractBuilder {
b := &ContractBuilder{
baseDir: ".",
cmdTemplate: defaultContractTemplate,
dryRun: false,
baseDir: ".",
cmdTemplate: defaultContractTemplate,
dryRun: false,
builtContracts: make(map[string]interface{}),
}
for _, opt := range opts {
......@@ -66,17 +69,21 @@ func NewContractBuilder(opts ...ContractBuilderOptions) *ContractBuilder {
// templateData holds the data for the command template
type contractTemplateData struct {
Layer string
BundlePath string
}
// Build executes the contract build command
func (b *ContractBuilder) Build(layer string, bundlePath string) error {
func (b *ContractBuilder) Build(_layer string, bundlePath string) error {
// since we ignore layer for now, we can skip the build if the file already
// exists: it'll be the same file!
if _, ok := b.builtContracts[bundlePath]; ok {
return nil
}
log.Printf("Building contracts bundle: %s", bundlePath)
// Prepare template data
data := contractTemplateData{
Layer: layer,
BundlePath: bundlePath,
}
......@@ -97,5 +104,6 @@ func (b *ContractBuilder) Build(layer string, bundlePath string) error {
}
}
b.builtContracts[bundlePath] = struct{}{}
return nil
}
......@@ -16,6 +16,8 @@ type DockerBuilder struct {
cmdTemplate *template.Template
// Dry run mode
dryRun bool
builtImages map[string]string
}
const cmdTemplateStr = "just {{.ProjectName}}-image {{.ImageTag}}"
......@@ -52,6 +54,7 @@ func NewDockerBuilder(opts ...DockerBuilderOptions) *DockerBuilder {
baseDir: ".",
cmdTemplate: defaultCmdTemplate,
dryRun: false,
builtImages: make(map[string]string),
}
for _, opt := range opts {
......@@ -69,6 +72,10 @@ type templateData struct {
// Build executes the docker build command for the given project and image tag
func (b *DockerBuilder) Build(projectName, imageTag string) (string, error) {
if builtImage, ok := b.builtImages[projectName]; ok {
return builtImage, nil
}
log.Printf("Building docker image for project: %s with tag: %s", projectName, imageTag)
// Prepare template data
data := templateData{
......@@ -94,5 +101,6 @@ func (b *DockerBuilder) Build(projectName, imageTag string) (string, error) {
}
// Return the image tag as confirmation of successful build
b.builtImages[projectName] = imageTag
return imageTag, nil
}
......@@ -13,6 +13,8 @@ type PrestateBuilder struct {
baseDir string
cmdTemplate *template.Template
dryRun bool
builtPrestates map[string]interface{}
}
const (
......@@ -48,9 +50,10 @@ func WithPrestateDryRun(dryRun bool) PrestateBuilderOptions {
// NewPrestateBuilder creates a new PrestateBuilder instance
func NewPrestateBuilder(opts ...PrestateBuilderOptions) *PrestateBuilder {
b := &PrestateBuilder{
baseDir: ".",
cmdTemplate: defaultPrestateTemplate,
dryRun: false,
baseDir: ".",
cmdTemplate: defaultPrestateTemplate,
dryRun: false,
builtPrestates: make(map[string]interface{}),
}
for _, opt := range opts {
......@@ -67,6 +70,10 @@ type prestateTemplateData struct {
// Build executes the prestate build command
func (b *PrestateBuilder) Build(path string) error {
if _, ok := b.builtPrestates[path]; ok {
return nil
}
log.Printf("Building prestate: %s", path)
// Prepare template data
......@@ -91,5 +98,6 @@ func (b *PrestateBuilder) Build(path string) error {
}
}
b.builtPrestates[path] = struct{}{}
return nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment