gitpages

A collection of scripts to securely webhost and publish git repositories.
git clone https://scm.kuandu.systems/git-raw/gitpages.git
Log | Files | Refs | README | LICENSE

install.sh (4645B)


      1 #!/bin/sh
      2 
      3 set -eu
      4 
      5 log() { printf 'info: %s\n' "$1"; }
      6 warn() { printf 'warning: %s\n' "$1" >&2; }
      7 error() {
      8   printf 'error: %s\n' "$1" >&2
      9   exit 1
     10 }
     11 
     12 usage() {
     13   printf 'usage: %s <git-user> <git-src> <web-root>\n' "$(basename "$0")"
     14   exit 1
     15 }
     16 
     17 setup_dirs() {
     18   install -d -m 755 -o "$USER_NAME" -g "$GROUP_NAME" "$VAR_DIR" "$LOG_DIR"
     19   install -d -m 755 "$BIN_DIR" "$SPOOL_DIR"
     20   install -d -m 755 -o "$USER_NAME" -g "$GROUP_NAME" "$VAR_DIR/staging"
     21 }
     22 
     23 setup_group() {
     24   if ! groupinfo "$GROUP_NAME" > /dev/null 2>&1; then
     25     if command -v groupadd > /dev/null 2>&1; then
     26       groupadd "$GROUP_NAME"
     27       log "Created group $GROUP_NAME"
     28     else
     29       error "Neither groupinfo nor groupadd found; cannot create group $GROUP_NAME. Please create it manually."
     30     fi
     31   fi
     32 }
     33 
     34 setup_user() {
     35   if ! id "$USER_NAME" > /dev/null 2>&1; then
     36     useradd -s /sbin/nologin \
     37       -d "$VAR_DIR" \
     38       -c "Gitpages service user" \
     39       -g "$GROUP_NAME" \
     40       -G "$GIT_GROUP" \
     41       "$USER_NAME"
     42     log "Created user $USER_NAME (primary group: $GROUP_NAME)"
     43   fi
     44 }
     45 
     46 setup_spool() {
     47   install -d -m 2775 -o "$GIT_USER" -g "$GROUP_NAME" "$QUEUE_DIR"
     48 }
     49 
     50 install_scripts() {
     51   if [ -f "./gitpages.sh" ]; then
     52     install -m 755 -o root -g wheel \
     53       ./gitpages.sh "$BIN_DIR/gitpages"
     54     log "Installed gitpages to $BIN_DIR/gitpages"
     55   else
     56     error "gitpages.sh not found"
     57   fi
     58 
     59   if [ -f "./gitpages.post-receive.hook" ]; then
     60     install -m 755 -o root -g wheel \
     61       ./gitpages.post-receive.hook "$BIN_DIR/gitpages.post-receive.hook"
     62     log "Installed post-receive hook to $BIN_DIR/gitpages.post-receive.hook"
     63   else
     64     error "gitpages.post-receive.hook not found"
     65   fi
     66 }
     67 
     68 setup_config() {
     69   config="$ETC_DIR/gitpages.conf"
     70 
     71   if [ -f "$config" ]; then
     72     warn "$config already exists; keeping existing configuration."
     73     return 0
     74   fi
     75 
     76   tmp="$(mktemp "$ETC_DIR/gitpages.conf.XXXXXX")"
     77   trap 'rm -f "$tmp"' EXIT INT TERM
     78   cat > "$tmp" << EOF
     79 GIT_SRC=$GIT_SRC
     80 WEB_ROOT=$WEB_ROOT
     81 GIT_RAW=$GIT_RAW
     82 GIT_HTML=$GIT_HTML
     83 ASSETS_DIR=$ASSETS_DIR
     84 EOF
     85 
     86   chmod 644 "$tmp"
     87   mv "$tmp" "$config"
     88   trap - EXIT INT TERM
     89   log "Wrote config to $config"
     90 }
     91 
     92 setup_logrotation() {
     93   if ! grep -qF "$LOG_DIR/updates.log" "$ETC_DIR"/newsyslog.conf; then
     94     echo "$LOG_DIR/updates.log ${USER_NAME}:${GROUP_NAME} 640 5 100 * J" >> "$ETC_DIR"/newsyslog.conf
     95     log "Log rotation appended to $ETC_DIR/newsyslog.conf."
     96   else
     97     log "Log rotation already configured in $ETC_DIR/newsyslog.conf."
     98   fi
     99 }
    100 
    101 setup_cron() {
    102   cron_line="*/5 * * * * $BIN_DIR/gitpages process_queue"
    103 
    104   if crontab -u "$USER_NAME" -l 2> /dev/null \
    105     | grep -qF "$cron_line"; then
    106     log "Cronjob already exists and is configured correctly."
    107   else
    108     {
    109       crontab -u "$USER_NAME" -l 2> /dev/null || true
    110       printf '%s\n' "$cron_line"
    111     } | crontab -u "$USER_NAME" -
    112     log "Cronjob set for gitpages user."
    113   fi
    114 }
    115 
    116 setup_webroot() {
    117   install -d -m 755 -o "root" -g "wheel" "$WEB_ROOT"
    118   install -d -m 755 -o "$USER_NAME" -g "$GROUP_NAME" "$WEB_ROOT/$GIT_HTML"
    119   install -d -m 755 -o "$USER_NAME" -g "$GROUP_NAME" "$WEB_ROOT/$GIT_RAW"
    120   log "Created web root and subdirectories under $WEB_ROOT"
    121 }
    122 
    123 main() {
    124   [ $# -ne 3 ] && usage
    125   GIT_USER="$1"
    126   GIT_SRC="$2"
    127   WEB_ROOT="$3"
    128 
    129   USER_NAME="_gitpages"
    130   GROUP_NAME="gitpages"
    131 
    132   GIT_RAW=git-raw
    133   GIT_HTML=git
    134   ASSETS_DIR=/var/gitpages/assets
    135 
    136   BIN_DIR="/usr/local/sbin"
    137   ETC_DIR="/etc"
    138   VAR_DIR="/var/gitpages"
    139   LOG_DIR="/var/log/gitpages"
    140   SPOOL_DIR="/var/spool/gitpages"
    141   QUEUE_DIR="$SPOOL_DIR/queue"
    142 
    143   # Validation
    144   if ! id "$GIT_USER" > /dev/null 2>&1; then
    145     error "User '$GIT_USER' does not exist."
    146   fi
    147 
    148   GIT_GROUP=$(id -gn "$GIT_USER") \
    149     || error "Could not determine primary group of '$GIT_USER'."
    150 
    151   log "Using Git user: $GIT_USER (group: $GIT_GROUP)"
    152 
    153   case "$GIT_SRC" in
    154     /*) : ;;
    155     *) error "GIT_SRC must be an absolute path" ;;
    156   esac
    157 
    158   [ -d "$GIT_SRC" ] || error "GIT_SRC directory '$GIT_SRC' not found"
    159 
    160   if ! su - "$GIT_USER" -c "test -r '$GIT_SRC'"; then
    161     error "GIT_USER '$GIT_USER' cannot read GIT_SRC '$GIT_SRC'"
    162   fi
    163 
    164   case "$WEB_ROOT" in
    165     /*) : ;;
    166     *) error "WEB_ROOT must be an absolute path" ;;
    167   esac
    168 
    169   log "Installing gitpages environment for git-user: $GIT_USER"
    170   log "Using WEB_ROOT: $WEB_ROOT"
    171 
    172   # Switch to the directory containing the installation files.
    173   SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
    174   cd "$SCRIPT_DIR" || error "cannot cd to $SCRIPT_DIR"
    175 
    176   setup_group
    177   setup_user
    178   setup_dirs
    179   setup_spool
    180   install_scripts
    181   setup_config
    182   setup_webroot
    183   setup_logrotation
    184   setup_cron
    185 
    186   log "Installation complete."
    187 }
    188 
    189 main "$@"