ghmd.sh (6071B)
1 #!/bin/sh 2 # GHMD is a shell script for setting up any of the following things: 3 # 1) a Git user on a remote instance (initial setup) 4 # 2) a private Git repo on the remote instance 5 # 3) a public Git repo using git:// protocol on the remote instance (if it uses systemd) 6 # 4) Git daemon (serving git:// protocol) on the remote instance 7 # 5) access via the Git daemon to individual repositories 8 # 6) repository description and clone URL for some services like stagit 9 # 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]") 10 # regardless of the actions, the user must have root permissions 11 # prerequisite: git package must be already installed on the server 12 # Created by Luxferre in 2024, released into public domain 13 14 GITUSR="git" 15 PARAM="$1" 16 USERHOST="$2" 17 THOST="${USERHOST##*@}" 18 SSHCMD="ssh $USERHOST" # instance ssh cmd 19 20 help() { 21 cat <<EOF 22 GHMD: single shell script for self-hosted Git repository management 23 24 Initialize Git user on a new server (must have Git installed): 25 26 $0 newsrv root@hostname 27 28 Create a new Git repository (e.g. git@hostname:myrepo.git): 29 30 $0 newrepo root@hostname myrepo 31 32 Set up Git protocol daemon (if the host is running systemd): 33 34 $0 gitd-sd root@hostname 35 36 Publish an existing Git repository on the daemon (e.g. git://hostname/myrepo.git): 37 38 $0 gitd-publish root@hostname myrepo 39 40 Unpublish an existing Git repository on the daemon: 41 42 $0 gitd-unpublish root@hostname myrepo 43 44 Set the (displayed) description of an existing Git repository: 45 46 $0 set-repo-desc root@hostname myrepo "This is a cool repo" 47 48 Set the (displayed) clone URL of an existing Git repository: 49 50 $0 set-repo-url root@hostname myrepo git://hostname/myrepo.git 51 52 Set the (displayed) owner name of an existing Git repository: 53 54 $0 set-repo-owner root@hostname myrepo "Me, the Author" 55 56 Created by Luxferre in 2024, released into public domain 57 EOF 58 } 59 60 case "$PARAM" in 61 "help") 62 help 63 ;; 64 "newsrv") # set up Git user on the server 65 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 66 $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" 67 echo "Now, you'll need to enter the newly created ${GITUSR} user password:" 68 ssh-copy-id ${GITUSR}@${THOST} 69 $SSHCMD "chsh $GITUSR -s $(which git-shell)" 70 echo "Git user set up on ${THOST}. Now use $0 newrepo ${GITUSR}@${THOST} [name] to set up new Git repos" 71 ;; 72 "newrepo") # set up a new Git repo 73 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 74 REPONAME="$3" 75 [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 76 REPODIR="${REPONAME}.git" 77 FULLREPODIR="/home/${GITUSR}/$REPODIR" 78 $SSHCMD "mkdir -p $FULLREPODIR;cd $FULLREPODIR;git init --bare --shared;chown -R ${GITUSR}:${GITUSR} ." 79 echo "Empty repository created at ${USERHOST}:${REPODIR}" 80 ;; 81 "set-repo-desc") # set the repo description for some services 82 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 83 REPONAME="$3" 84 [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 85 VALUE="$4" # it may be empty 86 REPODIR="${REPONAME}.git" 87 FULLREPODIR="/home/${GITUSR}/$REPODIR" 88 $SSHCMD "cd $FULLREPODIR;echo \"$VALUE\" > description;chown -R ${GITUSR}:${GITUSR} description" 89 echo "Description set for ${REPODIR}" 90 ;; 91 "set-repo-url") # set the repo clone URL for some services 92 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 93 REPONAME="$3" 94 [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 95 VALUE="$4" # it may be empty 96 REPODIR="${REPONAME}.git" 97 FULLREPODIR="/home/${GITUSR}/$REPODIR" 98 $SSHCMD "cd $FULLREPODIR;echo \"$VALUE\" > url;chown -R ${GITUSR}:${GITUSR} url" 99 echo "Clone URL set for ${REPODIR}" 100 ;; 101 "set-repo-owner") # set the repo owner name for some services 102 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 103 REPONAME="$3" 104 [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 105 VALUE="$4" # it may be empty 106 REPODIR="${REPONAME}.git" 107 FULLREPODIR="/home/${GITUSR}/$REPODIR" 108 $SSHCMD "cd $FULLREPODIR;echo \"$VALUE\" > owner;chown -R ${GITUSR}:${GITUSR} owner" 109 echo "Owner name set for ${REPODIR}" 110 ;; 111 "gitd-sd") # set up the Git daemon using a systemd unit 112 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 113 TMPUNIT="/tmp/git-daemon.service" 114 cat << EOF > $TMPUNIT 115 [Unit] 116 Description=Start Git Daemon 117 118 [Service] 119 ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/home/${GITUSR} /home/${GITUSR} 120 Restart=always 121 RestartSec=500ms 122 StandardOutput=syslog 123 StandardError=syslog 124 SyslogIdentifier=git-daemon 125 User=$GITUSR 126 Group=$GITUSR 127 128 [Install] 129 WantedBy=multi-user.target 130 EOF 131 scp $TMPUNIT ${USERHOST}:/etc/systemd/system/git-daemon.service 132 $SSHCMD "systemctl enable git-daemon; systemctl start git-daemon" 133 echo "Git daemon installed on ${THOST} via systemd" 134 rm -f $TMPUNIT 135 ;; 136 "gitd-publish") # make a repository public via the Git daemon 137 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 138 REPONAME="$3" 139 [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 140 REPODIR="${REPONAME}.git" 141 ACCFILE="/home/${GITUSR}/${REPODIR}/git-daemon-export-ok" 142 $SSHCMD "touch $ACCFILE; chown $GITUSR $ACCFILE" 143 echo "Repository git://${THOST}/$REPODIR made public" 144 ;; 145 "gitd-unpublish") # revoke repository publishing via the Git daemon 146 [[ -z "$USERHOST" ]] && echo "Error: no user and hostname!" && exit 1 147 REPONAME="$3" 148 [[ -z "$REPONAME" ]] && echo "Error: no repository name!" && exit 1 149 REPODIR="${REPONAME}.git" 150 ACCFILE="/home/${GITUSR}/${REPODIR}/git-daemon-export-ok" 151 $SSHCMD "rm -f $ACCFILE" 152 echo "Repository git://${THOST}/$REPODIR made private" 153 ;; 154 *) 155 help 156 esac 157