Forké de ZeTian/do_anduinos_distupgrade.sh

Dernière activité 2 weeks ago

Révision b7a751260b1373fff6563be275f19ae2aee7b0cc

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