gateways/git-commit: accept a full commit message
[racktables] / gateways / git-commit
1 #!/bin/sh
2
3 # This file is a part of RackTables, a datacenter and server room management
4 # framework. See accompanying file "COPYING" for the full copyright and
5 # licensing information.
6
7 # This script implements a simple (one file at a time) one-way feed into a git
8 # repository. To make a commit it takes the following PHP code:
9 #
10 # $params = array
11 # (
12 # 'racktables_pseudo_user',
13 # '/path/to/repository',
14 # 'path/to/file/within/the/repository',
15 # 'commit message text',
16 # );
17 # $rc = callScript ('git-commit', $params, $file_contents, $stdout, $stderr);
18 #
19 # The meaning of $stdout and $stderr is the same as in queryTerminal().
20 # The specified repository must exist and the specified pseudo-user must be
21 # able to write to the repository and run "git pull", "git commit" and "git push"
22 # without any user interaction (i.e. the git remote must be on a local
23 # filesystem or be configured to use SSH keys).
24 #
25 # The commit message text is optional; when omitted or empty, a default value
26 # will be used. The message may be a multi-line string, in which case it should
27 # follow the format recommended in the "discussion" section of the
28 # git-commit(1) man page.
29 #
30 # This script uses sudo to switch between the pseudo-users and requires an
31 # entry in sudoers along the following lines:
32 # httpduser ALL=(racktablesuser) NOPASSWD:/path/to/racktables/gateways/git-commit
33
34 [ $# -eq 3 -o $# -eq 4 ] || {
35 echo "Usage: $0 <pseudo-user> <repo dir> <path to file> [commit message]" >&2
36 exit 1
37 }
38
39 SUDOUSER=$1
40 REPODIR="$2"
41 FILEPATH="$3"
42 COMMITMSG="${4:-update $FILEPATH}"
43
44 [ `whoami` = "$SUDOUSER" ] || {
45 sudo --non-interactive --set-home --user=$SUDOUSER -- "$0" "$@"
46 exit $?
47 }
48
49 cd "$REPODIR"
50 git pull --quiet || {
51 echo "Failed to run 'git pull' (rc=$?)" >&2
52 exit 2
53 }
54
55 # New file contents is on stdin.
56 cat > "$FILEPATH" || {
57 echo "Failed to write new file contents, trying to roll back." >&2
58 git checkout --quiet -- "$FILEPATH" || {
59 echo "Failed to run 'git checkout' after a write error." >&2
60 exit 4
61 }
62 exit 3
63 }
64
65 git diff --quiet -- "$FILEPATH" || {
66 git add -- "$FILEPATH"
67 git commit --quiet --message="$COMMITMSG" -- "$FILEPATH"
68 git push --quiet || {
69 echo "Failed to run 'git push' (rc=$?)" >&2
70 exit 5
71 }
72 }
73
74 exit 0