Last active 2 months ago

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

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