Пример Python скрипта для копирования пакетов с одного Nexus репозитория в другой
Опубликовано:
Nexus является распространенным решением, позволяющим реализовать сервис репозитория пакетов. У него отсутствует нативное решение для выгрузки и загрузки пакетов из определенного репозитория. Но есть API, используя которое можно реализовать нашу задачу.
Подготовка к работе
Мы будем работать с python3. Установим его. Наши команды будут отличаться в зависимости от дистрибутива Linux.
а) Deb (Debian / Ubuntu / Astra):
apt install python3 python3-pip
б) RPM (Rocky Linux, CentOS):
dnf install python3 python3-pip
Установка выполнена.
Также нам нужен модуль requests для отправки HTTP-запросов. Его можно установить с помощью pip:
pip3 install requests
Наш скрипт мы поместим в отдельный каталог /scripts — создадим его:
mkdir /scripts
Создаем сам скрипт:
touch /scripts/copy_nexus_repo.py
Дадим права на запуск скрипта:
chmod +x /scripts/copy_nexus_repo.py
Мы готовы к созданию скрипта.
Пример кода
Пример содержит строки простого скрипта на питоне, который поможет перенести все пакеты NPM из одного Nexus репозитория в другой:
vi /scripts/copy_nexus_repo.py
- #!/usr/bin/env python3
- # -*- encoding: utf-8 -*-
- import requests
- import urllib3
- # Нам нужно отключить проверку сертификата. Чтобы не ругалась консоль, отключаем предупреждения, связанные с невалидными SSL
- urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
- REPO_NAME = "npm-repo-name"
- OLD_USERNAME = "username_old_nexus"
- OLD_PASSWORD = "password_old_nexus"
- OLD_BASE_URL = "https://old.dmosk.local/service/rest/v1/components?repository=" + REPO_NAME
- NEW_USERNAME = "username_new_nexus"
- NEW_PASSWORD = "password_new_nexus"
- NEW_BASE_URL = "https://new.dmosk.local/service/rest/v1/components?repository=" + REPO_NAME
- ALL_PACKAGES = []
- CONTINUATION_TOKEN = ''
- while True:
- # Добавляем токен для следующие страницы, если он есть или переходим по базовому урлу
- URL = OLD_BASE_URL + '&continuationToken=' + CONTINUATION_TOKEN if CONTINUATION_TOKEN else OLD_BASE_URL
- # Получаем список пакетов с сервера Nexus
- response = requests.get(URL, auth=(OLD_USERNAME, OLD_PASSWORD))
- # Завершаем процесс с ошибкой, если сервер вернул код не 200
- if response.status_code != 200:
- print(f"Ошибка запроса. Статус код: {response.status_code}")
- print(response.text)
- break
- # Сохраняем в переменную список с пакетами
- DATA = response.json()
- # Сохраняем полученные элементы в общий список
- if 'items' in DATA:
- for package_info in DATA['items']:
- ALL_PACKAGES.append({
- 'id': package_info.get('id'),
- 'name': package_info.get('name'),
- 'downloadUrl': package_info['assets'][0].get('downloadUrl'),
- 'path': package_info['assets'][0].get('path'),
- })
- # Получаем токен для следующей страницы или пустую строку
- CONTINUATION_TOKEN = DATA.get('continuationToken', '')
- # Выходим из цикла, если токена следующией страницы нет
- if not CONTINUATION_TOKEN:
- break
- # Пройдем по всем пакетам, скачаем их и загрузим в новый репозиторий
- for PKG_ARR in ALL_PACKAGES:
- # Скачиваем пакет и сохраняем в буфере
- download_response = requests.get(
- PKG_ARR['downloadUrl'],
- auth=(OLD_USERNAME, OLD_PASSWORD),
- stream=True
- )
- # Содержимое файла сохраняем в переменной
- file_content = download_response.content
- # Задаем метеданные для аплоада пакета в новый репозиторий
- files_payload = {
- 'npm.asset': (PKG_ARR['path'], file_content, 'application/x-tgz')
- }
- # Загружаем файл в новый репозиторий
- destination_response = requests.post(
- NEW_BASE_URL,
- auth=(NEW_USERNAME, NEW_PASSWORD),
- files=files_payload,
- verify=False
- )
- destination_response.raise_for_status()
* значения отмеченные желтым необходимо заменить на свои.
Описание скрипта
| 8 | В моем примере будем предполагать, что один из репозиториев не проходит проверку сертификата. В этом случае мы отключим данную проверку. |
| 10 - 18 | Переменные для вашей среды. Имя репозитория, для которого нам нужно скопировать пакеты, адрес nexus, данные аутентификации. |
| 20 - 21 | Определяем пустые переменные для списка пакетов и специального токена для перехода на новую страницу (Nexus API возвращает результаты постранично). |
| 23 - 54 | Nexus API возвращает информацию постранично. В данном блоке мы в цикле проходим по всем страницам и собираем массив данных со списком пакетов и краткой информацией о них. Результат мы фиксируем в списке ALL_PACKAGES. |
| 56 - 80 | Финальный блок, в котором мы циклом перебираем все пакеты, скачиваем из, сохраняя в переменной и загружая на новый Nexus, также используя API. Обратите внимание, что мы привели пример ситуации, когда на сервере есть проблема с сертификатом и используется verify=False для отключения проверки. Данная практика не является нормальной, но имеет место быть. |