From f646db4bed1a1f0b63e5e1eb652e8580d3b45d1b Mon Sep 17 00:00:00 2001 From: Laszlo Fogas Date: Sun, 6 Oct 2024 09:45:23 +0200 Subject: [PATCH] supporting Docker build contexts (support for monorepos) --- cmd/agent/imagebuild.go | 2 +- pkg/dashboard/gitops/helper.go | 8 ++++++-- pkg/dashboard/server/releases.go | 3 ++- pkg/dashboard/worker/gitops.go | 3 ++- pkg/dx/release.go | 1 + web/src/views/envConfig/imageWidget.jsx | 27 +++++++++++++++++++------ 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/cmd/agent/imagebuild.go b/cmd/agent/imagebuild.go index 6e59e62cf..6431c3c64 100644 --- a/cmd/agent/imagebuild.go +++ b/cmd/agent/imagebuild.go @@ -382,7 +382,7 @@ func generateJob(trigger dx.ImageBuildRequest, name, sourceUrl string) *batchv1. Image: "gcr.io/kaniko-project/executor:latest", Args: []string{ fmt.Sprintf("--dockerfile=/workspace/%s", trigger.Dockerfile), - "--context=dir:///workspace", + "--context=dir:///workspace/" + trigger.Context, fmt.Sprintf("--destination=%s:%s", trigger.Image, trigger.Tag), }, VolumeMounts: []corev1.VolumeMount{ diff --git a/pkg/dashboard/gitops/helper.go b/pkg/dashboard/gitops/helper.go index 7c4a41946..5e25b0179 100644 --- a/pkg/dashboard/gitops/helper.go +++ b/pkg/dashboard/gitops/helper.go @@ -391,11 +391,12 @@ func ExtractImageStrategy(envConfig *dx.Manifest) string { return "dynamic" } -func ExtractImageRepoTagDockerfileAndRegistry(envConfig *dx.Manifest, vars map[string]string) (string, string, string, string) { +func ExtractImageRepoTagDockerfileAndRegistry(envConfig *dx.Manifest, vars map[string]string) (string, string, string, string, string) { envConfig.ResolveVars(vars) image := envConfig.Values["image"] var repository, tag, dockerfile, registry string + context := "." if image != nil { imageMap := image.(map[string]interface{}) @@ -405,6 +406,9 @@ func ExtractImageRepoTagDockerfileAndRegistry(envConfig *dx.Manifest, vars map[s if val, ok := imageMap["tag"]; ok { tag = val.(string) } + if val, ok := imageMap["context"]; ok { + context = val.(string) + } if val, ok := imageMap["dockerfile"]; ok { dockerfile = val.(string) } @@ -413,5 +417,5 @@ func ExtractImageRepoTagDockerfileAndRegistry(envConfig *dx.Manifest, vars map[s } } - return repository, tag, dockerfile, registry + return repository, tag, context, dockerfile, registry } diff --git a/pkg/dashboard/server/releases.go b/pkg/dashboard/server/releases.go index 3f3c56393..d2f19c904 100644 --- a/pkg/dashboard/server/releases.go +++ b/pkg/dashboard/server/releases.go @@ -288,7 +288,7 @@ func release(w http.ResponseWriter, r *http.Request) { vars := artifact.CollectVariables() vars["APP"] = releaseRequest.App - imageRepository, imageTag, dockerfile, registry := gitops.ExtractImageRepoTagDockerfileAndRegistry(manifest, vars) + imageRepository, imageTag, context, dockerfile, registry := gitops.ExtractImageRepoTagDockerfileAndRegistry(manifest, vars) // Image push happens inside the cluster, pull is handled by the kubelet that doesn't speak cluster local addresses imageRepository = strings.ReplaceAll(imageRepository, "127.0.0.1:32447", "registry.infrastructure.svc.cluster.local:5000") imageBuildRequest = &dx.ImageBuildRequest{ @@ -299,6 +299,7 @@ func release(w http.ResponseWriter, r *http.Request) { TriggeredBy: user.Login, Image: imageRepository, Tag: imageTag, + Context: context, Dockerfile: dockerfile, Strategy: strategy, Registry: registry, diff --git a/pkg/dashboard/worker/gitops.go b/pkg/dashboard/worker/gitops.go index 20eb3c796..14362c3fd 100644 --- a/pkg/dashboard/worker/gitops.go +++ b/pkg/dashboard/worker/gitops.go @@ -703,7 +703,7 @@ func processArtifactEvent( strategy := gitops.ExtractImageStrategy(manifest) if strategy == "buildpacks" || strategy == "dockerfile" { // image build - imageRepository, imageTag, dockerfile, registry := gitops.ExtractImageRepoTagDockerfileAndRegistry(manifest, vars) + imageRepository, imageTag, context, dockerfile, registry := gitops.ExtractImageRepoTagDockerfileAndRegistry(manifest, vars) // Image push happens inside the cluster, pull is handled by the kubelet that doesn't speak cluster local addresses imageRepository = strings.ReplaceAll(imageRepository, "127.0.0.1:32447", "registry.infrastructure.svc.cluster.local:5000") imageBuildRequest := &dx.ImageBuildRequest{ @@ -714,6 +714,7 @@ func processArtifactEvent( TriggeredBy: "policy", Image: imageRepository, Tag: imageTag, + Context: context, Dockerfile: dockerfile, Strategy: strategy, Registry: registry, diff --git a/pkg/dx/release.go b/pkg/dx/release.go index d785b7994..f7938ddde 100644 --- a/pkg/dx/release.go +++ b/pkg/dx/release.go @@ -49,6 +49,7 @@ type ImageBuildRequest struct { Image string `json:"image"` Tag string `json:"tag"` SourcePath string `json:"sourcePath"` + Context string `json:"context"` Dockerfile string `json:"dockerfile"` Strategy string `json:"strategy"` Registry string `json:"registry"` diff --git a/web/src/views/envConfig/imageWidget.jsx b/web/src/views/envConfig/imageWidget.jsx index 0a58f2ca4..a16e3732e 100644 --- a/web/src/views/envConfig/imageWidget.jsx +++ b/web/src/views/envConfig/imageWidget.jsx @@ -25,6 +25,13 @@ export default function ImageWidget(props) { }) } + const setContext = (context) => { + setImage({ + ...image, + "context": context, + }) + } + const setStrategy = (strategy) => { let registry = {} registry = registries.find(r => r.variable === "customRegistry") @@ -50,6 +57,7 @@ export default function ImageWidget(props) { "registry": registry.variable, "repository": registry.url+"/{{ .APP }}", "tag": "{{ .SHA }}", + "context": ".", "dockerfile": "Dockerfile" }) break; @@ -192,14 +200,21 @@ export default function ImageWidget(props) {
- setTag(e.target.value)}/> + setTag(e.target.value)}/>
{ image.strategy === "dockerfile" && -
- - setDockerfile(e.target.value)}/> -

Case-sensitive relative path from the project root to the Dockerfile.

-
+ <> +
+ + setContext(e.target.value)}/> +

Case-sensitive relative path from the git repository root (signaled as '.') to the project root. Change it for monorepos, like 'backend/'.

+
+
+ + setDockerfile(e.target.value)}/> +

Case-sensitive relative path from the project root to the Dockerfile, like 'backend/Dockerfile'

+
+ }