- added install-polylith-systemd-units.sh: script to isntall systemd units for polylith deployments

- fixed some errors in INSTALL.md and added description for polylith service setup
This commit is contained in:
dymattic 2020-10-18 03:54:00 +02:00
parent 640e8c50ec
commit ae5db5fdc7
2 changed files with 320 additions and 3 deletions

View file

@ -30,6 +30,9 @@ If you want to run a polylith deployment, you also need:
* Apache Kafka 0.10.2+
Depending on your environment additional packages might be required for building to succeed.
On Debian 10 install "build-essential" to be on the safe side: `apt install build-essential`
## Building up a monolith deploment
Start by cloning the code:
@ -109,7 +112,7 @@ Assuming that Postgres 9.5 (or later) is installed:
* Create the component databases:
```bash
for i in account device mediaapi syncapi roomserver signingkeyserver federationsender appservice e2ekey naffka; do
for i in account device mediaapi syncapi roomserver signingkeyserver federationsender appservice e2ekey naffka userapi_accounts userapi_devices keyserver ; do
sudo -u postgres createdb -O dendrite dendrite_$i
done
```
@ -123,8 +126,17 @@ Each Dendrite server requires unique server keys.
In order for an instance to federate correctly, you should have a valid
certificate issued by a trusted authority, and private key to match. If you
don't and just want to test locally, generate the self-signed SSL certificate
for federation and the server signing key:
for federation and the server signing key.
`./bin/generate-keys` is used to generate keys and certificates.
In order to just generate the Matrix private key use this:
```bash
./bin/generate-keys --private-key matrix_key.pem
```
If you also need self-signed TLS-certificates use the following command:
```bash
./bin/generate-keys --private-key matrix_key.pem --tls-cert server.crt --tls-key server.key
```
@ -154,7 +166,7 @@ the monolith server. To do this, set `use_naffka: true` in your `dendrite.yaml`
configuration and uncomment the relevant Naffka line in the `database` section.
Be sure to update the database username and password if needed.
The monolith server can be started as shown below. By default it listens for
The monolith server can be started as shown below. By default, it listens for
HTTP connections on port 8008, so you can configure your Matrix client to use
`http://localhost:8008` as the server. If you set `--tls-cert` and `--tls-key`
as shown below, it will also listen for HTTPS connections on port 8448.
@ -295,3 +307,27 @@ amongst other things.
./bin/dendrite-user-api-server --config dendrite.yaml
```
### Set up Systemd Services _(polylith)_
In order to run the whole polylith deployment daemonized with Systemd
the following script can set them up for you **(root-privileges required)**:
```bash
# ./install-polylith-systemd-units.sh
```
Example:
```bash
# ./install-polylith-systemd-units.sh -u dendrite -d /home/dendrite/server/ all
```
* user: dendrite
* path: /home/dendrite/server/
* selection: all
In order to start all installed services the wrapper "polyDendrite.service" can be used:
```bash
# systemctl start polyDendrite.service
```
Monitor with

View file

@ -0,0 +1,281 @@
#!/bin/bash
#############################################
#Script to generate Systemd-Unit Files #
#Author: dymattic(@dymattic:schwifty.earth) #
#############################################
check_parameters() {
if [[ -z "${1:-}" ]]; then
echo "The specified command requires additional parameters. See help:" >&2
echo >&2
command_help >&2
exit 1
elif [[ "${1:0:1}" = "-" ]]; then
_exiterr "Invalid argument: ${1}"
fi
}
print_param_options()
{
echo "Available servers:"
for entry in "${SERVERS[@]}"; do
echo " - $entry"
done
}
#Array with all servers
SERVERS=( "client-api-proxy" \
"federation-api-proxy" \
"dendrite-client-api-server" \
"dendrite-sync-api-server" \
"dendrite-media-api-server" \
"dendrite-federation-api-server" \
"dendrite-room-server" \
"dendrite-federation-sender-server" \
"dendrite-appservice-server" \
"dendrite-key-server" \
"dendrite-signing-key-server" \
"dendrite-edu-server" \
"dendrite-user-api-server" \
)
#Generate unit files and output into /etc/systemd/system/<unit-file-name>
function generateServiceUnit()
{
declare SERVER=$1
declare USER=$2
declare DENDRITEDIR=$3
#
# Declaration of executin lines
#
declare -A EXECS
nl=$'\n'
read -r -d '' EXECS[clientapiproxy] <<EOF
/bin/client-api-proxy \
--bind-address ":8008" \
--client-api-server-url "http://localhost:7771" \
--sync-api-server-url "http://localhost:7773" \
--media-api-server-url "http://localhost:7774" \
EOF
read -r -d '' EXECS[federationapiproxy] <<EOF
/bin/federation-api-proxy \ $nl
--bind-address ":8448" \ $nl
--federation-api-url "http://localhost:7772" \ $nl
--media-api-server-url "http://localhost:7774" \ $nl
EOF
for ENTRY in $DENDRITEDIR/bin/dendrite-*-server; do
BINARY=$(basename $ENTRY)
EXECS[$(echo "${BINARY//-}")]="$ENTRY --config=dendrite.yaml"
done
#Check if already existent
CHECK=0
if [[ -f /etc/systemd/system/$SERVER.service && ( "$PARAM_FORCE" != "yes" || -z "$PARAM_FORCE" ) ]]; then
echo "Systemd-Unit file for $SERVER already exists."
while [[ "$CHECK" -ne 1 ]]
do
read -p " Overwrite? (Y/N):" -n1 -r INPUT
if [[ $INPUT =~ ^[Nn]$ ]]; then
echo "Skipping...";
return 0
elif [[ $INPUT =~ ^[Yy]$ ]]; then
CHECK=1
else
echo "Invalid input, try again!"
CHECK=0
fi
done
fi
current="${EXECS[$(echo "${SERVER//-}")]}"
cat <<-EOF > /etc/systemd/system/$SERVER.service
[Unit]
Description= $SERVER 1
# When systemd stops or restarts the app.service, the action is propagated to this unit
PartOf=polyDendrite.service
# Start this unit after the app.service start
After=polyDendrite.service
[Service]
User=$USER
WorkingDirectory=$DENDRITEDIR
# Pretend that the component is running
ExecStart=/home/dendrite/server$current
Restart=on-failure
[Install]
# This unit should start when app.service is starting
WantedBy=polyDendrite.service
EOF
if [[ $? -ne 0 ]]; then
echo "An error occurred. Exiting..."
exit 1
fi
/usr/bin/systemctl daemon-reload
echo "Enabling $SERVER.service..."
/usr/bin/systemctl enable $SERVER.service
echo "$SERVER Unit-File created..."
return 0
}
function generateServiceWrapper()
{
if [[ -f /etc/systemd/system/polyDendrite.service && ( "$PARAM_FORCE" != "yes" || -z "$PARAM_FORCE" ) ]]; then
echo "Systemd-Unit file for Dendrite Polylith Service wrapper already exists."
CHECK=0
while [[ "$CHECK" -ne 1 ]]
do
read -p " Overwrite? (Y/N):" -n1 -r INPUT
if [[ $INPUT =~ ^[Nn]$ ]]; then
echo
echo "Skipping...";
return 0
elif [[ $INPUT =~ ^[Yy]$ ]]; then
CHECK=1
else
echo "Invalid input, try again!"
CHECK=0
fi
done
fi
read -r -d '' polyUnit <<EOF
[Unit]
Description=Dendrite Polylith Service wrapper
[Service]
# The dummy program will exit
Type=oneshot
# Execute a dummy program
ExecStart=/bin/true
# This service shall be considered active after start
RemainAfterExit=yes
[Install]
# Components of this application should be started at boot time
WantedBy=multi-user.target
EOF
echo "$polyUnit" > /etc/systemd/system/polyDendrite.service
if [[ $? -ne 0 ]]; then
echo "An error occurred. Exiting..."
exit 1
fi
/usr/bin/systemctl daemon-reload
echo "Enabling polyDendrite.service..."
/usr/bin/systemctl enable polyDendrite.service
echo "$SERVER Unit-File created..."
return 0
}
function command_help()
{
echo "\
--help|-h - Display this message
--user|-u username - Specify username that executes the servers
--dir|-d /path/to/dendrite/dir - Set the path of the dendrite directory i.e. (/home/dendrite/)
[server-name][...] or all for all - Give list of server-names to install Systemd units for or leave empty for all"
return 0
}
declare -a inputarray
while (( ${#} )); do
case "${1}" in
--help|-h)
command_help
exit 0
;;
# PARAM_Usage: --user (-u) username
# PARAM_Description: Use specified user for service execution
--user|-u)
shift 1
check_parameters "${1:-}"
USER="${1}"
;;
# PARAM_Usage: --dir (-d) /path/to/dendrite/dir
# PARAM_Description: Use specified path to dendrite directory.
--dir|-d)
shift 1
check_parameters "${1:-}"
DENDRITEDIR="${1}"
;;
# PARAM_Usage: --force (-x)
# PARAM_Description: Force overwrite, don't ask
--force|-x)
PARAM_FORCE="yes"
;;
-*)
echo "Unknown parameter detected: ${1}"
command_help
exit 1
;;
*)
available=( ${SERVERS[@]} "all" )
if [[ ! " ${available[@]} " =~ " ${1} " ]]; then
echo "Invalid argument: ${1}"
print_param_options
exit 1
fi
inputarray+=( "${1}" )
;;
esac
shift 1
done
#Get user
if [[ -z "$USER" ]]; then
read -p "Enter username of user running dendrite: " USER
if [[ $USER = "" ]]; then
echo "Dendrite-User can not be empty..."
exit 1
fi
fi
#Get install dir
if [[ -z "$DENDRITEDIR" ]]; then
read -p "Enter path to dendrite-directory: " DENDRITEDIR
if [[ DENDRITEDIR = "" ]]; then
echo "Dendrite-Path can not be empty..."
exit 1
elif [[ ! -d $DENDRITEDIR/bin ]]; then
echo "There is no \"bin\"-Dir in $DENDRITEDIR. Right path? Exiting..."
fi
fi
DENDRITEDIR="$(echo $DENDRITEDIR | sed -e 's#/$##')"
#Let user decide which servers to create the unitfiles for...
if [[ -z "${inputarray[@]}" || "${inputarray[@]}" = "" ]]; then
echo "Enter a list of dendrite-servers separated by spaces to create Systemd-Units for or enter \"all\" to create all:"
print_param_options
while read -a inputarray; do
echo ${inputarray[1]}
done
fi
if [[ "${inputarray[@]}" = "" || "${inputarray[@]}" = "all" ]]; then
for part in "${SERVERS[@]}"; do
echo "$( generateServiceUnit $part $USER $DENDRITEDIR )"
done
else
for choice in "${inputarray[@]}"; do
echo "$( generateServiceUnit $choice $USER $DENDRITEDIR )"
done
fi
generateServiceWrapper
echo "Done.."
echo "You can start all Services by typing:
systemctl start polyDendrite.service"
echo "To start single servers use the appropriate service name instead."
exit 0