Как загружать deb-пакеты многопоточно с помощью metalink (скрипты и инструкция) 1
Рецепт был опубликован 7 апреля 2017 года в 16:30, а менялся 10 февраля 2020 года в 03:32.
Постоянная ссылка: https://www.nixp.ru/recipes/69.html
Входные данные: система Ubuntu Linux с установленной качалкой aria2 и настроенная на использование зеркала репозитория от Яндекса. Несмотря на то, что с mirror.yandex.ru загрузка происходит быстрее, чем со многих других зеркал, она всё ещё не так быстра, как позволяет подключение. Поэтому задача — качать пакеты на максимальной скорости.
Apt-p2p зависит от числа участников и в моей ситуации не помог, поэтому выбранное решение — многопоточная загрузка из нескольких источников с помощью создаваемого на ходу metalink-файла.
Шаблон, по которому скриптами будет создаваться файл загрузки (/root/opt/smpl.metalink):
<?xml version="1.0" encoding="UTF-8" ?>
<metalink version="3.0" generator="Metalink Editor version 0.4.1" xmlns="http://www.metalinker.org/">
<files>
<file name="forfilename">
<resources>
<url type="http" preference="100">received-link</url>
<url type="http" preference="110">one-more-link1</url>
<url type="http" preference="120">one-more-link2</url>
<url type="http" preference="130">one-more-link3</url>
<url type="http" preference="140">one-more-link4</url>
</resources>
</file>
</files>
</metalink>
Скрипт на Python для загрузки и установки обновлений (/root/opt/apt-mt-upd.py):
import os, subprocess, time
subprocess.call('apt-get update', shell=True)
getlink = 'apt-get upgrade -dqq --print-uris && apt-get dist-upgrade -dqq --print-uris '
rawlist = os.popen(getlink)
while True:
line = rawlist.readline()
link = (line.split(' ')[0]).replace('\'', '')
filename = (link.split('/')[-1]).replace('\'', '')
if 'http' in line:
#print(filename)
inmetalink = open('/root/opt/smpl.metalink')
tmpmetalink = inmetalink.read()
tmpmetalink = tmpmetalink.replace('forfilename', filename)
tmpmetalink = tmpmetalink.replace('received-link', link)
tmpmetalink = tmpmetalink.replace('one-more-link1', (link.replace('yandex.ru', 'corbina.net')))
tmpmetalink = tmpmetalink.replace('one-more-link2', (link.replace('yandex.ru', 'timeweb.ru')))
tmpmetalink = tmpmetalink.replace('one-more-link3', (link.replace('yandex.ru', 'rol.ru')))
tmpmetalink = tmpmetalink.replace('one-more-link4', (link.replace('mirror.yandex.ru', 'ru.archive.ubuntu.com')))
outmetalink = open('/var/cache/apt/archives/getdeb.metalink', 'w')
outmetalink.write(tmpmetalink)
outmetalink.close()
subprocess.call('aria2c -d /var/cache/apt/archives --max-connection-per-server=12 --min-split-size=1M -s 12 /var/cache/apt/archives/getdeb.metalink &', shell=True)
time.sleep(1.5)
else: break
while True:
time.sleep(1)
if list(os.popen('pidof aria2c')) == []: break
subprocess.call('apt-get -y upgrade && apt-get -y dist-upgrade', shell=True)
(Как видно из скрипта, для загрузки используются дополнительные российские зеркала репозиториев Ubuntu, подставляемые в шаблон на места one-more-linkX.)
Скрипт на Python, скачивающий пакеты без их установки, т.е. выполняющий apt-get install -d [download-only] (/root/opt/apt-mt-get.py):
import os, sys, subprocess, time
subprocess.call('apt-get update', shell=True)
getlink = 'apt-get install -dqq --print-uris ' + sys.argv[1]
rawlist = os.popen(getlink)
while True:
line = rawlist.readline()
link = (line.split(' ')[0]).replace('\'', '')
filename = (link.split('/')[-1]).replace('\'', '')
if 'http' in line:
#print(filename)
inmetalink = open('/root/opt/smpl.metalink')
tmpmetalink = inmetalink.read()
tmpmetalink = tmpmetalink.replace('forfilename', filename)
tmpmetalink = tmpmetalink.replace('received-link', link)
tmpmetalink = tmpmetalink.replace('one-more-link1', (link.replace('yandex.ru', 'corbina.net')))
tmpmetalink = tmpmetalink.replace('one-more-link2', (link.replace('yandex.ru', 'timeweb.ru')))
tmpmetalink = tmpmetalink.replace('one-more-link3', (link.replace('yandex.ru', 'rol.ru')))
tmpmetalink = tmpmetalink.replace('one-more-link4', (link.replace('mirror.yandex.ru', 'ru.archive.ubuntu.com')))
outmetalink = open('/var/cache/apt/archives/getdeb.metalink', 'w')
outmetalink.write(tmpmetalink)
outmetalink.close()
subprocess.call('aria2c -d /var/cache/apt/archives --max-connection-per-server=12 --min-split-size=1M -s 12 /var/cache/apt/archives/getdeb.metalink &', shell=True)
time.sleep(1)
else: break
while True:
time.sleep(1)
if list(os.popen('pidof aria2c')) == []: break
Как всё это использовать?
Обновление:
$ python3 /root/opt/apt-mt-upd.py
Загрузка пакета (на примере nexuiz-music):
$ python3 /root/opt/apt-mt-get.py nexuiz-music
- Из той же серии:
- Как установить пакеты в Debian/Ubuntu Linux, игнорируя вопросы конфигурации?
- Очистка Linux-системы Debian/Ubuntu от файлов, оставшихся после удаления пакетов
- Как отключить автоматическое обновление списка пакетов в Ubuntu Linux?
Последние комментарии
-
OlegL, 17 декабря 2023 года в 15:00 →
Перекличка
21
-
REDkiy, 8 июня 2023 года в 9:09 →
Как «замокать» файл для юниттеста в Python?
2
-
fhunter, 29 ноября 2022 года в 2:09 →
Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt?
6
-
Иванн, 9 апреля 2022 года в 8:31 →
Ассоциация РАСПО провела первое учредительное собрание
1
-
Kiri11.ADV1, 7 марта 2021 года в 12:01 →
Логи catalina.out в TomCat 9 в формате JSON
1
DevOps as a Service from Palark

