#!/bin/sh # GHMD is a shell script for setting up any of the following things: # 1) a Git user on a remote instance (initial setup) # 2) a private Git repo on the remote instance # 3) a public Git repo using git:// protocol on the remote instance (if it uses systemd) # 4) Git daemon (serving git:// protocol) on the remote instance # 5) access via the Git daemon to individual repositories # 6) repository description and clone URL for some services like stagit # Usage: ghmd.sh [newsrv | newrepo | gitd-sd | gitd-publish | gitd-unpublish | set-repo-desc | set-repo-url | set-repo-owner] user@host [name] ("[desc|url]") # regardless of the actions, the user must have root permissions # prerequisite: git package must be already installed on the server # Created by Luxferre in 2024, released into public domain GITUSR="git" PARAM="$1" USERHOST="$2" THOST="${USERHOST##*@}" SSHCMD="ssh $USERHOST" # instance ssh cmd help() { cat < /home/${GITUSR}/.ssh/authorized_keys; chown -R ${GITUSR} /home/${GITUSR}/.ssh" echo "Now, you'll need to enter the newly created ${GITUSR} user password:" ssh-copy-id ${GITUSR}@${THOST} $SSHCMD "chsh $GITUSR -s $(which git-shell)" echo "Git user set up on ${THOST}. Now use $0 newrepo ${GITUSR}@${THOST} [name] to set up new Git repos" ;; "newrepo") # set up a new Git repo [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 REPONAME="$3" [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 REPODIR="${REPONAME}.git" FULLREPODIR="/home/${GITUSR}/$REPODIR" $SSHCMD "mkdir -p $FULLREPODIR;cd $FULLREPODIR;git init --bare --shared;chown -R ${GITUSR}:${GITUSR} ." echo "Empty repository created at ${USERHOST}:${REPODIR}" ;; "set-repo-desc") # set the repo description for some services [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 REPONAME="$3" [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 VALUE="$4" # it may be empty REPODIR="${REPONAME}.git" FULLREPODIR="/home/${GITUSR}/$REPODIR" $SSHCMD "cd $FULLREPODIR;echo \"$VALUE\" > description;chown -R ${GITUSR}:${GITUSR} description" echo "Description set for ${REPODIR}" ;; "set-repo-url") # set the repo clone URL for some services [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 REPONAME="$3" [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 VALUE="$4" # it may be empty REPODIR="${REPONAME}.git" FULLREPODIR="/home/${GITUSR}/$REPODIR" $SSHCMD "cd $FULLREPODIR;echo \"$VALUE\" > url;chown -R ${GITUSR}:${GITUSR} url" echo "Clone URL set for ${REPODIR}" ;; "set-repo-owner") # set the repo owner name for some services [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 REPONAME="$3" [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 VALUE="$4" # it may be empty REPODIR="${REPONAME}.git" FULLREPODIR="/home/${GITUSR}/$REPODIR" $SSHCMD "cd $FULLREPODIR;echo \"$VALUE\" > owner;chown -R ${GITUSR}:${GITUSR} owner" echo "Owner name set for ${REPODIR}" ;; "gitd-sd") # set up the Git daemon using a systemd unit [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 TMPUNIT="/tmp/git-daemon.service" cat << EOF > $TMPUNIT [Unit] Description=Start Git Daemon [Service] ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/home/${GITUSR} /home/${GITUSR} Restart=always RestartSec=500ms StandardOutput=syslog StandardError=syslog SyslogIdentifier=git-daemon User=$GITUSR Group=$GITUSR [Install] WantedBy=multi-user.target EOF scp $TMPUNIT ${USERHOST}:/etc/systemd/system/git-daemon.service $SSHCMD "systemctl enable git-daemon; systemctl start git-daemon" echo "Git daemon installed on ${THOST} via systemd" rm -f $TMPUNIT ;; "gitd-publish") # make a repository public via the Git daemon [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 REPONAME="$3" [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 REPODIR="${REPONAME}.git" ACCFILE="/home/${GITUSR}/${REPODIR}/git-daemon-export-ok" $SSHCMD "touch $ACCFILE; chown $GITUSR $ACCFILE" echo "Repository git://${THOST}/$REPODIR made public" ;; "gitd-unpublish") # revoke repository publishing via the Git daemon [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 REPONAME="$3" [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 REPODIR="${REPONAME}.git" ACCFILE="/home/${GITUSR}/${REPODIR}/git-daemon-export-ok" $SSHCMD "rm -f $ACCFILE" echo "Repository git://${THOST}/$REPODIR made private" ;; *) help esac