Skip to content

Commit 0c39e1c

Browse files
Combine tools.deps and Leiningen images but still provide them under separate tags
1 parent 0e09eef commit 0c39e1c

File tree

9 files changed

+232
-327
lines changed

9 files changed

+232
-327
lines changed

src/docker_clojure/config.clj

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@
2222
(s/def ::distro qualified-keyword?)
2323
(s/def ::distros (s/coll-of ::distro :distinct true :into #{}))
2424

25-
(s/def ::build-tool (s/or ::specific-tool ::non-blank-string
26-
::all-tools #(= ::core/all %)))
25+
(s/def ::build-tool keyword?)
2726
(s/def ::build-tool-version
2827
(s/nilable (s/and ::non-blank-string #(re-matches #"[\d\.]+" %))))
29-
(s/def ::build-tools (s/map-of ::build-tool ::build-tool-version))
28+
(s/def ::installer-hash ::non-blank-string)
29+
(s/def ::version ::build-tool-version)
30+
(s/def ::build-tools (s/map-of ::build-tool
31+
(s/keys :req-un [::version ::installer-hash])))
32+
33+
3034

3135
(s/def ::maintainers
3236
(s/coll-of ::non-blank-string :distinct true :into #{}))
@@ -71,17 +75,13 @@
7175
17 :ubuntu/jammy
7276
:default :debian/bookworm})
7377

74-
(def build-tools
75-
{"lein" "2.11.2"
76-
"tools-deps" "1.11.1.1435"})
77-
78-
(def default-build-tool "tools-deps")
78+
(def ^:dynamic *build-tools*
79+
{:lein {:version "2.11.2"
80+
:installer-hash "28a1a62668c5f427b413a8677e376affaa995f023b1fcd06e2d4c98ac1df5f3e"}
81+
:tools-deps {:version "1.11.1.1435"
82+
:installer-hash "7edee5b12197a2dbe6338e672b109b18164cde84bea1f049ceceed41fc4dd10a"}})
7983

80-
(def installer-hashes
81-
{"lein" {"2.11.1" "03b3fbf7e6fac262f88f843a87b712a2b37f39cffc4f4f384436a30d8b01d6e4"
82-
"2.11.2" "28a1a62668c5f427b413a8677e376affaa995f023b1fcd06e2d4c98ac1df5f3e"}
83-
"tools-deps" {"1.11.1.1429" "bf08cfeb007118b7277aa7423734f5d507604b868f7fc44c0f9929ca9cd94ed4"
84-
"1.11.1.1435" "7edee5b12197a2dbe6338e672b109b18164cde84bea1f049ceceed41fc4dd10a"}})
84+
(def default-build-tool :tools-deps)
8585

8686
(def exclusions ; don't build these for whatever reason(s)
8787
#{; no more focal builds for JDK 20+

src/docker_clojure/core.clj

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
m))
5757

5858
(defn variant-map [[base-image jdk-version distro
59-
[build-tool build-tool-version]]]
59+
[build-tool build-tool-info]]]
6060
(let [variant-arch (get cfg/distro-architectures
6161
(-> distro namespace keyword))
6262
base {:jdk-version jdk-version
@@ -65,34 +65,31 @@
6565
jdk-version distro)
6666
:distro distro
6767
:build-tool build-tool
68-
:build-tool-version build-tool-version
68+
:build-tool-version (:version build-tool-info)
6969
:maintainer (str/join " & " cfg/maintainers)}]
70-
(-> base
71-
(assoc :docker-tag (default-docker-tag base))
72-
(assoc-if #(nil? (:build-tool-version base)) :build-tool-versions
73-
cfg/build-tools)
74-
(assoc-if #(seq variant-arch) :architectures variant-arch))))
70+
(cond-> base
71+
true (assoc :docker-tag (default-docker-tag base))
72+
variant-arch (assoc :architectures variant-arch))))
7573

7674
(defn pull-image [image]
7775
(sh "docker" "pull" image))
7876

79-
(defn generate-dockerfile! [installer-hashes variant]
77+
(defn generate-dockerfile! [variant]
8078
(let [build-dir (df/build-dir variant)
8179
filename "Dockerfile"]
8280
(log "Generating" (str build-dir "/" filename))
83-
(df/write-file build-dir filename installer-hashes variant)
81+
(df/write-file build-dir filename variant)
8482
(assoc variant
85-
:build-dir build-dir
86-
:dockerfile filename)))
83+
:build-dir build-dir
84+
:dockerfile filename)))
8785

88-
(defn build-image
89-
[installer-hashes {:keys [docker-tag base-image architectures] :as variant}]
86+
(defn build-image [{:keys [docker-tag base-image architectures] :as variant}]
9087
(let [image-tag (str "clojure:" docker-tag)
9188
_ (log "Pulling base image" base-image)
9289
_ (pull-image base-image)
9390

9491
{:keys [dockerfile build-dir]}
95-
(generate-dockerfile! installer-hashes variant)
92+
(generate-dockerfile! variant)
9693

9794
host-arch (let [jvm-arch (System/getProperty "os.arch")]
9895
(if (= "aarch64" jvm-arch)
@@ -126,33 +123,24 @@
126123

127124
(defn image-variant-combinations
128125
[base-images jdk-versions distros build-tools]
129-
(reduce
130-
(fn [variants jdk-version]
131-
(concat
132-
variants
133-
(let [jdk-base-images (get-or-default base-images jdk-version)]
134-
(loop [[bi & r] jdk-base-images
135-
acc #{}]
136-
(let [vs (combo/cartesian-product #{bi}
137-
#{jdk-version}
138-
(get-or-default distros bi)
139-
build-tools)
140-
acc' (concat acc vs)]
141-
(if (seq r)
142-
(recur r acc')
143-
acc'))))))
144-
#{} jdk-versions))
126+
(mapcat
127+
(fn [jdk-version]
128+
(let [jdk-base-images (get-or-default base-images jdk-version)]
129+
(mapcat #(combo/cartesian-product #{%}
130+
#{jdk-version}
131+
(get-or-default distros %)
132+
build-tools)
133+
jdk-base-images)))
134+
jdk-versions))
145135

146136
(defn image-variants
147137
[base-images jdk-versions distros build-tools]
148-
(into #{}
138+
(into []
149139
(comp
150140
(map variant-map)
151141
(remove #(= ::s/invalid (s/conform ::variant %))))
152-
(conj
153-
(image-variant-combinations base-images jdk-versions distros
154-
build-tools)
155-
latest-variant)))
142+
(image-variant-combinations base-images jdk-versions distros
143+
build-tools)))
156144

157145
(defn rand-delay
158146
"Runs argument f w/ any supplied args after a random delay of 100-1000 ms"
@@ -162,26 +150,25 @@
162150
(apply f args)))
163151

164152
(defn build-images
165-
[parallelization installer-hashes variants]
153+
[parallelization variants]
166154
(log "Building images" parallelization "at a time")
167155
(let [variants-ch (to-chan! variants)
168156
builds-ch (chan parallelization)]
169157
;; Kick off builds with a random delay so we don't have Docker race
170158
;; conditions (e.g. build container name collisions)
171159
(async/thread (pipeline-blocking parallelization builds-ch
172-
(map (partial rand-delay build-image
173-
installer-hashes))
160+
(map (partial rand-delay build-image))
174161
variants-ch))
175162
(while (<!! builds-ch))))
176163

177-
(defn generate-dockerfiles! [installer-hashes variants]
164+
(defn generate-dockerfiles! [variants]
178165
(doseq [variant variants]
179-
(generate-dockerfile! installer-hashes variant)))
166+
(generate-dockerfile! variant)))
180167

181168
(defn valid-variants []
182169
(remove (partial exclude? cfg/exclusions)
183170
(image-variants cfg/base-images cfg/jdk-versions cfg/distros
184-
cfg/build-tools)))
171+
cfg/*build-tools*)))
185172

186173
(defn generate-manifest! [variants args]
187174
(let [git-head (->> ["git" "rev-parse" "HEAD"] (apply sh) :out)
@@ -238,9 +225,9 @@
238225
(log "Generated" (count variants) "variants")
239226
(case cmd
240227
:clean (df/clean-all)
241-
:dockerfiles (generate-dockerfiles! cfg/installer-hashes variants)
228+
:dockerfiles (generate-dockerfiles! variants)
242229
:manifest (-> variants sort-variants (generate-manifest! args))
243-
:build-images (build-images parallelization cfg/installer-hashes variants)))
230+
:build-images (build-images parallelization variants)))
244231
(logger/stop))
245232

246233
(defn -main

src/docker_clojure/dockerfile.clj

Lines changed: 27 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,17 @@
11
(ns docker-clojure.dockerfile
22
(:require
3+
[clojure.java.io :as io]
34
[clojure.java.shell :refer [sh]]
45
[clojure.string :as str]
5-
[docker-clojure.dockerfile.lein :as lein]
6-
[docker-clojure.dockerfile.tools-deps :as tools-deps]
6+
[docker-clojure.dockerfile.combined :as combined]
77
[docker-clojure.dockerfile.shared :refer [copy-resource-file! entrypoint]]))
88

99
(defn build-dir [{:keys [base-image-tag jdk-version build-tool]}]
10-
(str/join "/" ["target"
11-
(str (str/replace base-image-tag ":" "-")
12-
(when-not (str/includes? base-image-tag (str jdk-version))
13-
(str "-" jdk-version)))
14-
(if (= :docker-clojure.core/all build-tool)
15-
"latest"
16-
build-tool)]))
17-
18-
(defn all-prereqs [dir variant]
19-
(tools-deps/prereqs dir variant))
20-
21-
(defn all-contents [installer-hashes variant]
22-
(concat
23-
["" "### INSTALL LEIN ###"]
24-
(lein/install
25-
installer-hashes
26-
(assoc variant :build-tool-version
27-
(get-in variant [:build-tool-versions "lein"])))
28-
["" "### INSTALL TOOLS-DEPS ###"]
29-
(tools-deps/install
30-
installer-hashes
31-
(assoc variant :build-tool-version
32-
(get-in variant [:build-tool-versions "tools-deps"])))
33-
[""]
34-
(entrypoint variant)
35-
["" "CMD [\"-M\", \"--repl\"]"]))
10+
(io/file "target"
11+
(str (str/replace base-image-tag ":" "-")
12+
(when-not (str/includes? base-image-tag (str jdk-version))
13+
(str "-" jdk-version)))
14+
(name build-tool)))
3615

3716
(defn copy-java-from-temurin-contents
3817
[{:keys [jdk-version] :as _variant}]
@@ -41,43 +20,30 @@
4120
"ENV PATH=\"${JAVA_HOME}/bin:${PATH}\""
4221
""])
4322

44-
(defn contents [installer-hashes {:keys [build-tool distro] :as variant}]
45-
(str/join "\n"
46-
(concat [(format "FROM %s" (:base-image-tag variant))
47-
""]
48-
(case (-> distro namespace keyword)
49-
(:debian :debian-slim) (copy-java-from-temurin-contents variant)
50-
[])
51-
(case build-tool
52-
:docker-clojure.core/all (all-contents installer-hashes variant)
53-
"lein" (lein/contents installer-hashes variant)
54-
"tools-deps" (tools-deps/contents installer-hashes variant)))))
23+
(defn contents [{:keys [distro base-image-tag] :as variant}]
24+
(->> (concat [(format "FROM %s" base-image-tag)
25+
""]
26+
(case (-> distro namespace keyword)
27+
(:debian :debian-slim) (copy-java-from-temurin-contents variant)
28+
[])
29+
(combined/contents variant))
30+
(str/join "\n")))
5531

56-
(defn shared-prereqs [dir {:keys [build-tool]}]
32+
(defn do-prereqs [dir {:keys [build-tool] :as variant}]
5733
(let [entrypoint (case build-tool
58-
"tools-deps" "clj"
59-
:docker-clojure.core/all "clj"
60-
build-tool)]
34+
:tools-deps "clj"
35+
:lein "lein")]
6136
(copy-resource-file! dir "entrypoint"
6237
#(str/replace % "@@entrypoint@@" entrypoint)
63-
#(.setExecutable % true false))))
64-
65-
(defn do-prereqs [dir {:keys [build-tool] :as variant}]
66-
(shared-prereqs dir variant)
67-
(case build-tool
68-
:docker-clojure.core/all (all-prereqs dir variant)
69-
"lein" (lein/prereqs dir variant)
70-
"tools-deps" (tools-deps/prereqs dir variant)))
71-
72-
(defn write-file [dir file installer-hashes variant]
73-
(let [{:keys [exit err]} (sh "mkdir" "-p" dir)]
74-
(if (zero? exit)
75-
(do
76-
(do-prereqs dir variant)
77-
(spit (str/join "/" [dir file])
78-
(str (contents installer-hashes variant) "\n")))
79-
(throw (ex-info (str "Error creating directory " dir)
80-
{:error err})))))
38+
#(.setExecutable % true false)))
39+
(copy-resource-file! dir "rlwrap.retry" identity
40+
#(.setExecutable % true false)))
41+
42+
(defn write-file [^java.io.File dir file variant]
43+
(.mkdirs dir)
44+
(do-prereqs dir variant)
45+
(spit (io/file dir file)
46+
(str (contents variant) "\n")))
8147

8248
(defn clean-all []
8349
(sh "sh" "-c" "rm -rf target/*"))
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
(ns docker-clojure.dockerfile.combined
2+
(:require
3+
[docker-clojure.dockerfile.lein :as lein]
4+
[docker-clojure.dockerfile.shared :as shared]
5+
[docker-clojure.dockerfile.tools-deps :as tools-deps]))
6+
7+
(def distro-deps
8+
{:debian-slim {:build #{"curl" "gnupg"}
9+
:runtime #{"rlwrap" "make" "git"}}
10+
:debian {:build #{"curl" "gnupg"}
11+
:runtime #{"rlwrap" "make" "git"}}
12+
:ubuntu {:build #{"gnupg"}
13+
;; install curl as a runtime dep b/c we need it at build time
14+
;; but upstream includes it so we don't want to uninstall it
15+
:runtime #{"rlwrap" "make" "git" "curl"}}
16+
:alpine {:build #{"curl" "tar" "gnupg" "openssl" "ca-certificates"}
17+
:runtime #{"bash" "make" "git"}}})
18+
19+
(defn install [variant]
20+
(concat
21+
(lein/env-preamble)
22+
(tools-deps/env-preamble)
23+
[""
24+
"WORKDIR /tmp"
25+
""]
26+
(shared/multiline-RUN
27+
(concat (shared/install-distro-deps distro-deps variant)
28+
(lein/installation-commands)
29+
(tools-deps/installation-commands)
30+
(shared/uninstall-distro-build-deps distro-deps variant)))
31+
[""]
32+
(lein/installation-postamble)
33+
(tools-deps/installation-postamble)))
34+
35+
(defn contents [{:keys [build-tool] :as variant}]
36+
(concat (install variant)
37+
[""]
38+
(shared/entrypoint variant)
39+
(case build-tool
40+
:lein (lein/command variant)
41+
:tools-deps (tools-deps/command variant))))
42+
43+
#_(contents {:build-tool :lein, :build-tool-version "2.11.2", :jdk-version 17})

0 commit comments

Comments
 (0)