aboutsummaryrefslogtreecommitdiffstats
path: root/roles/git/files/git-shell-commands
diff options
context:
space:
mode:
authorAaron LI <aly@aaronly.me>2018-04-18 16:41:27 +0800
committerAaron LI <aly@aaronly.me>2018-04-18 16:44:09 +0800
commit053cd1b7fe10f746792e0d1353fad4ad04e8ebe9 (patch)
tree93137af7af0b073383e0db5ae91cbe301f9bcdd1 /roles/git/files/git-shell-commands
parentf448bcbdf07cf988ab50950df95d822f359041db (diff)
downloadansible-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/addkey49
-rw-r--r--roles/git/files/git-shell-commands/create42
-rw-r--r--roles/git/files/git-shell-commands/env9
-rw-r--r--roles/git/files/git-shell-commands/help24
-rw-r--r--roles/git/files/git-shell-commands/list22
-rw-r--r--roles/git/files/git-shell-commands/make-private30
-rw-r--r--roles/git/files/git-shell-commands/make-public37
-rw-r--r--roles/git/files/git-shell-commands/no-interactive-login.disabled23
-rw-r--r--roles/git/files/git-shell-commands/set-desc31
-rw-r--r--roles/git/files/git-shell-commands/sync-github103
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