Aptly — создание собственного репозитория

Моя организация пишет софт под Linux.
Софт предназначен для работы на торговых точках, которые распределены географически.
Изначально ПО предоставлялось клиентам как набор deb пакетов под разные дистрибутивы и архитектуры со списком пакетов, которые нужно установить как зависимости до инсталляции этих deb файлов.
Хочу рассказать, каким был путь эволюции от распространения файлов через ftp до создания репозитория и запуска системы управления конфигурациями и начала внедрения в работу сервера непрерывной интеграции.

Зарождение жизни


Итак, софт — коммерческая разработка, которая пишется на Qt, все собирается под две архитектуры (i386 и amd64) и под несколько дистрибутивов. На текущий момент определились так: два-три последних релиза Debian и два последних LTS от Ubuntu. Плюс ко всему имеется несколько версий (на текущий момент три), которые используются у клиентов.
Три версии получились таким образом: при покупке софта клиенту предлагается поддержка и за достаточно разумные деньги предоставление новых версий софта. Изменение минорных версий предоставляется бесплатно вне зависимости от наличия поддержки. Мажорных — или при наличии поддержки, или продается заново только уже с дисконтом.

Пока версий было мало, и количество инсталляций у клиентов было невелико, вполне можно было обходится ftp. Выглядело это так: после сборки всех исходников в deb пакеты набор файлов для каждого клиента (в зависимости от версии) тарился в архив и выкладывался для каждого клиента на ftp в его собственный раздел. Со временем на ftp накапливалась масса одинаковых tar-ов у разных клиентов, которые приходилось время от времени удалять.
Шло время, клиенты добавлялись, сети клиентов росли в размерах, и обновлять версию софта на точках стало еще той задачей, особенно если учесть, что на 99% точек интернет был (да и остался) GPRS.

Кстати, о сборе пакетов. Скипты, которые собирали deb пакеты, изначально были написаны “300 лет тому назад” по какому-то мануалу на английком языке и IMHO не совсем правильно. Причесать и умыть скрипты помогли следующие статьи (за что их авторам хочу сказать спасибо):

Начало эволюции


Само собой был поднят вопрос о распространении собранных пакетов как-то более правильным способом. “И тут Остапа понесло” (с), решил все сделать правильно, так чтобы на рутинные операции тратилось минимум времени.

В качестве софта, который поддерживал репозиторий был выбран reprepro. На тот момент возможностей, которые он предоставлял, вполне хватало.

Далее, основываясь на опыте обновления, конфигурирования большого числа компьютеров, захотелось иметь инструмент по управлению конфигурациями. В помощь был призван гугл и хабр. Знакомился с ansible, chef, puppet и другими системами, названия которых уже не вспомню. По понятности конфигов, документированности, порогу вхождения и совокупности других параметров на вооружение был взят puppet. К puppet был прикручен foreman. И счастье наступило.

Прошло не очень много времени и захотелось в качестве управления репозиторием что-нибудь более другое. Reprepro всем устраивал, кроме возможности хранить в одном репозитории разные версии одного и того же пакета: чтобы была возможность быстро откатится на определенную версию в случае какой-то регрессии или, чтобы быстро поставить нужную версию и протестировать поведение системы определенной версии на определенном наборе данных на определенных аппаратных конфигурациях.

Как пример: одним клиентом было обнаружено падение приложения при работе с документами. Их набор данных на компьютерах разработчиков летал без вопросов, все открывалось и не падая замечательно работало. Собрали стенд, поставили такой же linux, ту же версию ПО, опять все работает и не падает. Начали поступать уже максимально параноидально — собрали другую машину максимально приближенную по характеристикам к машине клиента, объем диска, памяти, процессор, разрешение монитора и о чудо! повторили падение. Начали разбираться: выяснили, что суть в разрешении монитора, вернее не в разрешении как таковом, а в соотношении сторон. У разработчиков и на первой тестовой машине соотношение сторон монитора было 16:9, а у второй тестовой 4:3. В итоге вычисли, что к падению приводит одна строка в qss. Что было, конечно, большой неожиданностью. Так вот к чему этот пример. На момент этих тестов такого репозитория не было и на каждую собранную машину пришлось по старинке через scp копировать deb пакеты, ручками же ставить зависимости, после чего устанавливать сами пакеты и только потом проверять. Вместо того, чтобы за пару минут установить через aptitude со всеми зависимостями.

Пришлось гуглить. Нагуглилась в итоге статья. Начал разбираться с описанными в ней вариантами. Успел посмотреть на:
  • DAK — вообще не осилил. Начал именно с нее так как “official solution”, но к стыду своему вообще не смог понять, что делать с тем деревом проекта, который стянул мне git. Поэтому особо не напрягался и продолжил читать дальше.
  • Вторым продуктом, на который обратил внимание, стал mini-dak. И как бы все понятно по конфигу и с описанием более-менее ясно. Вот только остановила невозможность сделать имена репозиториев (то, что в терминах mini-dak називается suite) такие как хочу. Например я хочу получть путь к репозитарию такой:
    deb http://SERVER_NAME/ squeeze-evolution-beta non-free
    A не могу, потому-что где-то в глубине скриптов создается имя переменной со знаками “-” что в bash-e не работает. Попытки доработать скрипты напильником успехом не увенчались, ибо мой уровень программирования на bash несколько не дотягивает до уровня человека, который их писал, а убить кучу времени на изучение всех тонкостей bash (хоть и не самое плохое времяпровождение), но все же не хотелось.
  • Третим вариантом для ознакомления был выбран aptly. И похоже, что этот инструмент подходит.

Работа с aptly


Документация у aptly достаточно подробная и с примерами. Кроме того есть bash-completion.
Возможностей у aptly очень широкие, ниже приведу лишь те команды которые я использую. Интересующимся более глубоко ознакомиться рекомендую сайт продукта.

Создание репозитория:

Можно создавать сразу со всеми параметрами:
aptly repo create -comment="Wheezy prehistoric" -distribution="wheezy-prehistoric" -architectures="i386,amd64,all" -component="non-free" wheezy-prehistoric

Можно параметры дописать позже, а создать просто так:
aptly repo create wheezy-prehistoric

Изменение параметров

Меняем параметры по одному:
aptly repo edit -comment="Wheezy prehistoric" wheezy-prehistoric

Или все сразу:
aptly repo edit -comment="Wheezy prehistoric" -distribution="wheezy-prehistoric" -architectures="i386,amd64,all" -component="non-free" wheezy-prehistoric

Просмотр существующих репозиториев

aptly list

Получение информации о репозитории

общая информация:
aptly show wheezy-prehistoric

информации со списком пакетов:
aptly repo show -with-packages wheezy-prehistoric

Добавление пакетов в репозиторий

одного файла:
aptly repo add wheezy-prehistoric build//Debian-wheezy/chameleon-core_1.3.0-wheezy46_amd64.deb

всего каталога:
aptly repo add wheezy-prehistoric build//Debian-wheezy

при добавлении несколько смутило отсутствие автодополнения пути к файлу/каталогу

Публикация репозитория

aptly publish repo wheezy-prehistoric

Удаление публикации

aptly publish drop wheezy-prehistoric

Получить граф репозиториев

aptly graph


Также есть поддержка snapshot-ов, создания зеркал, перемещения пакетов между репозиториями, поддержка зависимостей, встроенный HTTP сервер для работы с опубликованными репозиториями.

Есть одна особенность о которой написал автору — pool один общий для всех репозиториев, что есть правильно, вот только если у меня в разных репозитариях лежат файлы с одинаковым именем, но разные по содержанию и размеру при публикации этих репозитариев никаких сообщений нет, по логике должно было хоть что-то написать. И в pool-е остается лежать файл первого опубликованного репозитория.
Кстати автор очень быстро отреагировал и создал на багтрекере задачу.

Эволюция продолжается


В данный момент пакеты собираются ручками на витруальных машинах. Что не есть хорошо. Уже начаты работы по внедрению в работу Jenkins. Из всего списка доступных средств для CI был выбран именно он. Изначально был установлен TeamCity, но стоимость лицензий была непонята из-за того, что есть другие проекты, которые полностью бесплатны и обладают не худшей функциональностью. По крайней мере, это выглядит сейчас именно так. Если в процессе эксплуатации Jenkins-а его возможностей по каким-то причинам будет недостаточно (хотя с таким количеством плагинов в это слабо верится), поменяем на что-то лучшее.

P.S.


В конце статьи хотелось бы подвести итоги.
Идея статьи была описать замечательный инструмент — aptly, т.к. на просторах Хабра не нашел о нем ничего. Ну а рассказать в стиле “вот инструмент — можно пользоваться” посчитал не интересным. Решил, что будет гораздо интересней почитать, каким именно путем развивалась моя организация и какие инструменты при этом использовала ну и обратить внимание сообщества на полезный инструмент с помощью личного примера.

Спасибо за внимание.
Поделиться публикацией
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 12
    0
    amd46 — да Вы троль! :)

    а за статью спасибо! Правда, сейчас мне это не актуально, но в свое время потратил немало времени на создание репозитариев и разграничение production/stage/test + CI, конечно.
      +1
      Ой, Акелла промахнулся :)
      Спасибо, поправлю.
        0
        Для простого менеджмента небольших репозиториев Debian также можно взглянуть на reprepro.
          0
          Да можно, но если даже в небольших проектах нужно несколько версий одного пакета, reprepro не подходит. Не в качестве пиара — IMHO aptly более интуитивно понятен лично мне с ним удобнее работать. Reprepro пользовался более года.
          0
          Интересно… Мы в свое время покурили open source и решили перейти на темную сторону использовать Artifactory Pro. Как раз в пару к Jenkins. После оценки трудозатрат на поднимание инфраструктуры коммерческое решение оказалось куда выгоднее. А вы молодец, справились…
            0
            Спасибо за похвалу.
            Когда полностью закончу запланированные работы может даже опишу как это все настраивалось и что в итоге получилось.
            0
            О, отлично.
            А Вы не в курсе, как в aptly вытащить штук пять пакетов из чужой репы в свою, желательно скачивая их руками? То есть, мне хочется в своем репозитории иметь все свои пакеты, собранные руками и не очень, и их зависимости из официальных репозиториев. Полное зеркало делать я не хочу.
              0
              Подозреваю, что это не реально.

              Есть команда (repo import) которая вытягивает из другого репозитория нужный пакет с зависимостями, но этот репозиторий уже должен быть с пакетам.

              Пытался сделать на репозитории типа mirror, но без команды update, которая делает зеркало, ничего не получилось. Так и написало «ERROR: unable to import: mirror not updated»

              Проверял так:

              aptly repo create -comment="test repos" -architectures="i386,amd64,all" -component="main" test-dependies
              gpg --no-default-keyring --keyring trustedkeys.gpg --keyserver keys.gnupg.net --recv-keys 473041FA B98321F9
              aptly -architectures="amd64" mirror create debian-main http://ftp.ru.debian.org/debian/ squeeze main
              aptly repo import debian-main test-dependies mysql
              aptly mirror drop debian-main
              aptly repo drop test-dependies
              

              Просто скачать руками из реозитория и добавить в свой не вопрос. С зависимостями, видать, нужно будет или разбираться руками или иметь зеркало.

              Может автор что подскажет реально ли это сделать хоть каким-нибудь другим образом…
                0
                Ну, отсутствие результата — тоже результат.

                И да, я — идиот. Оказывается, начиная с apt-get 0.8 в нем есть apt-get download, который делает именно то, что нужно, хотя и без рекурсии по зависимостям. Что, в принципе, уже неплохо.
                0
                Попробуйте спросить у автора: smira
                  0
                  aptly работает только с пакетами, которые полностью скачены (иначе нет возможности поддерживать snapshot).

                  «Чтобы вытащить 5 пакетов из зеркала», можно сделать примерно так:

                  aptly repo create repo1
                  aptly mirror create -architectures="i386" -filter='pkg1 | pkg2 | pkg3' mirror1 ....
                  aptly mirror update mirror1
                  aptly repo import mirror1 repo1 'Name'
                  


                  aptly выкачает только пакеты, которые удовлетворяют условиям фильтра, полный синтаксис здесь.
                    0
                    О, круто, спасибо. Кажется, у нас все-таки появится репозиторий для всего нужного.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое