summaryrefslogtreecommitdiff
path: root/git/install.sh
blob: 38bc8a84bb21aa0a4f3f9ec8589638749a72e4a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/env bash
# サーバー上で root として手動実行する
# repos.txt に基づいてベアリポジトリとワークツリーを作成し、
# git/hooks/ のフックを /var/git/*/hooks/ に展開する
set -euo pipefail

APP_DIR="$(cd "$(dirname "$0")/.." && pwd)"
REPOS_FILE="$APP_DIR/git/repos.txt"
HOOKS_SRC="$APP_DIR/git/hooks"
AUTH_KEYS_SRC="$APP_DIR/server/authorized_keys"
ADMIN_PUBKEY="$APP_DIR/hetzner-admin/id_rsa.pub"
ADMIN_KEY_RESTRICTION='command="/app/infra/hetzner-admin/run-command.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty'

if [[ "$(id -u)" -ne 0 ]]; then
    echo "ERROR: root として実行してください" >&2
    exit 1
fi

echo "=== SSH authorized_keys ==="
if [[ -f "$AUTH_KEYS_SRC" ]]; then
    mkdir -p /root/.ssh
    chmod 700 /root/.ssh
    # server/authorized_keys + hetzner-admin のコマンド制限付き鍵(あれば)で組み立てる。
    # 丸ごと上書きすると hetzner-admin の鍵が消えて管理画面の操作が認証失敗になるため
    tmp="$(mktemp)"
    cat "$AUTH_KEYS_SRC" > "$tmp"
    if [[ -f "$ADMIN_PUBKEY" ]]; then
        echo "${ADMIN_KEY_RESTRICTION} $(cat "$ADMIN_PUBKEY")" >> "$tmp"
    fi
    if diff -q "$tmp" /root/.ssh/authorized_keys >/dev/null 2>&1; then
        rm -f "$tmp"
        echo "  unchanged"
    else
        install -m 600 "$tmp" /root/.ssh/authorized_keys
        rm -f "$tmp"
        echo "  installed"
    fi
fi

echo ""
echo "=== Repositories ==="
while IFS=: read -r repo_name work_tree; do
    [[ "$repo_name" =~ ^#.*$ || -z "$repo_name" ]] && continue
    bare_repo="/var/git/${repo_name}.git"

    if [[ ! -d "$bare_repo" ]]; then
        echo "  create: $bare_repo"
        mkdir -p "$bare_repo"
        git init --bare "$bare_repo"
    else
        echo "  exists: $bare_repo"
    fi

    if [[ ! -d "$work_tree" ]]; then
        echo "  mkdir:  $work_tree"
        mkdir -p "$work_tree"
    fi
done < "$REPOS_FILE"

echo ""
echo "=== Hooks ==="
for repo_src in "$HOOKS_SRC"/*/; do
    repo_name="$(basename "$repo_src")"
    git_hooks_dir="/var/git/${repo_name}.git/hooks"

    if [[ ! -d "$git_hooks_dir" ]]; then
        echo "  SKIP: $git_hooks_dir not found ($repo_name)"
        continue
    fi

    for hook_file in "$repo_src"*; do
        hook_name="$(basename "$hook_file")"
        dst="$git_hooks_dir/$hook_name"
        if diff -q "$hook_file" "$dst" >/dev/null 2>&1; then
            echo "  unchanged: $repo_name/$hook_name"
        else
            cp "$hook_file" "$dst"
            chmod +x "$dst"
            echo "  installed: $repo_name/$hook_name"
        fi
    done
done

echo ""
echo "Done."