#!/bin/bash
#
# metadata_begin
# recipe: GitLab CE
# tags: centos9,centos9-stream,alma,rocky,oracle,fedora,debian11,debian12,ubuntu2004,ubuntu2204,ubuntu2404
# revision: 1
# description_ru: GitLab CE сервер
# description_en: GitLab CE server
# metadata_end
#

RNAME="GitLab_CE"

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

# Переменные
domainName="($DOMAINNAME)"
httpMethod="https"
GITLAB_CE_URL_DOWNLOAD="https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/"
SWAP_SIZE_FILE="1024"

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

# Проверка объёма ОЗУ. Если меньше 3 Гб, будет создан файл подкачки и ZRam в функцие mk_swap_zram_file
[ $(grep "MemTotal" /proc/meminfo | awk '{print $2}') -le 3040000 ] && lowMem="1"

# Проверка свободно места в корневом разделе. Должно быть не менее 7,5 Гб
[ $(df --output=avail / | grep "[0-9]") -ge 7500000 ] || { echo "There is not enough free space in the root partition. Free space must be at least 7,5G" && exit "1" ;}

# Информация об ОС
. /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
Пароль находится в файле /etc/gitlab/initial_root_password
Этот файл будет очищен при первом запуске повторной настройки через 24 часа.
ПРИМЕЧАНИЕ. Поскольку эти учетные данные могут присутствовать в файлах журналов
в виде обычного текста, настоятельно рекомендуется сменить пароль
https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password
${RNAME} доступен по адресу:
${httpMethod}://${domainName}
=========================

=========================
The ${RNAME} script completed successfully.
You can see the execution log in /root/${RNAME}.log
Password stored to /etc/gitlab/initial_root_password
This file will be cleaned up in first reconfigure run after 24 hours.
NOTE: Because these credentials might be present in your log files in plain text,
it is highly recommended to reset the password following
https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password
The ${RNAME} is available at:
${httpMethod}://${domainName}
=========================
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 $@
}

# Создание файла подкачки и ZRam
mk_swap_zram_file() {
if [ -z "$(swapon --show | grep zram)" ]; then
	case "${osLike}" in
	rhel )
		${DNF} -y install zram-generator
		${DNF} -y install zram-generator-defaults || return 0
		systemctl daemon-reload
		;;
	debian )
		ZRAM_CONFIG="/etc/systemd/zram-generator.conf"
		if [ "${ID}" = "debian" -a ${unaID} -eq 11 ]; then
			ZRAM_MIRROR="https://mirror.hoztnode.net/other/nabijaczleweli_xyz/debian/"
			printf "Types: deb\nURIs: ${ZRAM_MIRROR}\nSuites: bullseye\nComponents: main\ntrusted: yes\ncheck-valid-until: no\n" > /etc/apt/sources.list.d/systemd-zram.sources
			wget --no-check-certificate -O - ${ZRAM_MIRROR}/nabijaczleweli.gpg.key | apt-key add -
			wget --no-check-certificate -O - ${ZRAM_MIRROR}/pgp.txt | apt-key add -
		fi
		${DNF} update
		${DNF} -y install systemd-zram-generator
		[ "${ID}" = "ubuntu" -a ${unaID} -lt 24 ] && { sed -i '/^zram-fraction/czram-fraction\ =\ 1' ${ZRAM_CONFIG} ;} || \
		{ cp -ar ${ZRAM_CONFIG} ${ZRAM_CONFIG}.bak ; printf "[zram0]\n[zram1]\n" > ${ZRAM_CONFIG} ; }
		[ "${ID}" = "debian" -a ${unaID} -eq 11 ] && { rm -rf /etc/apt/sources.list.d/systemd-zram.sources ; ${DNF} autoclean ; }
		systemctl daemon-reload
		systemctl start systemd-zram-setup@zram0.service 2>&1 >/dev/null
		[ "${ID}" = "ubuntu" -a ${unaID} -lt 24 ] || systemctl start systemd-zram-setup@zram1.service 2>&1 >/dev/null
		;;
	esac
fi
sleep 2
[ "${ID}" = "ubuntu" ] && SWAP_SIZE_FILE="2048"
if [ ! -f /swapfile ]; then
	dd if=/dev/zero of=/swapfile bs=1MB count=${SWAP_SIZE_FILE}
	chmod 600 /swapfile
	mkswap /swapfile
	swapon /swapfile -p 101
	grep -q "^/swapfile" /etc/fstab || echo "/swapfile swap swap defaults 0 0" >> /etc/fstab
fi
swapTotal="$(cat /proc/meminfo | grep -i "SwapTotal" | awk '{print $2}')"
[ ${swapTotal} -le 2400000 ] && { echo "Low total memory" && exit 1 ; }
[ ${swapTotal} -le 3000000 -a "${ID}" = "ubuntu" ] && { echo "Low total memory" && exit 1 ; }
}

# Установка основных программ и подготовка базовых репозиториев
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 ca-certificates curl postfix
fi
if [ "${osLike}" = "rhel" ]; then
	${DNF} -y install curl policycoreutils perl
	${DNF} -y install postfix
fi
}

# настройка компонентов ОС
configure_system() {
grep -q "127.0.0.1" /etc/hosts || \
cat >> /etc/hosts <<- 'EOF'
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
EOF
}

# Определение и настройка фаервола
config_firewall() {
if [ -f /usr/sbin/ufw ] && $(ufw status | grep -i "Status" | grep -qi " active\|enable"); then
	ufw allow http
	ufw allow https
fi
if [ -f /usr/sbin/firewalld -a $(systemctl is-active firewalld.service 2>/dev/null) = "active" ]; then
	firewalldZone="$(firewall-cmd --get-default-zone)"
	firewall-cmd --permanent --zone=${firewalldZone} --remove-service=dhcpv6-client 2>&1 >/dev/null || return 0
	firewall-cmd --permanent --zone=${firewalldZone} --add-service=http
	firewall-cmd --permanent --zone=${firewalldZone} --add-service=https
	firewall-cmd --reload
fi
}

# Установка GitLab CE
install_gitlab_ce() {
case "${osLike}" in
	debian )
		wget -O /root/script.sh ${GITLAB_CE_URL_DOWNLOAD}/script.deb.sh
		;;
	rhel )
		wget -O /root/script.sh ${GITLAB_CE_URL_DOWNLOAD}/script.rpm.sh
		;;
esac  || { echo "Can not download install script" && exit 1 ; }
bash /root/script.sh && rm -rf /root/script.sh
if [ "${ID}" = "fedora" -a ${unaID} -ge 40 ]; then
	${DNF} -y install dnf-utils
	sed -i "s/fedora\/${VERSION_ID}/el\/9/" /etc/yum.repos.d/gitlab_gitlab-ce.repo
fi
[ -z "${domainName}" -o "${domainName}" = "()" ] && { domainName="${ipv4Addr}" && httpMethod="http" ; }
EXTERNAL_URL="${httpMethod}://${domainName}" \
${DNF} -y install gitlab-ce
}

install_soft
configure_system
[ -n "${lowMem}" ] && mk_swap_zram_file
config_firewall || { echo "Can not configure firewall" && exit 1 ; }
install_gitlab_ce || { echo "Can not install GitLab CE" && 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/users/sign_in 2>&1 | grep -qi "gitlab" && { final_text && exit 0 ; }
	q=$(($q + 1))
	sleep 2
done

exit 1