#!/bin/sh
# What an upgrade has to do again on a machine that is already a phone system.
#
# The first boot is the only thing that ever puts a service in a runlevel or
# writes Asterisk's files, and it returns at its first line once
# /etc/nuxpbx/installed exists. So a machine installed before a unit or a file
# existed never receives it: the firewall shipped that way, and on those
# machines /etc/init.d/nuxpbx-firewall arrives with the upgrade, is in no
# runlevel, and closes nothing for as long as the box stands. The Debian
# package's postinst has done this since it learned to; apk runs this script on
# an upgrade and not on an install, which is exactly the machine that needs it.
[ -e /etc/nuxpbx/installed ] || exit 0

for service in nuxpbx nuxpbx-firewall; do
	rc-update add "$service" default >/dev/null 2>&1 || true
done

# Where updates come from, for a machine installed before the path lost its
# branch. The first boot used to write alpine/<branch>/nuxpbx and nothing ever
# looked at that line again, so upgrading the machine to a newer Alpine left it
# pointing at a branch nothing is published under any more: apk finds nothing
# there and nuxpbx-update reports that the newest version is already installed.
# This upgrade arrived through the old path, which is the last thing it can do
# for that machine, so the line moves here. Debian's half of this lives in its
# postinst and runs on every configure, for the same reason.
if [ -f /etc/apk/repositories ]; then
	sed -i 's#\(apt\.team-nifty\.com/alpine/\)v[0-9.]*/nuxpbx#\1nuxpbx#' \
		/etc/apk/repositories
fi

# Started as well as added: a runlevel is read at the next boot, which on a
# phone system is months away, and the ports it closes are open until then.
# The script refuses rather than write rules it cannot see an ssh port in, so
# this cannot shut out whoever is typing.
if command -v nft >/dev/null 2>&1; then
	rc-service nuxpbx-firewall restart >/dev/null 2>&1 \
		|| echo "the ports were left open: nuxpbx-firewall refused, run it by hand to see why" >&2
fi

# The recordings and the mailboxes, which the first boot left readable by
# every account on the machine: 2775 keeps o+rx and the spool above them is
# shipped 0755, so a local login read every recorded call, every voicemail and
# the caller id beside each message. The first boot writes the narrower modes
# now and returns at its first line on a machine that is already a phone
# system, so this is the only thing that reaches the ones already standing.
# Both users that need these are in the asterisk group.
chmod 0750 /var/spool/asterisk 2>/dev/null || true
chmod 2770 /var/spool/asterisk/monitor /var/spool/asterisk/voicemail 2>/dev/null || true

# And the address this machine hands out, which the first boot learned to write
# down and the first boot alone: it returns at its first line once
# /etc/nuxpbx/installed exists, so every machine installed before that still
# falls back to the loopback address. That address goes into the pairing file a
# phone is set up from, the Listen link on a message and on a recording, the
# address a spreadsheet is fetched from, and public_url in GET /api/v1 -- and
# it is nobody else's machine, so a paired phone looks for the phone system
# inside itself. Read off this machine, like the welcome text.
#
# Only where the key is absent, so a name somebody typed in is left alone; and
# only where there is an address to name, so a box that cannot answer the
# question is asked again on the next upgrade rather than pinned to the
# loopback one for good. Debian's half of this lives in its postinst.
if [ -f /etc/nuxpbx/nuxpbx.env ] \
	&& ! grep -q '^NUXPBX_PUBLIC_URL=' /etc/nuxpbx/nuxpbx.env; then
	address=$(ip -4 -o addr show scope global 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -1)
	port=$(sed -n 's/^NUXPBX_HTTP_ADDR=.*:\([0-9][0-9]*\)$/\1/p' /etc/nuxpbx/nuxpbx.env | tail -1)
	if [ -n "$address" ]; then
		printf 'NUXPBX_PUBLIC_URL=http://%s:%s\n' "$address" "${port:-8080}" \
			>>/etc/nuxpbx/nuxpbx.env
	fi
fi

# And the new binary is the one that should be running.
rc-service nuxpbx restart >/dev/null 2>&1 || true

# The files nuxpbx renders for Asterisk are written at the first boot too, so
# an upgraded machine never receives one that was added since. Nothing else on
# the box renders them: the daemon does not at start, and the one path that
# does is a routing change pressed in a browser.
#
# After the restart, because the render reads the schema and the restart is
# what applies the migrations this version brought. Run before it, the render
# meets columns that do not exist yet and writes nothing at all, precisely on
# the upgrades that carry a file change. The restart returns once the service
# is started and not once the daemon has migrated, so the render is tried until
# the schema it needs is there, and what it says is kept rather than sent to
# /dev/null under a `|| true`.
tries=0
while :; do
	if said=$(/usr/sbin/nuxpbx-render 2>&1); then
		break
	fi
	tries=$((tries + 1))
	if [ "$tries" -ge 30 ]; then
		echo "Asterisk's files were not written: $said" >&2
		echo "run nuxpbx-render by hand once the phone system is up" >&2
		break
	fi
	sleep 1
done

exit 0
