summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLiam Crilly <liam.crilly@nginx.com>2023-10-16 10:32:19 +0100
committerLiam Crilly <liam.crilly@nginx.com>2023-10-16 10:32:19 +0100
commit43f140dfd318378f330ff019bb2a37c94d8f885c (patch)
tree9cf215c4e39802b9f7143c5552f142922d4374cd
parente78ada01402a1d2e658d752cbdcc8f2602ef8826 (diff)
downloadunit-43f140dfd318378f330ff019bb2a37c94d8f885c.tar.gz
unit-43f140dfd318378f330ff019bb2a37c94d8f885c.tar.bz2
Tools: unitc Docker mode.
Introduces a new remote host scheme docker:// that specifies a local container ID. By default, the control socket is assumed to be in the default location, as per the Docker Official Images for Unit. If not, the path to the control socket can be appended to the container ID.
Diffstat (limited to '')
-rw-r--r--tools/README.md18
-rwxr-xr-xtools/unitc46
2 files changed, 43 insertions, 21 deletions
diff --git a/tools/README.md b/tools/README.md
index 0bb80985..883bc107 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -55,10 +55,9 @@ The error log is monitored; when changes occur, new log entries are shown.
|---------|-|
| `-l` \| `--nolog` | Do not monitor the error log after configuration changes.
-#### Examples
+#### Local Examples
```shell
unitc /config
-unitc /control/applications/my_app/restart
unitc /config < unitconf.json
echo '{"*:8080": {"pass": "routes"}}' | unitc /config/listeners
unitc /config/applications/my_app DELETE
@@ -68,10 +67,12 @@ unitc /certificates/bundle cert.pem key.pem
### Remote Configuration
For remote instances of NGINX Unit, the control socket on the remote host can
be set with the `$UNIT_CTRL` environment variable. The remote control socket
-can be accessed over TCP or SSH, depending on the type of control socket:
+can be accessed over TCP, SSH, or Docker containers on the host, depending on
+the type of control socket:
* `ssh://[user@]remote_host[:ssh_port]/path/to/control.socket`
* `http://remote_host:unit_control_port`
+ * `docker://container_ID[/path/to/control.socket]`
> **Note:** SSH is recommended for remote confguration. Consider the
> [security implications](https://unit.nginx.org/howto/security/#secure-socket-and-state)
@@ -81,8 +82,9 @@ can be accessed over TCP or SSH, depending on the type of control socket:
|---------|-|
| `ssh://…` | Specify the remote Unix control socket on the command line.
| `http://…`*URI* | For remote TCP control sockets, the URI may include the protocol, hostname, and port.
+| `docker://…` | Specify the local container ID/name. The default Unix control socket can be overridden.
-#### Examples
+#### Remote Examples
```shell
unitc http://192.168.0.1:8080/status
UNIT_CTRL=http://192.168.0.1:8080 unitc /status
@@ -93,4 +95,12 @@ cat catchall_route.json | unitc POST /config/routes
echo '{"match":{"uri":"/wp-admin/*"},"action":{"return":403}}' | unitc INSERT /config/routes
```
+#### Docker Examples
+```shell
+unitc docker://d43251184c54 /config
+echo '{"http": {"log_route": true}}' | unitc docker://d43251184c54 /settings
+unitc docker://f4f3d9e918e6/root/unit.sock /control/applications/my_app/restart
+UNIT_CTRL=docker://4d0431488982 unitc /status/requests/total
+```
+
---
diff --git a/tools/unitc b/tools/unitc
index e0e725ec..e671f384 100755
--- a/tools/unitc
+++ b/tools/unitc
@@ -12,7 +12,7 @@ NOLOG=0
QUIET=0
CONVERT=0
URI=""
-SSH_CMD=""
+RPC_CMD=""
METHOD=PUT
CONF_FILES=()
@@ -82,6 +82,9 @@ while [ $# -gt 0 ]; do
elif [ "${1:0:6}" = "ssh://" ]; then
UNIT_CTRL=$1
shift
+ elif [ "${1:0:9}" = "docker://" ]; then
+ UNIT_CTRL=$1
+ shift
else
echo "${0##*/}: ERROR: Invalid option ($1)"
exit 1
@@ -115,9 +118,10 @@ Local options
Remote options
ssh://[user@]remote_host[:port]/path/to/control.socket # Remote Unix socket
http://remote_host:port/URI # Remote TCP socket
+ docker://container_ID[/non-default/control.socket] # Container on host
- A remote Unit control socket may also be defined with the \$UNIT_CTRL
- environment variable as http://remote_host:port -OR- ssh://… (as above)
+ A remote Unit instance may also be defined with the \$UNIT_CTRL environment
+ variable as http://remote_host:port or ssh://… or docker://… (as above).
__EOF__
exit 1
@@ -133,8 +137,16 @@ if [ "$UNIT_CTRL" = "" ]; then
fi
elif [ "${UNIT_CTRL:0:6}" = "ssh://" ]; then
REMOTE=1
- SSH_CMD="ssh $(echo $UNIT_CTRL | cut -f1-3 -d/)"
+ RPC_CMD="ssh $(echo $UNIT_CTRL | cut -f1-3 -d/)"
UNIT_CTRL="--unix-socket /$(echo $UNIT_CTRL | cut -f4- -d/) _"
+elif [ "${UNIT_CTRL:0:9}" = "docker://" ]; then
+ RPC_CMD="docker exec -i $(echo $UNIT_CTRL | cut -f3 -d/)"
+ DOCKSOCK=/$(echo "$UNIT_CTRL" | cut -f4- -d/)
+ if [ "$DOCKSOCK" = "/" ]; then
+ DOCKSOCK="/var/run/control.unit.sock" # Use default location if no path
+ fi
+ UNIT_CTRL="--unix-socket $DOCKSOCK _"
+ REMOTE=1
elif [ "${URI:0:1}" = "/" ]; then
REMOTE=1
fi
@@ -241,11 +253,11 @@ fi
#
if [ -t 0 ] && [ ${#CONF_FILES[@]} -eq 0 ]; then
if [ "$METHOD" = "DELETE" ]; then
- $SSH_CMD curl -X $METHOD $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ $RPC_CMD curl -X $METHOD $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
elif [ "$METHOD" = "EDIT" ]; then
EDITOR=$(test "$EDITOR" && printf '%s' "$EDITOR" || command -v editor || command -v vim || echo vi)
EDIT_FILENAME=/tmp/${0##*/}.$$${URI//\//_}
- $SSH_CMD curl -fsS $UNIT_CTRL$URI > $EDIT_FILENAME || exit 2
+ $RPC_CMD curl -fsS $UNIT_CTRL$URI > $EDIT_FILENAME || exit 2
if [ "${URI:0:12}" = "/js_modules/" ]; then
if ! hash jq 2> /dev/null; then
echo "${0##*/}: ERROR: jq(1) is required to edit JavaScript modules; install at <https://stedolan.github.io/jq/>"
@@ -255,23 +267,23 @@ if [ -t 0 ] && [ ${#CONF_FILES[@]} -eq 0 ]; then
EDIT_FILE=$EDIT_FILENAME.js
$EDITOR $EDIT_FILENAME.js || exit 2
# Remove the references, delete old config, push new config+reference
- $SSH_CMD curl -fsS $UNIT_CTRL/config/settings/js_module > /tmp/${0##*/}.$$_js_module && \
- $SSH_CMD curl -X DELETE $UNIT_CTRL/config/settings/js_module && \
- $SSH_CMD curl -fsSX DELETE $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
- printf "%s" "$(< $EDIT_FILENAME.js)" | $SSH_CMD curl -fX PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
- $SSH_CMD curl -X PUT --data-binary @/tmp/${0##*/}.$$_js_module $UNIT_CTRL/config/settings/js_module 2> /tmp/${0##*/}.$$
+ $RPC_CMD curl -fsS $UNIT_CTRL/config/settings/js_module > /tmp/${0##*/}.$$_js_module && \
+ $RPC_CMD curl -X DELETE $UNIT_CTRL/config/settings/js_module && \
+ $RPC_CMD curl -fsSX DELETE $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
+ printf "%s" "$(< $EDIT_FILENAME.js)" | $RPC_CMD curl -fX PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
+ $RPC_CMD curl -X PUT --data-binary @/tmp/${0##*/}.$$_js_module $UNIT_CTRL/config/settings/js_module 2> /tmp/${0##*/}.$$
elif [ $CONVERT -eq 1 ]; then
$CONVERT_FROM_JSON < $EDIT_FILENAME > $EDIT_FILENAME.yaml
$EDITOR $EDIT_FILENAME.yaml || exit 2
- $CONVERT_TO_JSON < $EDIT_FILENAME.yaml | $SSH_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ $CONVERT_TO_JSON < $EDIT_FILENAME.yaml | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
else
tr -d '\r' < $EDIT_FILENAME > $EDIT_FILENAME.json # Remove carriage-return from newlines
$EDITOR $EDIT_FILENAME.json || exit 2
- $SSH_CMD curl -X PUT --data-binary @$EDIT_FILENAME.json $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ $RPC_CMD curl -X PUT --data-binary @$EDIT_FILENAME.json $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
fi
else
SHOW_LOG=$(echo $URI | grep -c ^/control/)
- $SSH_CMD curl $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ $RPC_CMD curl $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
fi
else
if [ "$METHOD" = "INSERT" ]; then
@@ -281,9 +293,9 @@ else
fi
NEW_ELEMENT=$(cat ${CONF_FILES[@]})
echo $NEW_ELEMENT | jq > /dev/null || exit $? # Test the input is valid JSON before proceeding
- OLD_ARRAY=$($SSH_CMD curl -s $UNIT_CTRL$URI)
+ OLD_ARRAY=$($RPC_CMD curl -s $UNIT_CTRL$URI)
if [ "$(echo $OLD_ARRAY | jq -r type)" = "array" ]; then
- echo $OLD_ARRAY | jq ". |= [$NEW_ELEMENT] + ." | $SSH_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ echo $OLD_ARRAY | jq ". |= [$NEW_ELEMENT] + ." | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
else
echo "${0##*/}: ERROR: the INSERT method expects an array"
exit 3
@@ -293,7 +305,7 @@ else
cat ${CONF_FILES[@]} | $CONVERT_TO_JSON > /tmp/${0##*/}.$$_json
CONF_FILES=(/tmp/${0##*/}.$$_json)
fi
- cat ${CONF_FILES[@]} | $SSH_CMD curl -X $METHOD --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ cat ${CONF_FILES[@]} | $RPC_CMD curl -X $METHOD --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
fi
fi