#!/bin/bash
#
# metadata_begin
# recipe: Forgejo Git
# tags: centos9,centos9-stream,alma,rocky,oracle,fedora,debian11,debian12,ubuntu2004,ubuntu2204,ubuntu2404
# revision: 2
# description_ru: Forgejo Git server
# description_en: Forgejo Git server
# metadata_end
#

RNAME="Forgejo"

set -x

LOG_PIPE=/tmp/log.pipe.$$
mkfifo ${LOG_PIPE}
LOG_FILE=/root/${RNAME}.log
touch ${LOG_FILE}
chmod 600 ${LOG_FILE}
tee < ${LOG_PIPE} ${LOG_FILE} &
exec > ${LOG_PIPE}
exec 2> ${LOG_PIPE}

killjobs() {
    test -n "$(jobs -p)" && kill $(jobs -p) || :
}
trap killjobs INT TERM EXIT

echo
echo "=== Recipe ${RNAME} started at $(date) ==="
echo

# Переменные
FORGEJO_BIN_DOWNLOAD="https://codeberg.org/forgejo/forgejo/releases/download/v8.0.1/forgejo-8.0.1-linux-amd64"
FORGEJO_ASC_DOWNLOAD="https://codeberg.org/forgejo/forgejo/releases/download/v8.0.1/forgejo-8.0.1-linux-amd64.asc"
FORGEJO_SYSTEMD_SERVICE_DOWNLOAD="https://codeberg.org/forgejo/forgejo/raw/branch/forgejo/contrib/systemd/forgejo.service"
WORK_DIR="/usr/local/bin/"
ETC_DIR="/etc/forgejo/"
VAR_DIR="/var/lib/forgejo/"

# Определение IP-адресов и сетевой карты
ipv4Addr=$(ip route get 1 | grep -Po '(?<=src )[^ ]+')

# Информация об ОС
. /etc/os-release
osLike="${ID_LIKE}"
[ "${ID}" = "debian" ] && osLike="debian"
echo ${ID_LIKE} | grep -q "rhel\|fedora" && osLike="rhel"
[ "${ID}" = "fedora" ] && osLike="rhel"
unaID=$(echo ${VERSION_ID} | sed -r 's/\..+//')

# Определение пакетного менеджера
DNF="/usr/bin/yum"
[ -f /usr/bin/dnf ] && DNF="/usr/bin/dnf"
[ -f /usr/bin/apt ] && { export DEBIAN_FRONTEND=noninteractive ; DNF="apt_Installer" ; }
[ -n "${DNF}" ] || exit 1

# Финальный текст
final_text() {
cat > /root/${RNAME}-script-final.txt <<- EOF
=========================
Работа скрипта ${RNAME} успешно завершена.
Журнал выполнения вы можете посмотреть в файле /root/${RNAME}.log
Интсрукция от разработчика https://forgejo.org/docs/latest/admin/
База данных по умолчанию SQLite3
Панель ${RNAME} доступна по адресу:
http://${ipv4Addr}:3000/
=========================

=========================
The ${RNAME} script completed successfully.
You can see the execution log in /root/${RNAME}.log
Manual https://forgejo.org/docs/latest/admin/
Default database SQLite3
The ${RNAME} panel is available at:
http://${ipv4Addr}:3000/
=========================
EOF
}

# Определяем инсталятор apt и его опции. Обходим фоновые задачи установки и одновления ОС
apt_Installer() {
while ps uxaww | grep -v grep | grep -Eq 'apt|dpkg|unattended' ; do echo "waiting..." ; sleep 5 ; done && \
/usr/bin/apt -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-confdef" -q 	--allow-downgrades --allow-remove-essential --allow-change-held-packages $@
}

# Установка основных программ и подготовка базовых репозиториев
install_soft() {
if [ "${osLike}" = "debian" ]; then
	[ $(systemctl is-active unattended-upgrades.service 2>/dev/null) = "active" ] && { systemctl stop unattended-upgrades.service && unattServ="0" ; }
	${DNF} update && ${DNF} -y install git git-lfs gpg
fi
[ "${osLike}" = "rhel" ] && \
${DNF} -y install git git-lfs
}

# Определение и настройка фаервола
config_firewall() {
([ -f /usr/sbin/ufw ] && $(ufw status | grep -i "Status" | grep -qi " active\|enable")) && ufw allow 3000/tcp
if [ -f /usr/sbin/firewalld -a $(systemctl is-active firewalld.service 2>/dev/null) = "active" ]; then
	firewalldZone="$(firewall-cmd --get-default-zone)"
	[ ! -f /usr/lib/firewalld/services/forgejo.xml ] && \
	cat << 'EOF' > /etc/firewalld/services/forgejo.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Forgejo</short>
  <description>Forgejo Git server</description>
  <port protocol="tcp" port="3000"/>
</service>
EOF
	firewall-cmd --reload
	firewall-cmd --permanent --zone=${firewalldZone} --remove-service=dhcpv6-client 2>&1 >/dev/null || return 0
	firewall-cmd --permanent --zone=${firewalldZone} --add-service=forgejo
	firewall-cmd --reload
fi
}

# Установка Forgejo
install_forgejo() {
mkdir -p ${WORK_DIR}
wget -O /root/forgejo.asc ${FORGEJO_ASC_DOWNLOAD}
wget -O ${WORK_DIR}/forgejo ${FORGEJO_BIN_DOWNLOAD}
gpg --keyserver keys.openpgp.org --recv EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
$(gpg --verify /root/forgejo.asc ${WORK_DIR}/forgejo 2>&1 | grep -q "Good") || { echo "Can not verify GPG signature" && exit 1 ; } && rm -rf /root/forgejo.asc
chmod 755 ${WORK_DIR}/forgejo
case "${osLike}" in
	debian )
		adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
		;;
	rhel )
		groupadd --system git
		adduser --system --shell /bin/bash --comment 'Git Version Control' --gid git --home-dir /home/git --create-home git
		;;
esac  || { echo "Can not create user" && exit 1 ; }
mkdir -p ${VAR_DIR} && chown git:git ${VAR_DIR} && chmod 750 ${VAR_DIR}
mkdir -p ${ETC_DIR} && chown root:git ${ETC_DIR} && chmod 770 ${ETC_DIR}
cat > ${ETC_DIR}/app.ini <<- 'EOF'
[database]
DB_TYPE = sqlite3
HOST = 127.0.0.1:3306
NAME = forgejo
USER = forgejo
PASSWD =
SCHEMA =
SSL_MODE = disable
PATH = /var/lib/forgejo/data/forgejo.db
LOG_SQL = false
EOF
chmod 640 ${ETC_DIR}/app.ini
chown git:git ${ETC_DIR}/app.ini

wget -O /etc/systemd/system/forgejo.service ${FORGEJO_SYSTEMD_SERVICE_DOWNLOAD}

systemctl daemon-reload
systemctl enable forgejo.service
systemctl start forgejo.service
}

install_soft
install_forgejo || { echo "Can not install Forgejo" && exit 1 ; }
config_firewall || { echo "Can not configure firewall" && exit 1 ; }
[ -n "${unattServ}" ] && { systemctl start unattended-upgrades.service ; }

# Проверка
q=0
i=20
while [ $q -le $i ]; do
	curl -v --silent http://127.0.0.1:3000 2>&1 | grep -qi "forgejo" && final_text && exit 0
	q=$(($q + 1))
	sleep 2
done

exit 1
