#!/bin/sh
#
# metadata_begin
# recipe: Redmine
# tags: centos9,debian11,debian12,ubuntu2204,ubuntu2404,alma8,alma9,oracle8,oracle9,rocky8,rocky9
# revision: 27
# description_ru: Баг трекер Redmine. Логин: admin. Пароль или admin или пароль рута (зависит от ОС)
# description_en: Redmine bug tracker. Login: admin. Password: admin or Your root password (depend on os type)
# metadata_end
#
RNAME=Redmine
export REDMINE_VER_60=6.0.3
export REDMINE_VER_51=5.1.6
export REDMINE_VER_50=5.0.11

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}
umask 0022

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

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

if [ -f /etc/redhat-release ]; then
	OSNAME=centos
else
	OSNAME=debian
fi

RootMyCnf() {
	# Saving mysql password
	touch /root/.my.cnf 
	chmod 600 /root/.my.cnf
	echo "[client]" > /root/.my.cnf
	echo "password=${1}" >> /root/.my.cnf

}

Service() {
	# $1 - name
	# $2 - command

	if [ -n "$(which systemctl 2>/dev/null)" ]; then
		systemctl ${2} ${1}.service
	else
		if [ "${2}" = "enable" ]; then
			if [ "${OSNAME}" = "debian" ]; then
				update-rc.d ${1} enable
			else
				chkconfig ${1} on
			fi
		else
			service ${1} ${2}
		fi
	fi
}

NginxConfig() {
	echo '# Upstream Ruby process cluster for load balancing
upstream thin_cluster {
    server unix:/var/run/redmine/redmine.0.sock;
    server unix:/var/run/redmine/redmine.1.sock;
    server unix:/var/run/redmine/redmine.2.sock;
}

server {
    listen       80;
    server_name  your.domain.name;

    proxy_set_header   Host $http_host;                                                                                                                     
    proxy_set_header   X-Real-IP $remote_addr;                                                                                                                   
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;

    client_max_body_size       10m;
    client_body_buffer_size    128k;

    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;

    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;

    root /var/www/redmine/public;

    proxy_redirect off;

    location / {
        try_files $uri/index.html $uri.html $uri @cluster;
    }

    location @cluster {
        proxy_pass http://thin_cluster;
    }
}
' > ${1}
}

ThinSystemdBundleScl() {
	echo '[Unit]
Description=A fast and very simple Ruby web server
After=syslog.target network.target

[Service]
Type=forking
WorkingDirectory=/var/www/redmine
ExecStart=/usr/bin/scl enable rh-ruby25 -- bundle exec thin start -C /etc/thin/redmine.yml
ExecReload=/usr/bin/scl enable rh-ruby25 -- bundle exec thin restart -C /etc/thin/redmine.yml
ExecStop=/usr/bin/scl enable rh-ruby25 -- bundle exec thin stop -C /etc/thin/redmine.yml
TimeoutSec=300

[Install]
WantedBy=multi-user.target' > /etc/systemd/system/${1}.service

echo 'd /var/run/redmine 0755 redmine redmine -' > /etc/tmpfiles.d/${1}.conf
}

ThinSystemdBundle() {
echo '[Unit]
Description=A fast and very simple Ruby web server
After=syslog.target network.target

[Service]
Type=forking
WorkingDirectory=/var/www/redmine
ExecStart=/usr/bin/bundle exec thin start -C /etc/thin/redmine.yml
ExecReload=/usr/bin/bundle exec thin restart -C /etc/thin/redmine.yml
ExecStop=/usr/bin/bundle exec thin stop -C /etc/thin/redmine.yml
TimeoutSec=300

[Install]
WantedBy=multi-user.target' > /etc/systemd/system/${1}.service

echo 'd /var/run/redmine 0755 redmine redmine -' > /etc/tmpfiles.d/${1}.conf
}

NginxRepo() {
	# nginx repo
cat > /etc/yum.repos.d/nginx.repo << EOF
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/${OSREL}/\$basearch/
gpgcheck=0
enabled=1
EOF
}


if [ "${OSNAME}" = "debian" ]; then
	export DEBIAN_FRONTEND="noninteractive"

	# Wait firstrun script
	while ps uxaww | grep  -v grep | grep -Eq 'apt-get|dpkg' ; do echo "waiting..." ; sleep 3 ; done
	apt-get update --allow-releaseinfo-change || :
	apt-get update
	test -f /usr/bin/which || apt-get -y install which
	which lsb_release 2>/dev/null || apt-get -y install lsb-release
	which logger 2>/dev/null || apt-get -y install bsdutils
	pkglist="vim ruby ruby-dev gcc g++ libmagickwand-dev bundler nginx pwgen"

	if [ "$(lsb_release -s -c)" = "bullseye" ] || [ "$(lsb_release -s -c)" = "bookworm" ]; then
		pkglist="${pkglist} mariadb-server libmariadb-dev-compat libmariadb-dev libyaml-dev"
	else
    	pkglist="${pkglist} mysql-server mysql-client libmysqlclient-dev libyaml-dev"
	fi
	
	_tmppass="($PASS)"
	if [ -n "${_tmppass}" ] && [ "${_tmppass}" != "()" ]; then
		mysqlpass="${_tmppass}"
	else
		apt-get -y install pwgen
		mysqlpass=$(pwgen -s 10 1)
	fi

	if [ -z "$(ls /var/lib/mysql/)" ]; then
		install_mysql=yes
	fi
	if [ -n "${install_mysql}" ]; then
		# Setting mysql root password
		echo "mysql-server mysql-server/root_password password ${mysqlpass}" | debconf-set-selections
		echo "mysql-server mysql-server/root_password_again password ${mysqlpass}" | debconf-set-selections
	fi

	# Installing packages
	apt-get -y install ${pkglist} || apt-get -y install ${pkglist} || apt-get -y install ${pkglist}

	if [ "${install_mysql}" ] && [ ! -e /root/.my.cnf ]; then
		RootMyCnf ${mysqlpass}
	fi

else
	OSREL=$(rpm -qf --qf '%{version}' /etc/redhat-release | cut -d . -f 1)
	yum -y update
	# Setting proxy
	# shellcheck disable=SC2154
	if [ ! "($HTTPPROXYv4)" = "()" ]; then
		# Стрипаем пробелы, если они есть
		PR="($HTTPPROXYv4)"
		PR=$(echo ${PR} | sed "s/''//g" | sed 's/""//g')
		if [ -n "${PR}" ]; then
			echo "proxy=${PR}" >> /etc/yum.conf
		fi
	fi

	NginxRepo
	
	if [ "$OSREL" = "8" ]; then
        yum -y install epel-release || yum -y install oracle-epel-release-el8
		yum config-manager --set-enabled powertools
		yum config-manager --set-enabled ol8_codeready_builder
        pkglist="ruby ruby-devel rubygem-bundler libxslt-devel libxml2-devel tar redhat-rpm-config make ImageMagick libyaml-devel"
	else
		yum -y install epel-release || yum -y install oracle-epel-release-el9
		pkglist="ruby ruby-devel rubygem-bundler libxslt-devel libxml2-devel tar redhat-rpm-config make ImageMagick wget"
	fi
	if [ "${OSREL}" = "8" ]; then
		pkglist="${pkglist} mariadb-server mariadb-devel"
		mysqlname=mariadb
	else
		pkglist="${pkglist} mariadb mariadb-server mariadb-connector-c mariadb-connector-c-devel"
		mysqlname=mariadb
	fi
	pkglist="${pkglist} gcc gcc-c++ wget nginx which pwgen"

	yum -y install ${pkglist} || yum -y install ${pkglist} || yum -y install ${pkglist}
	# Removing proxy
	sed -r -i "/proxy=/d" /etc/yum.conf

	Service ${mysqlname} enable

	if [ -z "$(ls /var/lib/mysql/)" ]; then
		install_mysql=yes
	fi
	Service ${mysqlname} start

	if [ -n "${install_mysql}" ]; then
		# Setting mysql password
		_tmppass="($PASS)"
		if [ -n "${_tmppass}" ] && [ "${_tmppass}" != "()" ]; then
			mysqlpass="${_tmppass}"
		else
			rpm -q pwgen || yum -y install pwgen
			mysqlpass=$(pwgen -s 10 1)
		fi
		/usr/bin/mysqladmin -u root password ${mysqlpass}
		RootMyCnf ${mysqlpass}
		echo "DELETE FROM user WHERE Password='';" | mysql --defaults-file=/root/.my.cnf -N mysql
	fi
fi

# Fetch and extract
if [ "${OSREL}" = "8" ]; then
	wget --no-check-certificate -O /tmp/redmine-${REDMINE_VER_50}.tar.gz http://www.redmine.org/releases/redmine-${REDMINE_VER_50}.tar.gz
	mkdir -p /var/www/redmine
	tar --strip-components=1 -xpzf /tmp/redmine-${REDMINE_VER_50}.tar.gz -C /var/www/redmine
elif [ "$(lsb_release -s -c)" != "bookworm" ] || [ "${OSREL}" = "9" ]; then
	wget --no-check-certificate -O /tmp/redmine-${REDMINE_VER_51}.tar.gz http://www.redmine.org/releases/redmine-${REDMINE_VER_51}.tar.gz
	mkdir -p /var/www/redmine
	tar --strip-components=1 -xpzf /tmp/redmine-${REDMINE_VER_51}.tar.gz -C /var/www/redmine
else
	wget --no-check-certificate -O /tmp/redmine-${REDMINE_VER_60}.tar.gz http://www.redmine.org/releases/redmine-${REDMINE_VER_60}.tar.gz
	mkdir -p /var/www/redmine
	tar --strip-components=1 -xpzf /tmp/redmine-${REDMINE_VER_60}.tar.gz -C /var/www/redmine
fi

# Create db
echo "CREATE DATABASE redmine_prod DEFAULT CHARACTER SET utf8" | mysql --defaults-file=/root/.my.cnf -N || exit 1
echo "CREATE DATABASE redmine_dev DEFAULT CHARACTER SET utf8" | mysql --defaults-file=/root/.my.cnf -N || exit 1
redmine_db_pass=$(pwgen -s 10 1)
echo "CREATE USER 'redmine'@'localhost' IDENTIFIED BY '${redmine_db_pass}';" | mysql --defaults-file=/root/.my.cnf -N mysql || exit 1
echo "GRANT ALL PRIVILEGES ON redmine_dev.* TO 'redmine'@'localhost';" | mysql --defaults-file=/root/.my.cnf -N mysql || exit 1
echo "GRANT ALL PRIVILEGES ON redmine_prod.* TO 'redmine'@'localhost';" | mysql --defaults-file=/root/.my.cnf -N mysql || exit 1

# DB config
cat > /var/www/redmine/config/database.yml << EOF
development:
  adapter: mysql2
  database: redmine_dev
  host: localhost
  username: redmine
  password: ${redmine_db_pass}
production:
  adapter: mysql2
  database: redmine_prod
  host: localhost
  username: redmine
  password: ${redmine_db_pass}
EOF

useradd redmine
mkdir -p /var/run/redmine
chown redmine /var/run/redmine
cd /var/www/redmine || exit

export RAILS_ENV=production
export REDMINE_LANG=en
export HOME="/home/redmine"

# Gem installing
if [ "${OSNAME}" = "centos" ]; then
	if [ "${OSREL}" = "8" ]; then
		sed -i "/gem 'psych'/cgem 'psych', '>= 1.12.0', '<= 3.1.0'" Gemfile
	else
		gem update bundler
	fi
else
	if [ "$(lsb_release -s -c)" != "focal" ] ; then
		gem update bundler
	else
		sed -i "/gem 'thor'/cgem 'thor', '~> 1.0'" Gemfile
	fi
fi
echo "gem 'concurrent-ruby', '1.3.4'" >> Gemfile
echo 'gem "bigdecimal"' >> Gemfile
echo 'gem "json"' >> Gemfile
bundle update concurrent-ruby --conservative
bundle install --path .gem

# Run migration
pwgen -s 32 1 > config/master.key
chmod 600 config/master.key
# shellcheck disable=SC2086,SC2209
EDITOR=cat bundle exec rails credentials:edit
chown -R redmine:redmine config
bundle lock
sed -i "s/ffi ([0-9.]*)/ffi (1.16.3)/g" /var/www/redmine/Gemfile.lock
bundle install
bundle exec rake db:migrate || exit 1
bundle exec rake generate_secret_token

# load default data
bundle exec rake redmine:load_default_data

# Change password
_tmppass="($PASS)"
if [ -n "${_tmppass}" ] && [ "${_tmppass}" != "()" ]; then
	echo "update user set hashed_password='49d76bd94e46e59d575f399757c476a7dd22874b', salt='' where id=1;" | mysql --defaults-file=/root/.my.cnf -N mysql
fi


# Dir permisiions
mkdir -p tmp tmp/pdf public/plugin_assets
chown -R redmine:redmine files log tmp public/plugin_assets
chmod -R 755 files log tmp public/plugin_assets

# Thin

if [ "${OSNAME}" = "centos" ]; then
	echo 'gem "thin"' >> Gemfile
	bundle install
	ThinSystemdBundle thin-redmine
	systemctl daemon-reload
	thinservice=thin-redmine
else
	echo 'gem "thin"' >> Gemfile
	bundle install
	ThinSystemdBundle thin-redmine
	systemctl daemon-reload
	thinservice=thin-redmine
fi

mkdir -p /etc/thin
echo 'pid: /var/www/redmine/tmp/pids/thin.pid
group: redmine
wait: 30
timeout: 30
log: /var/www/redmine/log/thin.log
max_conns: 1024
require: []

environment: production
max_persistent_conns: 512
servers: 3
daemonize: true
user: redmine
socket: /var/run/redmine/redmine.sock
chdir: /var/www/redmine 
' > /etc/thin/redmine.yml

Service ${thinservice} enable
Service ${thinservice} start || exit 1

# Nginx
if [ -f /etc/nginx/conf.d/default.conf ]; then
	echo "#Disabled" > /etc/nginx/conf.d/default.conf
fi
if [ -f /etc/nginx/sites-enabled/default ]; then
	rm /etc/nginx/sites-enabled/default
fi
if [ "${OSREL}" = "8" ]; then
    sed -i '/server {/,$d'  /etc/nginx/nginx.conf
    echo '}' >> /etc/nginx/nginx.conf
fi
NginxConfig /etc/nginx/conf.d/redmine.conf

if Service apache2 status ; then
	Service apache2 stop
	Service apache2 disable
fi

Service nginx enable
Service nginx restart
if [ "${OSNAME}" = "centos" ]; then
    which firewall-cmd 2>/dev/null || exit 0
	firewall-cmd --permanent --zone=public --add-port=80/tcp
	firewall-cmd --reload
fi
