From 6f9155cbb377917fab893ea5a7b9da8479ec70f5 Mon Sep 17 00:00:00 2001
From: Aditya R <arajan@redhat.com>
Date: Mon, 16 May 2022 11:19:56 +0530
Subject: api: make no-op remote functional in /libpod/build

Podman API `libpod/build` accepts paramemter `remote` which overrides
`dockerfile` but currently parameter is no-op. Following commit adds
support for `remote` parameter in libpod API.

See: https://docs.podman.io/en/v3.2.3/_static/api.html#operation/ImageBuildLibpod
Closes: https://github.com/containers/podman/issues/13831

Signed-off-by: Aditya R <arajan@redhat.com>
---
 pkg/api/handlers/compat/images_build.go | 49 +++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 6 deletions(-)

(limited to 'pkg/api')

diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index f0d07f492..318688222 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -119,6 +119,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
 		Registry               string   `schema:"registry"`
 		Rm                     bool     `schema:"rm"`
 		RusageLogFile          string   `schema:"rusagelogfile"`
+		Remote                 string   `schema:"remote"`
 		Seccomp                string   `schema:"seccomp"`
 		Secrets                string   `schema:"secrets"`
 		SecurityOpt            string   `schema:"securityopt"`
@@ -169,14 +170,50 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
 
 	// convert addcaps formats
 	containerFiles := []string{}
-	if _, found := r.URL.Query()["dockerfile"]; found {
-		var m = []string{}
-		if err := json.Unmarshal([]byte(query.Dockerfile), &m); err != nil {
-			// it's not json, assume just a string
-			m = []string{filepath.Join(contextDirectory, query.Dockerfile)}
+	// Tells if query paramemter `dockerfile` is set or not.
+	dockerFileSet := false
+	if utils.IsLibpodRequest(r) && query.Remote != "" {
+		// The context directory could be a URL.  Try to handle that.
+		anchorDir, err := ioutil.TempDir(parse.GetTempDir(), "libpod_builder")
+		if err != nil {
+			utils.InternalServerError(w, err)
+		}
+		tempDir, subDir, err := buildahDefine.TempDirForURL(anchorDir, "buildah", query.Remote)
+		if err != nil {
+			utils.InternalServerError(w, err)
+		}
+		if tempDir != "" {
+			// We had to download it to a temporary directory.
+			// Delete it later.
+			defer func() {
+				if err = os.RemoveAll(tempDir); err != nil {
+					// We are deleting this on server so log on server end
+					// client does not have to worry about server cleanup.
+					logrus.Errorf("Cannot delete downloaded temp dir %q: %s", tempDir, err)
+				}
+			}()
+			contextDirectory = filepath.Join(tempDir, subDir)
+		} else {
+			// Nope, it was local.  Use it as is.
+			absDir, err := filepath.Abs(query.Remote)
+			if err != nil {
+				utils.BadRequest(w, "remote", query.Remote, err)
+			}
+			contextDirectory = absDir
 		}
-		containerFiles = m
 	} else {
+		if _, found := r.URL.Query()["dockerfile"]; found {
+			var m = []string{}
+			if err := json.Unmarshal([]byte(query.Dockerfile), &m); err != nil {
+				// it's not json, assume just a string
+				m = []string{filepath.Join(contextDirectory, query.Dockerfile)}
+			}
+			containerFiles = m
+			dockerFileSet = true
+		}
+	}
+
+	if !dockerFileSet {
 		containerFiles = []string{filepath.Join(contextDirectory, "Dockerfile")}
 		if utils.IsLibpodRequest(r) {
 			containerFiles = []string{filepath.Join(contextDirectory, "Containerfile")}
-- 
cgit v1.2.3-54-g00ecf