-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.sh
More file actions
executable file
·165 lines (147 loc) · 7.15 KB
/
Copy pathbootstrap.sh
File metadata and controls
executable file
·165 lines (147 loc) · 7.15 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/bin/bash
set -e
# Bootstrap a fresh Ubuntu machine: install git+ssh, configure git identity,
# generate an SSH key (if needed), wait for you to add it to GitHub, then
# clone the ubuntu-install repo. After this finishes you can run
# ./install-master.sh inside the cloned repo.
#
# This script is intentionally NOT part of install-master.sh — it's the
# chicken-and-egg "how do I even get the install scripts onto the machine"
# step. To run on a fresh box:
#
# curl -fsSL https://raw.githubusercontent.com/hofftodd/ubuntu-install/main/bootstrap.sh | bash
#
# Override defaults via env vars (otherwise you'll be prompted):
# GIT_USER_NAME, GIT_USER_EMAIL, SSH_KEY, SSH_KEY_COMMENT, REPO_URL, CLONE_DIR
GIT_USER_NAME="${GIT_USER_NAME:-}"
GIT_USER_EMAIL="${GIT_USER_EMAIL:-}"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/id_ed25519}"
REPO_URL="${REPO_URL:-git@github.com:hofftodd/ubuntu-install.git}"
CLONE_DIR="${CLONE_DIR:-$HOME/ubuntu-install}"
echo "═══════════════════════════════════════════════════════════"
echo " Ubuntu workstation bootstrap"
echo "═══════════════════════════════════════════════════════════"
# Prompt for any unset identity values. Read from /dev/tty so this works
# even when the script is piped through bash (curl ... | bash leaves stdin
# attached to the curl stream, not the terminal).
if [ -z "$GIT_USER_NAME" ]; then
read -r -p "Git user name (e.g. 'Jane Doe'): " GIT_USER_NAME < /dev/tty
fi
if [ -z "$GIT_USER_EMAIL" ]; then
read -r -p "Git user email (e.g. 'jane@example.com'): " GIT_USER_EMAIL < /dev/tty
fi
if [ -z "$GIT_USER_NAME" ] || [ -z "$GIT_USER_EMAIL" ]; then
echo "Name and email are required." >&2
exit 1
fi
SSH_KEY_COMMENT="${SSH_KEY_COMMENT:-$GIT_USER_EMAIL}"
echo
echo " Git user: ${GIT_USER_NAME} <${GIT_USER_EMAIL}>"
echo " SSH key: ${SSH_KEY}"
echo " Repo: ${REPO_URL}"
echo " Clone to: ${CLONE_DIR}"
echo
# ---- 1. Install git + ssh ---------------------------------------------------
echo "[1/5] Installing git and openssh-client..."
sudo apt-get update
sudo apt-get install -y git openssh-client curl
# glow is used by install-master.sh to render this repo's README from inside
# the TUI menu. It's not in default Ubuntu repos — pull it from Charm's apt
# repo. Skip if already installed (e.g. user added it manually).
if ! command -v glow >/dev/null 2>&1; then
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" \
| sudo tee /etc/apt/sources.list.d/charm.list >/dev/null
sudo apt-get update
sudo apt-get install -y glow
fi
# ---- 2. Configure git identity + sensible defaults --------------------------
echo
echo "[2/5] Configuring git..."
git config --global user.name "$GIT_USER_NAME"
git config --global user.email "$GIT_USER_EMAIL"
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global push.autoSetupRemote true
git config --global fetch.prune true
git config --global rebase.autoStash true
git config --global rerere.enabled true
git config --global merge.conflictStyle zdiff3
# ---- 3. Generate SSH key (if missing) ---------------------------------------
echo
echo "[3/5] SSH key..."
if [ -f "$SSH_KEY" ]; then
echo " Existing key found at $SSH_KEY — reusing."
else
mkdir -p "$(dirname "$SSH_KEY")"
chmod 700 "$(dirname "$SSH_KEY")"
ssh-keygen -t ed25519 -C "$SSH_KEY_COMMENT" -f "$SSH_KEY" -N ""
fi
# Make sure ssh-agent is running and the key is loaded.
if [ -z "${SSH_AUTH_SOCK:-}" ] || ! ssh-add -l >/dev/null 2>&1; then
eval "$(ssh-agent -s)" >/dev/null
fi
ssh-add "$SSH_KEY" 2>/dev/null || true
# ---- 4. Pause for user to register the key with GitHub ----------------------
echo
echo "═══════════════════════════════════════════════════════════"
echo " ADD THIS PUBLIC KEY TO GITHUB"
echo "═══════════════════════════════════════════════════════════"
cat "${SSH_KEY}.pub"
echo "═══════════════════════════════════════════════════════════"
echo
echo " → Open: https://github.com/settings/ssh/new"
echo " → Paste the line above and save."
echo
read -r -p "Press ENTER once you've added the key to GitHub..." < /dev/tty
# Add github.com to known_hosts non-interactively, then verify auth.
# Breadcrumbs on each substep — silent exits in this block were a debugging
# nightmare on WSL, where ssh-keyscan can crash on IPv6-only routes.
echo
echo "[4/5] Verifying SSH access to GitHub..."
echo " · ensuring ~/.ssh/known_hosts exists"
touch "$HOME/.ssh/known_hosts"
chmod 600 "$HOME/.ssh/known_hosts"
echo " · scanning github.com host keys (IPv4, 10s timeout)"
ssh-keyscan -4 -T 10 -t rsa,ecdsa,ed25519 github.com \
>> "$HOME/.ssh/known_hosts" || echo " (ssh-keyscan returned non-zero — continuing)"
sort -u "$HOME/.ssh/known_hosts" -o "$HOME/.ssh/known_hosts"
# `ssh -T git@github.com` exits 1 even on success ("you have successfully
# authenticated, but GitHub does not provide shell access"), so check the
# message body. Capture into a variable instead of piping to grep — piping
# to `grep -q` lets grep exit on first match and leaves ssh to die from
# SIGPIPE, which on some setups stalls long enough to look like a hang.
echo " · authenticating to git@github.com (IPv4, 10s timeout)"
ssh_output="$(ssh -T -n \
-4 \
-o BatchMode=yes \
-o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=10 \
git@github.com 2>&1 || true)"
if printf '%s\n' "$ssh_output" | grep -q "successfully authenticated"; then
echo " ✓ GitHub SSH auth working."
else
echo " ✗ Could not authenticate to GitHub via SSH." >&2
echo " ssh said:" >&2
printf ' %s\n' "$ssh_output" >&2
echo " Confirm the key was added at https://github.com/settings/keys" >&2
echo " then re-run this script." >&2
exit 1
fi
# ---- 5. Clone the repo ------------------------------------------------------
echo
echo "[5/5] Cloning ${REPO_URL} → ${CLONE_DIR}..."
if [ -d "$CLONE_DIR/.git" ]; then
echo " $CLONE_DIR already exists — pulling latest."
git -C "$CLONE_DIR" pull --ff-only
else
git clone "$REPO_URL" "$CLONE_DIR"
fi
echo
echo "═══════════════════════════════════════════════════════════"
echo " Bootstrap complete."
echo "═══════════════════════════════════════════════════════════"
echo " Next: cd ${CLONE_DIR} && ./install-master.sh"
echo