-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdate.sh
More file actions
executable file
·370 lines (334 loc) · 10.9 KB
/
update.sh
File metadata and controls
executable file
·370 lines (334 loc) · 10.9 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
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
#!/bin/bash
# Define colors and text styles
BOLD=$(tput bold)
RESET=$(tput sgr0)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4)
# Define the log file location
LOG_FILE="/tmp/update_log.txt"
# Initialize the log file
echo "Starting update at $(date)..." > "$LOG_FILE"
# Helper functions for displaying progress
function display_message() {
echo -n "${BOLD}$1${RESET}... "
}
function complete_message() {
echo -e "${GREEN}Done.${RESET}"
}
function skip_message() {
echo -e "${YELLOW}Skipped.${RESET}"
}
function info_message() {
echo -e "${BLUE}$1${RESET}"
}
# Function for showing a spinner while a command runs
function spinner() {
local pid=$!
local delay=0.1
local spin=('-' '\' '|' '/')
while kill -0 "$pid" 2>/dev/null; do
for i in "${spin[@]}"; do
echo -ne "\b$i" > /dev/tty
sleep $delay
done
done
wait $pid
local exit_code=$?
echo -ne "\b"
return $exit_code
}
# Run a command with spinner
function run_with_spinner() {
display_message "$1"
eval "$2" >> "$LOG_FILE" 2>&1 & spinner
if [ $? -eq 0 ]; then
complete_message
return 0
else
echo -e "${BOLD}${YELLOW}Failed.${RESET} Check log for details."
return 1
fi
}
# Define a custom apt function to enforce DEBIAN_FRONTEND
function apt2() {
sudo DEBIAN_FRONTEND=noninteractive apt "$@"
}
# Function to check if a command exists
function command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to get current version of a tool
function get_current_version() {
case "$1" in
"quarto")
if command_exists quarto; then
quarto --version 2>/dev/null || echo "unknown"
else
echo "not installed"
fi
;;
"rstudio-server")
if command_exists rstudio-server; then
rstudio-server version 2>/dev/null | cut -d' ' -f1 || echo "unknown"
else
echo "not installed"
fi
;;
*)
echo "unknown"
;;
esac
}
# Parse command line arguments
UPDATE_ALL=true
UPDATE_SYSTEM=false
UPDATE_R=false
UPDATE_QUARTO=false
UPDATE_RSTUDIO=false
UPDATE_VSCODE=false
UPDATE_DUCKDB=false
UPDATE_DOCKER=false
UPDATE_TOOLS=false
while [[ $# -gt 0 ]]; do
case $1 in
--system)
UPDATE_ALL=false
UPDATE_SYSTEM=true
shift
;;
--r)
UPDATE_ALL=false
UPDATE_R=true
shift
;;
--quarto)
UPDATE_ALL=false
UPDATE_QUARTO=true
shift
;;
--rstudio)
UPDATE_ALL=false
UPDATE_RSTUDIO=true
shift
;;
--vscode)
UPDATE_ALL=false
UPDATE_VSCODE=true
shift
;;
--duckdb)
UPDATE_ALL=false
UPDATE_DUCKDB=true
shift
;;
--docker)
UPDATE_ALL=false
UPDATE_DOCKER=true
shift
;;
--tools)
UPDATE_ALL=false
UPDATE_TOOLS=true
shift
;;
--help|-h)
echo "Usage: $0 [options]"
echo "Options:"
echo " --system Update system packages only"
echo " --r Update R only"
echo " --quarto Update Quarto only"
echo " --rstudio Update RStudio Server only"
echo " --vscode Update VS Code and extensions only"
echo " --duckdb Update DuckDB only"
echo " --docker Update Docker only"
echo " --tools Update development tools (Rust, uv, ruff, sqlfluff, rig) only"
echo " --help, -h Show this help message"
echo ""
echo "If no options are specified, all components will be updated."
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Define software versions (can be overridden by environment variables)
QUARTO_VERSION=${QUARTO_VERSION:-"1.8.27"}
RSTUDIO_SERVER_VERSION=${RSTUDIO_SERVER_VERSION:-"2026.01.0-392"}
echo -e "\n${BOLD}GCP Instance Update Script${RESET}"
echo "================================"
echo "Log file: ${GREEN}${LOG_FILE}${RESET}"
echo ""
# Display what will be updated
if [ "$UPDATE_ALL" = true ]; then
info_message "Updating all components..."
else
info_message "Selective update mode:"
[ "$UPDATE_SYSTEM" = true ] && echo " - System packages"
[ "$UPDATE_R" = true ] && echo " - R"
[ "$UPDATE_QUARTO" = true ] && echo " - Quarto"
[ "$UPDATE_RSTUDIO" = true ] && echo " - RStudio Server"
[ "$UPDATE_VSCODE" = true ] && echo " - VS Code and extensions"
[ "$UPDATE_DUCKDB" = true ] && echo " - DuckDB"
[ "$UPDATE_DOCKER" = true ] && echo " - Docker"
[ "$UPDATE_TOOLS" = true ] && echo " - Development tools"
fi
echo ""
# 1. Update system packages
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_SYSTEM" = true ]; then
run_with_spinner "Updating system packages" \
"apt2 update && apt2 upgrade -y"
fi
# 2. Update R
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_R" = true ]; then
if command_exists R; then
run_with_spinner "Updating R" \
"apt2 update && apt2 install -y r-base r-base-dev"
else
info_message "R is not installed. Skipping R update."
fi
fi
# 3. Update Quarto
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_QUARTO" = true ]; then
if command_exists quarto; then
current_version=$(get_current_version "quarto")
info_message "Current Quarto version: $current_version"
info_message "Target Quarto version: $QUARTO_VERSION"
if [ "$current_version" != "$QUARTO_VERSION" ]; then
run_with_spinner "Updating Quarto to version $QUARTO_VERSION" "
wget -q https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz && \
tar -xzf quarto-${QUARTO_VERSION}-linux-amd64.tar.gz && \
sudo rm -rf /opt/quarto-* && \
sudo mv quarto-${QUARTO_VERSION} /opt/quarto-${QUARTO_VERSION} && \
sudo rm -f /usr/local/bin/quarto && \
sudo ln -s /opt/quarto-${QUARTO_VERSION}/bin/quarto /usr/local/bin/quarto && \
rm quarto-${QUARTO_VERSION}-linux-amd64.tar.gz
"
# Update TinyTeX if it's installed
if [ -d "$HOME/.TinyTeX" ] || [ -d "/opt/TinyTeX" ]; then
run_with_spinner "Updating TinyTeX" \
"/opt/quarto-${QUARTO_VERSION}/bin/quarto install tinytex --update-path --no-prompt"
fi
else
info_message "Quarto is already at version $current_version. Skipping update."
fi
else
info_message "Quarto is not installed. Skipping Quarto update."
fi
fi
# 4. Update RStudio Server
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_RSTUDIO" = true ]; then
if command_exists rstudio-server; then
current_version=$(get_current_version "rstudio-server")
# Convert hyphen to plus for comparison
target_version_display=$(echo "$RSTUDIO_SERVER_VERSION" | sed 's/-/+/')
info_message "Current RStudio Server version: $current_version"
info_message "Target RStudio Server version: $target_version_display"
if [ "$current_version" != "$target_version_display" ]; then
# Stop RStudio Server before updating
run_with_spinner "Stopping RStudio Server" \
"sudo systemctl stop rstudio-server"
run_with_spinner "Updating RStudio Server to version $target_version_display" \
"wget -q https://download2.rstudio.org/server/jammy/amd64/rstudio-server-${RSTUDIO_SERVER_VERSION}-amd64.deb && \
sudo gdebi -n rstudio-server-${RSTUDIO_SERVER_VERSION}-amd64.deb && \
rm rstudio-server-${RSTUDIO_SERVER_VERSION}-amd64.deb"
# Start RStudio Server after updating
run_with_spinner "Starting RStudio Server" \
"sudo systemctl start rstudio-server"
else
info_message "RStudio Server is already at version $current_version. Skipping update."
fi
else
info_message "RStudio Server is not installed. Skipping RStudio Server update."
fi
fi
# 5. Update VS Code and extensions
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_VSCODE" = true ]; then
if command_exists code-server; then
# Update code-server
run_with_spinner "Updating VS Code (code-server)" \
"curl -fsSL https://code-server.dev/install.sh | sh"
# Update extensions
run_with_spinner "Updating VS Code extensions" "
code-server --install-extension ms-python.python --force && \
code-server --install-extension ms-toolsai.jupyter --force && \
code-server --install-extension quarto.quarto --force && \
code-server --install-extension charliermarsh.ruff --force
"
else
info_message "VS Code (code-server) is not installed. Skipping VS Code update."
fi
fi
# 6. Update DuckDB
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_DUCKDB" = true ]; then
run_with_spinner "Updating DuckDB" \
"curl -fsSL https://install.duckdb.org | sh"
fi
# 7. Update Docker
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_DOCKER" = true ]; then
if command_exists docker; then
info_message "Docker is installed. Checking for updates..."
# Docker updates are handled by apt, so we just update via apt
run_with_spinner "Updating Docker" \
"apt2 update && apt2 install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"
else
info_message "Docker is not installed. Skipping Docker update."
fi
fi
# 8. Update development tools
if [ "$UPDATE_ALL" = true ] || [ "$UPDATE_TOOLS" = true ]; then
# Update Rust
if [ -f "$HOME/.cargo/bin/rustup" ]; then
run_with_spinner "Updating Rust" \
"$HOME/.cargo/bin/rustup update"
else
info_message "Rust is not installed. Skipping Rust update."
fi
# Update uv and ruff
if command_exists uv; then
run_with_spinner "Updating uv" \
"curl -LsSf https://astral.sh/uv/install.sh | sh"
run_with_spinner "Updating ruff" \
"uv tool install --upgrade ruff"
else
info_message "uv is not installed. Skipping uv/ruff update."
fi
# Update sqlfluff
if command_exists sqlfluff; then
run_with_spinner "Updating SQLFluff" \
"uv tool install --upgrade sqlfluff"
else
info_message "SQLFluff is not installed. Skipping SQLFluff update."
fi
# Update rig
if command_exists rig; then
run_with_spinner "Updating rig" \
"apt2 update && apt2 install -y r-rig"
else
info_message "rig is not installed. Skipping rig update."
fi
fi
# Post-update message
echo ""
echo -e "${BOLD}${GREEN}Update complete!${RESET}"
echo -e "Log saved to: ${GREEN}${LOG_FILE}${RESET}"
echo ""
echo -e "${BOLD}Updated components:${RESET}"
if [ "$UPDATE_ALL" = true ]; then
echo " - All components have been checked and updated as needed"
else
[ "$UPDATE_SYSTEM" = true ] && echo " - System packages"
[ "$UPDATE_R" = true ] && echo " - R"
[ "$UPDATE_QUARTO" = true ] && echo " - Quarto"
[ "$UPDATE_RSTUDIO" = true ] && echo " - RStudio Server"
[ "$UPDATE_VSCODE" = true ] && echo " - VS Code and extensions"
[ "$UPDATE_DUCKDB" = true ] && echo " - DuckDB"
[ "$UPDATE_DOCKER" = true ] && echo " - Docker"
[ "$UPDATE_TOOLS" = true ] && echo " - Development tools (Rust, uv, ruff, sqlfluff, rig)"
fi
echo ""
echo -e "${BOLD}Note:${RESET} Unlike the setup script, no reboot is required."
echo "Services should continue running normally."