|
3 | 3 | [spire.facts :as facts]
|
4 | 4 | [spire.remote :as remote]
|
5 | 5 | [spire.utils :as utils]
|
| 6 | + [spire.context :as context] |
6 | 7 | [spire.module.rm :as rm]
|
7 | 8 | [spire.module.upload :as upload]
|
8 |
| - [clojure.string :as string])) |
| 9 | + [clojure.string :as string] |
| 10 | + [clojure.java.io :as io])) |
9 | 11 |
|
10 | 12 | (def failed-result {:exit 1 :out "" :err "" :result :failed})
|
11 | 13 |
|
|
27 | 29 |
|
28 | 30 | #_ (make-exists-string ["privatekey" "public\"key"])
|
29 | 31 |
|
30 |
| -(utils/defmodule shell* [{:keys [env dir shell out opts cmd creates stdin] |
| 32 | +(defn process-streams |
| 33 | + "Stream the stdout and stderr to the output module" |
| 34 | + [{:keys [file form meta host-config channel out-stream err-stream]}] |
| 35 | + (loop [out-data "" |
| 36 | + err-data ""] |
| 37 | + (let [avail (.available ^java.io.InputStream out-stream)] |
| 38 | + (if (pos? avail) |
| 39 | + (let [out-array (byte-array avail) |
| 40 | + res (.read ^java.io.InputStream out-stream out-array 0 avail)] |
| 41 | + (when-not (= -1 res) |
| 42 | + (spire.output.core/print-streams |
| 43 | + (context/deref* spire.state/output-module) |
| 44 | + file form meta host-config (String. out-array) nil) |
| 45 | + (recur (str out-data (String. out-array)) |
| 46 | + err-data))) |
| 47 | + ;; maybe we are at end of stream. try and read |
| 48 | + (let [res (.read ^java.io.InputStream out-stream)] |
| 49 | + (if-not (= -1 res) |
| 50 | + (do |
| 51 | + (spire.output.core/print-streams |
| 52 | + (context/deref* spire.state/output-module) |
| 53 | + file form meta host-config (str (char res)) nil) |
| 54 | + (recur (str out-data (char res)) |
| 55 | + err-data)) |
| 56 | + {:result :ok |
| 57 | + :exit (.waitFor ^java.lang.Process channel) |
| 58 | + :out out-data |
| 59 | + :out-lines (string/split-lines out-data) |
| 60 | + :err err-data})))))) |
| 61 | + |
| 62 | +(utils/defmodule shell* [{:keys [env dir shell out opts cmd creates stdin stream-out stream-key] |
31 | 63 | :or {env {}
|
32 | 64 | dir "."
|
33 |
| - shell "bash"} |
| 65 | + shell "bash" |
| 66 | + stream-key {} |
| 67 | + } |
34 | 68 |
|
35 | 69 | :as opts}]
|
36 | 70 | [host-string session {:keys [exec-fn shell-fn stdin-fn] :as shell-context}]
|
|
59 | 93 | ;; process as stdin
|
60 | 94 | (try
|
61 | 95 | (let [out-arg out
|
62 |
| - {:keys [exit out err] :as result} |
| 96 | + {:keys [ |
| 97 | + ;; normal execution |
| 98 | + exit out err |
| 99 | + |
| 100 | + ;; stream reporting |
| 101 | + channel out-stream err-stream] :as result} |
63 | 102 | (exec-fn session
|
64 | 103 | ;; command
|
65 | 104 | (shell-fn
|
|
74 | 113 | script))
|
75 | 114 |
|
76 | 115 | ;; output format
|
77 |
| - (or out-arg "UTF-8") |
| 116 | + (if stream-out |
| 117 | + :stream |
| 118 | + (or out-arg "UTF-8")) |
78 | 119 |
|
79 | 120 | ;; options
|
80 | 121 | (into {:agent-forwarding agent-forwarding}
|
81 | 122 | (or opts {})))]
|
82 |
| - (if (= :stream out-arg) |
83 |
| - (assoc result :result :pending) |
84 |
| - (assoc result |
85 |
| - :out-lines (string/split-lines out) |
86 |
| - :result (cond |
87 |
| - (zero? exit) :ok |
88 |
| - (= 255 exit) :changed |
89 |
| - :else :failed)))) |
| 123 | + (if stream-out |
| 124 | + (process-streams {:file (:file stream-key) |
| 125 | + :form (:form stream-key) |
| 126 | + :meta (:meta stream-key) |
| 127 | + :host-config (:host-config stream-key) |
| 128 | + :channel channel |
| 129 | + :out-stream out-stream |
| 130 | + :err-stream err-stream}) |
| 131 | + (if (= :stream out-arg) |
| 132 | + (assoc result :result :pending) |
| 133 | + (assoc result |
| 134 | + :out-lines (string/split-lines out) |
| 135 | + :result (cond |
| 136 | + (zero? exit) :ok |
| 137 | + (= 255 exit) :changed |
| 138 | + :else :failed))))) |
90 | 139 | (finally
|
91 | 140 | (when stdin (rm/rm* remote-script-file)))
|
92 | 141 | ))))
|
|
121 | 170 | these files exist on the machine, the command will not be executed
|
122 | 171 | and the job result will be reported as `:ok`
|
123 | 172 | "
|
124 |
| - [& args] |
125 |
| - `(utils/wrap-report ~&form (shell* ~@args))) |
| 173 | + [args] |
| 174 | + `(utils/wrap-report ~&form (shell* (assoc ~args :stream-key |
| 175 | + {:file ~(utils/current-file) |
| 176 | + :form (quote ~&form) |
| 177 | + :meta ~(meta &form) |
| 178 | + :host-config ~(spire.state/get-host-config)})))) |
126 | 179 |
|
127 | 180 |
|
128 | 181 | (def documentation
|
|
0 commit comments