Geforkt von ZeTian/do_anduinos_distupgrade.sh

Zuletzt aktiv 2 weeks ago

Änderung a3c0114f125a2c0b879c7f9dfff8ac4675861897

do_anduinos_distupgrade.sh Originalformat
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 "Ensuring current system (1.3 / Ubuntu 25.04) is fully updated..."
180
181 print_ok "Running apt update..."
182 apt update
183 judge "apt update"
184
185 print_ok "Installing any missing updates for the current version..."
186 # Use non-interactive flags to ensure current 1.3 packages are up-to-date
187 DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt upgrade -y
188 judge "apt upgrade"
189}
190
191function backup_ubuntu_sources() {
192 print_ok "Backing up Ubuntu official sources..."
193
194 mkdir -p "$UBUNTU_SOURCE_BACKUP"
195
196 # Backup ubuntu.sources if exists
197 if [ -f "/etc/apt/sources.list.d/ubuntu.sources" ]; then
198 cp /etc/apt/sources.list.d/ubuntu.sources "$UBUNTU_SOURCE_BACKUP/"
199 print_ok "Backed up ubuntu.sources"
200 fi
201
202 # Backup sources.list if it exists and is not empty
203 if [ -f "/etc/apt/sources.list" ] && [ -s "/etc/apt/sources.list" ]; then
204 cp /etc/apt/sources.list "$UBUNTU_SOURCE_BACKUP/"
205 print_ok "Backed up sources.list"
206 fi
207
208 judge "Backup Ubuntu sources"
209}
210
211function backup_and_remove_ppa() {
212 print_ok "Backing up and temporarily removing PPA sources..."
213
214 mkdir -p "$PPA_BACKUP_DIR"
215
216 # Move all files in /etc/apt/sources.list.d/ except ubuntu.sources
217 if [ -d "/etc/apt/sources.list.d" ]; then
218 for file in /etc/apt/sources.list.d/*; do
219 if [ -f "$file" ] && [ "$(basename "$file")" != "ubuntu.sources" ]; then
220 mv "$file" "$PPA_BACKUP_DIR/"
221 print_ok "Moved $(basename "$file") to backup"
222 fi
223 done
224 fi
225
226 print_ok "PPA sources moved to: $PPA_BACKUP_DIR"
227 judge "Backup and remove PPA sources"
228}
229
230function detect_apt_format() {
231 print_ok "Detecting APT source format..."
232
233 if [ -f "/etc/apt/sources.list.d/ubuntu.sources" ]; then
234 print_ok "Detected new DEB822 format (ubuntu.sources)"
235 return 0
236 elif [ -f "/etc/apt/sources.list" ] && [ -s "/etc/apt/sources.list" ]; then
237 print_ok "Detected old format (sources.list)"
238 return 1
239 else
240 print_error "Cannot detect APT source format"
241 rollback_on_error
242 fi
243}
244
245function convert_old_to_new_format() {
246 print_ok "Converting old format to new DEB822 format..."
247
248 if [ ! -f "/etc/apt/sources.list" ] || [ ! -s "/etc/apt/sources.list" ]; then
249 print_error "/etc/apt/sources.list not found or empty"
250 rollback_on_error
251 fi
252
253 # Backup the old sources.list
254 cp /etc/apt/sources.list /etc/apt/sources.list.backup
255
256 # Extract mirror URLs from existing sources.list (Restored from Old Script)
257 # Try to detect main archive mirror
258 MIRROR_URL=$(grep -E "^deb " /etc/apt/sources.list | grep -v "security" | head -1 | awk '{print $2}')
259 if [ -z "$MIRROR_URL" ]; then
260 MIRROR_URL="http://archive.ubuntu.com/ubuntu/"
261 fi
262
263 # Try to detect security mirror
264 SECURITY_URL=$(grep -E "^deb " /etc/apt/sources.list | grep "security" | head -1 | awk '{print $2}')
265 if [ -z "$SECURITY_URL" ]; then
266 SECURITY_URL="http://security.ubuntu.com/ubuntu/"
267 fi
268
269 print_ok "Detected mirror URL: $MIRROR_URL"
270 print_ok "Detected security URL: $SECURITY_URL"
271
272 # Create new ubuntu.sources file using detected mirrors
273 bash -c "cat > /etc/apt/sources.list.d/ubuntu.sources" <<EOF
274Types: deb
275URIs: ${MIRROR_URL}
276Suites: plucky plucky-updates plucky-backports
277Components: main restricted universe multiverse
278Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
279
280Types: deb
281URIs: ${SECURITY_URL}
282Suites: plucky-security
283Components: main restricted universe multiverse
284Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
285EOF
286
287 # Clear the old sources.list
288 bash -c 'echo "# This file is deprecated. See /etc/apt/sources.list.d/ubuntu.sources" > /etc/apt/sources.list'
289
290 judge "Convert to new format"
291}
292
293function replace_plucky_with_questing() {
294 print_ok "Replacing plucky with questing in ubuntu.sources..."
295
296 if [ ! -f "/etc/apt/sources.list.d/ubuntu.sources" ]; then
297 print_error "/etc/apt/sources.list.d/ubuntu.sources not found"
298 rollback_on_error
299 fi
300
301 sed -i 's/plucky/questing/g' /etc/apt/sources.list.d/ubuntu.sources
302 judge "Replace plucky with questing"
303
304 print_ok "Running apt update with questing repositories..."
305 apt update
306 judge "apt update with questing"
307}
308
309function install_coreutils_uutils() {
310 print_ok "Installing coreutils-from-uutils..."
311
312 DEBIAN_FRONTEND=noninteractive apt install -y coreutils-from-uutils
313 judge "Install coreutils-from-uutils"
314}
315
316function run_dist_upgrade() {
317 print_ok "Simulating apt dist-upgrade first..."
318 apt -s dist-upgrade > /dev/null
319 judge "apt -s dist-upgrade"
320
321 print_ok "Running apt dist-upgrade in non-interactive mode..."
322
323 # Configure dpkg to keep local versions by default
324 bash -c 'cat > /etc/apt/apt.conf.d/99-local-versions <<EOF
325Dpkg::Options {
326 "--force-confdef";
327 "--force-confold";
328}
329EOF'
330
331 # Run dist-upgrade
332 # Combine variables: DEBIAN_FRONTEND, NEEDRESTART_MODE, APT_LISTCHANGES
333 bash -c 'DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a APT_LISTCHANGES_FRONTEND=none \
334 apt-get -y dist-upgrade \
335 -o Dpkg::Options::="--force-confdef" \
336 -o Dpkg::Options::="--force-confold"'
337
338 judge "apt dist-upgrade"
339
340 # Remove temporary configuration
341 rm -f /etc/apt/apt.conf.d/99-local-versions
342}
343
344function update_release_files() {
345 print_ok "Updating release information files to 1.4.1..."
346
347 # Update /etc/os-release
348 if [ -f "/etc/os-release" ]; then
349 print_ok "Updating /etc/os-release..."
350 bash -c "cat > /etc/os-release" <<EOF
351PRETTY_NAME="AnduinOS 1.4.1"
352NAME="AnduinOS"
353VERSION_ID="1.4.1"
354VERSION="1.4.1 (questing)"
355VERSION_CODENAME=questing
356ID=ubuntu
357ID_LIKE=debian
358HOME_URL="https://www.anduinos.com/"
359SUPPORT_URL="https://github.com/Anduin2017/AnduinOS/discussions"
360BUG_REPORT_URL="https://github.com/Anduin2017/AnduinOS/issues"
361PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
362UBUNTU_CODENAME=questing
363EOF
364
365 judge "Update /etc/os-release"
366 fi
367
368 # Update /etc/lsb-release
369 if [ -f "/etc/lsb-release" ]; then
370 print_ok "Updating /etc/lsb-release..."
371
372 bash -c "cat > /etc/lsb-release" <<EOF
373DISTRIB_ID=AnduinOS
374DISTRIB_RELEASE=1.4.1
375DISTRIB_CODENAME=questing
376DISTRIB_DESCRIPTION="AnduinOS 1.4.1"
377EOF
378
379 judge "Update /etc/lsb-release"
380 fi
381
382 print_ok "Release files updated successfully"
383}
384
385function restore_ppa_sources() {
386 print_ok "Restoring PPA sources..."
387
388 if [ -d "$PPA_BACKUP_DIR" ]; then
389 ppa_count=$(ls -1 "$PPA_BACKUP_DIR" 2>/dev/null | wc -l)
390
391 if [ "$ppa_count" -gt 0 ]; then
392 for file in "$PPA_BACKUP_DIR"/*; do
393 if [ -f "$file" ]; then
394 mv "$file" /etc/apt/sources.list.d/
395 print_ok "Restored $(basename "$file")"
396 fi
397 done
398
399 print_ok "Running apt update with restored PPAs..."
400 apt update
401 judge "Restore PPA sources and update"
402 else
403 print_ok "No PPA sources to restore"
404 fi
405 else
406 print_warn "PPA backup directory not found, skipping restore"
407 fi
408}
409
410function main() {
411 # 1. Ensure we are root first
412 ensure_root
413
414 print_ok "Starting AnduinOS upgrade process..."
415
416 echo -e "${Yellow}WARNING: This script will upgrade your system from 1.3.7 (plucky) to 1.4.1 (questing).${Font}"
417 echo -e "${Yellow}Please ensure you have backed up important data before proceeding.${Font}"
418
419 # Interactive check only if we have a terminal (TTY)
420 if [ -t 0 ]; then
421 read -p "Do you want to continue? (y/N): " confirm
422 if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
423 print_error "Upgrade process aborted by user."
424 exit 1
425 fi
426 fi
427
428 # Step 0: Configure Unattended (Anti-Prompt)
429 configure_unattended
430
431 # Step 1: Check disk space
432 check_disk_space
433
434 # Step 2: Update current system
435 update_system
436
437 # Step 3: Backup Ubuntu official sources
438 backup_ubuntu_sources
439
440 # Step 4: Backup and remove PPA sources
441 backup_and_remove_ppa
442
443 # Step 5: Detect and convert APT format if needed
444 if ! detect_apt_format; then
445 convert_old_to_new_format
446 fi
447
448 # Step 6: Replace plucky with questing
449 replace_plucky_with_questing
450
451 # Step 7: Install coreutils-from-uutils
452 install_coreutils_uutils
453
454 # Step 8: Run dist-upgrade
455 run_dist_upgrade
456
457 # Step 9: Update release files (to 1.4.1)
458 update_release_files
459
460 # Step 10: Restore PPA sources
461 restore_ppa_sources
462
463 print_ok "Upgrade completed successfully!"
464 print_ok "Your system has been upgraded to AnduinOS 1.4.1 (questing)"
465 print_ok "Backup files are stored in: $BACKUP_DIR"
466 print_warn "Please reboot your system to complete the upgrade."
467}
468
469main