158 lines
5.9 KiB
Bash
158 lines
5.9 KiB
Bash
#!/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 <<EOF
|
||
|
|
GHMD: single shell script for self-hosted Git repository management
|
||
|
|
|
||
|
|
Initialize Git user on a new server (must have Git installed):
|
||
|
|
|
||
|
|
$0 newsrv root@hostname
|
||
|
|
|
||
|
|
Create a new Git repository (e.g. git@hostname:myrepo.git):
|
||
|
|
|
||
|
|
$0 newrepo root@hostname myrepo
|
||
|
|
|
||
|
|
Set up Git protocol daemon (if the host is running systemd):
|
||
|
|
|
||
|
|
$0 gitd-sd root@hostname
|
||
|
|
|
||
|
|
Publish an existing Git repository on the daemon (e.g. git://hostname/myrepo.git):
|
||
|
|
|
||
|
|
$0 gitd-publish root@hostname myrepo
|
||
|
|
|
||
|
|
Unpublish an existing Git repository on the daemon:
|
||
|
|
|
||
|
|
$0 gitd-unpublish root@hostname myrepo
|
||
|
|
|
||
|
|
Set the (displayed) description of an existing Git repository:
|
||
|
|
|
||
|
|
$0 set-repo-desc root@hostname myrepo "This is a cool repo"
|
||
|
|
|
||
|
|
Set the (displayed) clone URL of an existing Git repository:
|
||
|
|
|
||
|
|
$0 set-repo-url root@hostname myrepo git://hostname/myrepo.git
|
||
|
|
|
||
|
|
Set the (displayed) owner name of an existing Git repository:
|
||
|
|
|
||
|
|
$0 set-repo-owner root@hostname myrepo "Me, the Author"
|
||
|
|
|
||
|
|
Created by Luxferre in 2024, released into public domain
|
||
|
|
EOF
|
||
|
|
}
|
||
|
|
|
||
|
|
case "$PARAM" in
|
||
|
|
"help")
|
||
|
|
help
|
||
|
|
;;
|
||
|
|
"newsrv") # set up Git user on the server
|
||
|
|
[[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1
|
||
|
|
$SSHCMD "useradd ${GITUSR}; passwd ${GITUSR}; mkdir -p /home/${GITUSR}/.ssh; echo 'no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty' > /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
|
||
|
|
|