-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathtunnel.sh
More file actions
330 lines (303 loc) · 10.4 KB
/
tunnel.sh
File metadata and controls
330 lines (303 loc) · 10.4 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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
#! /bin/bash
#
# Manages Cloudflare tunnel for WordPress development environment.
# Starts a Cloudflare tunnel, updates WordPress database with the tunnel URL,
# and provides cleanup functionality on termination.
#
trap ctrl_c INT SIGINT SIGTERM
## Set Vars
CF_TUNNEL_PUBLIC_URL=''
CF_TUNNEL_HASH=''
PRECHECK_HOME_OPTION=''
WAIT_FOR_CF_URL=12
#######################################
# Signal handler for cleanup on termination.
# Reverts WordPress database to default URL and stops the Cloudflare tunnel.
# Globals:
# CF_TUNNEL_PUBLIC_URL - The public URL of the Cloudflare tunnel
# CF_TUNNEL_HASH - The Docker container hash of the tunnel
# Arguments:
# None (signal handler)
# Returns:
# Exits with status 0 after cleanup.
#######################################
function ctrl_c() {
echo
echo "Termination caught. Reverting site to basic.wordpress.test."
do_database_actions "$CF_TUNNEL_PUBLIC_URL" "https://basic.wordpress.test"
echo "Site basic-wordpress restored to defaults. Stopping Cloudflare tunnel."
kill_tunnel
echo "Cloudflare tunnel stopped."
exit 0
}
#######################################
# Print error message to stderr in red color.
# Globals:
# None
# Arguments:
# $1 - Error message to print
# Outputs:
# Writes error message to stderr in red color.
# Returns:
# None (uses printf)
#######################################
function echoerr() {
printf "\033[0;31m%s\n\033[0m" "$*" >&2
}
#######################################
# Print verbose message to stderr in cyan color.
# Globals:
# None
# Arguments:
# $1 - Verbose message to print
# Outputs:
# Writes message to stderr in cyan color.
# Returns:
# None (uses printf)
#######################################
function echoverb() {
printf "\033[0;36m%s\n\033[0m" "$*" >&2
}
#######################################
# Display a text box with the given string centered.
# Uses terminal colors for visual formatting.
# Globals:
# None
# Arguments:
# $1 - String to display in the box
# Outputs:
# Writes formatted box to stdout.
# Returns:
# None (uses echo and tput)
#######################################
function box_out() {
local s="$*"
tput setaf 5
echo "+-${s//?/-}-+
| ${s//?/ } |
| $(tput setaf 4)$s$(tput setaf 5) |
| ${s//?/ } |
+-${s//?/-}-+"
tput sgr 0
}
#######################################
# Update WordPress database with new home and siteurl values.
# Performs search-replace of old URL with new URL in the database.
# Globals:
# None
# Arguments:
# $1 - REPLACE_FROM: The old URL to replace
# $2 - REPLACE_TO: The new URL to use
# Outputs:
# Modifies WordPress database options via wp_cli.
# Returns:
# Exit status from wp_cli commands.
#######################################
function do_database_actions() {
local REPLACE_FROM="$1"
local REPLACE_TO="$2"
wp_cli option set home "$REPLACE_TO"
wp_cli option set siteurl "$REPLACE_TO"
wp_cli search-replace "$REPLACE_FROM" "$REPLACE_TO"
}
#######################################
# Stop the Cloudflare tunnel Docker container.
# Suppresses output unless verbose mode is enabled.
# Globals:
# CF_TUNNEL_HASH - The Docker container hash of the tunnel
# Arguments:
# None
# Outputs:
# None (output suppressed or sent to stdout/stderr)
# Returns:
# Exit status from docker stop command.
#######################################
function kill_tunnel() {
docker stop "$CF_TUNNEL_HASH" &>$([[ ! $_VERBOSE ]] && echo '/dev/null' || echo '/dev/stdout')
}
#######################################
# Execute wp-cli commands inside the basic-wordpress Docker container.
# Adds --quiet flag when verbose mode is disabled.
# Globals:
# _VERBOSE - Controls quiet mode for wp-cli
# Arguments:
# $@ - Arguments passed to wp-cli
# Outputs:
# Command output from wp-cli (unless quiet mode)
# Returns:
# Exit status from wp-cli command.
#######################################
function wp_cli() {
docker exec -ti basic-wordpress wp "$@" $([[ ! $_VERBOSE ]] && echo '--quiet')
return $?
}
#######################################
# Verify that the basic-wordpress Docker container is running.
# Exits with error if container is not detected.
# Globals:
# _VERBOSE - Controls verbose output
# Arguments:
# None
# Outputs:
# Success message to stdout if container is running.
# Error message to stderr if container is not running.
# Returns:
# Exits with 1 if container is not running.
#######################################
function pre_check_wp_container() {
if docker ps | grep $([[ ! $_VERBOSE ]] && echo '-q') basic-wordpress; then
echo "Container basic-wordpress seems to be running. Proceeding."
else
echoerr "Can't detect basic-wordpress container running. Aborting."
exit 1
fi
}
#######################################
# Restore WordPress database to pre-tunnel state.
# Replaces the previous tunnel URL with the default WordPress URL.
# Globals:
# PRECHECK_HOME_OPTION - The previous home URL from the database
# Arguments:
# None
# Outputs:
# Status messages to stdout/stderr.
# Returns:
# Exits with 1 if restoration fails.
#######################################
function attempt_restore() {
echo "Attempting restore of old tunnel remnants..."
if [[ $(do_database_actions "$PRECHECK_HOME_OPTION" "https://basic.wordpress.test") -eq 0 ]]; then
echo "Restored to basic settings."
else
echoerr "Restoration failed, verify manually or clean with 'clean.sh'. Aborting."
exit 1
fi
}
#######################################
# Pre-check the WordPress database home option before starting tunnel.
# Detects previous tunnel URLs and prompts for restoration if needed.
# Globals:
# PRECHECK_HOME_OPTION - Set to the current home option value
# _VERBOSE - Controls verbose output
# Arguments:
# None
# Outputs:
# Status messages and prompts to stdout/stderr.
# Returns:
# Exits with 1 if database is not in expected state.
#######################################
function pre_check_wp_database() {
PRECHECK_HOME_OPTION=$(wp_cli option get home | tr -d '[:space:]')
if [[ "$PRECHECK_HOME_OPTION" != "https://basic.wordpress.test" ]]; then
if [[ "$PRECHECK_HOME_OPTION" =~ .+trycloudflare.com$ ]]; then
echo "Previous 'trycloudflare.com' URL found in the database. This indicates a tunnel was started and not terminated properly. Attempt restore?"
select yn in "Yes" "No"; do
case $yn in
Yes ) attempt_restore; break;;
No ) echoerr "Aborting."; exit 1;;
esac
done
else
echoerr "Default home option (basic.wordpress.test) not found. Running a search-replace may corrupt the database. Please run 'clean.sh' to clean your environment and try again. Aborting."
exit 1
fi
fi
[[ "$_VERBOSE" ]] && echoverb "Default database option found, we can continue."
}
#######################################
# Extract the Cloudflare tunnel public URL from container logs.
# Parses log output to find the HTTPS URL provided by Cloudflare.
# Globals:
# WAIT_FOR_CF_URL - Maximum seconds to wait for URL
# CF_TUNNEL_HASH - The Docker container hash to check logs from
# Arguments:
# None
# Outputs:
# Writes the extracted URL to stdout (if found).
# Returns:
# Exits with 0 when URL is found, otherwise exits with non-zero.
#######################################
function cf_timed_check () {
timeout "$WAIT_FOR_CF_URL" docker logs -f "$CF_TUNNEL_HASH" 2>&1 | \
while read -r line; do
[[ "$line" =~ INF[\ \|]+https ]] && echo "$line" | grep -E 'INF[ \|]+https' | grep -oE 'https://[^ ]+' && exit 0
done
}
#######################################
# Start the Cloudflare tunnel Docker container and retrieve the public URL.
# Waits for Cloudflare to provide the tunnel URL from container logs.
# Globals:
# CF_TUNNEL_HASH - Set to the Docker container hash on success
# CF_TUNNEL_PUBLIC_URL - Set to the public tunnel URL on success
# WAIT_FOR_CF_URL - Maximum seconds to wait for URL
# _VERBOSE - Controls verbose output
# Arguments:
# None
# Outputs:
# Status messages to stdout/stderr.
# Returns:
# Exits with 1 if tunnel cannot be started or URL not retrieved.
#######################################
function start_cf_container() {
if ! CF_TUNNEL_HASH=$(docker run -d cloudflare/cloudflared:latest tunnel --url https://host.docker.internal:443 --no-tls-verify --http-host-header basic.wordpress.test --origin-server-name basic.wordpress.test); then
echoerr "Could not start a proper tunnel container. Aborting."
fi
[[ "$_VERBOSE" ]] && echoverb "Tunnel container hash: $CF_TUNNEL_HASH"
echo "Waiting a maximum of $WAIT_FOR_CF_URL seconds for Cloudflare to provide us with your URL."
CF_TUNNEL_PUBLIC_URL="$(cf_timed_check)"
[[ "$CF_TUNNEL_PUBLIC_URL" == '' ]] && echoerr "Could not retrieve a tunnel URL from Cloudflare. Dumping Cloudflare container logs and aborting." && docker logs --tail 20 "$CF_TUNNEL_HASH" && kill_tunnel && exit 1
}
#######################################
# Main entry point for the tunnel management script.
# Orchestrates container verification, database checks, tunnel startup,
# and URL display to the user.
# Globals:
# CF_TUNNEL_PUBLIC_URL - Set by start_cf_container
# CF_TUNNEL_HASH - Set by start_cf_container
# Arguments:
# None
# Outputs:
# Status messages and tunnel URL to stdout/stderr.
# Returns:
# Runs indefinitely until interrupted (via ctrl_c handler).
#######################################
function main() {
pre_check_wp_container
pre_check_wp_database
start_cf_container
echo "Performing replacements in the docker basic-wordpress container..."
do_database_actions "https://basic.wordpress.test" "$CF_TUNNEL_PUBLIC_URL"
echo
echo "Tunnel is set up. Here is your public URL:"
box_out "$CF_TUNNEL_PUBLIC_URL"
echo
echo "Be aware that your are granting public access to a part of your machine. Do not keep this tunnel running longer than necessary."
echo "Press CTRL + C to revert your site to basic.wordpress.test and exit the tunnel."
while true; do sleep 60; done
}
# Parse command-line arguments for optional flags.
# Supports --verbose/-v for verbose output and --restore/-r for pre-check only mode.
while test $# -gt 0; do
case "$1" in
-v|--verbose)
_VERBOSE=true
shift
;;
-r|--restore)
_RUN_RESTORE=true
shift
;;
*)
break
;;
esac
done
# If --restore flag was provided, only run pre-checks and optionally restore.
if [[ "$_RUN_RESTORE" ]]; then
echo "Only running pre-checks and potentially restore."
pre_check_wp_container
pre_check_wp_database
echo "Done."
exit 0
fi
main