如何将 gcloud 与 Babashka 一起使用
How to use gcloud with Babashka
我正在尝试使用 Babashka 替换我用来在 GCP Cloud Functions 上部署函数的几个 Bash 脚本。
下面的脚本可以运行,但我想知道是否有更好的方法来执行 gcloud
shell 命令:
#!/usr/bin/env bb
(require '[cheshire.core :as json]
'[clojure.java.shell :refer [sh]])
(let [package-json (json/parse-string (slurp "package.json") true)
name (:name package-json)
entry-point "entryPoint"
region "europe-west3"
memory "128MB"
runtime "nodejs14"
source "dist"
service-account "sa-function-invoker@prj-kitchen-sink.iam.gserviceaccount.com"
timeout "10s"]
(println "deploy function" name "with entry point" entry-point "to GCP Cloud Functions." "Attach service account" service-account)
(let [output (sh "gcloud" "functions" "deploy" name "--region" region "--entry-point" entry-point "--memory" memory "--runtime" runtime "--service-account" service-account "--source" source "--trigger-http" "--timeout" timeout)]
(if (= "" (:err output))
(println (:out output))
(println (:err output)))))
作为比较,我使用的 Bash 脚本更易于阅读:
#!/bin/bash
set -euo pipefail
FUNCTION_NAME=$(cat package.json | jq '{name}' | jq '.name' | sed 's/"//g')
FUNCTION_ENTRY_POINT=entryPoint
ATTACHED_SA=sa-function-invoker@prj-kitchen-sink.iam.gserviceaccount.com
MEMORY=128MB
echo "deploy function `${FUNCTION_NAME}` with entry point `${FUNCTION_ENTRY_POINT}` to GCP Cloud Functions. Attach service account `${ATTACHED_SA}`"
gcloud functions deploy ${FUNCTION_NAME} \
--project ${GCP_PROJECT_ID} \
--region ${GCP_REGION} \
--memory ${MEMORY} \
--runtime nodejs14 \
--service-account ${ATTACHED_SA} \
--source dist \
--entry-point ${FUNCTION_ENTRY_POINT} \
--timeout 10s
我想我的问题不是针对 Babashka 或 gcloud,而是关于如何使用 clojure.java.shell 构造命令的一般问题...
如果你想执行 shell 命令并看到直接输出,我建议使用 babashka.process/process
或 babashka.tasks/shell
:
@(babashka.process/process ["ls" "-la"] {:out :inherit :err :inherit})
@(babashka.process/process ["ls" "-la"] {:inherit true})
(babashka.tasks/shell "ls -la")
上述调用几乎相同,但 shell
还应用了 babashka.process/check
,如果退出代码非零则抛出。调用前的 @
符号与调用 deref
相同,意思是:等待进程完成。如果您不在前面添加,那么该过程将异步 运行。
更多信息:
展示了我用来简化调用 shell 的一个技巧
(shell-cmd cmd-str)
Runs a command string in the default OS shell (/bin/bash); returns result in a Clojure map. Example:
(shell-cmd "ls -ldF *")
;=> {:exit 0 ; unix exit status (0 -> normal)
:err '' ; text from any errors
:out '...' ; text output as would printed to console
}
它允许您编写单个命令字符串,而不必手动标记字符串的所有部分。实现非常简单:
(def ^:dynamic *os-shell* "/bin/bash") ; could also use /bin/zsh, etc
(defn shell-cmd
[cmd-str]
(let [result (shell/sh *os-shell* "-c" cmd-str)]
(if (= 0 (grab :exit result))
result
(throw (ex-info "shell-cmd: clojure.java.shell/sh failed, cmd-str:" (vals->map cmd-str result))))))
因此它允许您将命令字符串直接发送到 /bin/bash
并允许它正常解析参数。
几年前,我广泛使用它通过 AWS CLI 控制 AWS RDS 主机(创建、快照、选择、删除),它非常易于使用。
我正在尝试使用 Babashka 替换我用来在 GCP Cloud Functions 上部署函数的几个 Bash 脚本。
下面的脚本可以运行,但我想知道是否有更好的方法来执行 gcloud
shell 命令:
#!/usr/bin/env bb
(require '[cheshire.core :as json]
'[clojure.java.shell :refer [sh]])
(let [package-json (json/parse-string (slurp "package.json") true)
name (:name package-json)
entry-point "entryPoint"
region "europe-west3"
memory "128MB"
runtime "nodejs14"
source "dist"
service-account "sa-function-invoker@prj-kitchen-sink.iam.gserviceaccount.com"
timeout "10s"]
(println "deploy function" name "with entry point" entry-point "to GCP Cloud Functions." "Attach service account" service-account)
(let [output (sh "gcloud" "functions" "deploy" name "--region" region "--entry-point" entry-point "--memory" memory "--runtime" runtime "--service-account" service-account "--source" source "--trigger-http" "--timeout" timeout)]
(if (= "" (:err output))
(println (:out output))
(println (:err output)))))
作为比较,我使用的 Bash 脚本更易于阅读:
#!/bin/bash
set -euo pipefail
FUNCTION_NAME=$(cat package.json | jq '{name}' | jq '.name' | sed 's/"//g')
FUNCTION_ENTRY_POINT=entryPoint
ATTACHED_SA=sa-function-invoker@prj-kitchen-sink.iam.gserviceaccount.com
MEMORY=128MB
echo "deploy function `${FUNCTION_NAME}` with entry point `${FUNCTION_ENTRY_POINT}` to GCP Cloud Functions. Attach service account `${ATTACHED_SA}`"
gcloud functions deploy ${FUNCTION_NAME} \
--project ${GCP_PROJECT_ID} \
--region ${GCP_REGION} \
--memory ${MEMORY} \
--runtime nodejs14 \
--service-account ${ATTACHED_SA} \
--source dist \
--entry-point ${FUNCTION_ENTRY_POINT} \
--timeout 10s
我想我的问题不是针对 Babashka 或 gcloud,而是关于如何使用 clojure.java.shell 构造命令的一般问题...
如果你想执行 shell 命令并看到直接输出,我建议使用 babashka.process/process
或 babashka.tasks/shell
:
@(babashka.process/process ["ls" "-la"] {:out :inherit :err :inherit})
@(babashka.process/process ["ls" "-la"] {:inherit true})
(babashka.tasks/shell "ls -la")
上述调用几乎相同,但 shell
还应用了 babashka.process/check
,如果退出代码非零则抛出。调用前的 @
符号与调用 deref
相同,意思是:等待进程完成。如果您不在前面添加,那么该过程将异步 运行。
更多信息:
(shell-cmd cmd-str)
Runs a command string in the default OS shell (/bin/bash); returns result in a Clojure map. Example:
(shell-cmd "ls -ldF *")
;=> {:exit 0 ; unix exit status (0 -> normal)
:err '' ; text from any errors
:out '...' ; text output as would printed to console
}
它允许您编写单个命令字符串,而不必手动标记字符串的所有部分。实现非常简单:
(def ^:dynamic *os-shell* "/bin/bash") ; could also use /bin/zsh, etc
(defn shell-cmd
[cmd-str]
(let [result (shell/sh *os-shell* "-c" cmd-str)]
(if (= 0 (grab :exit result))
result
(throw (ex-info "shell-cmd: clojure.java.shell/sh failed, cmd-str:" (vals->map cmd-str result))))))
因此它允许您将命令字符串直接发送到 /bin/bash
并允许它正常解析参数。
几年前,我广泛使用它通过 AWS CLI 控制 AWS RDS 主机(创建、快照、选择、删除),它非常易于使用。