1673 lines
39 KiB
Bash
Executable file
1673 lines
39 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
#####################################################################
|
|
#
|
|
# Copyright (C) NGINX, Inc.
|
|
# Author: NGINX Unit Team, F5 Inc.
|
|
# Copyright 2024, Alejandro Colomar <alx@kernel.org>
|
|
#
|
|
#####################################################################
|
|
|
|
|
|
if test -n ${BASH_VERSION} && test "${BASH_VERSINFO[0]}" -eq 3; then
|
|
>&2 cat <<__EOF__ ;
|
|
Your version of bash(1) isn't supported by this script. You're probably
|
|
running on macOS. We recommend that you either install a newer version
|
|
of bash(1) or run this script with another shell, such as zsh(1):
|
|
|
|
$ ${SUDO_USER:+sudo }zsh $0 ...
|
|
__EOF__
|
|
exit 1;
|
|
fi;
|
|
|
|
|
|
set -Eefuo pipefail;
|
|
|
|
test -v BASH_VERSION \
|
|
&& shopt -s lastpipe;
|
|
|
|
test -v ZSH_VERSION \
|
|
&& setopt sh_word_split;
|
|
|
|
|
|
export LC_ALL=C
|
|
|
|
dry_run='no';
|
|
|
|
help_unit()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 [-h[h]] COMMAND [ARGS]
|
|
|
|
Subcommands
|
|
├── repo-config [-hn] [PKG-MANAGER OS-NAME OS-VERSION]
|
|
└── welcome [-hn]
|
|
|
|
DESCRIPTION
|
|
This script simplifies installing and configuring an NGINX Unit server
|
|
for first-time users.
|
|
|
|
Run '$0 COMMAND -h' for more information on a command.
|
|
|
|
COMMANDS
|
|
repo-config
|
|
Configure your package manager with the NGINX Unit repository
|
|
for later installation.
|
|
|
|
welcome
|
|
Create an initial configuration to serve a welcome web page
|
|
with NGINX Unit.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-hh, --help-more
|
|
Print help for more (advanced) commands.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
help_more_unit()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 [-h[h]] COMMAND [ARGS]
|
|
|
|
Subcommands
|
|
├── cmd [-h]
|
|
├── ctl [-h] [-s SOCK] SUBCOMMAND [ARGS]
|
|
│ ├── edit [-h] PATH
|
|
│ ├── http [-h] [-c CURLOPT] METHOD PATH
|
|
│ └── insert [-h] PATH INDEX
|
|
├── freeport [-h]
|
|
├── json-ins [-hn] JSON INDEX
|
|
├── os-probe [-h]
|
|
├── ps [-h] [-t TYPE]
|
|
├── repo-config [-hn] [PKG-MANAGER OS-NAME OS-VERSION]
|
|
├── restart [-hls]
|
|
├── sock [-h] SUBCOMMAND [ARGS]
|
|
│ ├── filter [-chs]
|
|
│ └── find [-h]
|
|
└── welcome [-hn]
|
|
|
|
DESCRIPTION
|
|
This script simplifies installing and configuring
|
|
an NGINX Unit server for first-time users.
|
|
|
|
Run '$0 COMMAND -h' for more information on a command.
|
|
|
|
COMMANDS
|
|
cmd Print the invocation line of unitd(8).
|
|
|
|
ctl Control a running unitd(8) instance via its control API socket.
|
|
|
|
freeport
|
|
Print an available TCP port.
|
|
|
|
json-ins
|
|
Insert a JSON element read from standard input into a JSON
|
|
array read from a file at a given INDEX.
|
|
|
|
os-probe
|
|
Probe the OS and print details about its version.
|
|
|
|
ps List unitd(8) processes.
|
|
|
|
repo-config
|
|
Configure your package manager with the NGINX Unit
|
|
repository for later installation.
|
|
|
|
restart
|
|
Restart all running unitd(8) instances.
|
|
|
|
sock Print the control API socket address.
|
|
|
|
welcome
|
|
Create an initial configuration to serve a welcome web page
|
|
with NGINX Unit.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print basic help (some commands are hidden).
|
|
|
|
-hh, --help-more
|
|
Print the hidden help with more commands.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
info()
|
|
{
|
|
>&2 echo "$(basename "$0"): info: $*";
|
|
}
|
|
|
|
warn()
|
|
{
|
|
>&2 echo "$(basename "$0"): error: $*";
|
|
}
|
|
|
|
err()
|
|
{
|
|
>&2 echo "$(basename "$0"): error: $*";
|
|
exit 1;
|
|
}
|
|
|
|
dry_run_echo()
|
|
{
|
|
if test "$dry_run" = "yes"; then
|
|
echo "$*";
|
|
fi;
|
|
}
|
|
|
|
dry_run_eval()
|
|
{
|
|
if test "$dry_run" = "yes"; then
|
|
echo " $*";
|
|
else
|
|
eval "$*";
|
|
fi;
|
|
}
|
|
|
|
run_trap()
|
|
{
|
|
trap -p "$1" \
|
|
| tr -d '\n' \
|
|
| sed "s/[^']*'\(.*\)'[^']*/\1/" \
|
|
| sed "s/'\\\\''/'/g" \
|
|
| read -r trap_cmd;
|
|
|
|
eval $trap_cmd;
|
|
trap - "$1";
|
|
}
|
|
|
|
|
|
help_unit_cmd()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 cmd [-h]
|
|
|
|
DESCRIPTION
|
|
Print the invocation line of running unitd(8) instances.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_cmd()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_cmd;
|
|
exit 0;
|
|
;;
|
|
-*)
|
|
err "cmd: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "cmd: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
unit_ps -t m \
|
|
| sed 's/.*\[\(.*\)].*/\1/';
|
|
}
|
|
|
|
|
|
help_unit_ctl()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 ctl [-h] [-s SOCK] SUBCOMMAND [ARGS]
|
|
|
|
Subcommands
|
|
├── edit [-h] PATH
|
|
├── http [-h] [-c CURLOPT] METHOD PATH
|
|
└── insert [-h] PATH INDEX
|
|
|
|
DESCRIPTION
|
|
Control a running unitd(8) instance through its control API socket.
|
|
|
|
Run '$0 ctl SUBCOMMAND -h' for more information on a
|
|
subcommand.
|
|
|
|
SUBCOMMANDS
|
|
edit Edit the unitd(8) configuration with an editor.
|
|
|
|
http Send an HTTP request to the control API socket.
|
|
|
|
insert Insert an element at the specified index into an array in the
|
|
JSON configuration.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-s, --sock SOCK
|
|
Use SOCK as the control API socket address. If not specified,
|
|
the script tries to find it. This value is used by subcommands.
|
|
|
|
The socket can be a tcp(7) socket or a unix(7) socket; in
|
|
the case of a unix(7) socket, it can exist locally or on
|
|
a remote machine, accessed through ssh(1). Accepted syntax
|
|
for SOCK:
|
|
|
|
unix:/path/to/control.sock
|
|
ssh://[user@]host[:port]/path/to/control.sock
|
|
[http[s]://]host[:port]
|
|
|
|
The last form is less secure than the first two; have a look:
|
|
<https://unit.nginx.org/howto/security/#secure-socket-and-stat>
|
|
|
|
ENVIRONMENT
|
|
Options take precedence over their equivalent environment variables;
|
|
if both are specified, the command-line option is used.
|
|
|
|
UNIT_CTL_SOCK
|
|
Equivalent to the option -s (--sock).
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_ctl()
|
|
{
|
|
|
|
if test -v UNIT_CTL_SOCK; then
|
|
local sock="$UNIT_CTL_SOCK";
|
|
fi;
|
|
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_ctl;
|
|
exit 0;
|
|
;;
|
|
-s | --sock)
|
|
if ! test $# -ge 2; then
|
|
err "ctl: $1: Missing argument.";
|
|
fi;
|
|
local sock="$2";
|
|
shift;
|
|
;;
|
|
-*)
|
|
err "ctl: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if test ! $# -ge 1; then
|
|
err 'ctl: Missing subcommand.';
|
|
fi;
|
|
|
|
if ! test -v sock; then
|
|
local sock="$(unit_sock_find)";
|
|
fi;
|
|
|
|
if echo $sock | grep '^ssh://' >/dev/null; then
|
|
local remote="$(echo $sock | sed 's,\(ssh://[^/]*\).*,\1,')";
|
|
local sock="$(echo $sock | sed 's,ssh://[^/]*\(.*\),unix:\1,')";
|
|
|
|
local remote_sock="$(echo "$sock" | unit_sock_filter -s)";
|
|
local local_sock="$(mktemp -u -p /var/run/unit/)";
|
|
local ssh_ctrl="$(mktemp -u -p /var/run/unit/)";
|
|
|
|
mkdir -p /var/run/unit/;
|
|
|
|
ssh -fMNnT -S "$ssh_ctrl" \
|
|
-o 'ExitOnForwardFailure yes' \
|
|
-L "$local_sock:$remote_sock" "$remote";
|
|
|
|
trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null;
|
|
unlink '$local_sock';" EXIT;
|
|
|
|
sock="unix:$local_sock";
|
|
fi;
|
|
|
|
case $1 in
|
|
edit)
|
|
shift;
|
|
unit_ctl_edit ---s "$sock" $@;
|
|
;;
|
|
http)
|
|
shift;
|
|
unit_ctl_http ---s "$sock" $@;
|
|
;;
|
|
insert)
|
|
shift;
|
|
unit_ctl_insert ---s "$sock" $@;
|
|
;;
|
|
*)
|
|
err "ctl: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
|
|
if test -v remote; then
|
|
run_trap EXIT;
|
|
fi;
|
|
}
|
|
|
|
|
|
help_unit_ctl_edit()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 ctl [CTL-OPTS] edit [-h] PATH
|
|
|
|
DESCRIPTION
|
|
Edit the JSON configuration with an editor. The current configuration
|
|
is downloaded into a temporary file, open with the editor, and then
|
|
sent back to the control API socket.
|
|
|
|
The following editors are tried in this order of preference: \$VISUAL,
|
|
\$EDITOR, editor(1), vi(1), vim(1), ed(1).
|
|
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
ENVIRONMENT
|
|
VISUAL
|
|
EDITOR
|
|
See environ(7).
|
|
|
|
SEE ALSO
|
|
$0 ctl http -h;
|
|
|
|
update-alternatives(1)
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_ctl_edit()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_ctl_edit;
|
|
exit 0;
|
|
;;
|
|
---s | ----sock)
|
|
local sock="$2";
|
|
shift;
|
|
;;
|
|
-*)
|
|
err "ctl: edit: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if ! test $# -ge 1; then
|
|
err 'ctl: edit: PATH: Missing argument.';
|
|
fi;
|
|
local req_path="$1";
|
|
|
|
echo "$req_path" \
|
|
| sed 's%^/js_modules/.*%.js%' \
|
|
| sed 's%^/config\>.*%.json%' \
|
|
| sed 's%^/.*%.txt%' \
|
|
| xargs mktemp --suffix \
|
|
| read -r tmp;
|
|
|
|
unit_ctl_http ---s "$sock" -c --no-progress-meter GET "$req_path" \
|
|
</dev/null >"$tmp";
|
|
|
|
$(
|
|
((test -v VISUAL && test -n "$VISUAL") && printf '%s\n' "$VISUAL") \
|
|
|| ((test -v EDITOR && test -n "$EDITOR") && printf '%s\n' "$EDITOR") \
|
|
|| command -v editor \
|
|
|| command -v vi \
|
|
|| command -v vim \
|
|
|| echo ed;
|
|
) "$tmp";
|
|
|
|
trap "info 'ctl: edit: Invalid configuration saved in <$tmp>.'" ERR
|
|
|
|
unit_ctl_http ---s "$sock" PUT "$req_path" <"$tmp";
|
|
|
|
trap - ERR;
|
|
}
|
|
|
|
|
|
help_unit_ctl_http()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 ctl [CTL-OPTS] http [-h] [-c CURLOPT] METHOD PATH
|
|
|
|
DESCRIPTION
|
|
Send an HTTP request to the unitd(8) control API socket.
|
|
|
|
The payload is read from standard input.
|
|
|
|
OPTIONS
|
|
-c, --curl CURLOPT
|
|
Pass CURLOPT as an option to curl. This script is implemented
|
|
in terms of curl(1), so it's useful to be able to tweak its
|
|
behavior. The option can be cumulatively used multiple times
|
|
(the result is also appended to UNIT_CTL_HTTP_CURLOPTS).
|
|
|
|
-h, --help
|
|
Print this help.
|
|
|
|
ENVIRONMENT
|
|
UNIT_CTL_HTTP_CURLOPTS
|
|
Equivalent to the option -c (--curl).
|
|
|
|
EXAMPLES
|
|
$0 ctl http -c --no-progress-meter GET /config >tmp;
|
|
|
|
SEE ALSO
|
|
<https://unit.nginx.org/controlapi/#api-manipulation>
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_ctl_http()
|
|
{
|
|
local curl_options="${UNIT_CTL_HTTP_CURLOPTS:-}";
|
|
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-c | --curl)
|
|
if ! test $# -ge 2; then
|
|
err "ctl: http: $1: Missing argument.";
|
|
fi;
|
|
curl_options="$curl_options $2";
|
|
shift;
|
|
;;
|
|
-h | --help)
|
|
help_unit_ctl_http;
|
|
exit 0;
|
|
;;
|
|
---s | ----sock)
|
|
local sock="$2";
|
|
shift;
|
|
;;
|
|
-*)
|
|
err "ctl: http: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if ! test $# -ge 1; then
|
|
err 'ctl: http: METHOD: Missing argument.';
|
|
fi;
|
|
local method="$1";
|
|
|
|
if ! test $# -ge 2; then
|
|
err 'ctl: http: PATH: Missing argument.';
|
|
fi;
|
|
local req_path="$2";
|
|
|
|
curl --fail-with-body $curl_options -X $method -d@- \
|
|
$(echo "$sock" | unit_sock_filter -c)${req_path};
|
|
}
|
|
|
|
|
|
help_unit_ctl_insert()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 ctl [CTL-OPTS] insert [-h] PATH INDEX
|
|
|
|
DESCRIPTION
|
|
Insert an element at the specified position (INDEX) into the JSON array
|
|
located at PATH in unitd(8) control API.
|
|
|
|
The new element is read from standard input.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
SEE ALSO
|
|
$0 ctl http -h;
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_ctl_insert()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_ctl_insert;
|
|
exit 0;
|
|
;;
|
|
---s | ----sock)
|
|
local sock="$2";
|
|
shift;
|
|
;;
|
|
-*)
|
|
err "ctl: insert: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if ! test $# -ge 1; then
|
|
err 'ctl: insert: PATH: Missing argument.';
|
|
fi;
|
|
local req_path="$1";
|
|
|
|
if ! test $# -ge 2; then
|
|
err 'ctl: insert: INDEX: Missing argument.';
|
|
fi;
|
|
local idx="$2";
|
|
|
|
local old="$(mktemp)";
|
|
|
|
unit_ctl_http ---s "$sock" -c --no-progress-meter GET "$req_path" \
|
|
</dev/null >"$old";
|
|
|
|
unit_json_ins "$old" "$idx" \
|
|
| unit_ctl_http ---s "$sock" PUT "$req_path";
|
|
}
|
|
|
|
|
|
help_unit_ctl_welcome()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 welcome [-hn]
|
|
|
|
DESCRIPTION
|
|
This script tests an NGINX Unit installation by creating an initial
|
|
configuration and serving a welcome web page. Recommended for
|
|
first-time users.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-n, --dry-run
|
|
Dry run. Print the commands to be run instead of actually
|
|
running them. Each command is preceded by a line explaining
|
|
what it does.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_ctl_welcome()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-f | --force)
|
|
local force='yes';
|
|
;;
|
|
-h | --help)
|
|
help_unit_ctl_welcome;
|
|
exit 0;
|
|
;;
|
|
-n | --dry-run)
|
|
dry_run='yes';
|
|
;;
|
|
-*)
|
|
err "welcome: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "welcome: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
command -v curl >/dev/null \
|
|
|| err 'welcome: curl(1) not found in PATH. It must be installed to run this script.';
|
|
|
|
www='/srv/www/unit/index.html';
|
|
if test -e "$www" && ! test -v force || ! test -w /srv; then
|
|
www="$HOME/srv/www/unit/index.html";
|
|
fi;
|
|
if test -e "$www" && ! test -v force; then
|
|
www="$(mktemp)";
|
|
mv "$www" "$www.html";
|
|
www="$www.html"
|
|
fi;
|
|
|
|
unit_ps -t m \
|
|
| wc -l \
|
|
| read -r nprocs \
|
|
||:
|
|
|
|
if test 0 -eq "$nprocs"; then
|
|
warn "welcome: NGINX Unit isn't running.";
|
|
warn 'For help with starting NGINX Unit, see:';
|
|
err " <https://unit.nginx.org/installation/#startup-and-shutdown>";
|
|
elif test 1 -ne "$nprocs"; then
|
|
err 'welcome: Only one NGINX Unit instance should be running.';
|
|
fi;
|
|
|
|
local sock="$(unit_sock_find)";
|
|
local curl_opt="$(unit_sock_find | unit_sock_filter -c)";
|
|
|
|
curl $curl_opt/ >/dev/null 2>&1 \
|
|
|| err "welcome: Can't reach the control API socket.";
|
|
|
|
if ! test -v force; then
|
|
unit_cmd \
|
|
| read -r cmd;
|
|
|
|
# Check unitd is not configured already.
|
|
echo "$cmd" \
|
|
| if grep '\--statedir' >/dev/null; then
|
|
echo "$cmd" \
|
|
| sed 's/ --/\n--/g' \
|
|
| grep '\--statedir' \
|
|
| cut -d' ' -f2;
|
|
else
|
|
$cmd --help \
|
|
| sed -n '/\--statedir/,+1p' \
|
|
| grep 'default:' \
|
|
| sed 's/ *default: "\(.*\)"/\1/';
|
|
fi \
|
|
| sed 's,$,/conf.json,' \
|
|
| read -r conffile \
|
|
||:;
|
|
|
|
if test -e $conffile; then
|
|
if ! unit_ctl_http ---s "$sock" 'GET' '/config' </dev/null 2>/dev/null | grep -q '^{}.\?$'; # The '.\?' is for the possible carriage return.
|
|
then
|
|
warn 'welcome: NGINX Unit is already configured. To overwrite';
|
|
err 'its current configuration, run the script again with --force.';
|
|
fi;
|
|
fi;
|
|
fi;
|
|
|
|
(
|
|
unit_freeport \
|
|
|| err "welcome: Can't find an available port.";
|
|
) \
|
|
| read -r port;
|
|
|
|
dry_run_echo 'Create a file to serve:';
|
|
dry_run_eval "mkdir -p $(dirname $www);";
|
|
dry_run_eval "tee '$www' >/dev/null"' <<__EOF__;
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Welcome to NGINX Unit</title>
|
|
<style type="text/css">
|
|
body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
|
|
h1,h2 { color: #00974d; }
|
|
li { margin-bottom: 0.5em; }
|
|
pre { background-color: beige; padding: 0.4em; }
|
|
hr { margin-top: 2em; border: 1px solid #00974d; }
|
|
.indent { margin-left: 1.5em; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Welcome to NGINX Unit</h1>
|
|
<p>Congratulations! NGINX Unit is installed and running.</p>
|
|
<h3>Useful Links</h3>
|
|
<ul>
|
|
<li><b><a href="https://unit.nginx.org/configuration/?referer=welcome">https://unit.nginx.org/configuration/</a></b><br>
|
|
To get started with Unit, see the <em>Configuration</em> docs, starting with
|
|
the <em>Quick Start</em> guide.</li>
|
|
<li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
|
|
See our GitHub repo to browse the code, contribute, or seek help from the
|
|
<a href="https://github.com/nginx/unit#community">community</a>.</li>
|
|
</ul>
|
|
|
|
<h2>Next steps</h2>
|
|
|
|
<h3>Check Current Configuration</h3>
|
|
<div class="indent">
|
|
<p>Unit'"'"'s control API is currently listening for configuration changes
|
|
on the '"$(unit_sock_find | grep -q '^unix:' && echo '<a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a>' || echo 'socket')"' at
|
|
<b>'"$(unit_sock_find)"'</b><br>
|
|
To see the current configuration:</p>
|
|
<pre>'"${SUDO_USER:+sudo }"'curl '"$curl_opt"'/config</pre>
|
|
</div>
|
|
|
|
<h3>Change Listener Port</h3>
|
|
<div class="indent">
|
|
<p>This page is served over a random TCP high port. To choose the default HTTP port (80),
|
|
replace the <b>"listeners"</b> object:</p>
|
|
<pre>echo '"'"'{"*:80": {"pass": "routes"}}'"'"' | '"${SUDO_USER:+sudo }"'curl -X PUT -d@- '"$curl_opt"'/config/listeners</pre>
|
|
Then remove the port number from the address bar and reload the page.
|
|
</div>
|
|
|
|
<hr>
|
|
<p><a href="https://unit.nginx.org/?referer=welcome">NGINX Unit — the universal web app server</a><br>
|
|
NGINX, Inc. © 2024</p>
|
|
</body>
|
|
</html>
|
|
__EOF__';
|
|
dry_run_echo;
|
|
dry_run_echo 'Give it appropriate permissions:';
|
|
dry_run_eval "chmod 644 '$www';";
|
|
dry_run_echo;
|
|
|
|
dry_run_echo 'Configure unitd:'
|
|
dry_run_eval "cat <<__EOF__ \\
|
|
| sed 's/8080/$port/' \\
|
|
| curl -X PUT -d@- $curl_opt/config;
|
|
{
|
|
\"listeners\": {
|
|
\"*:8080\": {
|
|
\"pass\": \"routes\"
|
|
}
|
|
},
|
|
\"routes\": [{
|
|
\"action\": {
|
|
\"share\": \"$www\"
|
|
}
|
|
}]
|
|
}
|
|
__EOF__";
|
|
|
|
dry_run_echo;
|
|
|
|
echo;
|
|
echo 'You may want to try the following commands now:';
|
|
echo;
|
|
echo 'Check out current unitd configuration:';
|
|
echo " ${SUDO_USER:+sudo} curl $curl_opt/config";
|
|
echo;
|
|
echo 'Browse the welcome page:';
|
|
echo " curl http://localhost:$port/";
|
|
}
|
|
|
|
|
|
help_unit_freeport()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 freeport [-h]
|
|
|
|
DESCRIPTION
|
|
Print an available TCP port.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_freeport()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_freeport;
|
|
exit 0;
|
|
;;
|
|
-*)
|
|
err "freeport: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "freeport: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
freeport="$(mktemp -t freeport-XXXXXX)";
|
|
|
|
cat <<__EOF__ \
|
|
| cc -x c -o $freeport -;
|
|
#include <netinet/in.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <strings.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
|
|
|
|
int32_t get_free_port(void);
|
|
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
int32_t port;
|
|
|
|
port = get_free_port();
|
|
if (port == -1)
|
|
exit(EXIT_FAILURE);
|
|
|
|
printf("%d\n", port);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
|
|
int32_t
|
|
get_free_port(void)
|
|
{
|
|
int sfd;
|
|
int32_t port;
|
|
socklen_t len;
|
|
struct sockaddr_in addr;
|
|
|
|
port = -1;
|
|
|
|
sfd = socket(PF_INET, SOCK_STREAM, 0);
|
|
if (sfd == -1) {
|
|
perror("socket()");
|
|
return -1;
|
|
}
|
|
|
|
bzero(&addr, sizeof(addr));
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
addr.sin_port = htons(0); // random port
|
|
|
|
len = sizeof(addr);
|
|
if (bind(sfd, (struct sockaddr *) &addr, len)) {
|
|
perror("bind()");
|
|
goto fail;
|
|
}
|
|
|
|
if (getsockname(sfd, (struct sockaddr *) &addr, &len)) {
|
|
perror("getsockname()");
|
|
goto fail;
|
|
}
|
|
|
|
port = ntohs(addr.sin_port);
|
|
|
|
fail:
|
|
close(sfd);
|
|
return port;
|
|
}
|
|
__EOF__
|
|
|
|
$freeport;
|
|
}
|
|
|
|
|
|
help_unit_json_ins()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 json-ins [-hn] JSON INDEX
|
|
|
|
ARGUMENTS
|
|
JSON Path to a JSON file containing a top-level array.
|
|
|
|
INDEX Position in the array to insert the element at.
|
|
|
|
DESCRIPTION
|
|
Insert a JSON element read from standard input into a JSON array read
|
|
from a file at a given INDEX.
|
|
|
|
The resulting array is printed to standard output.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-n, --dry-run
|
|
Dry run. Print the command to be run instead of actually
|
|
running it.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_json_ins()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_json_ins;
|
|
exit 0;
|
|
;;
|
|
-n | --dry-run)
|
|
dry_run='yes';
|
|
;;
|
|
-*)
|
|
err "json-ins: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if ! test $# -ge 1; then
|
|
err 'json-ins: JSON: Missing argument.';
|
|
fi;
|
|
local arr=$1;
|
|
|
|
if ! test $# -ge 2; then
|
|
err 'json-ins: INDEX: Missing argument.';
|
|
fi;
|
|
local idx=$2;
|
|
|
|
dry_run_eval "(
|
|
jq '.[0:$idx]' <'$arr';
|
|
echo '[';
|
|
jq .;
|
|
echo ']';
|
|
jq '.[$idx:]' <'$arr';
|
|
) \\
|
|
| sed '/^\[]$/d' \\
|
|
| sed '/^]$/{N;s/^]\n\[$/,/}' \\
|
|
| jq .;"
|
|
}
|
|
|
|
|
|
help_unit_os_probe()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 os-probe [-h]
|
|
|
|
DESCRIPTION
|
|
This script probes the OS and prints three fields, delimited by ':';
|
|
the first is the package manager, the second is the OS name, the third
|
|
is the OS version.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_os_probe()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_os_probe;
|
|
exit 0;
|
|
;;
|
|
-*)
|
|
err "os-probe: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "os-probe: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
local os=$(uname | tr '[:upper:]' '[:lower:]')
|
|
|
|
if [ "$os" != 'linux' ] && [ "$os" != 'freebsd' ]; then
|
|
err "os-probe: The OS isn't Linux or FreeBSD; can't proceed."
|
|
fi
|
|
|
|
if [ "$os" = 'linux' ]; then
|
|
if command -v apt-get >/dev/null; then
|
|
local pkgMngr='apt';
|
|
elif command -v dnf >/dev/null; then
|
|
local pkgMngr='dnf';
|
|
elif command -v yum >/dev/null; then
|
|
local pkgMngr='yum';
|
|
else
|
|
local pkgMngr='';
|
|
fi;
|
|
|
|
local osRelease='/etc/os-release';
|
|
|
|
if [ -f "$osRelease" ]; then
|
|
# The value for the ID and VERSION_ID may or may not be in quotes
|
|
local osName=$(grep "^ID=" "$osRelease" | sed s/\"//g | awk -F= '{ print $2 }' ||:)
|
|
local osVersion=$(grep '^VERSION_ID=' "$osRelease" | sed s/\"//g | awk -F= '{ print $2 }' || lsb_release -cs)
|
|
else
|
|
err "os-probe: Unable to determine OS and version, or the OS isn't supported."
|
|
fi
|
|
else
|
|
local pkgMngr='pkg';
|
|
local osName=$os
|
|
local osVersion=$(uname -rs | awk -F '[ -]' '{print $2}' ||:)
|
|
if [ -z "$osVersion" ]; then
|
|
err 'os-probe: Unable to get the FreeBSD version.'
|
|
fi
|
|
fi
|
|
|
|
osName=$(echo "$osName" | tr '[:upper:]' '[:lower:]')
|
|
echo "$pkgMngr:$osName:$osVersion"
|
|
}
|
|
|
|
|
|
help_unit_ps()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 ps [-h] [-t TYPE]
|
|
|
|
DESCRIPTION
|
|
List unitd(8) processes.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-t, --type TYPE
|
|
List only processes of type TYPE. The available types are:
|
|
|
|
- controller (c)
|
|
- main (m)
|
|
- router (r)
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_ps()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_ps;
|
|
exit 0;
|
|
;;
|
|
-t | --type)
|
|
if ! test $# -ge 2; then
|
|
err "ps: $1: Missing argument.";
|
|
fi;
|
|
local type=;
|
|
case "$2" in
|
|
c | controller)
|
|
local type_c='c';
|
|
;;
|
|
m | main)
|
|
local type_m='m';
|
|
;;
|
|
r | router)
|
|
local type_r='r';
|
|
;;
|
|
esac;
|
|
shift;
|
|
;;
|
|
-*)
|
|
err "ps: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "ps: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
ps awwx \
|
|
| if test -v type; then
|
|
grep ${type_c:+-e 'unit: controller'} \
|
|
${type_m:+-e 'unit: main'} \
|
|
${type_r:+-e 'unit: router'};
|
|
else
|
|
grep 'unit: ';
|
|
fi \
|
|
| grep -v grep \
|
|
||:
|
|
}
|
|
|
|
|
|
help_unit_repo_config()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 repo-config [-hn] [PKG-MANAGER OS-NAME OS-VERSION]
|
|
|
|
DESCRIPTION
|
|
This script configures the NGINX Unit repository for the system
|
|
package manager.
|
|
|
|
The script automatically detects the OS and proceeds accordingly.
|
|
However, if this automatic selection fails, you may specify the
|
|
package manager and the OS name and version.
|
|
|
|
ARGUMENTS
|
|
PKG-MANAGER
|
|
Supported: 'apt', 'dnf', and 'yum'.
|
|
|
|
OS-NAME
|
|
Supported: 'debian', 'ubuntu', 'fedora', 'rhel', and 'amzn2'.
|
|
|
|
OS-VERSION
|
|
For most distributions, this should be a numeric value; for
|
|
Debian derivatives, use the codename instead.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-n, --dry-run
|
|
Dry run. Print the commands to be run instead of actually
|
|
running them. Each command is preceded by a line explaining
|
|
what it does.
|
|
|
|
EXAMPLES
|
|
$ $(basename "$0") repo-config apt debian bullseye;
|
|
$ $(basename "$0") repo-config apt ubuntu jammy;
|
|
$ $(basename "$0") repo-config dnf fedora 36;
|
|
$ $(basename "$0") repo-config dnf rhel 9;
|
|
$ $(basename "$0") repo-config yum amzn2 2;
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_repo_config()
|
|
{
|
|
installAPT ()
|
|
{
|
|
local os_name="$2";
|
|
|
|
dry_run_echo "Install on $os_name";
|
|
dry_run_echo;
|
|
dry_run_eval 'curl --output /usr/share/keyrings/nginx-keyring.gpg https://unit.nginx.org/keys/nginx-keyring.gpg;';
|
|
dry_run_echo;
|
|
dry_run_eval 'apt-get install -y apt-transport-https lsb-release ca-certificates;';
|
|
|
|
if test $# -ge 3; then
|
|
local os_version="$3";
|
|
else
|
|
local os_version='$(lsb_release -cs)';
|
|
fi;
|
|
|
|
dry_run_echo;
|
|
dry_run_eval "printf 'deb [signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://packages.nginx.org/unit/$os_name/ %s unit\n' \"$os_version\" | tee /etc/apt/sources.list.d/unit.list;";
|
|
dry_run_eval "printf 'deb-src [signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://packages.nginx.org/unit/$os_name/ %s unit\n' \"$os_version\" | tee -a /etc/apt/sources.list.d/unit.list;";
|
|
dry_run_echo;
|
|
dry_run_eval 'apt-get update;';
|
|
}
|
|
|
|
installYumDnf ()
|
|
{
|
|
local pkg_mngr="$1";
|
|
local os_name="$2";
|
|
|
|
if test $# -ge 3; then
|
|
local os_version="$3";
|
|
else
|
|
local os_version='\$releasever';
|
|
fi;
|
|
|
|
dry_run_echo "Install on $os_name";
|
|
dry_run_echo;
|
|
|
|
dry_run_eval "cat >/etc/yum.repos.d/unit.repo <<__EOF__
|
|
[unit]
|
|
name=unit repo
|
|
baseurl=https://packages.nginx.org/unit/$os_name/$os_version/\\\$basearch/
|
|
gpgcheck=0
|
|
enabled=1
|
|
__EOF__";
|
|
|
|
dry_run_echo;
|
|
dry_run_eval "$pkg_mngr makecache;";
|
|
}
|
|
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_repo_config;
|
|
exit 0;
|
|
;;
|
|
-n | --dry-run)
|
|
dry_run='yes';
|
|
;;
|
|
-*)
|
|
err "repo-config: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if test $# -ge 1; then
|
|
local pkg_mngr="$1";
|
|
|
|
if ! test $# -ge 2; then
|
|
err "repo-config: OS-NAME: Missing argument.";
|
|
fi;
|
|
local os_name="$2";
|
|
|
|
if ! test $# -ge 3; then
|
|
err "repo-config: OS-VERSION: Missing argument.";
|
|
fi;
|
|
local os_version="$3";
|
|
fi;
|
|
|
|
command -v curl >/dev/null \
|
|
|| err 'repo-config: curl(1) not found in PATH. It must be installed to run this script.';
|
|
|
|
echo 'This script sets up the NGINX Unit repository';
|
|
|
|
if ! test $# -ge 3; then
|
|
local os_pkg_name_version=$(unit_os_probe || warn "On macOS, try 'brew install nginx/unit/unit'.")
|
|
local pkg_mngr=$(echo "$os_pkg_name_version" | awk -F: '{print $1}')
|
|
local os_name=$(echo "$os_pkg_name_version" | awk -F: '{print $2}')
|
|
local os_version=$(echo "$os_pkg_name_version" | awk -F: '{print $3}')
|
|
fi;
|
|
|
|
# Call the appropriate installation function
|
|
case "$pkg_mngr" in
|
|
apt)
|
|
case "$os_name" in
|
|
debian | ubuntu)
|
|
installAPT "$pkg_mngr" "$os_name" ${3:+$os_version};
|
|
;;
|
|
*)
|
|
err "repo-config: $os_name: The OS isn't supported.";
|
|
;;
|
|
esac
|
|
;;
|
|
yum | dnf)
|
|
case "$os_name" in
|
|
rhel | amzn | fedora)
|
|
installYumDnf "$pkg_mngr" "$os_name" "$os_version" ${3:+ovr};
|
|
;;
|
|
*)
|
|
err "repo-config: $os_name: The OS isn't supported.";
|
|
;;
|
|
esac;
|
|
;;
|
|
*)
|
|
err "repo-config: $pkg_mngr: The package manager isn't supported.";
|
|
;;
|
|
esac;
|
|
|
|
echo
|
|
echo 'All done; the NGINX Unit repository is set up.';
|
|
echo "Configured with '$pkg_mngr' on '$os_name' '$os_version'.";
|
|
echo 'Further steps: <https://unit.nginx.org/installation/#official-packages>'
|
|
}
|
|
|
|
|
|
help_unit_restart()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 restart [-hls]
|
|
|
|
DESCRIPTION
|
|
Restart all running unitd(8) instances.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-l, --log
|
|
Reset log file.
|
|
|
|
-s, --statedir
|
|
Reset \$statedir.
|
|
|
|
CAVEATS
|
|
This command will ask for confirmation before removing
|
|
directories; please review those prompts with care, as unknown
|
|
bugs in the command may attempt to wipe your file system.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_restart()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_restart;
|
|
exit 0;
|
|
;;
|
|
-l | --log)
|
|
local log_flag='yes';
|
|
;;
|
|
-s | --statedir)
|
|
local state_flag='yes';
|
|
;;
|
|
-*)
|
|
err "restart: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "restart: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
local cmds="$(unit_cmd)";
|
|
|
|
pkill -e unitd;
|
|
|
|
printf '%s\n' "$cmds" \
|
|
| while read -r cmd; do
|
|
if test -v log_flag; then
|
|
(
|
|
echo "$cmd" \
|
|
| grep '\--log' \
|
|
| sed 's/.*--log \+\([^ ]\+\).*/\1/' \
|
|
|| eval $cmd --help \
|
|
| grep -A1 '\--log FILE' \
|
|
| grep 'default:' \
|
|
| sed 's/.*"\(.*\)".*/\1/';
|
|
) \
|
|
| xargs rm -f;
|
|
fi;
|
|
|
|
if test -v state_flag; then
|
|
(
|
|
echo "$cmd" \
|
|
| grep '\--statedir' \
|
|
| sed 's/.*--statedir \+\([^ ]\+\).*/\1/' \
|
|
|| eval $cmd --help \
|
|
| grep -A1 '\--statedir DIR' \
|
|
| grep 'default:' \
|
|
| sed 's/.*"\(.*\)".*/\1/';
|
|
) \
|
|
| xargs -I {} find {} -mindepth 1 -maxdepth 1 \
|
|
| xargs rm -rfi;
|
|
fi;
|
|
|
|
eval $cmd;
|
|
done;
|
|
}
|
|
|
|
|
|
help_unit_sock()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 sock [-h] SUBCOMMAND [ARGS]
|
|
|
|
Subcommands
|
|
├── filter [-ch]
|
|
└── find [-h]
|
|
|
|
DESCRIPTION
|
|
Print the control API socket address of running unitd(8)
|
|
instances.
|
|
|
|
Run '$0 sock SUBCOMMAND -h' for more information on a
|
|
subcommand.
|
|
|
|
SUBCOMMANDS
|
|
filter Filter the output of the 'find' subcommand and transform it
|
|
to something suitable for running other commands, such as
|
|
curl(1) or ssh(1).
|
|
|
|
find Find and print the control API socket address of running
|
|
unitd(8) instances.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_sock()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_sock;
|
|
exit 0;
|
|
;;
|
|
-*)
|
|
err "sock: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if ! test $# -ge 1; then
|
|
err 'sock: Missing subcommand.';
|
|
fi;
|
|
|
|
case $1 in
|
|
filter)
|
|
shift;
|
|
unit_sock_filter $@;
|
|
;;
|
|
find)
|
|
shift;
|
|
unit_sock_find $@;
|
|
;;
|
|
*)
|
|
err "sock: $1: Unknown subcommand.";
|
|
;;
|
|
esac;
|
|
}
|
|
|
|
|
|
help_unit_sock_filter()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 sock filter [-chs]
|
|
|
|
DESCRIPTION
|
|
Filter the output of the 'sock find' command and transform it to
|
|
something suitable for running other commands, such as
|
|
curl(1) or ssh(1).
|
|
|
|
OPTIONS
|
|
-c, --curl
|
|
Print an argument suitable for curl(1).
|
|
|
|
-h, --help
|
|
Print this help.
|
|
|
|
-s, --ssh
|
|
Print a socket address suitable for use in an ssh(1) tunnel.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_sock_filter()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-c | --curl)
|
|
if test -v ssh_flag; then
|
|
err "sock: filter: $1: Missing argument.";
|
|
fi;
|
|
local curl_flag='yes';
|
|
;;
|
|
-h | --help)
|
|
help_unit_sock_filter;
|
|
exit 0;
|
|
;;
|
|
-s | --ssh)
|
|
if test -v curl_flag; then
|
|
err "sock: filter: $1: Missing argument.";
|
|
fi;
|
|
local ssh_flag='yes';
|
|
;;
|
|
-*)
|
|
err "sock: filter: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "sock: filter: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
while read -r control; do
|
|
|
|
if test -v curl_flag; then
|
|
if echo "$control" | grep '^unix:' >/dev/null; then
|
|
unix_socket="$(echo "$control" | sed 's/unix:/--unix-socket /')";
|
|
host='http://localhost';
|
|
else
|
|
unix_socket='';
|
|
host="$control";
|
|
fi;
|
|
|
|
echo "$unix_socket $host";
|
|
|
|
elif test -v ssh_flag; then
|
|
echo "$control" \
|
|
| sed -E 's,^(unix:|http://|https://),,';
|
|
|
|
else
|
|
echo "$control";
|
|
fi;
|
|
done;
|
|
}
|
|
|
|
|
|
help_unit_sock_find()
|
|
{
|
|
cat <<__EOF__ ;
|
|
SYNOPSIS
|
|
$0 sock find [-h]
|
|
|
|
DESCRIPTION
|
|
Find and print the control API socket address of running
|
|
unitd(8) instances.
|
|
|
|
OPTIONS
|
|
-h, --help
|
|
Print this help.
|
|
|
|
__EOF__
|
|
}
|
|
|
|
|
|
unit_sock_find()
|
|
{
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit_sock_find;
|
|
exit 0;
|
|
;;
|
|
-*)
|
|
err "sock: find: $1: Unknown option.";
|
|
;;
|
|
*)
|
|
err "sock: find: $1: Unknown argument.";
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
unit_cmd \
|
|
| while read -r cmd; do
|
|
if echo "$cmd" | grep '\--control' >/dev/null; then
|
|
echo "$cmd" \
|
|
| sed 's/ --/\n--/g' \
|
|
| grep '\--control' \
|
|
| cut -d' ' -f2;
|
|
else
|
|
if ! command -v $cmd >/dev/null; then
|
|
local cmd='unitd';
|
|
fi;
|
|
$cmd --help \
|
|
| sed -n '/\--control/,+1p' \
|
|
| grep 'default:' \
|
|
| sed 's/ *default: "\(.*\)"/\1/';
|
|
fi;
|
|
done;
|
|
}
|
|
|
|
|
|
while test $# -ge 1; do
|
|
case "$1" in
|
|
-h | --help)
|
|
help_unit;
|
|
exit 0;
|
|
;;
|
|
-hh | --help-more)
|
|
help_more_unit;
|
|
exit 0;
|
|
;;
|
|
-*)
|
|
err "$1: Unknown option.";
|
|
;;
|
|
*)
|
|
break;
|
|
;;
|
|
esac;
|
|
shift;
|
|
done;
|
|
|
|
if ! test $# -ge 1; then
|
|
err "Missing command.";
|
|
fi;
|
|
|
|
case $1 in
|
|
cmd)
|
|
shift;
|
|
unit_cmd $@;
|
|
;;
|
|
ctl)
|
|
shift;
|
|
unit_ctl $@;
|
|
;;
|
|
freeport)
|
|
shift;
|
|
unit_freeport $@;
|
|
;;
|
|
json-ins)
|
|
shift;
|
|
unit_json_ins $@;
|
|
;;
|
|
os-probe)
|
|
shift;
|
|
unit_os_probe $@;
|
|
;;
|
|
ps)
|
|
shift;
|
|
unit_ps $@;
|
|
;;
|
|
repo-config)
|
|
shift;
|
|
unit_repo_config $@;
|
|
;;
|
|
restart)
|
|
shift;
|
|
unit_restart $@;
|
|
;;
|
|
sock)
|
|
shift;
|
|
unit_sock $@;
|
|
;;
|
|
welcome)
|
|
shift;
|
|
unit_ctl_welcome $@;
|
|
;;
|
|
*)
|
|
err "$1: Unknown command.";
|
|
;;
|
|
esac;
|