#!/usr/bin/bash # author: Rénich Bon Ćirić # description: Sets up bare Git infrastructure for server push-to-deploy management set -euo pipefail IFS=$'\n\t' readonly RepoBase="/srv/git" readonly ReposDir="${RepoBase}/repos" readonly DeploysDir="${RepoBase}/deploys" readonly AdminUser="${SUDO_USER:-renich}" readonly MgmtRepo="${ReposDir}/management.git" readonly MgmtDeploy="${DeploysDir}/management.deploy" readonly HookFile="${MgmtDeploy}/hooks/post-receive" # 1. Privilege validation if [[ ${EUID} -ne 0 ]]; then echo "Error: This script must be run as root." >&2 exit 1 fi # 2. Package installation if ! command -v git &>/dev/null; then dnf install -y git fi # 3. System groups creation (idempotent) for grp in gitters deployers; do if ! getent group "${grp}" &>/dev/null; then groupadd -r "${grp}" fi done # Ensure the administrative user belongs to both groups if id -u "${AdminUser}" &>/dev/null; then usermod -aG gitters,deployers "${AdminUser}" fi # 4. Directory structure with SGID permissions install -d -m 2775 -g gitters "${RepoBase}" install -d -m 2775 -g gitters "${ReposDir}" install -d -m 2770 -g deployers "${DeploysDir}" # 5. Management bare repositories initialization (--shared=group) if [[ ! -d "${MgmtRepo}" ]]; then git init --bare --shared=group "${MgmtRepo}" chown -R root:gitters "${MgmtRepo}" chmod -R g+rwX "${MgmtRepo}" fi if [[ ! -d "${MgmtDeploy}" ]]; then git init --bare --shared=group "${MgmtDeploy}" chown -R root:deployers "${MgmtDeploy}" chmod -R g+rwX "${MgmtDeploy}" fi # 6. Post-receive deployment hook cat << 'EOF' > "${HookFile}" #!/usr/bin/bash set -euo pipefail IFS=$'\n\t' target_dir="/" export GIT_WORK_TREE="${target_dir}" export GIT_DIR="/srv/git/deploys/management.deploy" git checkout -f # Lock down /root if [[ -d /root ]]; then chmod 0700 /root fi # Normalize user homes and SELinux contexts if [[ -d /home ]]; then while IFS=: read -r username _ uid gid _ home _; do # Only process regular users (UID >= 1000) with home under /home if [[ ${uid} -ge 1000 && "${home}" == /home/* && -d "${home}" ]]; then chown -R "${username}:${gid}" "${home}" chmod 0700 "${home}" if command -v restorecon &>/dev/null && selinuxenabled 2>/dev/null; then restorecon -R "${home}" 2>/dev/null || true fi fi done < /etc/passwd fi # Restore SELinux contexts for root if command -v restorecon &>/dev/null && selinuxenabled 2>/dev/null; then restorecon -R /root 2>/dev/null || true fi EOF chown root:deployers "${HookFile}" chmod 0750 "${HookFile}" # 7. SELinux restoration on /srv/git if command -v restorecon &>/dev/null && selinuxenabled 2>/dev/null; then restorecon -R "${RepoBase}" 2>/dev/null || true fi cat << EOF ========================================================== Git deployment infrastructure setup complete. - Central repo : ${MgmtRepo} (group: gitters) - Deploy repo : ${MgmtDeploy} (group: deployers, target: /) - Admin user : ${AdminUser} (member of gitters, deployers) ========================================================== EOF