最後活躍 2 weeks ago

修訂 f7d5d8a951b1715fc6e6a2e596e9d2b2af236c5b

do_anduinos_distupgrade.sh 原始檔案
1#!/bin/bash
2
3#=================================================
4# AnduinOS Upgrade Script
5#=================================================
6# This script upgrades AnduinOS from 1.3.7 (plucky)
7# to 1.4.0 (questing).
8#
9# Run this script as root.
10# or user with privileges.
11#
12# Example:
13# sudo ./do_anduinos_distupgrade.sh
14#=================================================
15
16set -e
17set -o pipefail
18set -u
19
20Green="\033[32m"
21Red="\033[31m"
22Yellow="\033[33m"
23Blue="\033[36m"
24Font="\033[0m"
25GreenBG="\033[42;37m"
26RedBG="\033[41;37m"
27OK="${Green}[ OK ]${Font}"
28ERROR="${Red}[FAILED]${Font}"
29WARNING="${Yellow}[ WARN ]${Font}"
30
31BACKUP_DIR="/tmp/anduinos_upgrade_backup_$(date +%Y%m%d_%H%M%S)"
32PPA_BACKUP_DIR="$BACKUP_DIR/ppa"
33UBUNTU_SOURCE_BACKUP="$BACKUP_DIR/ubuntu_sources"
34
35function print_ok() {
36 echo -e "${OK} ${Blue} $1 ${Font}"
37}
38
39function print_error() {
40 echo -e "${ERROR} ${Red} $1 ${Font}"
41}
42
43function print_warn() {
44 echo -e "${WARNING} ${Yellow} $1 ${Font}"
45}
46
47function rollback_on_error() {
48 print_error "An error occurred during the upgrade process"
49 print_warn "Starting rollback procedure..."
50
51 # Restore ubuntu.sources if backup exists
52 if [ -f "$UBUNTU_SOURCE_BACKUP/ubuntu.sources" ]; then
53 print_ok "Restoring ubuntu.sources..."
54 cp "$UBUNTU_SOURCE_BACKUP/ubuntu.sources" /etc/apt/sources.list.d/
55 print_ok "Restored ubuntu.sources"
56 fi
57
58 # Restore sources.list if backup exists
59 if [ -f "$UBUNTU_SOURCE_BACKUP/sources.list" ]; then
60 print_ok "Restoring sources.list..."
61 cp "$UBUNTU_SOURCE_BACKUP/sources.list" /etc/apt/
62 print_ok "Restored sources.list"
63 fi
64
65 # Restore PPA sources
66 if [ -d "$PPA_BACKUP_DIR" ]; then
67 ppa_count=$(ls -1 "$PPA_BACKUP_DIR" 2>/dev/null | wc -l)
68
69 if [ "$ppa_count" -gt 0 ]; then
70 print_ok "Restoring PPA sources..."
71 for file in "$PPA_BACKUP_DIR"/*; do
72 if [ -f "$file" ]; then
73 cp "$file" /etc/apt/sources.list.d/
74 print_ok "Restored $(basename "$file")"
75 fi
76 done
77 fi
78 fi
79
80 # Remove temporary apt configuration if exists
81 if [ -f "/etc/apt/apt.conf.d/99-local-versions" ]; then
82 rm -f /etc/apt/apt.conf.d/99-local-versions
83 print_ok "Removed temporary apt configuration"
84 fi
85
86 # Run apt update to restore repository state
87 print_ok "Running apt update to restore repository state..."
88 apt update || true
89
90 print_warn "Rollback completed"
91 print_warn "Your system has been restored to the previous state"
92 print_warn "Backup files are preserved in: $BACKUP_DIR"
93 print_error "Please check the error messages above and try again"
94
95 exit 1
96}
97
98function judge() {
99 if [[ 0 -eq $? ]]; then
100 print_ok "$1 succeeded"
101 sleep 0.2
102 else
103 print_error "$1 failed"
104 rollback_on_error
105 fi
106}
107
108function check_disk_space() {
109 print_ok "Checking available disk space..."
110
111 # Get available space in /tmp (in KB)
112 local tmp_space=$(df /tmp | awk 'NR==2 {print $4}')
113 # Get available space in / (in KB)
114 local root_space=$(df / | awk 'NR==2 {print $4}')
115
116 # Convert to MB
117 local tmp_space_mb=$((tmp_space / 1024))
118 local root_space_mb=$((root_space / 1024))
119
120 # Required space: 2GB = 2048MB
121 local required_space=2048
122
123 print_ok "Available space in /tmp: ${tmp_space_mb}MB"
124 print_ok "Available space in /: ${root_space_mb}MB"
125
126 if [ "$tmp_space_mb" -lt "$required_space" ]; then
127 print_error "Insufficient disk space in /tmp. Required: ${required_space}MB, Available: ${tmp_space_mb}MB"
128 exit 1
129 fi
130
131 if [ "$root_space_mb" -lt "$required_space" ]; then
132 print_error "Insufficient disk space in /. Required: ${required_space}MB, Available: ${root_space_mb}MB"
133 exit 1
134 fi
135
136 print_ok "Disk space check passed"
137}
138
139function update_system() {
140 print_ok "Running apt update and upgrade..."
141 apt update
142 judge "apt update"
143 apt upgrade -y
144 judge "apt upgrade"
145}
146
147function backup_ubuntu_sources() {
148 print_ok "Backing up Ubuntu official sources..."
149
150 mkdir -p "$UBUNTU_SOURCE_BACKUP"
151
152 # Backup ubuntu.sources if exists
153 if [ -f "/etc/apt/sources.list.d/ubuntu.sources" ]; then
154 cp /etc/apt/sources.list.d/ubuntu.sources "$UBUNTU_SOURCE_BACKUP/"
155 print_ok "Backed up ubuntu.sources"
156 fi
157
158 # Backup sources.list if it exists and is not empty
159 if [ -f "/etc/apt/sources.list" ] && [ -s "/etc/apt/sources.list" ]; then
160 cp /etc/apt/sources.list "$UBUNTU_SOURCE_BACKUP/"
161 print_ok "Backed up sources.list"
162 fi
163
164 judge "Backup Ubuntu sources"
165}
166
167function backup_and_remove_ppa() {
168 print_ok "Backing up and temporarily removing PPA sources..."
169
170 mkdir -p "$PPA_BACKUP_DIR"
171
172 # Move all files in /etc/apt/sources.list.d/ except ubuntu.sources
173 if [ -d "/etc/apt/sources.list.d" ]; then
174 for file in /etc/apt/sources.list.d/*; do
175 if [ -f "$file" ] && [ "$(basename "$file")" != "ubuntu.sources" ]; then
176 mv "$file" "$PPA_BACKUP_DIR/"
177 print_ok "Moved $(basename "$file") to backup"
178 fi
179 done
180 fi
181
182 print_ok "PPA sources moved to: $PPA_BACKUP_DIR"
183 judge "Backup and remove PPA sources"
184}
185
186function detect_apt_format() {
187 print_ok "Detecting APT source format..."
188
189 if [ -f "/etc/apt/sources.list.d/ubuntu.sources" ]; then
190 print_ok "Detected new DEB822 format (ubuntu.sources)"
191 return 0
192 elif [ -f "/etc/apt/sources.list" ] && [ -s "/etc/apt/sources.list" ]; then
193 print_ok "Detected old format (sources.list)"
194 return 1
195 else
196 print_error "Cannot detect APT source format"
197 rollback_on_error
198 fi
199}
200
201function convert_old_to_new_format() {
202 print_ok "Converting old format to new DEB822 format..."
203
204 if [ ! -f "/etc/apt/sources.list" ] || [ ! -s "/etc/apt/sources.list" ]; then
205 print_error "/etc/apt/sources.list not found or empty"
206 rollback_on_error
207 fi
208
209 # Backup the old sources.list
210 cp /etc/apt/sources.list /etc/apt/sources.list.backup
211
212 # Extract mirror URLs from existing sources.list
213 # Try to detect main archive mirror
214 MIRROR_URL=$(grep -E "^deb " /etc/apt/sources.list | grep -v "security" | head -1 | awk '{print $2}')
215 if [ -z "$MIRROR_URL" ]; then
216 MIRROR_URL="http://archive.ubuntu.com/ubuntu/"
217 fi
218
219 # Try to detect security mirror
220 SECURITY_URL=$(grep -E "^deb " /etc/apt/sources.list | grep "security" | head -1 | awk '{print $2}')
221 if [ -z "$SECURITY_URL" ]; then
222 SECURITY_URL="http://security.ubuntu.com/ubuntu/"
223 fi
224
225 print_ok "Detected mirror URL: $MIRROR_URL"
226 print_ok "Detected security URL: $SECURITY_URL"
227
228 # Create new ubuntu.sources file using detected mirrors
229 bash -c "cat > /etc/apt/sources.list.d/ubuntu.sources" <<EOF
230Types: deb
231URIs: ${MIRROR_URL}
232Suites: plucky plucky-updates plucky-backports
233Components: main restricted universe multiverse
234Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
235
236Types: deb
237URIs: ${SECURITY_URL}
238Suites: plucky-security
239Components: main restricted universe multiverse
240Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
241EOF
242
243 # Clear the old sources.list
244 bash -c 'echo "# This file is deprecated. See /etc/apt/sources.list.d/ubuntu.sources" > /etc/apt/sources.list'
245
246 judge "Convert to new format"
247}
248
249function replace_plucky_with_questing() {
250 print_ok "Replacing plucky with questing in ubuntu.sources..."
251
252 if [ ! -f "/etc/apt/sources.list.d/ubuntu.sources" ]; then
253 print_error "/etc/apt/sources.list.d/ubuntu.sources not found"
254 rollback_on_error
255 fi
256
257 sed -i 's/plucky/questing/g' /etc/apt/sources.list.d/ubuntu.sources
258 judge "Replace plucky with questing"
259
260 print_ok "Running apt update with questing repositories..."
261 apt update
262 judge "apt update with questing"
263}
264
265function install_coreutils_uutils() {
266 print_ok "Installing coreutils-from-uutils..."
267
268 apt install -y coreutils-from-uutils
269 judge "Install coreutils-from-uutils"
270}
271
272function run_dist_upgrade() {
273 print_ok "Simulating apt dist-upgrade first..."
274 apt -s dist-upgrade
275 judge "apt -s dist-upgrade"
276
277 print_ok "Running apt dist-upgrade in non-interactive mode..."
278
279 # Set environment for non-interactive mode
280 export DEBIAN_FRONTEND=noninteractive
281
282 # Configure dpkg to keep local versions by default
283 bash -c 'cat > /etc/apt/apt.conf.d/99-local-versions <<EOF
284Dpkg::Options {
285 "--force-confdef";
286 "--force-confold";
287}
288EOF'
289
290 # Run dist-upgrade
291 bash -c 'DEBIAN_FRONTEND=noninteractive APT_LISTCHANGES_FRONTEND=none \
292 apt-get -y dist-upgrade \
293 -o Dpkg::Options::="--force-confdef" \
294 -o Dpkg::Options::="--force-confold"'
295
296 judge "apt dist-upgrade"
297
298 # Remove temporary configuration
299 rm -f /etc/apt/apt.conf.d/99-local-versions
300
301 unset DEBIAN_FRONTEND
302}
303
304function update_release_files() {
305 print_ok "Updating release information files..."
306
307 # Update /etc/os-release
308 if [ -f "/etc/os-release" ]; then
309 print_ok "Updating /etc/os-release..."
310 sed -i 's/UBUNTU_CODENAME=plucky/UBUNTU_CODENAME=questing/g' /etc/os-release
311 sed -i 's/VERSION_CODENAME=plucky/VERSION_CODENAME=questing/g' /etc/os-release
312 sed -i 's/VERSION_ID="1\.3\.7"/VERSION_ID="1.4.0"/g' /etc/os-release
313 sed -i 's/VERSION="1\.3\.7 (plucky)"/VERSION="1.4.0 (questing)"/g' /etc/os-release
314 sed -i 's/PRETTY_NAME="AnduinOS 1\.3\.7"/PRETTY_NAME="AnduinOS 1.4.0"/g' /etc/os-release
315 sed -i 's/PRETTY_NAME="AnduinOS 1\.3\.7"/PRETTY_NAME="AnduinOS 1.4.0"/g' /etc/os-release
316 judge "Update /etc/os-release"
317 fi
318
319 # Update /etc/lsb-release
320 if [ -f "/etc/lsb-release" ]; then
321 print_ok "Updating /etc/lsb-release..."
322 sed -i 's/DISTRIB_RELEASE=1\.3\.7/DISTRIB_RELEASE=1.4.0/g' /etc/lsb-release
323 sed -i 's/DISTRIB_CODENAME=plucky/DISTRIB_CODENAME=questing/g' /etc/lsb-release
324 sed -i 's/DISTRIB_DESCRIPTION="AnduinOS 1\.3\.7"/DISTRIB_DESCRIPTION="AnduinOS 1.4.0"/g' /etc/lsb-release
325 judge "Update /etc/lsb-release"
326 fi
327
328 print_ok "Release files updated successfully"
329}
330
331function restore_ppa_sources() {
332 print_ok "Restoring PPA sources..."
333
334 if [ -d "$PPA_BACKUP_DIR" ]; then
335 ppa_count=$(ls -1 "$PPA_BACKUP_DIR" 2>/dev/null | wc -l)
336
337 if [ "$ppa_count" -gt 0 ]; then
338 for file in "$PPA_BACKUP_DIR"/*; do
339 if [ -f "$file" ]; then
340 mv "$file" /etc/apt/sources.list.d/
341 print_ok "Restored $(basename "$file")"
342 fi
343 done
344
345 print_ok "Running apt update with restored PPAs..."
346 apt update
347 judge "Restore PPA sources and update"
348 else
349 print_ok "No PPA sources to restore"
350 fi
351 else
352 print_warn "PPA backup directory not found, skipping restore"
353 fi
354}
355
356function main() {
357 print_ok "Starting AnduinOS upgrade process..."
358
359 echo -e "${Yellow}WARNING: This script will upgrade your system from 1.3.7 (plucky) to 1.4.0 (questing).${Font}"
360 echo -e "${Yellow}Please ensure you have backed up important data before proceeding.${Font}"
361 read -p "Do you want to continue? (y/N): " confirm
362 if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
363 print_error "Upgrade process aborted by user."
364 exit 1
365 fi
366
367 # Check if running as root
368 if [[ "$(id -u)" -ne 0 ]]; then
369 print_error "This script must be run as root."
370 exit 1
371 fi
372
373 # Step 0: Check disk space
374 check_disk_space
375
376 # Step 1: Update current system
377 update_system
378
379 # Step 2: Backup Ubuntu official sources
380 backup_ubuntu_sources
381
382 # Step 3: Backup and remove PPA sources
383 backup_and_remove_ppa
384
385 # Step 4: Detect and convert APT format if needed
386 if ! detect_apt_format; then
387 convert_old_to_new_format
388 fi
389
390 # Step 5: Replace plucky with questing
391 replace_plucky_with_questing
392
393 # Step 6: Install coreutils-from-uutils
394 install_coreutils_uutils
395
396 # Step 7: Run dist-upgrade
397 run_dist_upgrade
398
399 # Step 8: Update release files
400 update_release_files
401
402 # Step 9: Restore PPA sources
403 restore_ppa_sources
404
405 print_ok "Upgrade completed successfully!"
406 print_ok "Your system has been upgraded to AnduinOS 1.4.0 (questing)"
407 print_ok "Backup files are stored in: $BACKUP_DIR"
408 print_warn "Please reboot your system to complete the upgrade."
409}
410
411main