【问题标题】:How to use gcloud with Babashka如何在 Babashka 中使用 gcloud
【发布时间】:2021-10-04 15:43:36
【问题描述】:

我正在尝试使用 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 构造命令...

【问题讨论】:

    标签: clojure gcloud babashka


    【解决方案1】:

    如果你想执行shell命令并看到直接输出,我推荐使用babashka.process/processbabashka.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 相同,表示:等待进程完成。如果你不预先设置,那么进程将异步运行。

    更多信息:

    【讨论】:

    • 感谢deref 的回答和提示。在执行配置虚拟机或执行任何其他长时间运行操作的 gcloud 命令时,省略 @ 可能是个好主意。
    【解决方案2】:

    this helper function 展示了我用来简化对 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 发送命令字符串,并允许它正常解析args。

    几年前我广泛使用它来通过 AWS CLI 控制 AWS RDS 主机(创建、快照、选择、删除),它非常易于使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 2018-12-23
      • 2015-09-10
      相关资源
      最近更新 更多