From 5754d433aa421c68b7558da92a852df69ab66e9d Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Wed, 7 Sep 2022 11:47:38 -0600 Subject: [PATCH] Allow env vars OS_NAME & OS_ARCH to override os props (#53) --- README.md | 12 ++++++++++- src/babashka/pods/impl.clj | 11 +++++++--- src/babashka/pods/impl/resolver.clj | 33 +++++++++++++++++++---------- src/babashka/pods/sci.clj | 3 ++- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 447b12e..4ecb804 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,17 @@ On the JVM: ### Where does the pod come from? -When calling `load-pod` with a string or vector of strings, the pod is looked up on the local file system (either using the PATH, or using an absolute path). When it is called with a qualified symbol and a version - like `(load-pod 'org.babashka/aws "0.0.5")` then it will be looked up in and downloaded from the [pod-registry](https://github.com/babashka/pod-registry). +When calling `load-pod` with a string or vector of strings (or declaring it in your `bb.edn`), +the pod is looked up on the local file system (either using the PATH, or using an absolute path). +When it is called with a qualified symbol and a version - like `(load-pod 'org.babashka/aws "0.0.5")` +then it will be looked up in and downloaded from the [pod-registry](https://github.com/babashka/pod-registry). + +By default babashka will search for a pod binary matching your system's OS and arch. If you want to download +pods for a different OS / arch (e.g. for deployment to servers), you can set one or both of the following +environment variables: + +- `BABASHKA_PODS_OS_NAME=Linux` (or `Mac OS X` or any other value returned by Java's `os.name` property) +- `BABASHKA_PODS_OS_ARCH=aarch64` (or `amd64` or any other value returned by Java's `os.arch` property) ### In a babashka project diff --git a/src/babashka/pods/impl.clj b/src/babashka/pods/impl.clj index c01ab24..52146b8 100644 --- a/src/babashka/pods/impl.clj +++ b/src/babashka/pods/impl.clj @@ -383,14 +383,19 @@ (read-readers describe-reply resolve-fn))] {:format format, :ops ops, :readers readers})) -(defn load-pod-metadata [pod-spec opts] - (let [{:keys [:pod-spec :opts]} (resolve-pod pod-spec opts) - running-pod (run-pod pod-spec opts) +(defn run-pod-for-metadata [pod-spec opts] + (let [running-pod (run-pod pod-spec opts) describe-reply (describe-pod running-pod) ops (describe->ops describe-reply)] (destroy* (assoc running-pod :ops ops)) describe-reply)) +(defn load-pod-metadata [unresolved-pod-spec {:keys [:download-only] :as opts}] + (let [{:keys [:pod-spec :opts]} (resolve-pod unresolved-pod-spec opts)] + (if download-only + (resolver/warn "Not running pod" unresolved-pod-spec "to pre-cache metadata because OS and/or arch are different than system") + (run-pod-for-metadata pod-spec opts)))) + (defn load-pod ([pod-spec] (load-pod pod-spec nil)) ([pod-spec opts] diff --git a/src/babashka/pods/impl/resolver.clj b/src/babashka/pods/impl/resolver.clj index 8432b43..61a170e 100644 --- a/src/babashka/pods/impl/resolver.clj +++ b/src/babashka/pods/impl/resolver.clj @@ -15,35 +15,42 @@ "x86_64" arch)) -(def os {:os/name (System/getProperty "os.name") - :os/arch (let [arch (System/getProperty "os.arch")] - (normalize-arch arch))}) +(defn normalize-os [os] + (-> os str/lower-case (str/replace #"\s+" "_"))) + +(def os + (delay + {:os/name (or (System/getenv "BABASHKA_PODS_OS_NAME") + (System/getProperty "os.name")) + :os/arch (let [arch (or (System/getenv "BABASHKA_PODS_OS_ARCH") + (System/getProperty "os.arch"))] + (normalize-arch arch))})) (defn warn [& strs] (binding [*out* *err*] (apply println strs))) (defn match-artifacts - ([package] (match-artifacts package (:os/arch os))) + ([package] (match-artifacts package (:os/arch @os))) ([package arch] (let [artifacts (:pod/artifacts package) res (filter (fn [{os-name :os/name os-arch :os/arch}] (let [os-arch (normalize-arch os-arch)] - (and (re-matches (re-pattern os-name) (:os/name os)) + (and (re-matches (re-pattern os-name) (:os/name @os)) (re-matches (re-pattern os-arch) arch)))) artifacts)] (if (empty? res) - (if (and (= "Mac OS X" (:os/name os)) - (= "aarch64" (:os/arch os))) + (if (and (= "Mac OS X" (:os/name @os)) + (= "aarch64" (:os/arch @os))) ;; Rosetta2 fallback on Apple M1 machines (match-artifacts package "x86_64") (throw (IllegalArgumentException. (format "No executable found for pod %s (%s) and OS %s/%s" (:pod/name package) (:pod/version package) - (:os/name os) - (:os/arch os))))) + (:os/name @os) + (:os/arch @os))))) res)))) (defn unzip [{:keys [^java.io.File zip-file @@ -148,7 +155,9 @@ (io/file base-file "repository" (str pod-name) - pod-version))) + pod-version + (normalize-os (:os/name @os)) + (:os/arch @os)))) (defn data-dir ^java.io.File @@ -156,7 +165,9 @@ pod-version :pod/version}] (io/file @pods-repo-dir (str pod-name) - pod-version)) + pod-version + (normalize-os (:os/name @os)) + (:os/arch @os))) (defn sha256 [file] (let [buf (byte-array 8192) diff --git a/src/babashka/pods/sci.clj b/src/babashka/pods/sci.clj index 240886d..986d2d4 100644 --- a/src/babashka/pods/sci.clj +++ b/src/babashka/pods/sci.clj @@ -43,7 +43,8 @@ (defn load-pod-metadata* [bb-edn-file pod-spec {:keys [:version :cache] :as opts}] (let [metadata (impl/load-pod-metadata pod-spec opts) - cache-file (when cache (metadata-cache-file bb-edn-file pod-spec opts))] + cache-file (when (and metadata cache) + (metadata-cache-file bb-edn-file pod-spec opts))] (when cache-file (io/make-parents cache-file) (when (fs/writable? (fs/parent cache-file))