1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
From 45d5f942a37eecfa7856200376b8cf8a35e071de Mon Sep 17 00:00:00 2001
From: Aditya R <arajan@redhat.com>
Date: Wed, 2 Nov 2022 14:34:26 +0530
Subject: [PATCH] compat,build: handle docker's preconfigured cacheTo,cacheFrom
Docker's newer clients popuates `cacheFrom` and `cacheTo` parameter
by default as empty array for all commands but buildah's design of
distributed cache expects this to be a repo not image hence parse
only the first populated repo and igore if empty array.
Signed-off-by: Aditya R <arajan@redhat.com>
---
pkg/api/handlers/compat/images_build.go | 43 ++++++++++++++++++++-----
test/apiv2/10-images.at | 7 ++++
2 files changed, 42 insertions(+), 8 deletions(-)
cf. https://github.com/containers/podman/pull/16380#issuecomment-1299918607
NB: this affects the podman release 4.3.0: building anything using the docker
client and targetting podman as a server is broken, even when not using any
cache-to/cache-from flag.
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index d4c8c0743a4..577dfcb26f6 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -399,20 +399,47 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
}
+ // Docker's newer clients popuates `cacheFrom` and `cacheTo` parameter
+ // by default as empty array for all commands but buildah's design of
+ // distributed cache expects this to be a repo not image hence parse
+ // only the first populated repo and igore if empty array.
+ // Read more here: https://github.com/containers/podman/issues/15928
+ // TODO: Remove this when buildah's API is extended.
+ compatIgnoreForcedCacheOptions := func(queryStr string) string {
+ query := queryStr
+ if strings.HasPrefix(query, "[") {
+ query = ""
+ var arr []string
+ parseErr := json.Unmarshal([]byte(query), &arr)
+ if parseErr != nil {
+ if len(arr) > 0 {
+ query = arr[0]
+ }
+ }
+ }
+ return query
+ }
+
var cacheFrom reference.Named
if _, found := r.URL.Query()["cachefrom"]; found {
- cacheFrom, err = parse.RepoNameToNamedReference(query.CacheFrom)
- if err != nil {
- utils.BadRequest(w, "cacheFrom", query.CacheFrom, err)
- return
+ cacheFromQuery := compatIgnoreForcedCacheOptions(query.CacheFrom)
+ if cacheFromQuery != "" {
+ cacheFrom, err = parse.RepoNameToNamedReference(cacheFromQuery)
+ if err != nil {
+ utils.BadRequest(w, "cacheFrom", cacheFromQuery, err)
+ return
+ }
}
}
var cacheTo reference.Named
if _, found := r.URL.Query()["cacheto"]; found {
- cacheTo, err = parse.RepoNameToNamedReference(query.CacheTo)
- if err != nil {
- utils.BadRequest(w, "cacheto", query.CacheTo, err)
- return
+ cacheToQuery := compatIgnoreForcedCacheOptions(query.CacheTo)
+ if cacheToQuery != "" {
+ cacheTo, err = parse.RepoNameToNamedReference(cacheToQuery)
+ if err != nil {
+ utils.BadRequest(w, "cacheto", cacheToQuery, err)
+ return
+ }
}
}
var cacheTTL time.Duration
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at
index 3ffc6f73856..19096280689 100644
--- a/test/apiv2/10-images.at
+++ b/test/apiv2/10-images.at
@@ -189,6 +189,13 @@ tar --format=posix -C $TMPD -cvf ${CONTAINERFILE_TAR} containerfile &> /dev/null
t POST "libpod/build?dockerfile=containerfile" $CONTAINERFILE_TAR 200 \
.stream~"STEP 1/1: FROM $IMAGE"
+# Newer Docker client sets empty cacheFrom for every build command even if it is not used,
+# following commit makes sure we test such use-case. See https://github.com/containers/podman/pull/16380
+#TODO: This test should be extended when buildah's cache-from and cache-to functionally supports
+# multiple remote-repos
+t POST "libpod/build?dockerfile=containerfile&cachefrom=[]" $CONTAINERFILE_TAR 200 \
+ .stream~"STEP 1/1: FROM $IMAGE"
+
# With -q, all we should get is image ID. Test both libpod & compat endpoints.
t POST "libpod/build?dockerfile=containerfile&q=true" $CONTAINERFILE_TAR 200 \
.stream~'^[0-9a-f]\{64\}$'
|