Skip to content

Commit 43f140d

Browse files
committed
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.
1 parent e78ada0 commit 43f140d

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

tools/README.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@ The error log is monitored; when changes occur, new log entries are shown.
5555
|---------|-|
5656
| `-l` \| `--nolog` | Do not monitor the error log after configuration changes.
5757

58-
#### Examples
58+
#### Local Examples
5959
```shell
6060
unitc /config
61-
unitc /control/applications/my_app/restart
6261
unitc /config < unitconf.json
6362
echo '{"*:8080": {"pass": "routes"}}' | unitc /config/listeners
6463
unitc /config/applications/my_app DELETE
@@ -68,10 +67,12 @@ unitc /certificates/bundle cert.pem key.pem
6867
### Remote Configuration
6968
For remote instances of NGINX Unit, the control socket on the remote host can
7069
be set with the `$UNIT_CTRL` environment variable. The remote control socket
71-
can be accessed over TCP or SSH, depending on the type of control socket:
70+
can be accessed over TCP, SSH, or Docker containers on the host, depending on
71+
the type of control socket:
7272

7373
* `ssh://[user@]remote_host[:ssh_port]/path/to/control.socket`
7474
* `http://remote_host:unit_control_port`
75+
* `docker://container_ID[/path/to/control.socket]`
7576

7677
> **Note:** SSH is recommended for remote confguration. Consider the
7778
> [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:
8182
|---------|-|
8283
| `ssh://…` | Specify the remote Unix control socket on the command line.
8384
| `http://…`*URI* | For remote TCP control sockets, the URI may include the protocol, hostname, and port.
85+
| `docker://…` | Specify the local container ID/name. The default Unix control socket can be overridden.
8486

85-
#### Examples
87+
#### Remote Examples
8688
```shell
8789
unitc http://192.168.0.1:8080/status
8890
UNIT_CTRL=http://192.168.0.1:8080 unitc /status
@@ -93,4 +95,12 @@ cat catchall_route.json | unitc POST /config/routes
9395
echo '{"match":{"uri":"/wp-admin/*"},"action":{"return":403}}' | unitc INSERT /config/routes
9496
```
9597

98+
#### Docker Examples
99+
```shell
100+
unitc docker://d43251184c54 /config
101+
echo '{"http": {"log_route": true}}' | unitc docker://d43251184c54 /settings
102+
unitc docker://f4f3d9e918e6/root/unit.sock /control/applications/my_app/restart
103+
UNIT_CTRL=docker://4d0431488982 unitc /status/requests/total
104+
```
105+
96106
---

tools/unitc

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ NOLOG=0
1212
QUIET=0
1313
CONVERT=0
1414
URI=""
15-
SSH_CMD=""
15+
RPC_CMD=""
1616
METHOD=PUT
1717
CONF_FILES=()
1818

@@ -82,6 +82,9 @@ while [ $# -gt 0 ]; do
8282
elif [ "${1:0:6}" = "ssh://" ]; then
8383
UNIT_CTRL=$1
8484
shift
85+
elif [ "${1:0:9}" = "docker://" ]; then
86+
UNIT_CTRL=$1
87+
shift
8588
else
8689
echo "${0##*/}: ERROR: Invalid option ($1)"
8790
exit 1
@@ -115,9 +118,10 @@ Local options
115118
Remote options
116119
ssh://[user@]remote_host[:port]/path/to/control.socket # Remote Unix socket
117120
http://remote_host:port/URI # Remote TCP socket
121+
docker://container_ID[/non-default/control.socket] # Container on host
118122
119-
A remote Unit control socket may also be defined with the \$UNIT_CTRL
120-
environment variable as http://remote_host:port -OR- ssh://… (as above)
123+
A remote Unit instance may also be defined with the \$UNIT_CTRL environment
124+
variable as http://remote_host:port or ssh://… or docker://… (as above).
121125
122126
__EOF__
123127
exit 1
@@ -133,8 +137,16 @@ if [ "$UNIT_CTRL" = "" ]; then
133137
fi
134138
elif [ "${UNIT_CTRL:0:6}" = "ssh://" ]; then
135139
REMOTE=1
136-
SSH_CMD="ssh $(echo $UNIT_CTRL | cut -f1-3 -d/)"
140+
RPC_CMD="ssh $(echo $UNIT_CTRL | cut -f1-3 -d/)"
137141
UNIT_CTRL="--unix-socket /$(echo $UNIT_CTRL | cut -f4- -d/) _"
142+
elif [ "${UNIT_CTRL:0:9}" = "docker://" ]; then
143+
RPC_CMD="docker exec -i $(echo $UNIT_CTRL | cut -f3 -d/)"
144+
DOCKSOCK=/$(echo "$UNIT_CTRL" | cut -f4- -d/)
145+
if [ "$DOCKSOCK" = "/" ]; then
146+
DOCKSOCK="/var/run/control.unit.sock" # Use default location if no path
147+
fi
148+
UNIT_CTRL="--unix-socket $DOCKSOCK _"
149+
REMOTE=1
138150
elif [ "${URI:0:1}" = "/" ]; then
139151
REMOTE=1
140152
fi
@@ -241,11 +253,11 @@ fi
241253
#
242254
if [ -t 0 ] && [ ${#CONF_FILES[@]} -eq 0 ]; then
243255
if [ "$METHOD" = "DELETE" ]; then
244-
$SSH_CMD curl -X $METHOD $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
256+
$RPC_CMD curl -X $METHOD $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
245257
elif [ "$METHOD" = "EDIT" ]; then
246258
EDITOR=$(test "$EDITOR" && printf '%s' "$EDITOR" || command -v editor || command -v vim || echo vi)
247259
EDIT_FILENAME=/tmp/${0##*/}.$$${URI//\//_}
248-
$SSH_CMD curl -fsS $UNIT_CTRL$URI > $EDIT_FILENAME || exit 2
260+
$RPC_CMD curl -fsS $UNIT_CTRL$URI > $EDIT_FILENAME || exit 2
249261
if [ "${URI:0:12}" = "/js_modules/" ]; then
250262
if ! hash jq 2> /dev/null; then
251263
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
255267
EDIT_FILE=$EDIT_FILENAME.js
256268
$EDITOR $EDIT_FILENAME.js || exit 2
257269
# Remove the references, delete old config, push new config+reference
258-
$SSH_CMD curl -fsS $UNIT_CTRL/config/settings/js_module > /tmp/${0##*/}.$$_js_module && \
259-
$SSH_CMD curl -X DELETE $UNIT_CTRL/config/settings/js_module && \
260-
$SSH_CMD curl -fsSX DELETE $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
261-
printf "%s" "$(< $EDIT_FILENAME.js)" | $SSH_CMD curl -fX PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
262-
$SSH_CMD curl -X PUT --data-binary @/tmp/${0##*/}.$$_js_module $UNIT_CTRL/config/settings/js_module 2> /tmp/${0##*/}.$$
270+
$RPC_CMD curl -fsS $UNIT_CTRL/config/settings/js_module > /tmp/${0##*/}.$$_js_module && \
271+
$RPC_CMD curl -X DELETE $UNIT_CTRL/config/settings/js_module && \
272+
$RPC_CMD curl -fsSX DELETE $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
273+
printf "%s" "$(< $EDIT_FILENAME.js)" | $RPC_CMD curl -fX PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
274+
$RPC_CMD curl -X PUT --data-binary @/tmp/${0##*/}.$$_js_module $UNIT_CTRL/config/settings/js_module 2> /tmp/${0##*/}.$$
263275
elif [ $CONVERT -eq 1 ]; then
264276
$CONVERT_FROM_JSON < $EDIT_FILENAME > $EDIT_FILENAME.yaml
265277
$EDITOR $EDIT_FILENAME.yaml || exit 2
266-
$CONVERT_TO_JSON < $EDIT_FILENAME.yaml | $SSH_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
278+
$CONVERT_TO_JSON < $EDIT_FILENAME.yaml | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
267279
else
268280
tr -d '\r' < $EDIT_FILENAME > $EDIT_FILENAME.json # Remove carriage-return from newlines
269281
$EDITOR $EDIT_FILENAME.json || exit 2
270-
$SSH_CMD curl -X PUT --data-binary @$EDIT_FILENAME.json $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
282+
$RPC_CMD curl -X PUT --data-binary @$EDIT_FILENAME.json $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
271283
fi
272284
else
273285
SHOW_LOG=$(echo $URI | grep -c ^/control/)
274-
$SSH_CMD curl $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
286+
$RPC_CMD curl $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
275287
fi
276288
else
277289
if [ "$METHOD" = "INSERT" ]; then
@@ -281,9 +293,9 @@ else
281293
fi
282294
NEW_ELEMENT=$(cat ${CONF_FILES[@]})
283295
echo $NEW_ELEMENT | jq > /dev/null || exit $? # Test the input is valid JSON before proceeding
284-
OLD_ARRAY=$($SSH_CMD curl -s $UNIT_CTRL$URI)
296+
OLD_ARRAY=$($RPC_CMD curl -s $UNIT_CTRL$URI)
285297
if [ "$(echo $OLD_ARRAY | jq -r type)" = "array" ]; then
286-
echo $OLD_ARRAY | jq ". |= [$NEW_ELEMENT] + ." | $SSH_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
298+
echo $OLD_ARRAY | jq ". |= [$NEW_ELEMENT] + ." | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
287299
else
288300
echo "${0##*/}: ERROR: the INSERT method expects an array"
289301
exit 3
@@ -293,7 +305,7 @@ else
293305
cat ${CONF_FILES[@]} | $CONVERT_TO_JSON > /tmp/${0##*/}.$$_json
294306
CONF_FILES=(/tmp/${0##*/}.$$_json)
295307
fi
296-
cat ${CONF_FILES[@]} | $SSH_CMD curl -X $METHOD --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
308+
cat ${CONF_FILES[@]} | $RPC_CMD curl -X $METHOD --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
297309
fi
298310
fi
299311

0 commit comments

Comments
 (0)