You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

312 lines
9.1 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
2 years ago
  1. #!/usr/bin/env sh
  2. #DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx"
  3. #DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem"
  4. #DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem"
  5. #DEPLOY_DOCKER_CONTAINER_CA_FILE="/path/to/ca.pem"
  6. #DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem"
  7. #DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload"
  8. _DEPLOY_DOCKER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/deploy-to-docker-containers"
  9. _DOCKER_HOST_DEFAULT="/var/run/docker.sock"
  10. docker_deploy() {
  11. _cdomain="$1"
  12. _ckey="$2"
  13. _ccert="$3"
  14. _cca="$4"
  15. _cfullchain="$5"
  16. _cpfx="$6"
  17. _debug _cdomain "$_cdomain"
  18. _getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL
  19. _debug2 DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
  20. if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
  21. _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
  22. _err "See: $_DEPLOY_DOCKER_WIKI"
  23. fi
  24. _savedeployconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
  25. if [ "$DOCKER_HOST" ]; then
  26. _saveaccountconf DOCKER_HOST "$DOCKER_HOST"
  27. fi
  28. if _exists docker && docker version | grep -i docker >/dev/null; then
  29. _info "Using docker command"
  30. export _USE_DOCKER_COMMAND=1
  31. else
  32. export _USE_DOCKER_COMMAND=
  33. fi
  34. export _USE_UNIX_SOCKET=
  35. if [ -z "$_USE_DOCKER_COMMAND" ]; then
  36. export _USE_REST=
  37. if [ "$DOCKER_HOST" ]; then
  38. _debug "Try use docker host: $DOCKER_HOST"
  39. export _USE_REST=1
  40. else
  41. export _DOCKER_SOCK="$_DOCKER_HOST_DEFAULT"
  42. _debug "Try use $_DOCKER_SOCK"
  43. if [ ! -e "$_DOCKER_SOCK" ] || [ ! -w "$_DOCKER_SOCK" ]; then
  44. _err "$_DOCKER_SOCK is not available"
  45. return 1
  46. fi
  47. export _USE_UNIX_SOCKET=1
  48. if ! _exists "curl"; then
  49. _err "Please install curl first."
  50. _err "We need curl to work."
  51. return 1
  52. fi
  53. if ! _check_curl_version; then
  54. return 1
  55. fi
  56. fi
  57. fi
  58. _getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE
  59. _debug2 DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
  60. if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
  61. _savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
  62. fi
  63. _getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE
  64. _debug2 DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
  65. if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
  66. _savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
  67. fi
  68. _getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE
  69. _debug2 DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
  70. if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
  71. _savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
  72. fi
  73. _getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE
  74. _debug2 DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
  75. if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
  76. _savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
  77. fi
  78. _getdeployconf DEPLOY_DOCKER_CONTAINER_PFX_FILE
  79. _debug2 DEPLOY_DOCKER_CONTAINER_PFX_FILE "$DEPLOY_DOCKER_CONTAINER_PFX_FILE"
  80. if [ "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" ]; then
  81. _savedeployconf DEPLOY_DOCKER_CONTAINER_PFX_FILE "$DEPLOY_DOCKER_CONTAINER_PFX_FILE"
  82. fi
  83. _getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD
  84. _debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
  85. if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
  86. _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" "base64"
  87. fi
  88. _cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")"
  89. _info "Container id: $_cid"
  90. if [ -z "$_cid" ]; then
  91. _err "can not find container id"
  92. return 1
  93. fi
  94. if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
  95. if ! _docker_cp "$_cid" "$_ckey" "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"; then
  96. return 1
  97. fi
  98. fi
  99. if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
  100. if ! _docker_cp "$_cid" "$_ccert" "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"; then
  101. return 1
  102. fi
  103. fi
  104. if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
  105. if ! _docker_cp "$_cid" "$_cca" "$DEPLOY_DOCKER_CONTAINER_CA_FILE"; then
  106. return 1
  107. fi
  108. fi
  109. if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
  110. if ! _docker_cp "$_cid" "$_cfullchain" "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"; then
  111. return 1
  112. fi
  113. fi
  114. if [ "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" ]; then
  115. if ! _docker_cp "$_cid" "$_cpfx" "$DEPLOY_DOCKER_CONTAINER_PFX_FILE"; then
  116. return 1
  117. fi
  118. fi
  119. if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
  120. _info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
  121. if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then
  122. return 1
  123. fi
  124. fi
  125. return 0
  126. }
  127. #label
  128. _get_id() {
  129. _label="$1"
  130. if [ "$_USE_DOCKER_COMMAND" ]; then
  131. docker ps -f label="$_label" --format "{{.ID}}"
  132. elif [ "$_USE_REST" ]; then
  133. _err "Not implemented yet."
  134. return 1
  135. elif [ "$_USE_UNIX_SOCKET" ]; then
  136. _req="{\"label\":[\"$_label\"]}"
  137. _debug2 _req "$_req"
  138. _req="$(printf "%s" "$_req" | _url_encode)"
  139. _debug2 _req "$_req"
  140. listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")"
  141. _debug2 "listjson" "$listjson"
  142. echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4
  143. else
  144. _err "Not implemented yet."
  145. return 1
  146. fi
  147. }
  148. #id cmd
  149. _docker_exec() {
  150. _eargs="$*"
  151. _debug2 "_docker_exec $_eargs"
  152. _dcid="$1"
  153. shift
  154. if [ "$_USE_DOCKER_COMMAND" ]; then
  155. docker exec -i "$_dcid" sh -c "$*"
  156. elif [ "$_USE_REST" ]; then
  157. _err "Not implemented yet."
  158. return 1
  159. elif [ "$_USE_UNIX_SOCKET" ]; then
  160. _cmd="$*"
  161. #_cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')"
  162. _debug2 _cmd "$_cmd"
  163. #create exec instance:
  164. cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"sh\", \"-c\", \"$_cmd\"]}")"
  165. _debug2 cjson "$cjson"
  166. execid="$(echo "$cjson" | cut -d '"' -f 4)"
  167. _debug execid "$execid"
  168. ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")"
  169. _debug2 ejson "$ejson"
  170. if [ "$ejson" ]; then
  171. _err "$ejson"
  172. return 1
  173. fi
  174. else
  175. _err "Not implemented yet."
  176. return 1
  177. fi
  178. }
  179. #id from to
  180. _docker_cp() {
  181. _dcid="$1"
  182. _from="$2"
  183. _to="$3"
  184. _info "Copying file from $_from to $_to"
  185. _dir="$(dirname "$_to")"
  186. _debug2 _dir "$_dir"
  187. if ! _docker_exec "$_dcid" mkdir -p "$_dir"; then
  188. _err "Can not create dir: $_dir"
  189. return 1
  190. fi
  191. if [ "$_USE_DOCKER_COMMAND" ]; then
  192. if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
  193. _docker_exec "$_dcid" tee "$_to" <"$_from"
  194. else
  195. _docker_exec "$_dcid" tee "$_to" <"$_from" >/dev/null
  196. fi
  197. if [ "$?" = "0" ]; then
  198. _info "Success"
  199. return 0
  200. else
  201. _info "Error"
  202. return 1
  203. fi
  204. elif [ "$_USE_REST" ]; then
  205. _err "Not implemented yet."
  206. return 1
  207. elif [ "$_USE_UNIX_SOCKET" ]; then
  208. _frompath="$_from"
  209. if _startswith "$_frompath" '/'; then
  210. _frompath="$(echo "$_from" | cut -b 2-)" #remove the first '/' char
  211. fi
  212. _debug2 "_frompath" "$_frompath"
  213. _toname="$(basename "$_to")"
  214. _debug2 "_toname" "$_toname"
  215. _debug2 "_from" "$_from"
  216. if ! tar --transform="s,$(printf "%s" "$_frompath" | tr '*' .),$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then
  217. _err "copy error"
  218. return 1
  219. fi
  220. return 0
  221. else
  222. _err "Not implemented yet."
  223. return 1
  224. fi
  225. }
  226. #sock method endpoint data content-type
  227. _curl_unix_sock() {
  228. _socket="$1"
  229. _method="$2"
  230. _endpoint="$3"
  231. _data="$4"
  232. _ctype="$5"
  233. if [ -z "$_ctype" ]; then
  234. _ctype="Content-Type: application/json"
  235. fi
  236. _debug _data "$_data"
  237. _debug2 "url" "http://localhost$_endpoint"
  238. if [ "$_CURL_NO_HOST" ]; then
  239. _cux_url="http:$_endpoint"
  240. else
  241. _cux_url="http://localhost$_endpoint"
  242. fi
  243. if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
  244. curl -vvv --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
  245. else
  246. curl --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
  247. fi
  248. }
  249. _check_curl_version() {
  250. _cversion="$(curl -V | grep '^curl ' | cut -d ' ' -f 2)"
  251. _debug2 "_cversion" "$_cversion"
  252. _major="$(_getfield "$_cversion" 1 '.')"
  253. _debug2 "_major" "$_major"
  254. _minor="$(_getfield "$_cversion" 2 '.')"
  255. _debug2 "_minor" "$_minor"
  256. if [ "$_major" -ge "8" ]; then
  257. #ok
  258. return 0
  259. fi
  260. if [ "$_major" = "7" ]; then
  261. if [ "$_minor" -lt "40" ]; then
  262. _err "curl v$_cversion doesn't support unit socket"
  263. _err "Please upgrade to curl 7.40 or later."
  264. return 1
  265. fi
  266. if [ "$_minor" -lt "50" ]; then
  267. _debug "Use short host name"
  268. export _CURL_NO_HOST=1
  269. else
  270. export _CURL_NO_HOST=
  271. fi
  272. return 0
  273. else
  274. _err "curl v$_cversion doesn't support unit socket"
  275. _err "Please upgrade to curl 7.40 or later."
  276. return 1
  277. fi
  278. }