diff options
author | Aaron LI <aly@aaronly.me> | 2018-04-18 16:41:27 +0800 |
---|---|---|
committer | Aaron LI <aly@aaronly.me> | 2018-04-18 16:44:09 +0800 |
commit | 053cd1b7fe10f746792e0d1353fad4ad04e8ebe9 (patch) | |
tree | 93137af7af0b073383e0db5ae91cbe301f9bcdd1 /roles/git/files/git-shell-commands | |
parent | f448bcbdf07cf988ab50950df95d822f359041db (diff) | |
download | ansible-dfly-vps-053cd1b7fe10f746792e0d1353fad4ad04e8ebe9.tar.bz2 |
Add git role: host git repos and share repos via cgit
* Host git repositories
* Share git repositories through web interface via cgit
* The static resources used by cgit is also managed/deployed by a git repo ^_^
Diffstat (limited to 'roles/git/files/git-shell-commands')
-rw-r--r-- | roles/git/files/git-shell-commands/addkey | 49 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/create | 42 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/env | 9 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/help | 24 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/list | 22 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/make-private | 30 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/make-public | 37 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/no-interactive-login.disabled | 23 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/set-desc | 31 | ||||
-rw-r--r-- | roles/git/files/git-shell-commands/sync-github | 103 |
10 files changed, 370 insertions, 0 deletions
diff --git a/roles/git/files/git-shell-commands/addkey b/roles/git/files/git-shell-commands/addkey new file mode 100644 index 0000000..670fd94 --- /dev/null +++ b/roles/git/files/git-shell-commands/addkey @@ -0,0 +1,49 @@ +#!/bin/sh +# +# ~/git-shell-commands/addkey +# +# An interactive command to add a new SSH public key to the authorized +# key list. To ensure the integrity of the authorized_keys file, the +# script makes sure you've entered a valid key (which must be entered +# all on one line). For security, the script also disables some SSH +# options for the key when it adds it. +# +# NOTE: +# This interactive command is NOT allowed through a SSH connection, +# use `sudo su - git` from other (admin) user instead. +# +# Credit: +# * Hosting an admin-friendly git server with git-shell +# http://planzero.org/blog/2012/10/24/hosting_an_admin-friendly_git_server_with_git-shell +# +# Aaron LI +# 2017-06-18 +# + +if [ -n "${SSH_CONNECTION}" ]; then + echo "Sorry, this command is not allowed through a SSH connection" + exit 1 +fi + +# Read in the SSH key +echo "Input the SSH public key to be added (ED25519/RSA):" +read key + +# Generate a fingerprint +fingerprint=$(echo "${key}" | ssh-keygen -lf -) + +# Check for errors +if [ $(echo "${fingerprint}" | egrep -c '(ED25519|RSA)') -eq 0 ]; then + # Display the fingerprint error and clean up + echo "Invalid key: ${fingerprint}" + exit 1 +fi + +# Add the key to the authorized keys file and clean up +[ ! -d "${HOME}/.ssh" ] && mkdir -m 0700 ${HOME}/.ssh +echo ${key} >> ${HOME}/.ssh/authorized_keys +chmod 0600 ${HOME}/.ssh/authorized_keys + +# Display the fingerprint for reference +echo "Success! Added a key with the following fingerprint:" +echo ${fingerprint} diff --git a/roles/git/files/git-shell-commands/create b/roles/git/files/git-shell-commands/create new file mode 100644 index 0000000..21cacc1 --- /dev/null +++ b/roles/git/files/git-shell-commands/create @@ -0,0 +1,42 @@ +#!/bin/sh +# +# ~/git-shell-commands/create +# +# An interactive command to create a new repository. The `.git` extension +# is automatically added if missing, in order to let `list` command find +# this repository. +# +# Credit: +# * Hosting an admin-friendly git server with git-shell +# http://planzero.org/blog/2012/10/24/hosting_an_admin-friendly_git_server_with_git-shell +# +# Aaron LI +# 2017-06-18 +# + +if [ $# -eq 0 ]; then + echo "Usage: create <project.git> [ description ]" + exit 1 +fi + +# Set the project name, adding `.git` extension if missing +project="${1%.[gG][iI][tT]}.git" +shift + +if [ -d "${HOME}/${project}" ]; then + echo "ERROR: repository '${project}' already exists!" + exit 2 +fi + +# Create and initialise the project +mkdir "${HOME}/${project}" && \ + cd "${HOME}/${project}" && \ + git --bare init + +description="$@" +if [ -n "${description}" ]; then + echo "${description}" > ${HOME}/${project}/description +fi + +echo "Created Git repository: ${project}" +echo "Description: $(cat ${HOME}/${project}/description)" diff --git a/roles/git/files/git-shell-commands/env b/roles/git/files/git-shell-commands/env new file mode 100644 index 0000000..8b4b496 --- /dev/null +++ b/roles/git/files/git-shell-commands/env @@ -0,0 +1,9 @@ +#!/bin/sh +# +# Print current environment. +# +# Aaron LI +# 2017-06-18 +# + +/usr/bin/env diff --git a/roles/git/files/git-shell-commands/help b/roles/git/files/git-shell-commands/help new file mode 100644 index 0000000..9e37fd2 --- /dev/null +++ b/roles/git/files/git-shell-commands/help @@ -0,0 +1,24 @@ +#!/bin/sh +# +# /usr/local/share/git-core/contrib/git-shell-commands/help +# +# Aaron LI +# 2017-06-18 +# + +if tty -s; then + echo "Run 'help' for help, or 'exit' to leave. Available commands:" +else + echo "Run 'help' for help. Available commands:" +fi + +dir=$(dirname "$0") +cd "${dir}" + +for cmd in *; do + case "${cmd}" in + help) ;; + *.disabled) ;; + *) [ -f "${cmd}" ] && [ -x "${cmd}" ] && echo "${cmd}" ;; + esac +done diff --git a/roles/git/files/git-shell-commands/list b/roles/git/files/git-shell-commands/list new file mode 100644 index 0000000..2977541 --- /dev/null +++ b/roles/git/files/git-shell-commands/list @@ -0,0 +1,22 @@ +#!/bin/sh +# +# /usr/local/share/git-core/contrib/git-shell-commands/list +# +# Aaron LI +# 2017-06-19 +# + +. ${HOME}/vars.conf + +for repo in $(ls -d *.git); do + is_bare_repo=$(git --git-dir="${repo}" rev-parse --is-bare-repository) + if [ "${is_bare_repo}" = "true" ]; then + echo "* ${repo}" + if [ -e "${PUBLIC}/${repo}" ]; then + echo " [public]" + fi + if [ -f "${repo}/description" ]; then + echo " $(cat ${repo}/description)" + fi + fi +done diff --git a/roles/git/files/git-shell-commands/make-private b/roles/git/files/git-shell-commands/make-private new file mode 100644 index 0000000..432d847 --- /dev/null +++ b/roles/git/files/git-shell-commands/make-private @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (c) 2017 Aaron LI <aly@aaronly.me> +# MIT License +# +# Turn a public Git repository to be private to `cgit`. +# +# 2017-06-19 +# + +. ${HOME}/vars.conf + +if [ $# -ne 1 ]; then + echo "usage: make-private <repository.git>" + exit 1 +fi + +project="${1%.[gG][iI][tT]}.git" + +if [ ! -d "${project}" ]; then + echo "ERROR: repository '${project}' not exists!" + exit 2 +elif [ -L "${PUBLIC}/${project}" ]; then + rm "${PUBLIC}/${project}" + echo "Made repository '${project}' private." + exit 0 +else + echo "Repository '${project}' not public." + exit 0 +fi diff --git a/roles/git/files/git-shell-commands/make-public b/roles/git/files/git-shell-commands/make-public new file mode 100644 index 0000000..f1dfb1d --- /dev/null +++ b/roles/git/files/git-shell-commands/make-public @@ -0,0 +1,37 @@ +#!/bin/sh +# +# Copyright (c) 2017 Aaron LI <aly@aaronly.me> +# MIT License +# +# Make an existing Git repository public by linking it into +# `repos.public`, which is exported via `cgit`. +# +# 2017-06-19 +# + +. ${HOME}/vars.conf + +if [ $# -ne 1 ]; then + echo "usage: make-public <repository.git>" + exit 1 +fi + +if [ ! -e "${PUBLIC}" ]; then + echo "ERROR: public directory '${PUBLIC}' not exists!" + exit 1 +fi + +project="${1%.[gG][iI][tT]}.git" + +if [ ! -d "${project}" ]; then + echo "ERROR: repository '${project}' not exists!" + exit 3 +elif [ -L "${PUBLIC}/${project}" ]; then + echo "Repository '${project}' already made public." + exit 0 +else + ln -sv ../${project} ${PUBLIC}/${project} + echo "Made repository '${project}' public." + exit 0 +fi + diff --git a/roles/git/files/git-shell-commands/no-interactive-login.disabled b/roles/git/files/git-shell-commands/no-interactive-login.disabled new file mode 100644 index 0000000..3be7efc --- /dev/null +++ b/roles/git/files/git-shell-commands/no-interactive-login.disabled @@ -0,0 +1,23 @@ +#!/bin/sh +# +# ~/git-shell-commands/no-interactive-login +# +# Disable interactive logins, displaying a greeting instead. +# See git-shell(1) +# +# Remove/rename this script to allow interactive logins, e.g., +# allow `su - git` to add SSH keys. +# +# +# Aaron LI +# 2017-06-18 +# + +cat <<_EOF_ +Hi ${USER}! +You've successfully authenticated, but interactive shell +access is not provided. +Bye~ +_EOF_ + +exit 128 diff --git a/roles/git/files/git-shell-commands/set-desc b/roles/git/files/git-shell-commands/set-desc new file mode 100644 index 0000000..3d0a1be --- /dev/null +++ b/roles/git/files/git-shell-commands/set-desc @@ -0,0 +1,31 @@ +#!/bin/sh +# +# ~/git-shell-commands/set-desc +# +# Set the description of an existing Git repository. +# +# Aaron LI +# 2017-08-22 +# + +if [ $# -lt 2 ]; then + echo "Usage: set-desc <project.git> <description>" + exit 1 +fi + +# Set the project name, adding `.git` extension if missing +project="${1%.[gG][iI][tT]}.git" +shift + +if [ ! -d "${HOME}/${project}" ]; then + echo "ERROR: repository '${project}' not exists!" + exit 2 +fi + +description="$@" +if [ -n "${description}" ]; then + echo "${description}" > ${HOME}/${project}/description +fi + +echo "Set description of Git repository: ${project}" +echo "Description: $(cat ${HOME}/${project}/description)" diff --git a/roles/git/files/git-shell-commands/sync-github b/roles/git/files/git-shell-commands/sync-github new file mode 100644 index 0000000..9eef43e --- /dev/null +++ b/roles/git/files/git-shell-commands/sync-github @@ -0,0 +1,103 @@ +#!/bin/sh +# +# Copyright (c) 2017 Aaron LI <aly@aaronly.me> +# MIT License +# +# Sync public repositories to GitHub. +# +# 2017-06-25 +# + +. ${HOME}/vars.conf + +# Return 0 if the GitHub repository exists +has_github_repo() { + local repo url + repo=$(basename $1) + repo="${repo%.git}" + url="${GITHUB_API}/repos/${GITHUB_USER}/${repo}" + echo "Check existence on GitHub: ${url}" + curl -s ${url} | grep -q '"owner"' +} + + +# Add the "github" remote if not exists +add_remote_github() { + local gitdir_ repo url ret + gitdir_="$1" + url=$(git --git-dir="${gitdir_}" remote get-url github 2>&1) + ret=$? + if [ ${ret} -eq 0 ]; then + # Already has the "github" remote + echo "Remote 'github': ${url}" + else + repo=$(basename ${gitdir_}) + url="${GITHUB_URL}:${GITHUB_USER}/${repo}" + git --git-dir="${gitdir_}" remote add github ${url} + echo "Added remote 'github': ${url}" + git --git-dir="${gitdir_}" remote update github + fi +} + + +# Check whether the repository needs push to remote "github"; +# Return 0 if needs push. +# +# Credit: +# * Check if pull needed in Git +# https://stackoverflow.com/a/3278427/4856091 +# * List Git commits not pushed to the origin yet +# https://stackoverflow.com/a/3080554/4856091 +# +need_push_github() { + local gitdir_ unpushed + gitdir_="$1" + unpushed=$(git --git-dir="${gitdir_}" \ + log --oneline github/master..master | wc -l) + if [ ${unpushed} -eq 0 ]; then + echo "Already up-to-date" && false + else + echo "${unpushed} commits need push" && true + fi +} + + +if [ $# -eq 0 ]; then + cat <<_EOF_ +usage: + sync-github <repo.git> ... + sync-github @<repo_dir> + +e.g., + sync-github @${PUBLIC} +_EOF_ + exit 1 +fi + + +if [ "$(echo $1 | cut -c1)" = "@" ]; then + REPO_DIR="${1#@}" + REPOS=$(ls -d ${REPO_DIR}/*.git) +else + REPOS="$@" +fi + +echo "=== Selected Repositories ===" +for repo in ${REPOS}; do + repo2="${repo%.[gG][iI][tT]}.git" + echo "* ${repo2}" +done + +for repo in ${REPOS}; do + repo2="${repo%.[gG][iI][tT]}.git" + echo "=== Sync Repository: ${repo2} ===" + if ! has_github_repo ${repo2}; then + echo "WARNING: no such repo on GitHub: ${repo2}" + continue + fi + add_remote_github ${repo2} + if need_push_github ${repo2}; then + echo "Push commits to GitHub ..." + git --git-dir="${repo2}" push --mirror github + fi +done |