Files
zulip/scripts/lib/install
Anders Kaseorg c517e95e6b install: Move ourself to deployments path before creating venv.
This prevents the venv from ending up with references to /root.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2025-03-25 10:17:17 -07:00

780 lines
27 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -e
usage() {
# A subset of this documentation also appears in docs/production/install.md
cat <<'EOF'
Usage:
install --hostname=zulip.example.com --email=zulip-admin@example.com [options...]
install --help
Options:
--hostname=zulip.example.com
The user-accessible domain name for this Zulip server, i.e.,
what users will type in their web browser. Required, unless
--no-init-db or --puppet-classes is set, and --certbot is not.
--email=zulip-admin@example.com
The email address of the person or team who should get support
and error emails from this Zulip server. Required, unless
--no-init-db or --puppet-classes is set and --certbot is not.
--certbot
Obtains a free SSL certificate for the server using Certbot,
https://certbot.eff.org/ Recommended. Conflicts with --self-signed-cert.
--self-signed-cert
Generate a self-signed SSL certificate for the server. This isnt suitable for
production use, but may be convenient for testing. Conflicts with --certbot.
--postgresql-database-name=zulip
Sets the PostgreSQL database name.
--postgresql-database-user=zulip
Sets the PostgreSQL database user.
--postgresql-version=16
Sets the version of PostgreSQL that will be installed.
--postgresql-missing-dictionaries
Set postgresql.missing_dictionaries, which alters the initial database. Use with
cloud managed databases like RDS. Conflicts with --no-overwrite-settings.
--no-init-db
Does not do any database initialization; use when you already have a Zulip
database.
--puppet-classes
Comma-separated list of Puppet classes to install; defaults to
'zulip:::profile::standalone'. Implies --no-init-db.
--no-overwrite-settings
Preserve existing `/etc/zulip` configuration files.
--no-dist-upgrade
Skip the initial `apt-get dist-upgrade`.
--push-notifications
With this option, the Zulip installer registers your server for the Mobile
Push Notification Service, and sets up the initial default configuration.
You will be immediately prompted to agree to the Terms of Service, and your
server will be registered at the end of the installation process.
--no-push-notifications
Disable push notifications registration (the default if neither
flag is provided).
--no-submit-usage-statistics
If you enable push notifications, by default your server
will submit basic metadata (required for billing and for
determining free plan eligibility), as well as aggregate usage
statistics. You can disable submitting usage statistics by passing
this flag.
If push notifications are not enabled, data won't be submitted, so
this flag is redundant.
--agree-to-terms-of-service
If you enable push notifications, you can pass this flag to indicate
that you have read and agree to the Zulip Terms of Service:
<https://zulip.com/policies/terms>.
This skips the Terms of Service prompt, allowing for running the installer
with --push-notifications in scripts without requiring user input.
EOF
}
system_requirements_failure() {
set +x
echo >&2
cat >&2
cat <<EOF >&2
For more information, see:
https://zulip.readthedocs.io/en/latest/production/requirements.html
EOF
exit 1
}
# Shell option parsing. Over time, we'll want to move some of the
# environment variables below into this self-documenting system.
args="$(getopt -o '' --long help,hostname:,email:,certbot,self-signed-cert,cacert:,postgresql-database-name:,postgresql-database-user:,postgresql-version:,postgresql-missing-dictionaries,no-init-db,puppet-classes:,no-overwrite-settings,no-dist-upgrade,push-notifications,no-push-notifications,no-submit-usage-statistics,agree-to-terms-of-service -n "$0" -- "$@")"
eval "set -- $args"
while true; do
case "$1" in
--help)
usage
exit 0
;;
--hostname)
EXTERNAL_HOST="$2"
shift
shift
;;
--email)
ZULIP_ADMINISTRATOR="$2"
shift
shift
;;
--certbot)
USE_CERTBOT=1
shift
;;
--self-signed-cert)
SELF_SIGNED_CERT=1
shift
;;
--postgresql-database-name)
POSTGRESQL_DATABASE_NAME="$2"
shift
shift
;;
--postgresql-database-user)
POSTGRESQL_DATABASE_USER="$2"
shift
shift
;;
--postgresql-version)
POSTGRESQL_VERSION="$2"
shift
shift
;;
--postgresql-missing-dictionaries)
POSTGRESQL_MISSING_DICTIONARIES=1
shift
;;
--no-init-db)
NO_INIT_DB=1
shift
;;
--puppet-classes)
PUPPET_CLASSES="$2"
NO_INIT_DB=1
shift
shift
;;
--no-overwrite-settings)
NO_OVERWRITE_SETTINGS=1
shift
;;
--no-dist-upgrade)
NO_DIST_UPGRADE=1
shift
;;
--push-notifications)
if [ -n "$NO_PUSH_NOTIFICATIONS" ]; then
echo "error: --push-notifications and --no-push-notifications are incompatible." >&2
exit 1
fi
PUSH_NOTIFICATIONS=1
shift
;;
--no-push-notifications)
if [ -n "$PUSH_NOTIFICATIONS" ]; then
echo "error: --push-notifications and --no-push-notifications are incompatible." >&2
exit 1
fi
NO_PUSH_NOTIFICATIONS=1
shift
;;
--no-submit-usage-statistics)
NO_SUBMIT_USAGE_STATISTICS=1
shift
;;
--agree-to-terms-of-service)
AGREE_TO_TERMS_OF_SERVICE_FLAG=1
shift
;;
--)
shift
break
;;
esac
done
if [ "$#" -gt 0 ]; then
usage >&2
exit 1
fi
## Options from environment variables.
#
# Specify options for apt.
read -r -a APT_OPTIONS <<<"${APT_OPTIONS:-}"
# Install additional packages.
read -r -a ADDITIONAL_PACKAGES <<<"${ADDITIONAL_PACKAGES:-}"
# Comma-separated list of Puppet manifests to install. The default is
# zulip::profile::standalone for an all-in-one system or
# zulip::profile::docker for Docker. Use
# e.g. zulip::profile::app_frontend for a Zulip frontend server.
PUPPET_CLASSES="${PUPPET_CLASSES:-zulip::profile::standalone}"
POSTGRESQL_VERSION="${POSTGRESQL_VERSION:-16}"
if [ -n "$SELF_SIGNED_CERT" ] && [ -n "$USE_CERTBOT" ]; then
set +x
echo "error: --self-signed-cert and --certbot are incompatible" >&2
echo >&2
usage >&2
exit 1
fi
if [ -n "$POSTGRESQL_MISSING_DICTIONARIES" ] && [ -n "$NO_OVERWRITE_SETTINGS" ]; then
set +x
echo "error: --postgresql-missing-dictionaries and --no-overwrite-settings are incompatible" >&2
echo >&2
usage >&2
exit 1
fi
if [ -z "$EXTERNAL_HOST" ] || [ -z "$ZULIP_ADMINISTRATOR" ]; then
if [ -n "$USE_CERTBOT" ] || [ -z "$NO_INIT_DB" ]; then
usage >&2
exit 1
fi
fi
if [ "$EXTERNAL_HOST" = zulip.example.com ] \
|| [ "$ZULIP_ADMINISTRATOR" = zulip-admin@example.com ]; then
# These example values are specifically checked for and would fail
# later; see check_config in zerver/lib/management.py.
echo 'error: The example hostname and email must be replaced with real values.' >&2
echo >&2
usage >&2
exit 1
fi
case "$POSTGRESQL_VERSION" in
[0-9] | [0-9].* | 1[0-2] | 1[0-2].*)
echo "error: PostgreSQL 13 or newer is required." >&2
exit 1
;;
esac
if [ -z "$PUSH_NOTIFICATIONS" ] && [ -z "$NO_PUSH_NOTIFICATIONS" ]; then
# Unless specified, we default to --no-push-notifications
NO_PUSH_NOTIFICATIONS=1
fi
# We set these to Python-style True/False string values, for easy
# insertion into the settings.py file.
if [ -n "$PUSH_NOTIFICATIONS" ]; then
SERVICE_MOBILE_PUSH="True"
# --push-notifications also enables SUBMIT_USAGE_STATISTICS, unless the user
# explicitly opted out by passing --no-submit-usage-statistics.
if [ -n "$NO_SUBMIT_USAGE_STATISTICS" ]; then
SERVICE_SUBMIT_USAGE_STATISTICS="False"
else
SERVICE_SUBMIT_USAGE_STATISTICS="True"
fi
else
SERVICE_MOBILE_PUSH="False"
# SUBMIT_USAGE_STATISTICS without PUSH_NOTIFICATIONS is an unusual
# configuration that we don't need to offer in the installer.
SERVICE_SUBMIT_USAGE_STATISTICS="False"
fi
# ToS acceptance needs to be ensured if --push-notifications is passed.
if [ -n "$PUSH_NOTIFICATIONS" ]; then
# If the user provided the --agree-to-terms-of-service flag, we can just proceed.
if [ -n "$AGREE_TO_TERMS_OF_SERVICE_FLAG" ]; then
PUSH_NOTIFICATIONS_SERVICE_TOS_AGREED=1
echo "Push notifications will be enabled, as you agreed to the Zulip Terms of Service"
echo "by passing the --agree-to-terms-of-service flag."
sleep 2
else
# If user asked for push notifications, prompt for ToS acceptance.
echo
echo "You chose to register your server for the Mobile Push Notifications Service."
echo "Doing so will share basic metadata with the service's maintainers, including:"
echo
echo "* The server's configured hostname: $EXTERNAL_HOST"
echo "* The server's configured contact email address: $ZULIP_ADMINISTRATOR"
echo "* Basic metadata about each organization hosted by the server; see:"
echo " <https://zulip.com/doc-permalinks/basic-metadata>"
if [ -z "$NO_SUBMIT_USAGE_STATISTICS" ]; then
echo "* The server's usage statistics; see:"
echo " <https://zulip.com/doc-permalinks/usage-statistics>"
fi
echo
echo "For details on why a centralized push notification service is necessary, see:"
echo " <https://zulip.com/doc-permalinks/why-service>"
echo
echo "Use of this service is governed by the Zulip Terms of Service:"
echo " <https://zulip.com/policies/terms>"
echo
read -r -p "Do you want to agree to the Zulip Terms of Service and proceed? [Y/n] " tos_prompt
echo
# Normalize the users response to lowercase.
case "${tos_prompt,,}" in
"" | y | yes)
echo "Great! Push notifications will be enabled; continuing with installation..."
PUSH_NOTIFICATIONS_SERVICE_TOS_AGREED=1
sleep 2
;;
*)
echo "In order to enable push notifications, you must agree to the Terms of Service."
echo "If you do not want to enable push notifications, run the command without the --push-notifications flag."
exit 1
;;
esac
fi
fi
# Do set -x after option parsing is complete
set -x
ZULIP_PATH="$(readlink -f "$(dirname "$0")"/../..)"
# Force a known locale. Some packages on PyPI fail to install in some locales.
export LC_ALL="C.UTF-8"
export LANG="C.UTF-8"
export LANGUAGE="C.UTF-8"
# Force a known path; this fixes problems on Debian where `su` from
# non-root may not adjust `$PATH` to root's.
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Check for a supported OS release.
if [ -f /etc/os-release ]; then
os_info="$(
. /etc/os-release
printf '%s\n' "$ID" "$ID_LIKE" "$VERSION_ID" "$VERSION_CODENAME"
)"
{
read -r os_id
read -r os_id_like
read -r os_version_id
read -r os_version_codename || true
} <<<"$os_info"
case " $os_id $os_id_like " in
*' debian '*)
package_system="apt"
;;
*' rhel '*)
package_system="yum"
;;
esac
fi
if ! "$ZULIP_PATH/scripts/lib/supported-os"; then
system_requirements_failure <<EOF
Unsupported OS release: $os_id $os_version_id
Zulip in production is supported only on:
- Debian 12
- Ubuntu 22.04 LTS
- Ubuntu 24.04 LTS
EOF
fi
machine="$(uname -m)"
if [ "$machine" != x86_64 ] && [ "$machine" != aarch64 ]; then
system_requirements_failure <<EOF
Unsupported CPU architecture: $machine (expected x86_64 or aarch64).
EOF
fi
dpkg_architecture="$(dpkg --print-architecture)"
if [ "$dpkg_architecture" != amd64 ] && [ "$dpkg_architecture" != arm64 ]; then
system_requirements_failure <<EOF
Unsupported OS architecture: $dpkg_architecture (expected amd64 or arm64).
EOF
fi
has_universe() {
apt-cache policy \
| grep -q "^ release v=$os_version_id,o=Ubuntu,a=$os_version_codename,n=$os_version_codename,l=Ubuntu,c=universe"
}
if [ "$os_id" = ubuntu ] && ! has_universe && ! { apt-get update && has_universe; }; then
system_requirements_failure <<EOF
You must enable the Ubuntu Universe repository before installing
Zulip. You can do this with:
sudo add-apt-repository universe
sudo apt update
EOF
fi
case ",$PUPPET_CLASSES," in
*,zulip::profile::standalone,* | *,zulip::profile::postgresql,*)
if [ "$package_system" = apt ]; then
# We're going to install PostgreSQL from the PostgreSQL apt
# repository; this may conflict with the existing PostgreSQL.
OTHER_PG="$(dpkg --get-selections \
| grep -E '^postgresql-[0-9]+\s+install$' \
| grep -v "^postgresql-$POSTGRESQL_VERSION\b" \
| cut -f 1)" || true
if [ -n "$OTHER_PG" ]; then
INDENTED="${OTHER_PG//$'\n'/$'\n' }"
SPACED="${OTHER_PG//$'\n'/ }"
cat <<EOF
The following PostgreSQL servers were found to already be installed:
$INDENTED
Zulip needs to install PostgreSQL $POSTGRESQL_VERSION, but does not wish
to uninstall existing databases in order to do so. Remove all other
PostgreSQL servers manually before running the installer:
sudo apt-get remove $SPACED
EOF
exit 1
fi
fi
;;
esac
# Check for at least ~1.86GB of RAM before starting installation;
# otherwise users will find out about insufficient RAM via weird
# errors like a segfault running `pip install`.
# Additionally, some AWS images that are advertised to be 2 GB
# are actually 1880000B in size.
mem_kb=$(head -n1 /proc/meminfo | awk '{print $2}')
if [ "$mem_kb" -lt 1860000 ]; then
set +x
echo -e '\033[0;31m' >&2
echo "Insufficient RAM. Zulip requires at least 2GB of RAM." >&2
echo >&2
echo -e '\033[0m' >&2
exit 1
fi
# Anything under 5GB, we recommended allocating 2GB of swap. Error
# out if there's no swap.
swap_kb=$(grep SwapTotal /proc/meminfo | awk '{print $2}')
if [ "$mem_kb" -lt 5000000 ] && [ "$swap_kb" -eq 0 ]; then
set +x
echo -e '\033[0;31m' >&2
echo "No swap allocated; when running with < 5GB of RAM, we recommend at least 2GB of swap." >&2
echo "https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-22-04" >&2
echo >&2
echo -e '\033[0m' >&2
exit 1
fi
# Do package update, e.g. do `apt-get update` on Debian
if [ "$package_system" = apt ]; then
# setup-apt-repo does an `apt-get update`
"$ZULIP_PATH"/scripts/lib/setup-apt-repo
elif [ "$package_system" = yum ]; then
"$ZULIP_PATH"/scripts/lib/setup-yum-repo
fi
# Check early for missing SSL certificates
if [ "$PUPPET_CLASSES" = "zulip::profile::standalone" ] && [ -z "$USE_CERTBOT""$SELF_SIGNED_CERT" ] && { ! [ -e "/etc/ssl/private/zulip.key" ] || ! [ -e "/etc/ssl/certs/zulip.combined-chain.crt" ]; }; then
set +x
cat <<EOF
No SSL certificate found. One or both required files is missing:
/etc/ssl/private/zulip.key
/etc/ssl/certs/zulip.combined-chain.crt
Suggested solutions:
* For most sites, the --certbot option is recommended.
* If you have your own key and cert, see docs linked below
for how to install them.
* For non-production testing, try the --self-signed-cert option.
For help and more details, see our SSL documentation:
https://zulip.readthedocs.io/en/latest/production/ssl-certificates.html
Once fixed, just rerun scripts/setup/install; it'll pick up from here!
EOF
exit 1
fi
# don't run dist-upgrade in one click apps to make the
# installation process more seamless.
if [ -z "$NO_DIST_UPGRADE" ]; then
if [ "$package_system" = apt ]; then
apt-get -y dist-upgrade "${APT_OPTIONS[@]}"
elif [ "$package_system" = yum ]; then
# On CentOS, there is no need to do `yum -y upgrade` because `yum -y
# update` already does the same thing.
:
fi
fi
if [ "$package_system" = apt ]; then
# Note that any additions to these lists must also be added to
# `zulip::profile::base` such that the new dependency is seen by
# upgrades, as well as new installs.
if ! apt-get install -y --no-install-recommends \
python3 python3-yaml puppet git curl jq crudini \
"${ADDITIONAL_PACKAGES[@]}"; then
set +x
echo -e '\033[0;31m' >&2
echo "Installing packages failed; is network working and (on Ubuntu) the universe repository enabled?" >&2
echo >&2
echo -e '\033[0m' >&2
exit 1
fi
elif [ "$package_system" = yum ]; then
if ! yum install -y \
python3 python3-pyyaml puppet git curl jq crudini \
"${ADDITIONAL_PACKAGES[@]}"; then
set +x
echo -e '\033[0;31m' >&2
echo "Installing packages failed; is network working?" >&2
echo >&2
echo -e '\033[0m' >&2
exit 1
fi
fi
# We generate a self-signed cert even with certbot, so we can use the
# webroot authenticator, which requires nginx be set up with a
# certificate.
if [ -n "$SELF_SIGNED_CERT" ] || [ -n "$USE_CERTBOT" ]; then
"$ZULIP_PATH"/scripts/setup/generate-self-signed-cert \
--exists-ok "${EXTERNAL_HOST:-$(hostname)}"
fi
# Generate /etc/zulip/zulip.conf .
mkdir -p /etc/zulip
has_class() {
grep -qx "$1" /var/lib/puppet/classes.txt
}
# puppet apply --noop fails unless the user that it _would_ chown
# files to exists; https://tickets.puppetlabs.com/browse/PUP-3907
#
# The home directory here should match what's declared in base.pp.
id -u zulip &>/dev/null || useradd -m zulip --home-dir /home/zulip
if [ -n "$NO_OVERWRITE_SETTINGS" ] && [ -e "/etc/zulip/zulip.conf" ]; then
"$ZULIP_PATH"/scripts/zulip-puppet-apply --noop \
--write-catalog-summary \
--classfile=/var/lib/puppet/classes.txt
else
# Write out more than we need, and remove sections that are not
# applicable to the classes that are actually necessary.
cat <<EOF >/etc/zulip/zulip.conf
[machine]
puppet_classes = $PUPPET_CLASSES
deploy_type = production
[postgresql]
version = $POSTGRESQL_VERSION
EOF
if [ -n "$POSTGRESQL_MISSING_DICTIONARIES" ]; then
crudini --set /etc/zulip/zulip.conf postgresql missing_dictionaries true
fi
"$ZULIP_PATH"/scripts/zulip-puppet-apply --noop \
--write-catalog-summary \
--classfile=/var/lib/puppet/classes.txt
# We only need the PostgreSQL version setting on database hosts,
# or hosts which talk directly to the database (e.g. application
# hosts); but we don't know if this is a database host until we
# have the catalog summary.
if (! has_class "zulip::postgresql_common" && ! has_class "zulip::postgresql_client") || [ "$package_system" != apt ]; then
crudini --del /etc/zulip/zulip.conf postgresql
fi
if [ -n "$POSTGRESQL_DATABASE_NAME" ]; then
crudini --set /etc/zulip/zulip.conf postgresql database_name "$POSTGRESQL_DATABASE_NAME"
fi
if [ -n "$POSTGRESQL_DATABASE_USER" ]; then
crudini --set /etc/zulip/zulip.conf postgresql database_user "$POSTGRESQL_DATABASE_USER"
fi
fi
if has_class "zulip::app_frontend_base"; then
# Frontend deploys use /home/zulip/deployments; without this, the
# install directory is also only readable by root.
mkdir -p /home/zulip/deployments
deploy_path=$("$ZULIP_PATH"/scripts/lib/zulip_tools.py make_deploy_path)
mv "$ZULIP_PATH" "$deploy_path"
ln -nsf /home/zulip/deployments/next "$ZULIP_PATH"
ln -nsf "$deploy_path" /home/zulip/deployments/next
# Create and activate a virtualenv
"$deploy_path"/scripts/lib/create-production-venv "$deploy_path"
"$deploy_path"/scripts/lib/install-node
if [ -z "$NO_OVERWRITE_SETTINGS" ] || ! [ -e "/etc/zulip/settings.py" ]; then
cp -a "$deploy_path"/zproject/prod_settings_template.py /etc/zulip/settings.py
if [ -n "$EXTERNAL_HOST" ]; then
sed -i "s/^EXTERNAL_HOST =.*/EXTERNAL_HOST = '$EXTERNAL_HOST'/" /etc/zulip/settings.py
fi
if [ -n "$ZULIP_ADMINISTRATOR" ]; then
sed -i "s/^ZULIP_ADMINISTRATOR =.*/ZULIP_ADMINISTRATOR = '$ZULIP_ADMINISTRATOR'/" /etc/zulip/settings.py
fi
# Set SERVICE settings based on what the user provided.
if grep -q -E "^#?\s*ZULIP_SERVICE_PUSH_NOTIFICATIONS = " /etc/zulip/settings.py; then
sed -i -E "s/^#?\s*ZULIP_SERVICE_PUSH_NOTIFICATIONS = .*/ZULIP_SERVICE_PUSH_NOTIFICATIONS = $SERVICE_MOBILE_PUSH/" /etc/zulip/settings.py
else
echo "ZULIP_SERVICE_PUSH_NOTIFICATIONS = $SERVICE_MOBILE_PUSH" >>/etc/zulip/settings.py
fi
if grep -q -E "^#?\s*ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS = " /etc/zulip/settings.py; then
sed -i -E "s/^#?\s*ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS = .*/ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS = $SERVICE_SUBMIT_USAGE_STATISTICS/" /etc/zulip/settings.py
else
echo "ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS = $SERVICE_SUBMIT_USAGE_STATISTICS" >>/etc/zulip/settings.py
fi
fi
ln -nsf /etc/zulip/settings.py "$deploy_path"/zproject/prod_settings.py
"$deploy_path"/scripts/setup/generate_secrets.py --production
else
deploy_path="$ZULIP_PATH"
fi
"$deploy_path"/scripts/zulip-puppet-apply -f
if [ "$package_system" = apt ]; then
apt-get -y --with-new-pkgs upgrade
elif [ "$package_system" = yum ]; then
# No action is required because `yum update` already does upgrade.
:
fi
if [ -n "$USE_CERTBOT" ]; then
"$deploy_path"/scripts/setup/setup-certbot \
"$EXTERNAL_HOST" --email "$ZULIP_ADMINISTRATOR"
fi
if has_class "zulip::nginx" && ! has_class "zulip::profile::docker"; then
# Check nginx was configured properly now that we've installed it.
# Most common failure mode is certs not having been installed.
if ! nginx -t; then
(
set +x
cat <<EOF
Verifying the Zulip nginx configuration failed!
This is almost always a problem with your SSL certificates. See:
https://zulip.readthedocs.io/en/latest/production/ssl-certificates.html
Once fixed, just rerun scripts/setup/install; it'll pick up from here!
EOF
exit 1
)
fi
fi
if has_class "zulip::profile::rabbitmq"; then
if ! rabbitmqctl status >/dev/null; then
set +x
cat <<EOF
RabbitMQ seems to not have started properly after the installation process.
Often this is caused by misconfigured /etc/hosts in virtualized environments.
For more information, see:
https://github.com/zulip/zulip/issues/53#issuecomment-143805121
EOF
exit 1
fi
fi
# Set up a basic .gitconfig for the 'zulip' user
if [ -n "$ZULIP_ADMINISTRATOR" ]; then
(
cd / # Make sure the current working directory is readable by zulip
su zulip -c "git config --global user.email $ZULIP_ADMINISTRATOR"
su zulip -c "git config --global user.name 'Zulip Server ($EXTERNAL_HOST)'"
)
fi
if ! has_class "zulip::app_frontend_base"; then
set +x
cat <<EOF
Success!
Not configuring PostgreSQL, or /home/zulip/deployments, because this
is not a front-end install.
EOF
exit 0
fi
ln -nsf "$deploy_path" /home/zulip/deployments/current
ln -nsf /etc/zulip/settings.py "$deploy_path"/zproject/prod_settings.py
mkdir -p "$deploy_path"/prod-static/serve
cp -rT "$deploy_path"/prod-static/serve /home/zulip/prod-static
chown -R zulip:zulip /home/zulip /var/log/zulip /etc/zulip/settings.py
if ! [ -e /home/zulip/deployments/current/zulip-git-version ]; then
mkdir /srv/zulip.git
chown zulip:zulip /srv/zulip.git
su zulip -c 'git clone --bare --mirror /home/zulip/deployments/current /srv/zulip.git'
su zulip -c 'cd /home/zulip/deployments/current && ./scripts/lib/update-git-upstream && ./tools/cache-zulip-git-version'
fi
if ! [ -e "/home/zulip/prod-static/generated" ]; then
# If we're installing from a Git checkout, we need to run
# `tools/update-prod-static` in order to build the static
# assets.
su zulip -c '/home/zulip/deployments/current/tools/update-prod-static'
fi
if [ -n "$NO_INIT_DB" ]; then
set +x
cat <<EOF
Success!
Stopping because --no-init-db was passed. To complete the
installation, configure PostgreSQL by creating the database and
database user, and then run:
su zulip -c '/home/zulip/deployments/current/scripts/setup/initialize-database'
su zulip -c '/home/zulip/deployments/current/manage.py generate_realm_creation_link'
EOF
if [ -n "$PUSH_NOTIFICATIONS" ]; then
echo
echo "Since you specified you want to enable the push notification service, you'll also need to "
echo "manually register your server by running:"
echo
echo " su zulip -c '/home/zulip/deployments/current/manage.py register_server'"
echo
fi
exit 0
else
/home/zulip/deployments/current/scripts/setup/create-database
su zulip -c '/home/zulip/deployments/current/scripts/setup/initialize-database --quiet'
if [ -n "$PUSH_NOTIFICATIONS" ]; then
if [ -z "$PUSH_NOTIFICATIONS_SERVICE_TOS_AGREED" ]; then
# This should be impossible as the installation should have aborted early if the user
# passed --push-notifications without accepting the ToS. But we include this as a precaution
# to not allow future bugs to cause ToS acceptance to be skipped.
SKIP_TOS_AGREEMENT_OPTION=""
else
SKIP_TOS_AGREEMENT_OPTION="--agree-to-terms-of-service"
fi
set +x
echo "Services enabled, attempting to register server..."
set -x
# Without PYTHONUNBUFFERED=1, stdout/stderr might end up displayed not in chronological order, resulting
# in confusing output to the user.
su zulip -c "PYTHONUNBUFFERED=1 /home/zulip/deployments/current/manage.py register_server ${SKIP_TOS_AGREEMENT_OPTION}" \
|| {
set +x
echo
echo "WARNING: Server registration for push notifications failed."
echo "This does not affect the rest of your Zulip installation."
echo
echo "To enable push notifications after resolving the issue, run:"
echo " su zulip -c '/home/zulip/deployments/current/manage.py register_server'"
echo
set -x
}
fi
su zulip -c '/home/zulip/deployments/current/manage.py generate_realm_creation_link'
fi