Last active 2 months ago

Скрипт заменяет штатные репозитории в Debian 12/13 и AlmaLinux 8/9/10 на локальные российские зеркала.

Revision 4bd4ed6bae077990c471e4304581856a1214700c

update-repos.sh Raw
1#!/bin/bash
2
3# Скрипт для замены репозиториев на локальные российские зеркала
4# Поддерживает Debian 12/13 и AlmaLinux 8/9/10
5
6set -e # Выход при ошибках
7
8# Цвета для вывода
9RED='\033[0;31m'
10GREEN='\033[0;32m'
11YELLOW='\033[1;33m'
12BLUE='\033[0;34m'
13NC='\033[0m' # No Color
14
15# Функция для вывода с цветом
16print_message() {
17 echo -e "${GREEN}[INFO]${NC} $1"
18}
19
20print_warning() {
21 echo -e "${YELLOW}[WARN]${NC} $1"
22}
23
24print_error() {
25 echo -e "${RED}[ERROR]${NC} $1"
26}
27
28print_debug() {
29 echo -e "${BLUE}[DEBUG]${NC} $1"
30}
31
32# Функция для определения ОС
33detect_os() {
34 if [ -f /etc/os-release ]; then
35 . /etc/os-release
36 OS_NAME="$ID"
37 OS_VERSION="$VERSION_ID"
38 OS_VERSION_MAJOR=$(echo "$OS_VERSION" | cut -d. -f1)
39 OS_CODENAME="$VERSION_CODENAME"
40 elif [ -f /etc/redhat-release ]; then
41 if grep -qi "alma" /etc/redhat-release; then
42 OS_NAME="almalinux"
43 elif grep -qi "centos" /etc/redhat-release; then
44 OS_NAME="centos"
45 elif grep -qi "rocky" /etc/redhat-release; then
46 OS_NAME="rocky"
47 else
48 OS_NAME="rhel"
49 fi
50 # Извлекаем версию из redhat-release
51 OS_VERSION=$(grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release | head -1)
52 if [ -z "$OS_VERSION" ]; then
53 OS_VERSION=$(grep -oE '[0-9]+' /etc/redhat-release | head -1)
54 fi
55 OS_VERSION_MAJOR=$(echo "$OS_VERSION" | cut -d. -f1)
56 else
57 print_error "Не удалось определить операционную систему"
58 exit 1
59 fi
60
61 print_message "Обнаружена ОС: $OS_NAME $OS_VERSION (мажорная версия: $OS_VERSION_MAJOR)"
62}
63
64# Функция для создания резервной копии файла
65backup_file() {
66 local file="$1"
67 local backup="${file}.backup.$(date +%Y%m%d_%H%M%S)"
68
69 if [ -f "$file" ]; then
70 cp "$file" "$backup"
71 print_message "Создана резервная копия: $backup"
72 echo "$backup" # Возвращаем имя резервной копии
73 fi
74}
75
76# Функция для проверки доступности зеркала
77check_mirror() {
78 local mirror="$1"
79 local test_url="$2"
80
81 print_debug "Проверка доступности зеркала: $mirror"
82
83 if curl --silent --head --fail --max-time 5 "$test_url" > /dev/null 2>&1; then
84 print_message "Зеркало $mirror доступно"
85 return 0
86 else
87 print_warning "Зеркало $mirror недоступно или отвечает медленно"
88 return 1
89 fi
90}
91
92# Функции для Debian
93setup_debian_repos() {
94 local version="$1"
95 local sources_list="/etc/apt/sources.list"
96 local sources_dir="/etc/apt/sources.list.d/"
97
98 print_message "Настройка репозиториев для Debian $version"
99
100 # Создаем резервную копию
101 backup_file "$sources_list"
102
103 # Российские зеркала для Debian
104 # Список приоритетных зеркал (проверяем доступность)
105 local mirrors=(
106 "http://mirror.yandex.ru/debian/"
107 "http://ftp.ru.debian.org/debian/"
108 "http://mirror.truenetwork.ru/debian/"
109 )
110
111 local selected_mirror=""
112 local selected_security_mirror=""
113
114 # Проверяем доступность зеркал
115 for mirror in "${mirrors[@]}"; do
116 if check_mirror "$mirror" "${mirror}dists/stable/Release"; then
117 selected_mirror="$mirror"
118 # Для зеркал безопасности используем соответствующие URL
119 if [[ "$mirror" == *"mirror.yandex.ru"* ]]; then
120 selected_security_mirror="http://mirror.yandex.ru/debian-security/"
121 elif [[ "$mirror" == *"ftp.ru.debian.org"* ]]; then
122 selected_security_mirror="http://ftp.ru.debian.org/debian-security/"
123 else
124 selected_security_mirror="${mirror%-}/debian-security/"
125 fi
126 break
127 fi
128 done
129
130 # Если ни одно зеркало не доступно, используем Yandex по умолчанию
131 if [ -z "$selected_mirror" ]; then
132 print_warning "Все зеркала недоступны, используем Yandex по умолчанию"
133 selected_mirror="http://mirror.yandex.ru/debian/"
134 selected_security_mirror="http://mirror.yandex.ru/debian-security/"
135 fi
136
137 print_message "Используется основное зеркало: $selected_mirror"
138 print_message "Используется зеркало безопасности: $selected_security_mirror"
139
140 # Определяем кодовое имя релиза
141 local codename
142 case "$version" in
143 "12") codename="bookworm" ;;
144 "13") codename="trixie" ;;
145 *) codename="bookworm" ;; # По умолчанию для других версий
146 esac
147
148 # Создаем новый sources.list с выбранными зеркалами
149 cat > "$sources_list" << EOF
150# Российские зеркала для Debian $version ($codename)
151deb $selected_mirror $codename main contrib non-free non-free-firmware
152deb $selected_mirror $codename-updates main contrib non-free non-free-firmware
153deb $selected_security_mirror $codename-security main contrib non-free non-free-firmware
154
155# Дополнительные компоненты
156# deb $selected_mirror $codename-backports main contrib non-free non-free-firmware
157EOF
158
159 # Обновляем репозитории в sources.list.d с помощью sed
160 for file in "$sources_dir"*.list; do
161 if [ -f "$file" ]; then
162 backup_file "$file"
163 print_debug "Обновление репозиториев в файле: $(basename "$file")"
164
165 # Заменяем стандартные репозитории на российские зеркала
166 sed -i \
167 -e "s|http://deb.debian.org/debian|$selected_mirror|g" \
168 -e "s|https://deb.debian.org/debian|$selected_mirror|g" \
169 -e "s|http://security.debian.org|$selected_security_mirror|g" \
170 -e "s|https://security.debian.org|$selected_security_mirror|g" \
171 -e "s|http://ftp.debian.org|$selected_mirror|g" \
172 -e "s|https://ftp.debian.org|$selected_mirror|g" \
173 "$file"
174 fi
175 done
176
177 print_message "Обновление списка пакетов..."
178 if apt-get update; then
179 print_message "Список пакетов успешно обновлен"
180 else
181 print_warning "Обновление списка пакетов завершилось с предупреждениями"
182 fi
183}
184
185# Функции для AlmaLinux
186setup_almalinux_repos() {
187 local version="$1"
188 local repo_dir="/etc/yum.repos.d/"
189
190 print_message "Настройка репозиториев для AlmaLinux $version"
191
192 # Российские зеркала для AlmaLinux
193 local mirrors=(
194 "http://mirror.yandex.ru/almalinux/"
195 "http://mirror.nucleus.be/almalinux/" # Российское зеркало Selectel
196 "http://mirror.docker.ru/almalinux/"
197 )
198
199 local selected_mirror=""
200
201 # Проверяем доступность зеркал
202 for mirror in "${mirrors[@]}"; do
203 if check_mirror "$mirror" "${mirror}${version}/BaseOS/x86_64/os/repodata/repomd.xml"; then
204 selected_mirror="$mirror"
205 break
206 fi
207 done
208
209 # Если ни одно зеркало не доступно, используем Yandex по умолчанию
210 if [ -z "$selected_mirror" ]; then
211 print_warning "Все зеркала недоступны, используем Yandex по умолчанию"
212 selected_mirror="http://mirror.yandex.ru/almalinux/"
213 fi
214
215 print_message "Используется зеркало: $selected_mirror"
216
217 # Создаем резервные копии всех репозиториев
218 print_message "Создание резервных копий репозиториев..."
219 for repo_file in "$repo_dir"*.repo; do
220 if [ -f "$repo_file" ]; then
221 backup_file "$repo_file"
222 fi
223 done
224
225 # Основные файлы репозиториев для AlmaLinux
226 local repo_files=(
227 "almalinux.repo"
228 "almalinux-baseos.repo"
229 "almalinux-appstream.repo"
230 "almalinux-extras.repo"
231 "almalinux-powertools.repo" # Для версии 8
232 "almalinux-crb.repo" # Для версий 9+
233 )
234
235 # Список паттернов для замены
236 local patterns=(
237 "https://repo.almalinux.org"
238 "http://repo.almalinux.org"
239 "https://mirror.almalinux.org"
240 "http://mirror.almalinux.org"
241 "https://cdn.redhat.com"
242 "http://cdn.redhat.com"
243 )
244
245 # Заменяем URL во всех репозиторных файлах с помощью sed
246 print_message "Замена URL репозиториев на российские зеркала..."
247
248 for repo_file in "$repo_dir"*.repo; do
249 if [ -f "$repo_file" ]; then
250 local filename=$(basename "$repo_file")
251 print_debug "Обработка файла: $filename"
252
253 # Создаем временный файл для новой конфигурации
254 local temp_file=$(mktemp)
255
256 # Обрабатываем файл построчно
257 while IFS= read -r line; do
258 # Заменяем baseurl и metalink
259 if [[ "$line" =~ ^(baseurl|metalink)\s*= ]]; then
260 # Заменяем все паттерны на выбранное зеркало
261 local new_line="$line"
262 for pattern in "${patterns[@]}"; do
263 new_line="${new_line//$pattern/$selected_mirror}"
264 done
265
266 # Для baseurl добавляем параметры репозитория
267 if [[ "$new_line" =~ ^baseurl= ]] && [[ ! "$new_line" =~ /\$releasever/ ]]; then
268 new_line="baseurl=$selected_mirror\$releasever/\$basearch/os/"
269 fi
270
271 echo "$new_line" >> "$temp_file"
272 else
273 echo "$line" >> "$temp_file"
274 fi
275 done < "$repo_file"
276
277 # Заменяем оригинальный файл
278 mv "$temp_file" "$repo_file"
279
280 # Дополнительная обработка sed для надежности
281 sed -i \
282 -e "s|https://repo.almalinux.org|$selected_mirror|gI" \
283 -e "s|http://repo.almalinux.org|$selected_mirror|gI" \
284 -e "s|https://mirror.almalinux.org|$selected_mirror|gI" \
285 -e "s|http://mirror.almalinux.org|$selected_mirror|gI" \
286 -e "s|https://cdn.redhat.com|$selected_mirror|gI" \
287 -e "s|http://cdn.redhat.com|$selected_mirror|gI" \
288 "$repo_file"
289
290 # Отключаем metalink и включаем baseurl
291 sed -i \
292 -e '/^metalink/s/^/#/' \
293 -e '/^#baseurl/s/^#//' \
294 -e '/^mirrorlist/s/^/#/' \
295 "$repo_file"
296 fi
297 done
298
299 # Специфичные настройки для разных версий
300 case "$version" in
301 "8")
302 # Для версии 8
303 for repo_file in "$repo_dir"almalinux*.repo; do
304 if [ -f "$repo_file" ]; then
305 sed -i \
306 -e "s|/AppStream/|/AppStream/|g" \
307 -e "s|/PowerTools/|/PowerTools/|g" \
308 -e "s|/BaseOS/|/BaseOS/|g" \
309 "$repo_file"
310 fi
311 done
312 ;;
313 "9"|"10")
314 # Для версий 9 и 10
315 for repo_file in "$repo_dir"almalinux*.repo; do
316 if [ -f "$repo_file" ]; then
317 sed -i \
318 -e "s|/AppStream/|/AppStream/|g" \
319 -e "s|/CRB/|/CRB/|g" \
320 -e "s|/BaseOS/|/BaseOS/|g" \
321 "$repo_file"
322 fi
323 done
324 ;;
325 esac
326
327 print_message "Очистка кэша DNF..."
328 dnf clean all
329
330 print_message "Проверка доступности репозиториев..."
331 if dnf repolist -v; then
332 print_message "Репозитории успешно настроены"
333
334 # Показываем информацию о репозиториях
335 echo ""
336 print_message "Список активных репозиториев:"
337 dnf repolist enabled
338 else
339 print_warning "Есть проблемы с доступностью репозиториев"
340 print_warning "Проверьте настройки сети или выберите другое зеркало"
341 fi
342}
343
344# Функция для проверки текущих репозиториев
345check_current_repos() {
346 print_message "Текущие репозитории:"
347
348 case "$OS_NAME" in
349 "debian")
350 grep -h "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null | head -10
351 ;;
352 "almalinux")
353 grep -h "^\s*baseurl" /etc/yum.repos.d/*.repo 2>/dev/null | head -10
354 ;;
355 esac
356}
357
358# Функция для отката изменений
359rollback_changes() {
360 print_message "Поиск резервных копий для отката..."
361
362 case "$OS_NAME" in
363 "debian")
364 local backup_files=$(find /etc/apt -name "*.backup.*" -type f | sort -r)
365 ;;
366 "almalinux")
367 local backup_files=$(find /etc/yum.repos.d -name "*.backup.*" -type f | sort -r)
368 ;;
369 esac
370
371 if [ -z "$backup_files" ]; then
372 print_error "Резервные копии не найдены"
373 return 1
374 fi
375
376 # Берем последнюю резервную копию
377 local latest_backup=$(echo "$backup_files" | head -1)
378 local original_file="${latest_backup%.backup.*}"
379
380 print_message "Восстановление из: $latest_backup"
381 print_message "В файл: $original_file"
382
383 if cp "$latest_backup" "$original_file"; then
384 print_message "Откат выполнен успешно"
385
386 # Обновляем кэш пакетов
387 case "$OS_NAME" in
388 "debian")
389 apt-get update
390 ;;
391 "almalinux")
392 dnf clean all
393 dnf repolist
394 ;;
395 esac
396 else
397 print_error "Ошибка при откате изменений"
398 fi
399}
400
401# Основная функция
402main() {
403 # Проверяем права суперпользователя
404 if [ "$EUID" -ne 0 ]; then
405 print_error "Запустите скрипт с правами root (sudo)"
406 exit 1
407 fi
408
409 print_message "Начало настройки локальных репозиториев..."
410
411 # Определяем ОС
412 detect_os
413
414 # Показываем текущие репозитории
415 check_current_repos
416
417 echo ""
418 print_warning "Вы собираетесь заменить репозитории на российские зеркала."
419 print_warning "Будут созданы резервные копии конфигурационных файлов."
420 echo ""
421
422 read -p "Продолжить? (y/N): " -n 1 -r
423 echo
424 if [[ ! $REPLY =~ ^[Yy]$ ]]; then
425 print_message "Операция отменена пользователем"
426 exit 0
427 fi
428
429 # Выбираем действие в зависимости от ОС
430 case "$OS_NAME" in
431 "debian")
432 setup_debian_repos "$OS_VERSION_MAJOR"
433 ;;
434 "almalinux")
435 setup_almalinux_repos "$OS_VERSION_MAJOR"
436 ;;
437 "centos"|"rocky"|"rhel")
438 print_warning "Обнаружена $OS_NAME, будет применена конфигурация для AlmaLinux"
439 setup_almalinux_repos "$OS_VERSION_MAJOR"
440 ;;
441 *)
442 print_error "Неподдерживаемая операционная система: $OS_NAME"
443 print_warning "Поддерживаются только Debian, AlmaLinux, CentOS, Rocky Linux и RHEL"
444 exit 1
445 ;;
446 esac
447
448 echo ""
449 print_message "Настройка репозиториев успешно завершена!"
450 print_warning "Рекомендуется проверить работоспособность репозиториев:"
451
452 case "$OS_NAME" in
453 "debian")
454 echo " apt update && apt install -y neofetch"
455 ;;
456 "almalinux"|"centos"|"rocky"|"rhel")
457 echo " dnf update && dnf install -y neofetch"
458 ;;
459 esac
460}
461
462# Обработка аргументов командной строки
463if [[ $# -gt 0 ]]; then
464 case $1 in
465 "-h"|"--help")
466 echo "Использование: $0 [OPTIONS]"
467 echo "Скрипт для замены штатных репозиториев на локальные российские зеркала"
468 echo ""
469 echo "Опции:"
470 echo " -h, --help Показать эту справку"
471 echo " -c, --check Проверить текущие репозитории"
472 echo " -r, --rollback Откатить последние изменения"
473 echo " -v, --verbose Подробный вывод"
474 echo ""
475 echo "Поддерживаемые ОС:"
476 echo " - Debian 12 (Bookworm)"
477 echo " - Debian 13 (Trixie)"
478 echo " - AlmaLinux 8"
479 echo " - AlmaLinux 9"
480 echo " - AlmaLinux 10"
481 echo " - CentOS/Rocky Linux/RHEL 8/9/10"
482 echo ""
483 echo "Автоматически создаются резервные копии конфигурационных файлов"
484 exit 0
485 ;;
486 "-c"|"--check")
487 detect_os
488 check_current_repos
489 exit 0
490 ;;
491 "-r"|"--rollback")
492 detect_os
493 rollback_changes
494 exit 0
495 ;;
496 "-v"|"--verbose")
497 set -x # Включить режим отладки
498 main
499 ;;
500 *)
501 print_error "Неизвестный аргумент: $1"
502 echo "Используйте $0 --help для справки"
503 exit 1
504 ;;
505 esac
506else
507 # Запуск основной функции
508 main
509fi