#!/usr/bin/env sh #DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx" #DOCKER_HOST=/var/run/docker.sock | tcp://localhost:8888 #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="http://xxxxxx" _DOCKER_HOST_DEFAULT="/var/run/docker.sock" docker_deploy() { _cdomain="$1" _ckey="$2" _ccert="$3" _cca="$4" _cfullchain="$5" 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 _savedomainconf 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 if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" fi if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" fi if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE" fi if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" fi if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then _savedomainconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" 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_RELOAD_CMD" ]; then 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" $@ elif [ "$_USE_REST" ]; then _err "Not implemented yet." return 1 elif [ "$_USE_UNIX_SOCKET" ]; then _cmd="$@" _cmd="$(printf "$_cmd" | sed 's/ /","/g')" _debug2 _cmd "$_cmd" #create exec instance: cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_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" 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")" _docker_exec "$_dcid" mkdir -p "$_dir" if [ "$_USE_DOCKER_COMMAND" ]; then cat "$_from" | _docker_exec "$_dcid" tee "$_to" >/dev/null 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" if ! tar --transform="s,$_frompath,$_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$_minor" -lt "740" ]; then _err "curl v$_cversion doesn't support unit socket" return 1 fi if [ "$_major$_minor" -lt "750" ]; then _debug "Use short host name" export _CURL_NO_HOST=1 else export _CURL_NO_HOST= fi return 0 }