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
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							312 lines
						
					
					
						
							9.1 KiB
						
					
					
				| #!/usr/bin/env sh | |
|  | |
| #DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx" | |
| 
 | |
| #DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem" | |
| #DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem" | |
| #DEPLOY_DOCKER_CONTAINER_CA_FILE="/path/to/ca.pem" | |
| #DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem" | |
| #DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload" | |
| 
 | |
| _DEPLOY_DOCKER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/deploy-to-docker-containers" | |
| 
 | |
| _DOCKER_HOST_DEFAULT="/var/run/docker.sock" | |
| 
 | |
| docker_deploy() { | |
|   _cdomain="$1" | |
|   _ckey="$2" | |
|   _ccert="$3" | |
|   _cca="$4" | |
|   _cfullchain="$5" | |
|   _cpfx="$6" | |
|   _debug _cdomain "$_cdomain" | |
|   _getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL | |
|   _debug2 DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL" | |
|   if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then | |
|     _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container." | |
|     _err "See: $_DEPLOY_DOCKER_WIKI" | |
|   fi | |
| 
 | |
|   _savedeployconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL" | |
| 
 | |
|   if [ "$DOCKER_HOST" ]; then | |
|     _saveaccountconf DOCKER_HOST "$DOCKER_HOST" | |
|   fi | |
| 
 | |
|   if _exists docker && docker version | grep -i docker >/dev/null; then | |
|     _info "Using docker command" | |
|     export _USE_DOCKER_COMMAND=1 | |
|   else | |
|     export _USE_DOCKER_COMMAND= | |
|   fi | |
| 
 | |
|   export _USE_UNIX_SOCKET= | |
|   if [ -z "$_USE_DOCKER_COMMAND" ]; then | |
|     export _USE_REST= | |
|     if [ "$DOCKER_HOST" ]; then | |
|       _debug "Try use docker host: $DOCKER_HOST" | |
|       export _USE_REST=1 | |
|     else | |
|       export _DOCKER_SOCK="$_DOCKER_HOST_DEFAULT" | |
|       _debug "Try use $_DOCKER_SOCK" | |
|       if [ ! -e "$_DOCKER_SOCK" ] || [ ! -w "$_DOCKER_SOCK" ]; then | |
|         _err "$_DOCKER_SOCK is not available" | |
|         return 1 | |
|       fi | |
|       export _USE_UNIX_SOCKET=1 | |
|       if ! _exists "curl"; then | |
|         _err "Please install curl first." | |
|         _err "We need curl to work." | |
|         return 1 | |
|       fi | |
|       if ! _check_curl_version; then | |
|         return 1 | |
|       fi | |
|     fi | |
|   fi | |
| 
 | |
|   _getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE | |
|   _debug2 DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then | |
|     _savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" | |
|   fi | |
| 
 | |
|   _getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE | |
|   _debug2 DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then | |
|     _savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" | |
|   fi | |
| 
 | |
|   _getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE | |
|   _debug2 DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then | |
|     _savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" | |
|   fi | |
| 
 | |
|   _getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE | |
|   _debug2 DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then | |
|     _savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" | |
|   fi | |
| 
 | |
|   _getdeployconf DEPLOY_DOCKER_CONTAINER_PFX_FILE | |
|   _debug2 DEPLOY_DOCKER_CONTAINER_PFX_FILE "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" ]; then | |
|     _savedeployconf DEPLOY_DOCKER_CONTAINER_PFX_FILE "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" | |
|   fi | |
| 
 | |
|   _getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD | |
|   _debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then | |
|     _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" "base64" | |
|   fi | |
| 
 | |
|   _cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")" | |
|   _info "Container id: $_cid" | |
|   if [ -z "$_cid" ]; then | |
|     _err "can not find container id" | |
|     return 1 | |
|   fi | |
| 
 | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then | |
|     if ! _docker_cp "$_cid" "$_ckey" "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"; then | |
|       return 1 | |
|     fi | |
|   fi | |
| 
 | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then | |
|     if ! _docker_cp "$_cid" "$_ccert" "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"; then | |
|       return 1 | |
|     fi | |
|   fi | |
| 
 | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then | |
|     if ! _docker_cp "$_cid" "$_cca" "$DEPLOY_DOCKER_CONTAINER_CA_FILE"; then | |
|       return 1 | |
|     fi | |
|   fi | |
| 
 | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then | |
|     if ! _docker_cp "$_cid" "$_cfullchain" "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"; then | |
|       return 1 | |
|     fi | |
|   fi | |
| 
 | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" ]; then | |
|     if ! _docker_cp "$_cid" "$_cpfx" "$DEPLOY_DOCKER_CONTAINER_PFX_FILE"; then | |
|       return 1 | |
|     fi | |
|   fi | |
| 
 | |
|   if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then | |
|     _info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" | |
|     if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then | |
|       return 1 | |
|     fi | |
|   fi | |
|   return 0 | |
| } | |
| 
 | |
| #label | |
| _get_id() { | |
|   _label="$1" | |
|   if [ "$_USE_DOCKER_COMMAND" ]; then | |
|     docker ps -f label="$_label" --format "{{.ID}}" | |
|   elif [ "$_USE_REST" ]; then | |
|     _err "Not implemented yet." | |
|     return 1 | |
|   elif [ "$_USE_UNIX_SOCKET" ]; then | |
|     _req="{\"label\":[\"$_label\"]}" | |
|     _debug2 _req "$_req" | |
|     _req="$(printf "%s" "$_req" | _url_encode)" | |
|     _debug2 _req "$_req" | |
|     listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")" | |
|     _debug2 "listjson" "$listjson" | |
|     echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4 | |
|   else | |
|     _err "Not implemented yet." | |
|     return 1 | |
|   fi | |
| } | |
| 
 | |
| #id  cmd | |
| _docker_exec() { | |
|   _eargs="$*" | |
|   _debug2 "_docker_exec $_eargs" | |
|   _dcid="$1" | |
|   shift | |
|   if [ "$_USE_DOCKER_COMMAND" ]; then | |
|     docker exec -i "$_dcid" sh -c "$*" | |
|   elif [ "$_USE_REST" ]; then | |
|     _err "Not implemented yet." | |
|     return 1 | |
|   elif [ "$_USE_UNIX_SOCKET" ]; then | |
|     _cmd="$*" | |
|     #_cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')" | |
|     _debug2 _cmd "$_cmd" | |
|     #create exec instance: | |
|     cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"sh\", \"-c\", \"$_cmd\"]}")" | |
|     _debug2 cjson "$cjson" | |
|     execid="$(echo "$cjson" | cut -d '"' -f 4)" | |
|     _debug execid "$execid" | |
|     ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")" | |
|     _debug2 ejson "$ejson" | |
|     if [ "$ejson" ]; then | |
|       _err "$ejson" | |
|       return 1 | |
|     fi | |
|   else | |
|     _err "Not implemented yet." | |
|     return 1 | |
|   fi | |
| } | |
| 
 | |
| #id from  to | |
| _docker_cp() { | |
|   _dcid="$1" | |
|   _from="$2" | |
|   _to="$3" | |
|   _info "Copying file from $_from to $_to" | |
|   _dir="$(dirname "$_to")" | |
|   _debug2 _dir "$_dir" | |
|   if ! _docker_exec "$_dcid" mkdir -p "$_dir"; then | |
|     _err "Can not create dir: $_dir" | |
|     return 1 | |
|   fi | |
|   if [ "$_USE_DOCKER_COMMAND" ]; then | |
|     if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then | |
|       _docker_exec "$_dcid" tee "$_to" <"$_from" | |
|     else | |
|       _docker_exec "$_dcid" tee "$_to" <"$_from" >/dev/null | |
|     fi | |
|     if [ "$?" = "0" ]; then | |
|       _info "Success" | |
|       return 0 | |
|     else | |
|       _info "Error" | |
|       return 1 | |
|     fi | |
|   elif [ "$_USE_REST" ]; then | |
|     _err "Not implemented yet." | |
|     return 1 | |
|   elif [ "$_USE_UNIX_SOCKET" ]; then | |
|     _frompath="$_from" | |
|     if _startswith "$_frompath" '/'; then | |
|       _frompath="$(echo "$_from" | cut -b 2-)" #remove the first '/' char | |
|     fi | |
|     _debug2 "_frompath" "$_frompath" | |
|     _toname="$(basename "$_to")" | |
|     _debug2 "_toname" "$_toname" | |
|     _debug2 "_from" "$_from" | |
|     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 | |
|       _err "copy error" | |
|       return 1 | |
|     fi | |
|     return 0 | |
|   else | |
|     _err "Not implemented yet." | |
|     return 1 | |
|   fi | |
| 
 | |
| } | |
| 
 | |
| #sock method  endpoint data content-type | |
| _curl_unix_sock() { | |
|   _socket="$1" | |
|   _method="$2" | |
|   _endpoint="$3" | |
|   _data="$4" | |
|   _ctype="$5" | |
|   if [ -z "$_ctype" ]; then | |
|     _ctype="Content-Type: application/json" | |
|   fi | |
|   _debug _data "$_data" | |
|   _debug2 "url" "http://localhost$_endpoint" | |
|   if [ "$_CURL_NO_HOST" ]; then | |
|     _cux_url="http:$_endpoint" | |
|   else | |
|     _cux_url="http://localhost$_endpoint" | |
|   fi | |
| 
 | |
|   if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then | |
|     curl -vvv --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url" | |
|   else | |
|     curl --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url" | |
|   fi | |
| 
 | |
| } | |
| 
 | |
| _check_curl_version() { | |
|   _cversion="$(curl -V | grep '^curl ' | cut -d ' ' -f 2)" | |
|   _debug2 "_cversion" "$_cversion" | |
| 
 | |
|   _major="$(_getfield "$_cversion" 1 '.')" | |
|   _debug2 "_major" "$_major" | |
| 
 | |
|   _minor="$(_getfield "$_cversion" 2 '.')" | |
|   _debug2 "_minor" "$_minor" | |
| 
 | |
|   if [ "$_major" -ge "8" ]; then | |
|     #ok | |
|     return 0 | |
|   fi | |
|   if [ "$_major" = "7" ]; then | |
|     if [ "$_minor" -lt "40" ]; then | |
|       _err "curl v$_cversion doesn't support unit socket" | |
|       _err "Please upgrade to curl 7.40 or later." | |
|       return 1 | |
|     fi | |
|     if [ "$_minor" -lt "50" ]; then | |
|       _debug "Use short host name" | |
|       export _CURL_NO_HOST=1 | |
|     else | |
|       export _CURL_NO_HOST= | |
|     fi | |
|     return 0 | |
|   else | |
|     _err "curl v$_cversion doesn't support unit socket" | |
|     _err "Please upgrade to curl 7.40 or later." | |
|     return 1 | |
|   fi | |
| 
 | |
| }
 |