# Руководство разрабочика Ubuntu

Добро пожаловать в руководство разработчика Ubuntu! Это официальная документация по всем темам, связанных с разработкой Ubuntu и сборкой пакетов для этой операционной системы. После прочтения этого руководства вы:

- будете знать о самых важных утилитах, процессах и командах в разработке Ubuntu,

- сможете правильно настроить вашу среду разработки,

- узнаете, как присоединиться к нашему сообществу,

- исправите настоящую ошибку в Ubuntu в процессе изучения руководства.

Ubuntu — не только свободная операционная система с открытым исходным кодом, её платформа также является открытой и обеспечивает прозрачность разработки. Можно легко получить исходный код для каждого отдельного компонента, и каждое отдельное изменение в платформе Ubuntu можно проверить.

Это означает, что вы можете принять активное участие в её улучшении, и сообщество разработчиков платформы Ubuntu всегда заинтересовано в привлечении новых участников.

Ubuntu также является сообществом замечательных людей, верящих в то, что программное обеспечение должно быть свободным и доступным для всех. Участники сообщества приветствуют вас и хотят, чтобы вы тоже к ним присоединились. Мы хотим, чтобы вы принимали участие в нашей работе, задавали вопросы, делали Ubuntu лучше вместе с нами.

Если у вас возникнут трудности: не волнуйтесь! Прочтите раздел о коммуникации, и вы узнаете, как легко связаться с остальными разработчиками.

Это руководство состоит из двух разделов:

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

- Набор статей базы знаний, в которых подробнее рассматриваются используемые нами инструменты и рабочие процессы.

Это руководство фокусируется на методе создания пакетов Ubuntu Distributed Development. Это новый способ работы с пакетами, который использует ветки распределённой системы управления версиями. В настоящее время он имеет некоторые ограничения, поэтому многие команды Ubuntu по-прежнему пользуются традиционными методами создания пакетов. Чтобы узнать о различиях, смотрите страницу Введение в UDD.

## Статьи

### Введение в разработку Ubuntu

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

Каждый раз, когда выпускается новая версия приложения, или когда кто-нибудь вносит изменение в исходный код, входящий в состав Ubuntu, пакет исходного кода должен быть загружен на сборочные компьютеры Launchpad для компиляции. Получившиеся двоичные пакеты затем помещаются в архив и его зеркала в различных странах. URL-ссылки в `/etc/apt/sources.list` указывают на архив или зеркало. Каждый день создаются образы для ряда различных разновидностей Ubuntu. Их можно использовать в различных обстоятельствах. Есть образы, которые можно записать на USB-носитель или на DVD, а также образы для сетевой установки и образы, подходящие для телефонов и планшетов. Ubuntu Desktop, Ubuntu Server, Kubuntu и другие разновидности определяют список необходимых пакетов, которые попадут в образ. Затем эти образы используются для тестов установки и обеспечивают обратную связь для планирования следующего выпуска.

Разработка Ubuntu сильно зависит от текущей фазы цикла выпуска. Мы выпускаем новую версию Ubuntu каждые шесть месяцев, что возможно только благодаря тому, что мы устанавливаем точные даты «заморозки». По достижении каждой даты заморозки ожидается, что разработчики будут вносить более редкие и менее значительные изменения. Заморозка новых функций (feature freeze) — это первая крупная дата заморозки, наступающая после прохождения первой половины цикла разработки. На этом этапе новые функции должны в основном быть реализованы. В оставшуюся часть цикла предполагается сфокусироваться на исправлении ошибок. После этого «замораживается» пользовательский интерфейс, затем документация, ядро и т.п., после чего выпускается бета-версия (beta release), которая подвергается интенсивному тестированию. После того, как выпущена бета-версия, исправляются только критические ошибки, и выпускается release candidate, который, если он не содержит серьёзных ошибок, становится в дальнейшем финальным выпуском.

Thousands of source packages, billions of lines of code, hundreds of contributors require a lot of communication and planning to maintain high standards of quality. At the beginning and in the middle of each release cycle we have the Ubuntu Developer Summit where developers and contributors come together to plan the features of the next releases. Every feature is discussed by its stakeholders and a specification is written that contains detailed information about its assumptions, implementation, the necessary changes in other places, how to test it and so on. This is all done in an open and transparent fashion, so you can participate remotely and listen to a videocast, chat with attendants and subscribe to changes of specifications, so you are always up to date.

Однако на совещании могут быть обсуждены не все изменения, так как Ubuntu зависит от изменений, вносимых в другие проекты. Поэтому участники разработки Ubuntu остаются постоянно на связи. Большинство команд или проектов используют отдельные списки рассылки, чтобы избежать большого потока не связанных с их специализацией писем. Для более непосредственной координации разработчики и добровольные участники используют Internet Relay Chat (IRC). Все обсуждения являются открытыми и публичными.

Ещё одним важным инструментом связи являются отчёты об ошибках. Если в пакете или части инфраструктуры обнаружена ошибка, отчёт о ней отправляется на Launchpad. В этом отчёте собрана вся информация, и при необходимости сведения о важности, статусе ошибки и лице, назначенном для её устранения, обновляются. Это делает отчёт об ошибке эффективным средством отслеживания ошибок в пакетах или проектах и оптимизации рабочей нагрузки.

Большая часть доступных в Ubuntu программ создана не самими разработчиками Ubuntu. Многие из программ написаны разработчиками из других проектов с открытым исходным кодом, а затем интегрированы в Ubuntu. Такие проекты принято называть «апстримом» (от англ. upstream — вверх по течению), так как их исходный код вливается в Ubuntu, где мы «просто» интегрируем его в систему. Связь с апстримом очень важна для Ubuntu. Не только Ubuntu получает программный код из апстрима, но и апстрим получает пользователей, отчёты об ошибках и патчи от Ubuntu (и других дистрибутивов).

Наиболее важным апстримом для Ubuntu является Debian. Debian — это дистрибутив, на котором основана Ubuntu, и именно там созданы многие инженерные решения, касающиеся инфраструктуры пакетов. По традиции, в Debian для каждого отдельного пакета всегда имеется сопровождающий (мэйнтейнер) или отдельная группа сопровождения. В Ubuntu тоже есть команды, заинтересованные в работе над подмножеством пакетов и, разумеется, каждый разработчик имеет собственную область компетенции, но участие (и права загрузки изменений) обычно доступны любому, кто продемонстрирует способность и желание работать.

Внести изменение в Ubuntu новому участнику не так трудно, как кажется, и это может быть весьма полезным опытом. Это позволяет не только научиться чему-то новому и увлекательному, но и поделиться своим решением проблемы с миллионами других пользователей.

Разработка открытого программного обеспечения происходит в распределённом мире, в котором у разработчиков могут быть различные цели и различные области интересов. Например, может быть так, что отдельный апстрим заинтересован в работе над крупным нововведением, в то время как Ubuntu, вследствие тесного расписания релизов, более заинтересована в выпуске стабильной версии, в которой лишь исправлены некоторые ошибки. Поэтому мы используем «Ubuntu Distributed Development», где работа над кодом ведётся в различных ветках, которые затем сливаются друг с другом после проверки кода и достаточного количества обсуждений.

В приведённом выше примере имеет смысл включить в Ubuntu существующую версию проекта, сделать исправления ошибок, добавить их в апстрим для следующего выпуска проекта и включить его (если он к этому пригоден) в следующий выпуск Ubuntu. Это будет наилучшим компромиссом и ситуацией, в которой выигрывают обе стороны.

Чтобы исправить ошибку в Ubuntu, нужно сначала получить исходный код пакета, поработать над его исправлением, снабдить свою работу документацией, чтобы другим разработчикам и пользователям было легко понять, что именно вы сделали, а затем собрать пакет и протестировать его. После того, как вы протестировали изменённый пакет, можно предложить включить его в текущий разрабатываемый релиз Ubuntu. Разработчик с правом загрузки проверит ваш пакет и затем интегрирует его в Ubuntu.

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

Дополнительные шаги, которые вы можете предпринять, — это адаптирование вашего изменения для предыдущих поддерживаемых выпусков Ubuntu и отправление его в апстрим.

Наиболее важные требования для успешной разработки в Ubuntu: уметь «заставлять вещи снова работать», не бояться читать документацию и задавать вопросы, быть командным игроком и иметь некоторую склонность к работе детектива.

Подходящими местами для получения ответов на ваши вопросы являются `ubuntu-motu@lists.ubuntu.com` и `#ubuntu-motu` на `irc.freenode.net`. Там вы легко найдёте множество новых друзей и людей, разделяющих вашу страсть: делать мир лучше, улучшая открытое программное обеспечение.

### Подготовка

Существует несколько вещей, которые нужно сделать перед началом разработки в Ubuntu. Эта статья поможет вам подготовить компьютер к работе с пакетами и отправке ваших пакетов на платформу хостинга Ubuntu — Launchpad. Вот что здесь описано:

- Установка программ для работы с пакетами. Они включают в себя:

  - специфичные для Ubuntu утилиты создания пакетов

  - криптографическую программу, которая позволит другим удостовериться, что работа выполнена именно вами

  - дополнительные программы шифрования, обеспечивающие безопасную передачу файлов

- Создание и настройка учётной записи на Launchpad

- Настройка вашей среды разработки для облегчения локальной сборки пакетов, взаимодействия с другими разработчиками и отправки ваших изменений на Launchpad.

Примечание

Рекомендуется выполнять работу по созданию пакетов в текущей разрабатываемой версии Ubuntu. Это позволит вам тестировать изменения в той же среде, в которую они в действительности затем будут внесены.

Don’t worry though, you can use Testdrive or chroots to safely use the development release.

#### Установка базового программного обеспечения для создания пакетов

Существует множество инструментов, которые могут значительно упростить жизнь разработчику Ubuntu. Вы познакомитесь с ними далее в этом руководстве. Чтобы установить большинство инструментов, нужно выполнить следующую команду:

    $ sudo apt-get install gnupg pbuilder ubuntu-dev-tools bzr-builddeb apt-file

Примечание: Начиная с Ubuntu 11.10 «Oneiric Ocelot» (или если включен репозиторий Backports в текущем поддерживаемом выпуске), следующая команда устанавливает всё вышеупомянутое и другие инструменты, часто используемые в разработке Ubuntu:

    $ sudo apt-get install packaging-dev

Эта команда установит следующие программы:

- `gnupg` – GNU Privacy Guard, содержит инструменты, необходимые для создания криптографического ключа, которым вы будете подписывать файлы, отправляемые на Launchpad.

- `pbuilder` – инструмент для создания готовых к дальнейшему распространению сборок пакетов в чистой и изолированной среде.

- `ubuntu-dev-tools` (и его непосредственная зависимость `devscripts`) – набор инструментов, упрощающих многие задачи по созданию пакетов.

- `bzr-builddeb` (и его зависимость – `bzr`) – управление распределёнными версиями с помощью Bazaar, новый способ работы с пакетами для Ubuntu, упрощающий совместную работу многих людей над одним и тем же кодом и позволяющий с лёгкостью объединять результаты их труда друг с другом.

- `apt-file` предоставляет простой способ найти двоичный пакет, содержащий заданный файл.

##### Создание ключа GPG

GPG или GNU Privacy Guard — это реализация стандарта OpenPGP, позволяющего подписывать и шифровать сообщения и файлы. Это может быть полезно для различных целей. В нашем случае важно иметь возможность подписывать файлы своим ключом, чтобы другие могли убедиться, что над файлами работали именно вы. При отправке пакета исходного кода на Launchpad он будет принят только в том случае, если можно точно определить, кто именно отправил пакет.

Чтобы сгенерировать новый ключ GPG, наберите:

    $ gpg --gen-key

GPG сначала спросит, какой тип ключа вы хотите создать. Выбор по умолчанию (RSA и DSA) вполне подойдёт. Далее он попросит указать размер ключа. Размер по умолчанию (в настоящее время 2048) подойдёт, но 4096 надёжнее. Далее, программа спросит, хотите ли вы, чтобы срок действия ключа истёк через какое-то время. Безопаснее ответить “0”, что означает, что срок действия не истечёт никогда. Последний вопрос будет о вашем имени и адресе электронной почты. Просто выберите адрес, которым вы пользуетесь при разработке Ubuntu, дополнительные адреса можно будет добавить позже. Добавлять комментарий не обязательно. После этого нужно указать надёжную парольную фразу (парольная фраза — это просто пароль, в котором допускается использовать пробелы).

Теперь GPG создаст для вас ключ, что может занять некоторое время. Для его создания понадобятся случайные байты, поэтому будет просто замечательно, если вы зададите своей системе какую-нибудь работу. Подвигайте указатель мыши, наберите несколько абзацев случайного текста, загрузите любую веб-страницу.

Когда процесс будет завершён, вы получите сообщение наподобие следующего:

    pub   4096R/43CDE61D 2010-12-06
          Key fingerprint = 5C28 0144 FB08 91C0 2CF3  37AC 6F0B F90F 43CD E61D
    uid                  Daniel Holbach <dh@mailempfang.de>
    sub   4096R/51FBE68C 2010-12-06

В данном случае, `43CDE61D` — это идентификатор ключа (key ID).

Затем нужно загрузить открытую (public) часть вашего ключа на сервер ключей, чтобы все могли идентифицировать сообщения и файлы, как отправленные вами. Для этого введите:

    $ gpg --send-keys --keyserver keyserver.ubuntu.com <KEY ID>

Эта команда отправит ваш ключ на сервер ключей Ubuntu, а сеть серверов ключей автоматически синхронизирует ключ между собой. После того, как эта синхронизация завершится, ваш подписанный открытый ключ будет готов для удостоверения сделанного вами вклада во всём мире.

##### Создание ключа SSH

SSH или Secure Shell — это протокол, позволяющий безопасно обмениваться данными по сети. Обычной практикой является использование SSH для доступа и открытия командной оболочки на другом компьютере и для безопасной пересылки файлов. В наших целях мы в основном будем использовать SSH для безопасной отправки пакетов исходного кода на Launchpad.

Чтобы сгенерировать ключ SSH, введите:

    $ ssh-keygen -t rsa

Имя файла по умолчанию обычно вполне годится, так что можете оставить его как есть. Для целей безопасности настоятельно рекомендуется задать парольную фразу.

##### Настройка pbuilder

`pbuilder` позволяет локально собирать пакеты на вашем компьютере. Он служит нескольким целям:

- Сборка будет выполнена в минимальной и чистой среде. Это даст возможность убедиться, что сборку удастся успешно воспроизвести и на других компьютерах, но при этом поможет избежать изменений в вашей локальной системе

- Отпадает необходимость в локальной установке всех сборочных зависимостей

- Можно настроить несколько экземпляров для различных выпусков Ubuntu и Debian

Настроить `pbuilder` очень просто. Наберите

    $ pbuilder-dist <release> create

where <release> is for example raring, saucy, trusty or in the case of Debian maybe sid. This will take a while as it will download all the necessary packages for a “minimal installation”. These will be cached though.

#### Подготовка к работе с Launchpad

После того, как базовая локальная конфигурация создана, следующим шагом будет настройка системы для работы с Launchpad. В этом разделе мы сфокусируемся на следующих вопросах:

> - Что такое Launchpad и как создать учётную запись на Launchpad

> - Загрузка ваших ключей GPG и SSH на Launchpad

> - Настройка Bazaar для работы с Launchpad

> - Настройка Bash для работы с Bazaar

##### Сведения о Launchpad

Launchpad является центральным элементом инфраструктуры, используемой нами в Ubuntu. Он хранит не только наши пакеты и наш код, но и такие вещи, как переводы, отчёты об ошибках, а также информацию о людях, работающих над Ubuntu и их принадлежности к различным командам. Вы можете также использовать Launchpad, чтобы опубликовать предлагаемые вами исправления и попросить других разработчиков Ubuntu проверить и поддержать их.

Вам понадобится зарегистрироваться на Launchpad и предоставить некоторое минимальное количество информации о себе. Это позволит вам скачивать или отправлять исходный код, отправлять отчёты об ошибках и т.п.

Кроме хостинга Ubuntu, Launchpad может предоставлять место для любого свободного программного проекта. Дополнительную информацию смотрите на Справочных вики-страницах Launchpad.

##### Создание учётной записи на Launchpad

Если у вас ещё нет учётной записи на Launchpad, можно легко создать её. Если учётная запись есть, но вы не помните свой Launchpad id, его можно определить, зайдя на https://launchpad.net/~ и взглянув на часть URL после символа «~».

При регистрации на Launchpad вас попросят выбрать отображаемое имя. Рекомендуется указать здесь ваше настоящее имя, чтобы ваши коллеги - разработчики Ubuntu могли лучше с вами познакомиться.

При регистрации новой учётной записи Launchpad отправит вам письмо со ссылкой, которую нужно открыть в веб-браузере, чтобы подтвердить указанный вами адрес электронной почты. Если вы не получили письмо, проверьте папку нежелательной почты (спама).

Справочная страница новой учётной записи на Launchpad предоставит больше информации о процессе и дополнительных настройках, которые вы можете изменить.

##### Загрузка вашего ключа GPG на Launchpad

First, you will need to get your fingerprint and key ID.

Чтобы узнать свой отпечаток ключа GPG (fingerprint), наберите:

    $ gpg --fingerprint email@address.com

и вы увидите что-то наподобие:

    pub   4096R/43CDE61D 2010-12-06
          Key fingerprint = 5C28 0144 FB08 91C0 2CF3  37AC 6F0B F90F 43CD E61D
    uid                  Daniel Holbach <dh@mailempfang.de>
    sub   4096R/51FBE68C 2010-12-06

Then run this command to submit your key to Ubuntu keyserver:

    $ gpg --keyserver keyserver.ubuntu.com --send-keys 43CDE61D

where `43CDE61D` should be replaced by your key ID (which is in the first line of output of the previous command). Now you can import your key to Launchpad.

Зайдите на https://launchpad.net/~/+editpgpkeys и скопируйте данные из строки «Key fingerprint» в текстовое поле. В приведённом выше примере это будет `5C28 0144 FB08 91C0 2CF3 37AC 6F0B F90F 43CD E61D`. Затем щёлкните «Import Key».

Launchpad воспользуется отпечатком ключа для проверки наличия вашего ключа на сервере ключей Ubuntu и, в случае успеха, отправит вам зашифрованное сообщение электронной почты, предлагающее подтвердить импорт ключа. Проверьте свою почту и прочтите письмо, полученное с Launchpad. Если ваш клиент электронной почты поддерживает шифрование OpenPGP, он предложит ввести пароль, который вы выбрали при создании ключа GPG. Введите пароль, затем щёлкните на ссылке, чтобы подтвердить, что этот ключ принадлежит вам.

Launchpad зашифрует своё почтовое сообщение вашим открытым ключом, чтобы убедиться, что ключ действительно ваш. Если вы пользуетесь почтовым клиентом Thunderbird, используемым по умолчанию в Ubuntu, для дешифровки сообщения можно установить расширение Enigmail. Если ваш почтовый клиент не поддерживает шифрование OpenPGP, скопируйте зашифрованное содержимое письма, наберите в терминале `gpg` и вставьте содержимое письма в окно терминала.

Вернувшись на сайт Launchpad, воспользуйтесь кнопкой «Confirm», чтобы Launchpad завершил импорт вашего ключа OpenPGP.

Дополнительную информацию можно найти на https://help.launchpad.net/YourAccount/ImportingYourPGPKey

##### Загрузка вашего ключа SSH на Launchpad

Откройте в веб-браузере https://launchpad.net/~/+editsshkeys, а в текстовом редакторе файл `~/.ssh/id_rsa.pub`. Это открытая часть вашего ключа SSH, поэтому можно без опасений предоставить к ней общий доступ на Launchpad. Скопируйте содержимое файла и вставьте его в текстовое поле на веб-странице с меткой «Add an SSH key». Затем щёлкните «Import Public Key».

Для получения дополнительной информации об этом процессе посетите страницу о создании ключевой пары SSH на Launchpad.

##### Настройка Bazaar

Bazaar — это инструмент, который мы используем для хранения изменений в коде логичным и предсказуемым способом, а также обмена предлагаемыми изменениями и их слияния, даже в том случае, если разработка ведётся параллельно несколькими людьми. Он используется в новом методе работы с пакетами Ubuntu — Ubuntu Distributed Development.

Что сообщить Bazaar о том, кто вы, просто наберите:

    $ bzr whoami "Bob Dobbs <subgenius@example.com>"
    $ bzr launchpad-login subgenius

whoami сообщит Bazaar, какое имя и адрес электронной почты он должен использовать для ваших коммитов. С помощью launchpad-login вы указываете свой Launchpad ID. Это код, который идентифицирует вашу учётную запись на Launchpad.

Примечание: если вы не помните свой идентификатор, перейдите на https://launchpad.net/~ и посмотрите, куда вас перенаправляет эта страница. Часть URL после символа «~» — это и есть ваш Launchpad ID.

##### Настройка командной оболочки

Как и Bazaar, инструментам создания пакетов Debian/Ubuntu понадобится некоторая информация о вас. Просто откройте ~/.bashrc в текстовом редакторе и добавьте внизу что-то вроде этого:

    export DEBFULLNAME="Bob Dobbs"
    export DEBEMAIL="subgenius@example.com"

Затем сохраните файл и перезапустите терминал или наберите:

    $ source ~/.bashrc

(Если вы не пользуетесь стандартной командной оболочкой bash, отредактируйте конфигурационный файл той оболочки, которую вы предпочитаете использовать.)

### Ubuntu Distributed Development — введение

Это руководство фокусируется на работе с пакетами с использованием метода Ubuntu Distributed Development (UDD).

Ubuntu Distributed Development (UDD) — это новая технология разработки пакетов Ubuntu, использующая инструменты, процессы и последовательности действий, характерные для типичной схемы разработки программ, основанной на распределённой системе управления версиями (DVCS). DVCS, используемая в UDD — это Bazaar.

#### Ограничения традиционных методов создания пакетов

Традиционно пакеты Ubuntu хранятся в архивных tar-файлах. Традиционный пакет исходного кода состоит из tar-файла с исходным кодом из апстрима, “debian” tar-файла (или сжатого diff-файл для более старых пакетов), содержащего набор входных файлов для создания пакета, и файла .dsc с метаданными. Чтобы посмотреть на традиционный пакет, выполните команду:

    $ apt-get source kdetoys

Она загрузит исходники из апстрима `kdetoys_4.6.5.orig.tar.bz2`, набор входных файлов `kdetoys_4.6.5-0ubuntu1.debian.tar.gz` и метаданные `kdetoys_4.6.5-0ubuntu1~ppa1.dsc`. Если у вас установлен dpkg-dev, она извлечёт их содержимое и предоставит вам пакет исходного кода.

Traditional packaging would edit these files and upload. However this gives limited opportunity to collaborate with other developers, changes have to be passed around as diff files with no central way to track them and two developers can not make changes at the same time. So most teams have moved to putting their packaging in a revision control system. This makes it easier for several developers to work on a package together. However there is no direct connection between the revision control system and the archive packages so the two must be manually kept in sync. Since each team works in its own revision control system a prospective developer must first work out where that is and how to get the packaging before they can work on the package.

#### Ubuntu Distributed Development

With Ubuntu Distributed Development all packages in the Ubuntu (and Debian) archive are automatically imported into Bazaar branches on our code hosting site Launchpad. Changes can be made directly to these branches in incremental steps and by anyone with commit access. Changes can also be made in forked branches and merged back in with Merge Proposals when they are large enough to need review or if they are by someone without direct commit access.

UDD branches are all in a standard location, so doing a checkout is easy:

    $ bzr branch ubuntu:kdetoys

The merge history includes two separate branches, one for the upstream source and one which adds the `debian/` packaging directory:

    $ cd kdetoys
    $ bzr qlog

(Эта команда использует в качестве графического интерфейса qbzr. Для вывода в консоль, запустите `log` вместо `qlog`.)

This UDD branch of kdetoys shows the full packaging for each version uploaded to Ubuntu with grey circles and the upstream source versions with green circles. Versions are tagged with either the version in Ubuntu such as `4:4.2.29-0ubuntu1` or for the upstream branch with the upstream version `upstream-4.2.96`.

Many Ubuntu packages are based on the packages in Debian, UDD also imports the Debian package into our branches. In the kdetoys branch above the Debian versions from unstable are from the merge with blue circles while those from Debian experimental are from the merge with yellow circles. Debian releases are tagged with their version number, e.g., `4:4.2.2-1`.

Таким образом из UDD-ветки вы можете увидеть полную историю изменений пакета и сравнить любые две версии. Например, чтобы увидеть различия между версией 4.2.2 в Debian и 4.2.2 в Ubuntu, используйте:

    $ bzr qdiff -r tag:4:4.2.2-1..tag:4:4.2.2-1ubuntu1

(Эта команда использует графический интерфейс qbzr. Запустите `diff` вместо `qdiff` для вывода в консоль.)

Здесь мы можем ясно увидеть, что было изменено в Ubuntu по сравнению с Debian-версией. Очень удобно.

#### Bazaar

Ветки UDD используют Bazaar — распределённую систему управления версиями, которая проста в использовании для тех, кто знаком с такими популярными системами, как Subversion, и в то же время предоставляет всю мощь Git.

Чтобы создавать пакеты с помощью UDD, вам нужно знать основы того, как использовать Bazaar для управления файлами. Для знакомства с Bazaar смотрите Пятиминутный урок по Bazaar и Руководство пользователя Bazaar.

#### Ограничения UDD

Ubuntu Distributed Development — новый метод работы с пакетами Ubuntu. В настоящее время он имеет некоторые существенных ограничения:

- Doing a full branch with history can take a lot of time and network resources. You may find it quicker to do a lightweight checkout `bzr checkout --lightweight ubuntu:kdetoys` but this will need a network access for any further bzr operations.
- Working with patches is fiddly. Patches can be seen as a branched revision control system, so we end up with RCS on top of RCS.
- There is no way to build directly from branches. You need to create a source package and upload that.
- Some packages have not been successfully imported into UDD branches. Recent versions of Bazaar will automatically notify you when this is the case. You can also check the status of the package importer manually before working on a branch.

All of the above are being worked on and UDD is expected to become the main way to work on Ubuntu packages soon. However currently most teams within Ubuntu do not yet work with UDD branches for their development. However because UDD branches are the same as the packages in the archive any team should be able to accept merges against them.

### Исправление ошибок в Ubuntu

#### Вступление

Если вы следовали инструкциям по подготовке к разработке Ubuntu, всё должно быть уже готово к работе.

Как вы можете видеть на картинке выше, в процессе исправления ошибок в Ubuntu нет никаких сюрпризов: вы находите проблему, получаете код, исправляете его, тестируете, отправляете на Launchpad и просите, чтобы его проверили и объединили с основным кодом. В этом руководстве мы пройдем через все необходимые шаги, один за другим.

#### Поиск проблемы

Существуют различные способы найти, над чем можно поработать. Это может быть ошибка, которую вы обнаружили сами (что даёт вам отличную возможность проверить своё исправление) или проблема, которую вы заметили где-то ещё, например в отчёте об ошибке.

Harvest хранит различные списки TODO, касающиеся разработки Ubuntu. Это списки ошибок, которые были уже исправлены в апстриме или в Debian, списки небольших ошибок (мы называем их «bitesize») и так далее. Просмотрите их и найдите ошибку, исправлением которой вы хотите заняться.

#### Выяснение того, что нужно исправить

Если вы не знаете, в каком пакете исходного кода содержится ошибка, но знаете путь к этому приложению в вашей системе, то вы сможете найти пакет исходного кода, над которым требуется поработать.

Предположим, вы обнаружили ошибку в Tomboy, приложении для создания заметок на рабочем столе. Приложение Tomboy можно запустить, выполнив `/usr/bin/tomboy` в командной строке. Чтобы найти двоичный пакет, содержащий это приложение, используйте следующую команду:

    $ apt-file find /usr/bin/tomboy

Команда выведет следующую информацию:

    tomboy: /usr/bin/tomboy

Обратите внимание на то, что часть, предшествующая двоеточию, является именем двоичного пакета. Часто бывает так, что у пакета исходного кода и двоичного пакета различные имена. Чаще всего это происходит, когда один пакет исходного кода используется, чтобы создать несколько различных двоичных пакетов. Чтобы найти исходный пакет для определенного двоичного пакета, введите:

    $ apt-cache showsrc tomboy | grep ^Package:
    Package: tomboy
    $ apt-cache showsrc python-vigra | grep ^Package:
    Package: libvigraimpex

Команда `apt-cache` установлена в Ubuntu по умолчанию.

#### Получение кода

Когда вы знаете, над каким пакетом исходного кода работать, вы можете загрузить копию этого пакета, и заняться отладкой. При распределённой разработке Ubuntu это делается при помощи клонирования bzr-репозитория этого пакета. Launchpad поддерживает Bazaar-ветки для всех пакетов в Ubuntu.

Как только вы получили локальную копию исходного кода, вы можете исследовать ошибку, исправить её, и отправить своё исправление на Launchpad, в виде Bazaar-ветки. Как только вы станете достаточно уверены в своём исправлении, вы можете отправить заявку на слияние, то есть попросить других разработчиков просмотреть и одобрить ваше изменение. В случае согласия с вашими изменениями они загрузят ваши изменения в репозиторий. От вашего изменения получать пользу все — в том числе и вы, чьё имя будет стоять в списке изменений. Вы теперь на пути становления разработчиком Ubuntu!

Мы опишем специфику загрузки кода, отправки изменений, и создания заявки на просмотр в следующимх разделах.

#### Исправление ошибки

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

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

- Система отслеживания ошибок апстрима (и Debian) — открытые и закрытые ошибки,

- История версий в апстриме (или в новой версии) может содержать сведения об исправлении ошибки,

- отчёты об ошибках и новые версии пакетов в Debian и других дистрибутивах.

Теперь можно создать патч, содержащий исправление ошибки. Команда `edit-patch` — самый простой способ добавить патч к пакету. Выполните:

    $ edit-patch 99-new-patch

Эта команда скопирует файлы, необходимые для сборки пакета, во временную директорию. Вы можете изменять эти файлы в текстовом редакторе или применять патчи из upstream, например:

    $ patch -p1 < ../bugfix.patch

После редактирования файла наберите `exit` или нажмите `control-d`, чтобы выйти из временной командной оболочки. Новый патч будет добавлен в `debian/patches`.

#### Тестирование исправления

Чтобы собрать тестовый пакет с вашими изменениями, выполните следующие команды:

    $ bzr builddeb -- -S -us -uc
    $ pbuilder-dist <release> build ../<package>_<version>.dsc

Это создаст пакет исходного кода из содержимого ветки (`-us -uc` просто позволяет пропустить этап подписывания пакета исходного кода), а `pbuilder-dist` соберёт пакет из исходного кода для любого выбранного вами `релиза`.

После успешного завершения сборки установите пакет из `~/pbuilder/<release>_result/` (с помощью `sudo dpkg -i <пакет>_<версия>.deb`). Затем проверьте, удалось ли устранить ошибку.

##### Документирование исправления

Очень важно документировать свои изменения в достаточной степени, чтобы разработчикам впоследствии не пришлось гадать, какими были основания и предпосылки сделанных вами изменений. Каждый пакет исходного кода Debian и Ubuntu включает в себя файл `debian/changelog`, в котором отслеживаются вносимые в пакет изменения.

Самый простой способ обновить его — это выполнить:

    $ dch -i

Эта команда добавит в файл шаблон записи и запустит редактор, в котором вы сможете добавить недостающую информацию. Вот пример этой записи:

    specialpackage (1.2-3ubuntu4) trusty; urgency=low

      * debian/control: updated description to include frobnicator (LP: #123456)

     -- Emma Adams <emma.adams@isp.com>  Sat, 17 Jul 2010 02:53:39 +0200

Команда `dch` должна заполнить первую и последнюю строку этой записи в файле changelog. Первая строка содержит имя пакета исходного кода, номер его версии, в какой релиз Ubuntu он загружен, срочность (почти всегда низкая — ‘low’). Последняя строка всегда содержит имя, адрес электронной почты и метку времени изменения (в формате RFC 5322).

Теперь давайте сфокусируемся на том, что должно содержаться в самой записи файла changelog. Очень важно задокументировать:

> 1. где сделано изменение

> 2. что было изменено

> 3. где происходило обсуждение этого изменения

В нашем (довольно редком) примере последнему пункту соответствует `(LP: #123456)`, то есть сслыка на ошибку на Launchpad с номером 123456. Отчёты об ошибках, темы списков рассылки или спецификации обычно являются хорошими источниками информации для обоснования изменений. В качестве дополнительного приза, если вы используете нотацию `LP: #<номер>` для ошибок на Launchpad, то ошибка автоматически получит статус закрытой при отправке пакета в Ubuntu.

##### Закрепление изменения

Написав и сохранив запись в changelog, мы можем просто запустить:

    debcommit

и изменение будет залито (локально) с вашей записью changelog в качестве сообщения коммита.

Для Launchpad-репозитория, в который отправлять ваши изменения, используйте cледующее имя:

    lp:~<yourlpid>/ubuntu/<release>/<package>/<branchname>

Это может быть, например:

    lp:~emmaadams/ubuntu/trusty/specialpackage/fix-for-123456

Так что, если вы просто выполните:

    bzr push lp:~emmaadams/ubuntu/trusty/specialpackage/fix-for-123456
    bzr lp-propose

всё должно быть готово. Команда push выполнит отправку на Launchpad, а вторая команда откроет страницу удалённой ветки на Launchpad в вашем браузере. Найдите там ссылку «(+) Propose for merging» и щёлкните на ней, чтобы кто-нибудь проверил изменение и включил его в Ubuntu.

Наша статья о поиске поручительства предоставляет дополнительные подробности о получении обратной связи для предложенных вами изменений.

Если ваша ветка исправляет ошибку в стабильном выпуске или это исправление безопасности, прочтите нашу статью Обновления безопасности и стабильных выпусков.

### Демонстрация: исправление ошибки в Ubuntu

Хотя техника исправления ошибки одинакова для любых ошибок, каждая ошибка всё же в чём то отличается от других. Данный пример исправления конкретной ошибки может помочь вам понять, что обычно следует принять во внимание.

Примечание

Во время написания данной статьи эта ошибка ещё не была исправлена. Возможно, у тому времени, когда вы будете читать статью, ошибку уже исправят. Считайте это просто примером и постарайте адаптировать его к конкретной проблеме, с которой вы столкнётесь.

#### Подтверждение проблемы

Предположим, в описании пакета `bumprace` отсутствует информация о его домашней странице. В качестве первого шага, следует проверить, не исправлена ли уже эта ошибка. Сделать это просто: посмотрите в Центре приложений или запустите:

    apt-cache show bumprace

Вывод команды должен быть примерно следующим:

    Package: bumprace
    Priority: optional
    Section: universe/games
    Installed-Size: 136
    Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
    Original-Maintainer: Christian T. Steigies <cts@debian.org>
    Architecture: amd64
    Version: 1.5.4-1
    Depends: bumprace-data, libc6 (>= 2.4), libsdl-image1.2 (>= 1.2.10),
             libsdl-mixer1.2, libsdl1.2debian (>= 1.2.10-1)
    Filename: pool/universe/b/bumprace/bumprace_1.5.4-1_amd64.deb
    Size: 38122
    MD5sum: 48c943863b4207930d4a2228cedc4a5b
    SHA1: 73bad0892be471bbc471c7a99d0b72f0d0a4babc
    SHA256: 64ef9a45b75651f57dc76aff5b05dd7069db0c942b479c8ab09494e762ae69fc
    Description-en: 1 or 2 players race through a multi-level maze
     In BumpRacer, 1 player or 2 players (team or competitive) choose among 4
     vehicles and race through a multi-level maze. The players must acquire
     bonuses and avoid traps and enemy fire in a race against the clock.
     For more info, see the homepage at http://www.linux-games.com/bumprace/
    Description-md5: 3225199d614fba85ba2bc66d5578ff15
    Bugs: https://bugs.launchpad.net/ubuntu/+filebug
    Origin: Ubuntu

В качестве контрпримера можно привести `gedit`, где домашняя страница указана:

    $ apt-cache show gedit | grep ^Homepage
    Homepage: http://www.gnome.org/projects/gedit/
    $

В некоторых случаях вы можете столкнуться с тем, что проблема, решение которой вы ищете, уже кем-то устранена. Чтобы избежать напрасной траты времени и труда, имеет смысл проделать кое-какую детективную работу.

#### Изучение ситуации с ошибкой

Сначала нужно проверить, не существует ли уже сообщения об этой ошибке в Ubuntu. Возможно, кто-то уже работает над её исправлением, или мы можем как-то внести свой вклад в решение этой проблемы. Для Ubuntu мы взглянем на https://bugs.launchpad.net/ubuntu/+source/bumprace и увидим, что открытого отчёта о нашей ошибке там нет.

Примечание

Для Ubuntu URL `https://bugs.launchpad.net/ubuntu/+source/<пакет>` всегда приводит на страницу ошибок в указанном пакете исходного кода.

В Debian, который является основным источником пакетов Ubuntu мы взглянем на http://bugs.debian.org/src:bumprace и также не найдём там сообщения о нашей ошибке.

Примечание

Для Debian URL `http://bugs.debian.org/src:<пакет>` всегда приводит на страницу ошибок в указанном пакете исходного кода.

Ошибка, над которой мы работаем, необычна в том смысле, что она касается только пакетирования `bumprace`. Если бы это была ошибка в исходном коде, полезно было бы также проверить систему отслеживания ошибок апстрима. К сожалению, эта процедура часто различается для каждого отдельного пакета, но всегда можно воспользоваться поиском в интернете, и в большинстве случаев вы обнаружите, что она окажется не такой уж сложной.

#### Предложение помощи

Если вы обнаружили открытую ошибку, которая ещё никому не назначена, и вы готовы взяться за её устранение, следует написать комментарий с вашим решением. Включите в него как можно больше информации: При каких обстоятельствах появляется ошибка? Как вы её исправили? Тестировали ли вы свой способ устранения ошибки?

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

Будет замечательно, если вы можете предложить свою помощь, и она, несомненно, будет с готовностью принята.

#### Исправление ошибки

В данном конкретном примере недостаточно просто найти веб-сайт `bumprace` и определить адрес его домашней страницы. Нужно убедиться, что сайт работает, и он не является просто каталогом различных программ. http://www.linux-games.com/bumprace/ выглядит подходящим местом.

Чтобы взяться за ошибку в пакете исходного кода, нам понадобится этот исходный код, и мы легко можем получить его, набрав:

    bzr branch ubuntu:bumprace

Если вы прочитали обзор каталога Debian, то помните, вероятно, что домашняя страница указывается в первой части `debian/control`, в секции, начинающейся с `Source:`.

Так что теперь мы должны выполнить команду:

    cd bumprace

и отредактировать `debian/control`, добавив `Homepage: http://www.linux-games.com/bumprace/`. В конце первой секции должно быть подходящее место для этого. После внесения изменений сохраните файл.

Если теперь вы выполните:

    bzr diff

вы должны увидеть что-то вроде этого:

    === modified file 'debian/control'
    --- debian/control      2012-05-14 23:38:14 +0000
    +++ debian/control      2012-09-03 15:45:30 +0000
    @@ -12,6 +12,7 @@
                    libtool,
                    zlib1g-dev
     Standards-Version: 3.9.3
    +Homepage: http://www.linux-games.com/bumprace/

     Package: bumprace
     Architecture: any

Синтаксис diff очень прост для понимания. `+` указывает строку, которая была добавлена. В нашем случае она была добавлена непосредственно перед второй секцией, начинающейся с `Package`, которая указывает на готовый двоичный пакет.

#### Документирование исправления

Важно пояснить своим коллегам - разработчикам, что именно вы сделали. Если вы наберёте:

    dch -i

это запустит редактор, с шаблоном записи в changelog, которую вам остаётся лишь дозаполнить. В нашем случае должно подойти что-то наподобие `debian/control: Added project's homepage.` Затем сохраните файл. Чтобы ещё раз проверить, что всё работает, наберите:

    bzr diff debian/changelog

и вы увидите что-то вроде этого:

    === modified file 'debian/changelog'
    --- debian/changelog    2012-05-14 23:38:14 +0000
    +++ debian/changelog    2012-09-03 15:53:52 +0000
    @@ -1,3 +1,9 @@
    +bumprace (1.5.4-1ubuntu1) UNRELEASED; urgency=low
    +
    +  * debian/control: Added project's homepage.
    +
    + -- Peggy Sue <peggy.sue@example.com>  Mon, 03 Sep 2012 17:53:12 +0200
    +
     bumprace (1.5.4-1) unstable; urgency=low

       * new upstream version, sound and music have been removed (closes: #613344)

Несколько дополнительных соображений:

> - Если у вас есть ссылка на ошибку на Launchpad, которую исправляет ваше изменение, добавьте (`LP: #<номер ошибки>`) в запись changelog, например: `(LP: #123456)`.

> - Если вы хотите, чтобы ваше исправление было включено в Debian, синтаксис для ошибки в Debian будет `(Closes: #<номер ошибки>)`, например: `(Closes: #123456)`.

> - Если это ссылка на сообщение об ошибке в апстриме или в Debian, или на обсуждение в почтовой рассылке, также укажите её.

> - Старайтесь делать перенос строк после 80 символов.

> - Старайтесь излагать подробно: не стоит писать целое эссе, но укажите достаточно информации, чтобы понять мог любой человек (даже если он не вникал глубоко в эту проблему).

> - Укажите, как и где вы исправили ошибку.

#### Тестирование исправления

Чтобы проверить исправление, вам понадобится настроить свою среду разработки, затем собрать пакет, установить его и проверить, что проблема устранена. В нашем случае это будут следующие действия:

    bzr bd -- -S
    pbuilder-dist <current Ubuntu release> build ../bumprace_*.dsc
    dpkg -I ~/pbuilder/*_result/bumprace_*.deb

Первой командой мы создаём пакет исходного кода из ветки, затем собираем его с помощью `pbuilder`, после чего проверяем, правильно ли добавлено поле домашней страницы в получившемся пакете.

Примечание

В большинстве случаев вам придётся действительно установить пакет, чтобы проверить правильность его работы. Наш случай намного проще. Если сборка завершилась успешно, готовые двоичные пакеты можно будет найти в `~/pbuilder/<выпуск>_result`. Установите их с помощью `sudo dpkg -i <пакет>.deb` или двойного щелчка на них в файловом менеджере.

После того, как мы убедились, что проблема решена, следующим шагом будет поделиться своим решением со всем миром.

#### Применение исправления

Важно попытаться продвинуть ваше исправление как можно дальше в upstream. Это позволит любому взять исходный код в том виде, в каком он представлен в upstream, и не применять к нему никаких дополнительных модификаций.

В нашем случае мы установили, что ошибка относится только к пакетам Ubuntu и Debian. Так как Ubuntu основана на Debian, мы должны отправить исправление в Debian. После того, как в Debian появится исправленный пакет, он попадёт также и в Ubuntu. Наша ошибка не критична, поэтому можно так сделать. Если же важно применить исправление как можно скорее, то необходимо отправить исправление в несколько баг-трекеров (если оно затрагивает соотвествующие проекты).

Чтобы отправить патч в Debian, просто наберите:

    submittodebian

Эта команда проведёт вас через несколько шагов, необходимых для оформления отчёта об ошибке и отправки его в правильное место. Обязательно просмотрите ваши изменения, чтобы убедиться, что там нет ничего постороннего.

Коммуникация имеет очень большое значение, поэтому при добавлении описания предоставьте хорошее и дружественное объяснение.

Если всё прошло нормально, то вы должны получить почтовое сообщение от системы отслеживания ошибок Debian с дополнительной информацией. Иногда это может занять несколько минут.

Примечание

Если проблема наблюдается только в Ubuntu, вы можете воспользоваться инструкцией по поиску спонсора.

#### Дополнительные замечания

Если вы можете внести в пакет несколько тривиальных исправлений сразу, сделайте это. Это позволит разработчикам быстрее рассмотреть и применить эти изменения.

Если вы хотите внести несколько больших изменений, лучше посылать патчи или запросы на слияние отдельно для каждого изменения. Это проще, если уже созданы индивидуальные сообщения об ошибках.

### Создание пакетов для новых программ

Хотя в архиве Ubuntu имеются тысячи пакетов, есть ещё много программ, которыми никто не занимается. Если вы знаете о какой-то замечательной программе, о которой, по вашему мнению, стоит узнать более широкому кругу пользователей, вы можете попробовать приложить свою руку к созданию пакета для Ubuntu или PPA. Это руководство проведёт вас через этапы создания пакета для новой программы.

Сначала вам следует прочитать статью Подготовка, чтобы подготовить свою среду разработки.

#### Проверка программы

Первым этапом создания пакета является получение tar-файла из апстрима («апстримом» мы называем авторов приложений) и проверка того, что он нормально компилируется и запускается.

Это руководство проведёт вас через процесс создания пакета для небольшого приложения GNU Hello, доступного на GNU.org.

Если у вас ещё нет инструментов сборки, установите их. Также установите все необходимые зависимости.

Установим инструменты сборки:

    $ sudo apt-get install build-essential

Скачаем основной пакет:

    $ wget -O hello-2.7.tar.gz "http://ftp.gnu.org/gnu/hello/hello-2.7.tar.gz"

Теперь распакуем основной пакет:

    $ tar xf hello-2.7.tar.gz
    $ cd hello-2.7

Это приложение использует систему сборки autoconf, так что нам нужно запустить `./configure` для подготовки к компиляции.

При этом будет проверено наличие необходимых для сборки зависимостей. Поскольку `hello` — простой пример, `build-essential` обеспечит нас всем, что нужно. Для более сложных программ, команда завершится ошибкой, если у нас нет необходимых библиотек и файлов для разработки. Установите требуемые пакеты и повторите процесс, пока команда не завершится успешно.:

    $ ./configure

Теперь нужно скомпилировать исходный код:

    $ make

Если компиляция завершилась успешно, можно установить и запустить программу:

    $ sudo make install
    $ hello

#### Создание пакета

`bzr-builddeb` содержит модуль для создания нового пакета из шаблона. Этот модуль является обёрткой вокруг команды `dh_make` . Он уже должен быть у вас, если вы установили `packaging-dev`. Запустите команду, указав имя пакета, номер версии и путь к tar-архиву из апстрима:

    $ sudo apt-get install dh-make
    $ cd ..
    $ bzr dh-make hello 2.7 hello-2.7.tar.gz

When it asks what type of package type `s` for single binary. This will import the code into a branch and add the `debian/` packaging directory. Have a look at the contents. Most of the files it adds are only needed for specialist packages (such as Emacs modules) so you can start by removing the optional example files:

    $ cd hello/debian
    $ rm *ex *EX

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

In `debian/changelog` change the version number to an Ubuntu version: `2.7-0ubuntu1` (upstream version 2.7, Debian version 0, Ubuntu version 1). Also change `unstable` to the current development Ubuntu release such as `trusty`.

Much of the package building work is done by a series of scripts called `debhelper`. The exact behaviour of `debhelper` changes with new major versions, the compat file instructs `debhelper` which version to act as. You will generally want to set this to the most recent version which is `9`.

Файл `control` содержит все метаданные пакета. Первый абзац описывает пакет исходных кодов. Второй и следующие абзацы описывают двоичные пакеты, которые должны быть собраны. Нам понадобится добавить пакеты, необходимые для компиляции приложения в `Build-Depends:`. Для `hello` он должен включать, как минимум:

    Build-Depends: debhelper (>= 9)

Также нужно заполнить описание программы в поле `Description:`.

`copyright` нужно заполнить в соответствии с лицензией на источник из апстрима. Согласно файлу hello/COPYING, это лицензия GNU GPL 3 или более поздняя её версия.

`docs` должен содержать любые файлы документации из апстрима, которые, по вашему мнению, должны быть включены в готовый пакет.

`README.source` и `README.Debian` необходимы, лишь если ваш пакет имеет какие-то нестандартные функции. У нас таких нет, так что можно удалить эти файлы.

`source/format` можно оставить как есть, он описывает формат версии пакета исходного кода, который должен быть `3.0 (quilt)`.

`rules` — самый сложный файл. Это Makefile, который компилирует код и превращает его в двоичный пакет. К счастью, основную часть работы в наши дни автоматически выполняет `debhelper 7`, так что универсальная цель `%` просто запускает сценарий `dh`, который делает всё, что необходимо.

Все эти файлы подробнее описаны в статье обзор каталога debian.

Finally commit the code to your packaging branch:

    $ bzr commit -m "Initial commit of Debian packaging."

#### Сборка пакета

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

    $ bzr builddeb -- -us -uc
    $ cd ../../

`bzr builddeb` — это команда для сборки пакета в его текущем местоположении. `-us -uc` сообщает что подписывать пакет с помощью GPG не требуется. Результат будет помещён в каталог «..».

Просмотреть содержимое пакета можно с помощью:

    $ lesspipe hello_2.7-0ubuntu1_amd64.deb

Install the package and check it works (later you will be able to uninstall it using `sudo apt-get remove hello` if you want):

    $ sudo dpkg --install hello_2.7-0ubuntu1_amd64.deb

You can also install all packages at once using:

    $ sudo debi

#### Дальнейшие шаги

Even if it builds the .deb binary package, your packaging may have bugs. Many errors can be automatically detected by our tool `lintian` which can be run on both the source .dsc metadata file and the .deb binary package:

    $ lintian hello_2.7-0ubuntu1.dsc
    $ lintian hello_2.7-0ubuntu1_amd64.deb

Описание каждой проблемы, о которой он сообщает, можно найти на веб-сайте lintian.

After making a fix to the packaging you can rebuild using `-nc` “no clean” without having to build from scratch:

    $ bzr builddeb -- -nc -us -uc

Убедившись, что пакет успешно собирается локально, вы должны проверить, правильно ли его сборка будет проходить в чистой системе, с помощью `pbuilder`. Поскольку вскоре мы собираемся загрузить его в PPA (персональный архив пакетов), эту загрузку нужно снабдить цифровой подписью, чтобы Launchpad мог удостовериться, что загрузку сделали вы (узнать о том, что загрузка будет подписана, можно по отсутствию передаваемых `bzr builddeb` флагов `-us` и `-uc`, которые мы использовали ранее). Для подписывания своей работы вам понадобится настроить GPG. Если вы ещё не настроили `pbuilder-dist` или GPG, сделайте это сейчас:

    $ bzr builddeb -S
    $ cd ../build-area
    $ pbuilder-dist trusty build hello_2.7-0ubuntu1.dsc

После того как вы останетесь довольны получившимся пакетом, нужно, чтобы его проверили другие люди. Вы можете выгрузить ветку на Launchpad для проверки:

    $ bzr push lp:~<lp-username>/+junk/hello-package

Uploading it to a PPA will ensure it builds and give an easy way for you and others to test the binary packages. You will need to set up a PPA in Launchpad and then upload with `dput`:

    $ dput ppa:<lp-username>/<ppa-name> hello_2.7-0ubuntu1.changes

Смотрите раздел «Загрузка» для дополнительной информации.

You can ask for reviews in `#ubuntu-motu` IRC channel, or on the MOTU mailing list. There might also be a more specific team you could ask such as the GNU team for more specific questions.

#### Submitting for inclusion

Существует несколько путей, которыми пакет может попасть в Ubuntu. В большинстве случаев лучшим путём может быть прохождение сначала через Debian. Это позволит вашему пакету стать доступным для наибольшего количества пользователей, так как он будет доступен не только в Debian и Ubuntu, но и во всех дистрибутивах, созданных на их основе. Вот несколько полезных ссылок по отправке новых пакетов в Debian:

> - Debian Mentors FAQ — debian-mentors является основным местом для создания, просмотра и загрузки в Debian новых пакетов. Здесь вы можете найти разработчика Debian для загрузки вашего пакета в архив.

> - Work-Needing and Prospective Packages — Информация о том, как подать “Intent to Package” и “Request for Package” заявки, а также список открытых ITP и RFP.

> - Debian Developer’s Reference, 5.1. New packages — весь документ бесценен для создателей пакетов как для Ubuntu, так и для Debian. Этот раздел документирует процессы по отправке новых пакетов.

В некоторых случаях может иметь смысл сначала отправить пакет непосредственно в Ubuntu. Например, если версия Debian находится в состоянии заморозки, что делает маловероятным своевременное попадание вашего пакета в новый выпуск Ubuntu. Этот процесс документирован в разделе “New Packages” вики-страниц Ubuntu.

#### Sreenshots

Once you have uploaded a package to debian, you should add screenshots to allow propective users to see what the program is like. These should be uploaded to http://screenshots.debian.net/upload .

### Обновления безопасности и обновления стабильных релизов

#### Исправление ошибок безопасности в Ubuntu

##### Вступление

Fixing security bugs in Ubuntu is not really any different than fixing a regular bug in Ubuntu, and it is assumed that you are familiar with patching normal bugs. To demonstrate where things are different, we will be updating the dbus package in Ubuntu 12.04 LTS (Precise Pangolin) for a security update.

##### Получение исходного кода

In this example, we already know we want to fix the dbus package in Ubuntu 12.04 LTS (Precise Pangolin). So first you need to determine the version of the package you want to download. We can use the `rmadison` to help with this:

    $ rmadison dbus | grep precise
    dbus | 1.4.18-1ubuntu1   | precise          | source, amd64, armel, armhf, i386, powerpc
    dbus | 1.4.18-1ubuntu1.4 | precise-security | source, amd64, armel, armhf, i386, powerpc
    dbus | 1.4.18-1ubuntu1.4 | precise-updates  | source, amd64, armel, armhf, i386, powerpc

Typically you will want to choose the highest version for the release you want to patch that is not in -proposed or -backports. Since we are updating Precise’s dbus, you’ll download 1.4.18-1ubuntu1.4 from precise-updates:

    $ bzr branch ubuntu:precise-updates/dbus

##### Создание патча

Теперь, когда мы имеем исходный пакет, мы должны сделать патч для исправления уязвимости. Вы можете использовать любой метод, подходящий для данного пакета, в том числе методы UDD, но в этом примере будем использовать `edit-patch` (из пакета ubuntu-dev-tools). `edit-patch` — это самый простой способ для исправления пакетов, работающий с любой системой патчей, которую вы можете себе представить.

Чтобы создать патч с помощью `edit-patch`:

    $ cd dbus
    $ edit-patch 99-fix-a-vulnerability

This will apply the existing patches and put the packaging in a temporary directory. Now edit the files needed to fix the vulnerability. Often upstream will have provided a patch so you can apply that patch:

    $ patch -p1 < /home/user/dbus-vulnerability.diff

После внесения необходимых изменений просто нажмите Ctrl-D или наберите exit, чтобы покинуть временную командную оболочку.

##### Форматирование файла changelog и патчей

After applying your patches you will want to update the changelog. The `dch` command is used to edit the `debian/changelog` file and `edit-patch` will launch `dch` automatically after un-applying all the patches. If you are not using `edit-patch`, you can launch `dch -i` manually. Unlike with regular patches, you should use the following format (note the distribution name uses precise-security since this is a security update for Precise) for security updates:

    dbus (1.4.18-2ubuntu1.5) precise-security; urgency=low

      * SECURITY UPDATE: [DESCRIBE VULNERABILITY HERE]
        - debian/patches/99-fix-a-vulnerability.patch: [DESCRIBE CHANGES HERE]
        - [CVE IDENTIFIER]
        - [LINK TO UPSTREAM BUG OR SECURITY NOTICE]
        - LP: #[BUG NUMBER]
    ...

Обновите свой патч для использования соответствующих тегов. Ваш патч должен содержать как минимум теги Origin, Description и Bug-Ubuntu. Например, отредактируйте `debian/patches/99-fix-a-vulnerability.patch`, чтобы он имел приблизительно следующие строки:

    ## Description: [DESCRIBE VULNERABILITY HERE]
    ## Origin/Author: [COMMIT ID, URL OR EMAIL ADDRESS OF AUTHOR]
    ## Bug: [UPSTREAM BUG URL]
    ## Bug-Ubuntu: https://launchpad.net/bugs/[BUG NUMBER]
    Index: dbus-1.4.18/dbus/dbus-marshal-validate.c
    ...

Multiple vulnerabilities can be fixed in the same security upload; just be sure to use different patches for different vulnerabilities.

##### Проверка и отправка вашей работы

На этом этапе процесс такой же, как при исправлении обычных ошибок в Ubuntu. А именно, вам нужно:

> 1. Выполнить сборку пакета и проверить, что он компилируется без ошибок и компилятор не выдаёт никаких дополнительных предупреждений

> 2. Выполнить обновление с предыдущей версии пакета до новой версии

> 3. Убедиться, что новый пакет закрывает уязвимость и не вносит никаких ухудшений

> 4. Submit your work via a Launchpad merge proposal and file a Launchpad bug being sure to mark the bug as a security bug and to subscribe `ubuntu-security-sponsors`

Если это уязвимость в безопасности, о которой ещё не объявлено публично, то не отправляйте предложение слияния и убедитесь, что вы пометили свою ошибку, как приватную (private).

The filed bug should include a Test Case, i.e. a comment which clearly shows how to recreate the bug by running the old version then how to ensure the bug no longer exists in the new version.

The bug report should also confirm that the issue is fixed in Ubuntu versions newer than the one with the proposed fix (in the above example newer than Precise). If the issue is not fixed in newer Ubuntu versions you should prepare updates for those versions too.

#### Обновления стабильного релиза

Мы также разрешаем вносить обновления в выпуски, в которых пакет содержит серьёзную ошибку, такую как значительная регрессия по сравнению с предыдущим выпуском или ошибка, которая может привести к потере данных. Из-за того, что такие изменения сами потенциально могут привести к появлению дополнительных ошибок, мы позволяем делать это только там, где изменения легко можно понять и проверить.

Процесс обновлений стабильного выпуска (Stable Release Updates или SRU) такой же, как и для исправлений ошибок безопасности, за исключением того, что нужно подписать на отчёт об ошибке команду `ubuntu-sru`.

The update will go into the `proposed` archive (for example `precise-proposed`) where it will need to be checked that it fixes the problem and does not introduce new problems. After a week without reported problems it can be moved to `updates`.

Дополнительную информацию смотрите на вики-странице Stable Release Updates.

### Патчи для пакетов

Sometimes, Ubuntu package maintainers have to change the upstream source code in order to make it work properly on Ubuntu. Examples include, patches to upstream that haven’t yet made it into a released version, or changes to the upstream’s build system needed only for building it on Ubuntu. We could change the upstream source code directly, but doing this makes it more difficult to remove the patches later when upstream has incorporated them, or extract the change to submit to the upstream project. Instead, we keep these changes as separate patches, in the form of diff files.

Существуют различные способы работы с патчами для пакетов Debian. К счастью, мы остановимся на одной системе, Quilt, которая сейчас используется большинством пакетов.

Let’s look at an example package, `kamoso` in Trusty:

    $ bzr branch ubuntu:trusty/kamoso

Патчи хранятся в `debian/patches`. Для этого пакета имеется один патч `kubuntu_01_fix_qmax_on_armel.diff` для исправления ошибки компиляции на платформе ARM. Этому патчу присвоено имя, описывающее, что он делает, номер патча по порядку (чтобы избежать путаницы, если два патча имеют одинаковое имя) и, в данном случае, команда Kubuntu добавила свой собственный префикс, чтобы показать, что патч исходит от них, а не от Debian.

Порядок применения патчей хранится в `debian/patches/series`.

#### Патчи с помощью Quilt

Перед работой с Quilt нужно указать этой системе, где искать патчи. Добавьте в `~/.bashrc` следующее:

    export QUILT_PATCHES=debian/patches

And source the file to apply the new export:

    $ . ~/.bashrc

По умолчанию все патчи применяются уже с UDD извлечений или загружаемых пакетов. Вы можете проверить это с помощью:

    $ quilt applied
    kubuntu_01_fix_qmax_on_armel.diff

Если вы хотите удалить патч, нужно выполнить `pop`:

    $ quilt pop
    Removing patch kubuntu_01_fix_qmax_on_armel.diff
    Restoring src/kamoso.cpp

    No patches applied

А чтобы применить патч, используйте `push`:

    $ quilt push
    Applying patch kubuntu_01_fix_qmax_on_armel.diff
    patching file src/kamoso.cpp

    Now at patch kubuntu_01_fix_qmax_on_armel.diff

#### Добавление нового патча

Для добавления нового патча нужно указать Quilt создать новый патч, сообщить ему, какие файлы этот патч должен изменить, отредактировать файлы, а затем обновить патч:

    $ quilt new kubuntu_02_program_description.diff
    Patch kubuntu_02_program_description.diff is now on top
    $ quilt add src/main.cpp
    File src/main.cpp added to patch kubuntu_02_program_description.diff
    $ sed -i "s,Webcam picture retriever,Webcam snapshot program,"
    src/main.cpp
    $ quilt refresh
    Refreshed patch kubuntu_02_program_description.diff

Шаг `quilt add` важен: если вы забудете его сделать, файлы не попадут в патч.

Теперь изменения будут в `debian/patches/kubuntu_02_program_description.diff`, а в файл `series` будет добавлена информация о новом патче. Вы должны добавить новый файл в исходные файлы для пакета:

    $ bzr add debian/patches/kubuntu_02_program_description.diff
    $ bzr add .pc/*
    $ dch -i "Add patch kubuntu_02_program_description.diff to improve the program description"
    $ bzr commit

Quilt keeps its metadata in the `.pc/` directory, so currently you need to add that to the packaging too. This should be improved in future.

Как правило, следует проявлять осторожность при добавлении патчей к программам, если они исходят не из апстрима. Часто имеется веская причина, по которой изменения ещё не были сделаны. В рассмотренном выше примере изменяется строка в пользовательском интерфейсе, так что это может поломать все переводы. Если сомневаетесь, спросите автора из апстрима перед тем, как добавить патч.

#### Patch Headers

We recommend that you tag every patch with DEP-3 headers by putting them at the top of patch file. Here are some headers that you can use:

Description: | Description of what the patch does. It is formatted like `Description` field in `debian/control`: first line is short description, starting with lowercase letter, the next lines are long description, indented with a space.
Author: | Кто написал патч (например, “Jane Doe <packager@example.com>”).
Origin: | Откуда пришёл этот патч (например, “upstream”), если заголовок Author отсутствует.
Bug-Ubuntu: | Ссылка на информацию об ошибке на Launchpad, предпочтительно, в краткой форме (наподобие https://bugs.launchpad.net/bugs/XXXXXXX). Если также имеются отчёты об ошибках в апстриме или системах отслеживания ошибок Debian, добавьте заголовки Bug или Bug-Debian.
Forwarded: | Whether the patch was forwarded upstream. Either “yes”, “no” or “not-needed”.
Last-Update: | Дата последней ревизии (в форме “ГГГГ-ММ-ДД”).

#### Обновление до новых версий из апстрима

Чтобы выполнить обновление до последней версии, вы можете использовать команду `bzr merge-upstream`:

    $ bzr merge-upstream --version 2.0.2 https://launchpad.net/ubuntu/+archive/primary/+files/kamoso_2.0.2.orig.tar.bz2

When you run this command, all patches will be unapplied, because they can become out of date. They might need to be refreshed to match the new upstream source or they might need to be removed altogether. To check for problems, apply the patches one at a time:

    $ quilt push
    Applying patch kubuntu_01_fix_qmax_on_armel.diff
    patching file src/kamoso.cpp
    Hunk #1 FAILED at 398.
    1 out of 1 hunk FAILED -- rejects in file src/kamoso.cpp
    Patch kubuntu_01_fix_qmax_on_armel.diff can be reverse-applied

Если для патча указано `it can be reverse-applied`, значит патч уже был применён апстримом, так что мы можем удалить этот патч:

    $ quilt delete kubuntu_01_fix_qmax_on_armel
    Removed patch kubuntu_01_fix_qmax_on_armel.diff

Затем продолжайте:

    $ quilt push
    Applied kubuntu_02_program_description.diff

Неплохой мыслью будет выполнить refresh, это обновит патч относительно изменений исходного кода в апстриме:

    $ quilt refresh
    Refreshed patch kubuntu_02_program_description.diff

Затем выполните фиксацию, как обычно:

    $ bzr commit -m "new upstream version"

#### Создание пакета с использованием Quilt

Modern packages use Quilt by default, it is built into the packaging format. Check in `debian/source/format` to ensure it says `3.0 (quilt)`.

Для более старых пакетов, использующих формат 1.0, необходимо использовать Quilt явно, обычно с помощью включения make-фала в `debian/rules`.

#### Конфигурирование Quilt

Вы можете воспользоваться файлом `~/.quiltrc` для конфигурирования quilt. Вот несколько опций, которые могут быть полезны при использовании quilt с пакетами Debian:

    # Set the patches directory
    QUILT_PATCHES="debian/patches"
    # Remove all useless formatting from the patches
    QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
    # The same for quilt diff command, and use colored output
    QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"

#### Другие системы управления патчами

Other patch systems used by packages include `dpatch` and `cdbs simple-patchsys`, these work similarly to Quilt by keeping patches in `debian/patches` but have different commands to apply, un-apply or create patches. You can find out which patch system is used by a package by using the `what-patch` command (from the `ubuntu-dev-tools` package). You can use `edit-patch`, shown in previous chapters, as a reliable way to work with all systems.

In even older packages changes will be included directly to sources and kept in the `diff.gz` source file. This makes it hard to upgrade to new upstream versions or differentiate between patches and is best avoided.

Не изменяйте систему патчей, не обсудив это с сопровождающим Debian или имеющей отношение к делу командой Ubuntu. Если существующей системы патчей нет, можете добавить Quilt.

### Fixing FTBFS packages

Перед тем, как пакет можно будет использовать в Ubuntu, он должен быть собран из исходного кода. Если это не удаётся, пакет, вероятно, будет ожидать в -proposed и не будет доступен в архивах Ubuntu. Полный список пакетов, которые не удалось собрать из исходного кода, можно найти на http://qa.ubuntuwire.org/ftbfs/. На этой странице показано 5 основных категорий:

> - Package failed to build (F): Что-то действительно пошло не так в процессе сборки.

> - Cancelled build (X): The build has been cancelled for some reason. These should probably be avoided to start with.

> - Package is waiting on another package (M): Этот пакет ожидает сборки или обновления другого пакета, или (если это пакет в main) одна из его зависимостей находится не в той части архива.

> - Failure in the chroot (C): Part of the chroot failed, this is most likely fixed by a rebuild. Ask a developer to rebuild the package and that should fix it.
> - Failed to upload (U): The package could not upload. This is usually just a case of asking for a rebuild, but check the build log first.

#### Первые шаги

The first thing you’ll want to do is see if you can reproduce the FTBFS yourself. Get the code either by running `bzr branch lp:ubuntu/PACKAGE` and then getting the tarball or running `dget PACKAGE_DSC` on the .dsc file from the launchpad page. Once you have that, build it in a schroot.

You should be able to reproduce the FTBFS. If not, check if the build is downloading a missing dependency, which means you just need to make that a build-dependency in debian/control. Building the package locally can also help find if the issue is caused by a missing, unlisted, dependency (builds locally but fails on a schroot).

#### Checking Debian

Once you have reproduced the issue, it’s time to try and find a solution. If the package is in Debian as well, you can check if the package builds there by going to http://packages.qa.debian.org/PACKAGE. If Debian has a newer version, you should merge it. If not, check the buildlogs and bugs linked on that page for any extra information on the ftbfs or patches. Debian also maintains a list of command FTBFSs and how to fix them which can be found at https://wiki.debian.org/qa.debian.org/FTBFS, you will want to check it for solutions too.

#### ARM64

Ubuntu has added arm64 as a architecture recently, but many packages fail to build on it. A full list of the packages not building are at qa.ubuntuwire.org/ftbfs/arm64.html. Many of these are caused by packages using outdated autotools helper files. Any package with the lintian warning ancient-autotools-helper-file or outdated-autotools-helper-file will have this issue. Adding autotools-dev or dh-autoreconf to the build proccess will usually fix this.

#### Other causes of a package to FTBFS

If a package is in main and missing a dependency that is not in main, you will have to file a MIR bug. https://wiki.ubuntu.com/MainInclusionProcess explains the procedure.

#### Исправление ошибки

Once you have found a fix to the problem, follow the same process as any other bug. Make a patch, add it to a bzr branch or bug, subscribe ubuntu-sponsors, then try to get it included upstream and/or in Debian.

### Общие библиотеки

Общие библиотеки — это скомпилированный код, предназначенный для совместного использования несколькими различными программами. Они распространяются в виде файлов `.so` в `/usr/lib/`.

A library exports symbols which are the compiled versions of functions, classes and variables. A library has a name called an SONAME which includes a version number. This SONAME version does not necessarily match the public release version number. A program gets compiled against a given SONAME version of the library. If any of the symbols is removed or changes then the version number needs to be changed which forces any packages using that library to be recompiled against the new version. Version numbers are usually set by upstream and we follow them in our binary package names called an ABI number, but sometimes upstreams do not use sensible version numbers and packagers have to keep separate version numbers.

Библиотеки обычно распространяются апстримом в виде отдельных выпусков. Иногда они распространяются, как часть программы. В последнем случае они могут быть включены в двоичный пакет вместе с программой (это называется bundling), если вы не предполагаете использование этих библиотек другими программами, но чаще их всё же следует выделять в отдельные двоичные пакеты.

Сами библиотеки помещаются в двоичный пакет с именем `libfoo1`, где `foo` — имя библиотеки, а `1` — версия из SONAME. Файлы разработки из пакета, такие как заголовочные файлы, необходимые для компиляции программ с библиотекой, помещаются в пакет с именем `libfoo-dev`.

#### Пример

В качестве примера мы используем libnova:

    $ bzr branch ubuntu:trusty/libnova
    $ sudo apt-get install libnova-dev

Чтобы найти SONAME библиотеки, выполните:

    $ readelf -a /usr/lib/libnova-0.12.so.2 | grep SONAME

SONAME в данном случае `libnova-0.12.so.2`, что соответствует имени файла (как правило, но не всегда). Здесь апстрим поместил номер версии из апстрима, как часть SONAME, и задал ABI-версию `2`. Имена библиотечных пакетов должны следовать SONAME библиотеки, которую они содержат. Двоичный библиотечный пакет называется `libnova-0.12-2`, где `libnova-0.12` — имя библиотеки, а `2` — наш ABI-номер.

Если авторы из апстрима внесли несовместимые изменения в свою библиотеку, они должны изменить номер версии SONAME, а мы должны переименовать нашу библиотеку. Любые другие пакеты, использующие наш библиотечный пакет, нужно будет перекомпилировать с новой весрией, это называется переходом (transition) и требует некоторых усилий. Надо надеяться, наш ABI-номер продолжит соответствовать SONAME апстрима, но иногда они вносят несовместимости без изменения их номера версии, а нам нужно изменить наш.

Взглянув на debian/libnova-0.12-2.instal, мы увидим, что он включает в себя два файла:

    usr/lib/libnova-0.12.so.2
    usr/lib/libnova-0.12.so.2.0.0

Вторая строчка — настоящая библиотека, с полным номером версии. Первая — символическая ссылка, указывающая на настоящую библиотеку. Программы, использующие библиотеку, как правило, будут пользоваться символической ссылкой.

`libnova-dev.install` includes all the files needed to compile a program with this library. Header files, a config binary, the `.la` libtool file and `libnova.so` which is another symlink pointing at the library, programs compiling against the library do not care about the major version number (although the binary they compile into will).

Файлы `.la` (libtool) необходимы в некоторых не-Linux системах с плохой поддержкой библиотек, но в системах Debian они обычно вызывают больше проблем, чем решают. Текущая цель Debian — убрать файлы .la (Debian goal to remove .la files), и мы должны в этом помочь.

#### Статические библиотеки

Пакет -dev также содержит `usr/lib/libnova.a`. Это статическая библиотека, альтернатива общей библиотеке. Любая программа, скомпилированная со статической библиотекой, содержит её код непосредственно в себе. Это позволяет не беспокоиться о двоичной совместимости библиотеки. Однако это также означает, что любые ошибки, в том числе уязвимости в безопасности, не будут исправлены за счёт обновления библиотеки, пока программа не будет перекомпилирована. По этой причине использовать программы со статическими библиотеками не рекомендуется.

#### Символьные файлы

When a package builds against a library the `shlibs` mechanism will add a package dependency on that library. This is why most programs will have `Depends: ${shlibs:Depends}` in `debian/control`. That gets replaced with the library dependencies at build time. However shlibs can only make it depend on the major ABI version number, `2` in our libnova example, so if new symbols get added in libnova 2.1 a program using these symbols could still be installed against libnova ABI 2.0 which would then crash.

To make the library dependencies more precise we keep `.symbols` files that list all the symbols in a library and the version they appeared in.

libnova не имеет символьного файла, так что мы можем создать его. Начните с компиляции пакета:

    $ bzr builddeb -- -nc

Опция `-nc` указывает не удалять сборочные файлы после завершения компиляции. Перейдите в каталог сборки и выполните `dpkg-gensymbols` для пакета библиотеки:

    $ cd ../build-area/libnova-0.12.2/
    $ dpkg-gensymbols -plibnova-0.12-2 > symbols.diff

Это создаст diff-файл, который вы сможете применить самостоятельно:

    $ patch -p0 < symbols.diff

Which will create a file named similar to `dpkg-gensymbolsnY_WWI` that lists all the symbols. It also lists the current package version. We can remove the packaging version from that listed in the symbols file because new symbols are not generally added by new packaging versions, but by the upstream developers:

    $ sed -i s,-0ubuntu2,, dpkg-gensymbolsnY_WWI

Теперь переместите файл туда, где он должен находиться, зафиксируйте изменения и выполните тестовую сборку:

    $ mv dpkg-gensymbolsnY_WWI ../../libnova/debian/libnova-0.12-2.symbols
    $ cd ../../libnova
    $ bzr add debian/libnova-0.12-2.symbols
    $ bzr commit -m "add symbols file"
    $ bzr builddeb

Если компиляция выполняется успешно, значит символьный файл не содержит ошибок. С выходом следующей апстрим-версии libnova вам придётся снова запустить dpkg-gensymbols, чтобы создать diff для обновления символьного файла.

#### Символьные файлы библиотек C++

C++ имеет ещё более строгие стандарты двоичной совместимости, чем C. Команда Debian Qt/KDE поддерживает несколько сценариев для работы с ними: посетите их страницу Working with symbols files, чтобы узнать как пользоваться этими сценариями.

#### Информация для дальнейшего чтения

В Debian Library Packaging Guide (автор: Junichi Uekawa) эта тема рассматривается более подробно.

### Бэкпортирование обновлений программ

Иногда вам требуется сделать новую функциональность доступной в стабильном выпуске, и это не исправление критической ошибки. Для этого есть две опции: загрузить пакет в PPA или подготовить бэкпорт.

#### Персональные архивы пакетов (PPA)

Использование PPA имеет ряд преимуществ. Это достаточно просто, вам не понадобится одобрение от кого бы то ни было, но недостаток в том, что пользователям придётся вручную подключать PPA. Это нестандартный источник приложений.

Документация по PPA на Launchpad достаточно подробна и на её освоение вам не потребуется много времени.

#### Официальные бэкпорты Ubuntu

Целью проекта Backports является предоставление пользователям новой функциональности. Из-за рисков уменьшения стабильности при портировании новшеств, бэкпорты недоступны пользователям, пока они не включат их. Поэтому бэкпорты не являются местом для исправления ошибок. Если в пакете Ubuntu обнаружена ошибка, она должна быть исправлена через обновления безопасности и стабильности.

Когда вы определите, требуется ли вам адаптировать ваши изменения для стабильного релиза, вам будет необходимо собрать и протестировать ваш пакет на данном релизе. Команда `pbuilder-dist` (из пакета `ubuntu-dev-tools`) поможет вам сделать это.

Чтобы подать заявку на бэкпорт, можно использовать утилиту `requestbackport` (также из пакета `ubuntu-dev-tools`). Она определит все промежуточные выпуски, для которых пакет также придётся бэкпортировать, покажет, какие пакеты зависят от данного, и создаст заявку. Она также включит список требуемых тестов в заявку.

## База знаний

### Связь в Ubuntu Development

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

#### Почтовые рассылки

Почтовые рассылки — это достаточно эффективный инструмент, если вы хотите обсудить идеи в команде и убедиться что вы оповестили всех, несмотря на различия в часовых поясах.

С точки зрения разработки, это наиболее важные из рассылок:

- https://lists.ubuntu.com/mailman/listinfo/ubuntu-devel-announce (только анонсы, самые важные объявления разработки попадают сюда)

- https://lists.ubuntu.com/mailman/listinfo/ubuntu-devel (главная дискуссия разработчиков Ubuntu )

- https://lists.ubuntu.com/mailman/listinfo/ubuntu-motu (обсуждения команды MOTU, получение справки по созданию пакетов)

#### Каналы IRC

Для онлайн-дискуссии подключитесь к irc.freenode.net и присоединяйтесь к любому из каналов:

- #ubuntu-devel (для главной дискуссии разработчиков)

- #ubuntu-motu (для обсуждений команды MOTU и получения помощи)

### Общий обзор каталога `debian/`

Эта статья даёт краткие пояснения к различным файлам, важным для создания пакетов Ubuntu, которые содержатся в каталоге `debian/`. Самыми важными из них являются `changelog`, `control`, `copyright`, and `rules`. Они требуются для всех пакетов. Многие дополнительные файлы в `debian/` могут использоваться для настройки и изменения поведения пакета. Некоторые из этих файлов обсуждаются в этой статье, но это далеко не полный список.

#### Файл changelog

Этот файл, как следует из его названия — это список изменений, внесённых в каждую версию. Он имеет особый формат, который показывает имя пакета, версию, дистрибутив, изменения, и кто вносил изменения в данное время. Если у вас есть ключ GPG (смотрите: Подготовка), убедитесь, что вы используете в `changelog` те же имя и адрес электронной почты, что и в вашем ключе. Ниже приведен шаблон `changelog`:

    package (version) distribution; urgency=urgency

     * change details
      - more change details
     * even more change details

    -- maintainer name <email address>[two spaces]  date

Формат (особенно даты) важен. Дата должна быть в формате RFC 5322, который можно увидеть при выполнении команды `date -R`. Для удобства, можно использовать для редактирования changelog команду `dch`. Она обновит дату автоматически.

Пункты с незначительными изменениями отмечаются дефисом «-», в то время как в важных пунктах используется звездочка «*».

Если вы создаёте пакет «с нуля», `dch --create` (`dch` находится в пакете `devscripts`) создаст для вас стандартный файл `debian/changelog`.

Вот пример файла `changelog` для hello:

    hello (2.8-0ubuntu1) trusty; urgency=low

      * New upstream release with lots of bug fixes and feature improvements.

    -- Jane Doe <packager@example.com>  Thu, 21 Oct 2013 11:12:00 -0400

Обратите внимание, что версия имеет `-0ubuntu1` добавленный к нему, это - distro версия, используемая так, чтобы упаковка могла быть обновлена (чтобы исправить ошибки, например) с новыми закачками в той же исходной версии выпуска.

Ubuntu и Debian используют немного различающиеся схемы нумерации версий пакетов, чтобы избежать конфликта пакетов с одной и той же исходной версией. Если пакет Debian был изменён в Ubuntu, к концу Debian-версии добавляется `ubuntuX` (где `X` — номер редакции в Ubuntu). Таким образом, если пакет Debian hello `2.6-1` был изменён в Ubuntu, номер версии будет `2.6-1ubuntu1`. Если пакет приложения в Debian не существует, то редакция Debian равна `0` (например, `2.6-0ubuntu1`).

Для дальнейшей информации смотрите раздел о файле changelog (Раздел 4.4) в «Debian Policy Manual».

#### Файл control

Файл `control` содержит информацию, которую использует менеджер пакетов (такой, как `apt-get`, `synaptic` или `adept`), сборочные зависимости, информацию мэйнтейнера и многое другое.

Для пакета Ubuntu `hello` файл `control` выглядит следующим образом:

    Source: hello
    Section: devel
    Priority: optional
    Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
    XSBC-Original-Maintainer: Jane Doe <packager@example.com>
    Standards-Version: 3.9.5
    Build-Depends: debhelper (>= 7)
    Vcs-Bzr: lp:ubuntu/hello
    Homepage: http://www.gnu.org/software/hello/

    Package: hello
    Architecture: any
    Depends: ${shlibs:Depends}
    Description: The classic greeting, and a good example
     The GNU hello program produces a familiar, friendly greeting. It
     allows non-programmers to use a classic computer science tool which
     would otherwise be unavailable to them. Seriously, though: this is
     an example of how to do a Debian package. It is the Debian version of
     the GNU Project's `hello world' program (which is itself an example
     for the GNU Project).

Первый абзац описывает исходный пакет, включая список пакетов, требуемых для сборки данного пакета из исходного кода, в поле `Build-Depends`. Он также содержит некоторую метаинформацию, такую как имя мэйнтейнера, версию Debian Policy, с которой компилируется пакет, местоположение репозитория управления версиями и домашнюю страницу апстрима.

Обратите внимание, что в Ubuntu мы указываем в поле `Maintainer` общий адрес, поскольку кто угодно может внести изменения в любой пакет (в отличие от Debian, где изменение пакетов обычно доступно лишь определённому человеку или команде). Обычно в пакетах Ubuntu в поле `Maintainer` указывается `Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>`. Если это поле было изменено, старое значение сохраняется в поле `XSBC-Original-Maintainer`. Это делается автоматически сценарием `update-maintainer` из пакета `ubuntu-dev-tools`. Дополнительную информацию смотрите в Debian Maintainer Field spec на вики-страницах Ubuntu.

Каждый дополнительный абзац описывает бинарный пакет, который будет создан.

Для получения дополнительной информации смотрите раздел о файле control (Глава 5) в «Debian Policy Manual».

#### Файл copyright

Этот файл показывает информацию о копирайте на исходный код upstream и файлы, необходимые для сборки пакетов. Ubuntu и Debian Policy (Section 12.5) требуют, чтобы каждый пакет устанавливал сжатую версию информации о копирайте и лицензии в `/usr/share/doc/$(package_name)/copyright`.

Как правило, информацию об авторских правах можно найти в файле `COPYING` в каталоге с исходным кодом программы. Этот файл должен включать такую информацию, как имена автора и упаковщика, URL, из которого получен источник, строку со значком копирайта с указанием года и владельца авторских прав, а также сам текст авторского права. Шаблон для примера:

    Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
    Upstream-Name: Hello
    Source: ftp://ftp.example.com/pub/games

    Files: *
    Copyright: Copyright 1998 John Doe <jdoe@example.com>
    License: GPL-2+

    Files: debian/*
    Copyright: Copyright 1998 Jane Doe <packager@example.com>
    License: GPL-2+

    License: GPL-2+
     This program is free software; you can redistribute it
     and/or modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
     version 2 of the License, or (at your option) any later
     version.
     .
     This program is distributed in the hope that it will be
     useful, but WITHOUT ANY WARRANTY; without even the implied
     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the GNU General Public License for more
     details.
     .
     You should have received a copy of the GNU General Public
     License along with this package; if not, write to the Free
     Software Foundation, Inc., 51 Franklin St, Fifth Floor,
     Boston, MA  02110-1301 USA
     .
     On Debian systems, the full text of the GNU General Public
     License version 2 can be found in the file
     `/usr/share/common-licenses/GPL-2'.

Этот пример соответствует формату Machine-readable debian/copyright. Мы рекомендуем вам также использовать этот формат.

#### Файл rules

Последний файл, который мы рассмотрим, это `rules`. Он выполняет всю работу по сборке нашего пакета. Это Makefile, в котором есть функции компиляции программы, её установки и создания `.deb`-пакета из установленных файлов. В нём есть также функция очистки файлов сборки, которая удаляет всё, кроме собственно пакета исходного кода.

Вот упрощённый пример файла rules, созданного `dh_make` (который можно найти в пакете `dh-make`):

    #!/usr/bin/make -f
    # -*- makefile -*-

    # Uncomment this to turn on verbose mode.
    #export DH_VERBOSE=1

    %:
           dh  $@

Давайте рассмотрим этот файл внимательнее. На каждом этапе сборки `debian/rules` вызывается с аргументом, который передаётся `/usr/bin/dh`, который, в свою очередь, вызывает необходимые команды `dh_*`.

`dh` запускает последовательность команд debhelper. Поддерживаемые последовательности соответствуют целям файла `debian/rules`: «build», «clean», «install», «binary-arch», «binary-indep» и «binary». Чтобы увидеть, какие команды выполняются в каждой цели, наберите:

    $ dh binary-arch --no-act

Командам из последовательности `binary-indep` передаётся аргумент `-i`, чтобы они затрагивали только архитектурно-независимые пакеты, а командам из последовательности `binary-arch` — аргумент `-a`, чтобы онм затрагивали только архитектурно-зависимые пакеты.

Каждая команда debhelper при её успешном выполненении делает запись в журнале `debian/package.debhelper.log` (который затем удаляет dh_clean.) Таким образом dh может определить, какие команды уже были выполнены и для каких пакетов, что помогает избежать повторного выполнения этих команд.

При каждом запуске `dh` он изучает журнал, находит добавленные последними команды, которые относятся к указанной последовательности. Затем он продолжает выполнение со следующей команды в этой последовательности. Опции `--until`, `--before`, `--after` и `--remaining` могут изменить это поведение.

Если в `debian/rules` есть функция с именем, похожим на `override_dh_команда`, то вместо данной команды `dh` выполнит данную функцию. Эта функция может запустить ту же команду с другими аргументами, или же совершенно другую команду. (Замечание: для использования этой функциональности при сборке требуется пакет debhelper версии не менее 7.0.50).

За дополнительными примерами обратитесь к `/usr/share/doc/debhelper/examples/` и `man dh`. Смотрите также раздел о файле rules (Раздел 4.9) в «Debian Policy Manual».

#### Дополнительные файлы

##### Файл install

Файл `install` используется `dh_install` для установки файлов в двоичный пакет. Он имеет два стандартных варианта использования:

- Для установки в ваш пакет файлов, не установленных оригинальной системой сборки.

- Разделение одного большого пакета источника на несколько бинарных пакетов.

В первом случае файл `install` должен содержать одну строку для каждого устанавливаемого файла, указывающую как файл, так и установочный каталог. Например, следующий файл `install` установит сценарий `foo` из корневого каталога пакета исходного кода в `usr/bin` и desktop-файл из каталога `debian` в `usr/share/applications`:

    foo usr/bin
    debian/bar.desktop usr/share/applications

Если пакет исходного кода производит несколько двоичных пакетов, `dh` установит файлы в `debian/tmp` вместо установки непосредственно в `debian/<пакет>`. Файлы, установленные в `debian/tmp` затем можно переместить в отдельные двоичные пакеты с помощью нескольких файлов `$имя_пакета.install`. Это часто делается, чтобы разбить большое количество не зависящих от архитектуры данных из зависящих от архитектуры пакетов в пакеты `Architecture: all`. В этом случае нужно указать только имена устанавливаемых файлов (или каталогов), без установочного каталога. Например, `foo.install`, содерщащий только зависящие от архитектуры файлы, может выглядеть наподобие:

    usr/bin/
    usr/lib/foo/*.so

В то время как `foo-common.install`, содержащий только не зависящие от архитектуры файлы, может выглядеть так:

    /usr/share/doc/
    /usr/share/icons/
    /usr/share/foo/
    /usr/share/locale/

Будут созданы два двоичных пакета: `foo` и `foo-common`. Для обоих требуется их собственный абзац в `debian/control`.

Для дополнительных подробностей смотрите `man dh_install` и раздел о файле install (Раздел 5.11) в «Debian New Maintainers’ Guide».

##### Файл watch

Файл `debian/watch` позволяет автоматически проверять наличие новых версий в апстриме с помощью инструмента `uscan` из пакета `devscripts`. Первой строкой файла watch должна быть версия формата (3 на момент написания этого руководства), а следующий строки содержат любые URL для анализа. Например:

    version=3

    http://ftp.gnu.org/gnu/hello/hello-(.*).tar.gz

Запуск `uscan` в корневом каталоге исходников сравнит номер апстрим-версии в `debian/changelog` с последней доступной в апстриме версией. Если в апстриме найдена новая версия, она будет автоматически загружена. Например:

    $ uscan
    hello: Newer version (2.7) available on remote site:
      http://ftp.gnu.org/gnu/hello/hello-2.7.tar.gz
      (local version is 2.6)
    hello: Successfully downloaded updated package hello-2.7.tar.gz
        and symlinked hello_2.7.orig.tar.gz to it

Если ваши тарболы «живут» на Launchpad, файл `debian/watch` будет немного более сложным (о том, почему это так, смотрите Question 21146 и Bug 231797). В этом случае используйте что-то наподобие:

    version=3
    https://launchpad.net/flufl.enum/+download http://launchpad.net/flufl.enum/.*/flufl.enum-(.+).tar.gz

Дополнительные сведения смотрите в `man uscan` и в разделе о файле watch (Раздел 4.11) «Debian Policy Manual».

Список пакетов, для которых файл `watch` сообщает о том, что они не синхронизированы с апстримом, смотрите Ubuntu External Health Status.

##### Файл source/format

Этот файл указывает формат пакета исходного кода. Он должен содержать одну строку, показывающую выбранный формат:

- `3.0 (native)` для «родных» пакетов Debian (апстрим-версия отсутствует)

- `3.0 (quilt)` для пакетов с отдельным тарболом из апстрима

- `1.0` для пакетов, желающих явно указать формат по умолчанию

В настоящее время по умолчанию выбирается формат пакета исходного кода 1.0, если этот файл отсутствует. В файле source/format можно указать его явно. Если вы не используете этот файл для указания формата исходного кода, Lintian выдаст предупреждение об отстутствии файла. Это чисто информационное предупреждение и его можно без опасений проигнорировать.

Рекомендуется использовать более новый формат 3.0. Он предоставляет некоторые новые возможности:

- Поддержка дополнительных форматов сжатия: bzip2, lzma и xz

- Поддержка нескольких архивов с оригинальным исходным кодом

- Необязательно перепаковывать архив с оригинальным исходным кодом, чтобы удалить директорию `debian`.

- Специфичные для Debian изменения теперь хранятся не в одном файле .diff.gz, а в виде нескольких патчей, совместимых с quilt, в каталоге `debian/patches/`

http://wiki.debian.org/Projects/DebSrc3.0 подытоживает дополнительную информацию, касающуюся перехода на формат пакетов исходого кода 3.0.

Для получения дополнительных подробностей смотрите `man dpkg-source` и раздел о файле source/format (Раздел 5.21) в «Debian New Maintainers’ Guide».

#### Дополнительные ресурсы

В дополнение к ссылкам на «Debian Policy Manual» в каждом вышеприведённом разделе, «Debian New Maintainers’ Guide» содержит более подробное описание каждого файла. Глава 4, «Required files under the debian directory» описывает файлы control, changelog, copyright и rules. В Главе 5, «Other files under the debian directory» описаны дополнительные файлы, которые могут быть использованы.

### autopkgtest: Автоматическое тестирование пакетов

Документ DEP 8 specification определяет способ лёгкой интеграции автоматического тестирования в пакеты. Всё, что необходимо сделать для добавления теста к пакету, это:

- добавить следующую строчку к разделу Source в `debian/control`:

      XS-Testsuite: autopkgtest

- добавить файл `debian/tests/control`, который определяет требования к тестовому окружению,

- добавить тесты в `debian/tests`.

#### Требования к тестовому окружению

В файле `debian/tests/control` вы можете указать требования к тестовому окружению. Например, можно задать список необходимых для тестирования пакетов, указать, требуется ли восстановление окружения после тестов, и нужны ли привилегии `root`. Все доступные опции указаны в DEP 8 specification.

Сейчас мы рассмотрим пакет исходного кода `glib2.0`. В очень простом случае он будет выглядеть так:

    Tests: build
    Depends: libglib2.0-dev, build-essential

Это будет означать, что для теста `debian/tests/build` требуются пакеты `libglib2.0-dev` и `build-essential`.

Примечание

В поле `Depends` можно указать `@`, если вы хотите установки всех бинарных пакетов, собранных из рассматриваемого пакета исходного кода.

#### Настоящие тесты

Тест, соответствующий рассмотренному выше примеру, будет выглядеть так:

    #!/bin/sh
    # autopkgtest check: Build and run a program against glib, to verify that the
    # headers and pkg-config file are installed correctly
    # (C) 2012 Canonical Ltd.
    # Author: Martin Pitt <martin.pitt@ubuntu.com>

    set -e

    WORKDIR=$(mktemp -d)
    trap "rm -rf $WORKDIR" 0 INT QUIT ABRT PIPE TERM
    cd $WORKDIR
    cat <<EOF > glibtest.c
    #include <glib.h>

    int main()
    {
        g_assert_cmpint (g_strcmp0 (NULL, "hello"), ==, -1);
        g_assert_cmpstr (g_find_program_in_path ("bash"), ==, "/bin/bash");
        return 0;
    }
    EOF

    gcc -o glibtest glibtest.c `pkg-config --cflags --libs glib-2.0`
    echo "build: OK"
    [ -x glibtest ]
    ./glibtest
    echo "run: OK"

Здесь небольшая программа на языке C копируется во временную директорию, затем компилируется с использованием системных библиотек (с использованием флагов и путей к библиотекам, определённых через `pkg-config`). Затем запускается скомпилированный файл, который запускает несколько основных функций glib.

Несмотря на то, что тест небольшой и очень простой, он тестирует некоторое количество основных компонентов системы. Это позволит заранее выявить критические ошибки, если они возникнут.

#### Выполнение теста

Тестовый скрипт может быть легко запущен сам по себе, но если вы хотите убедиться, что тестовое окружение правильно настроено, вы можете использовать для запуска скрипт `adt-run` из пакета `autopkgtest`. Самый простой способ — выполнение этой команды в дереве исходного кода:

    sudo adt-run --no-built-binaries --built-tree=. --- adt-virt-null

Минус данного подхода — то, что он позволяет запустить тесты на локальной машине, но не даёт никаких гарантий того, что он будет работать в минимальном окружении. Например, будет сложно убедиться, что правильно указаны все нужные зависимости. С lp:auto-package-testing, у нас есть более продвинутые средства тестирования. Они используют «чистую» виртуальную машину для запуска тестов. Чтобы воспользоваться этими средствами, сперва нужно установить необходимые зависимости:

    sudo apt-get install qemu-utils kvm eatmydata

Затем получите исходный код с Launchpad:

    bzr branch lp:auto-package-testing
    cd auto-package-testing

And provision a Trusty AMD64 system:

    ./bin/prepare-testbed -r trusty amd64

This command will create a pristine Trusty AMD64 VM from a cloud image. To run the tests, simply run:

    ./bin/run-adt-test -r trusty -a amd64 \
        -S file:///tmp/glib2.0-2.35.7/ glib2.0

This would use the source package in `/tmp/glib2.0-2.35.7/` and run the tests from this tree against the package `glib2.0` from the archive. The option `-S` also supports schemes for bzr, git, and apt sources. If you only specify a source with `-S` but do not specify a package name, this will instead build the branch and install the binaries from that build; this is useful if you want to run tests on a newer version than the one packaged in Ubuntu, or the package is not in Ubuntu at all. If use the `-k` flag you can log into the virtual machine after the tests were run. This makes it very easy to debug issues.

Больше ценной информации по опциям тестирования можно найти в auto-package-testing documentation.

#### Дальнейшие примеры

Этот список не полон, но может помочь вам получить представление о том, как автоматические тесты реализованы, и как они используются в Ubuntu.

- Тесты libxml2 tests очень похожи. Они также производят тестовую сборку небольшого куска C-кода и запускают его.

- Тесты gtk+3.0 tests также производят проверку компиляции/линковки/запуска в тесте «build». Есть также дополнительный тест «python3-gi», который проверяет, что библиотека GTK может быть использована через механизм интроспекции.

- В ubiquity tests, выполняются тесты, предоставленные разработчиками.

- Тесты gvfs tests тестируют различную функциональность gvfs и представляют интерес, так как эмулируют использование CD, Samba, DAV и других компонентов.

#### Инфраструктура Ubuntu

Packages which have `autopkgtest` enabled will have their tests run whenever they get uploaded or any of their dependencies change. The output of automatically run autopkgtest tests can be viewed on the web and is regularly updated.

Несмотря на то, что у Debian пока нет инфраструктуры автоматического тестирования, тесты следует отправлять в Debian, так как DEP-8 — спецификация Debian, и разработчики и пользователи Debian могут запускать тесты вручную.

Пакеты Debian с заголовком `XS-Testsuite`, скопированные в Ubuntu, также будут добавлены в список тестируемых пакетов.

#### Добавление теста в Ubuntu

Процесс добавления и отправки autopkgtest-теста для пакета похож на процесс исправления ошибки в Ubuntu. Необходимо просто:

- выполните `bzr branch ubuntu:<имя_пакета>`,

- включите тесты в `debian/control`,

- создайте директорию `debian/tests`,

- создайте `debian/tests/control`, следуя требованиям DEP 8 Specification,

- добавьте ваши тесты в `debian/tests`,

- закрепить ваши изменения, отправить их на Launchpad, создать заявку на слияние (merge proposal) и дождаться, пока она будет рассмотрена (как и любое другое изменение пакета).

#### Чем вы можете помочь

Команда инженеров Ubuntu создала список необходимых тестов (list of required test-cases), где пакеты, которым требуются тесты, разбиты на различные категории. Там вы можете посмотреть на примеры таких тестов и сами заняться каким-то из них.

Если у вас возникнут какие-то проблемы, зайдите на #ubuntu-quality IRC channel, на котором есть готовые помочь вам разработчики.

### Получение исходного кода

#### URL пакетов исходного кода

Bazaar предоставляет несколько очень удобных сокращений для доступа к веткам исходного кода с Launchpad для пакетов как Ubuntu, так и Debian.

Чтобы сослаться на ветки исходного кода, используйте:

    ubuntu:package

где package — имя пакета, который вам нужен. Этот URL ссылается на пакеты в текущей разрабатываемой версии Ubuntu. Чтобы сослаться на ветку Tomboy в разрабатываемой версии, нужно использовать:

    ubuntu:tomboy

To refer to the version of a source package in an older release of Ubuntu, just prefix the package name with the release’s code name. E.g. to refer to Tomboy’s source package in Saucy use:

    ubuntu:saucy/tomboy

Поскольку первые буквы кодовых имён не повторяются, можно сократить имя выпуска:

    ubuntu:s/tomboy

Похожую схему можно использовать для доступа к веткам исходного кода в Debian, хотя здесь нет сокращений для имён выпусков Debian. Чтобы получить доступ к ветке Tomboy в текущем разрабатываемом выпуске Debian, используйте:

    debianlp:tomboy

and to access Tomboy in Debian Wheezy use:

    debianlp:wheezy/tomboy

#### Получение исходного кода

Каждый пакет исходного кода в Ubuntu связан с веткой исходного кода на Launchpad. Launchpad автоматически обновляет эти ветки исходного кода, хотя процесс не полностью «защищён от дурака».

Есть несколько вещей, которые мы сделаем в первую очередь, чтобы сделать рабочий процесс более эффективным впоследствии. После того, как вы освоите процесс, вы узнаете, когда имеет смысл пропускать эти этапы.

##### Creating a shared repository

Say that you want to work on the Tomboy package, and you’ve verified that the source package is named `tomboy`. Before actually branching the code for Tomboy, create a shared repository to hold the branches for this package. The shared repository will make future work much more efficient.

Воспользуйтесь для этого командой bzr init-repo, передав ей имя каталога, который вы хотите использовать:

    $ bzr init-repo tomboy

Вы увидите, что в вашей текущей рабочей области создан каталог tomboy. Перейдите в него для продолжения работы:

    $ cd tomboy

##### Получение ветки trunk

Мы используем команду bzr branch для создания локальной ветки пакета. Целевой каталог назовём tomboy.dev, просто потому, что так легче запомнить:

    $ bzr branch ubuntu:tomboy tomboy.dev

Каталог tomboy.dev представляет собой версию Tomboy в разрабатываемой версии Ubuntu, и вы всегда можете перейти в этот каталог и выполнить bzr pull для получения любых будущих обновлений.

##### Проверка актуальности версии

When you do your `bzr branch` you will get a message telling you if the packaging branch is up to date. For example:

    $ bzr branch ubuntu:tomboy
    Most recent Ubuntu version: 1.8.0-1ubuntu1.2
    Packaging branch status: CURRENT
    Branched 86 revisions.

Occasionally the importer fails and packaging branches do not match what is in the archive. A message saying:

    Packaging branch status: OUT-OF-DATE

means the importer has failed. You can find out why on http://package-import.ubuntu.com/status/ and file a bug on the UDD project to get the issue resolved.

##### Tar-файл из апстрима

Получить tar из апстрима можно с помощью:

    bzr get-orig-source

This will try a number of methods to get the upstream tar, firstly by recreating it from the `upstream-x.y` tag in the bzr archive, then by downloading from the Ubuntu archive, lastly by running `debian/rules get-orig-source`. The upstream tar will also be recreated when using bzr to build the package:

    bzr builddeb

The builddeb plugin has several configuration options.

##### Получение ветки для определённого выпуска

When you want to do something like a stable release update (SRU), or you just want to examine the code in an old release, you’ll want to grab the branch corresponding to a particular Ubuntu release. For example, to get the Tomboy package for Quantal do:

    $ bzr branch ubuntu:m/tomboy quantal

##### Импорт пакета исходного кода Debian

If the package you want to work on is available in Debian but not Ubuntu, it’s still easy to import the code to a local bzr branch for development. Let’s say you want to import the newpackage source package. We’ll start by creating a shared repository as normal, but we also have to create a working tree to which the source package will be imported (remember to cd out of the tomboy directory created above):

    $ bzr init-repo newpackage
    $ cd newpackage
    $ bzr init debian
    $ cd debian
    $ bzr import-dsc http://ftp.de.debian.org/debian/pool/main/n/newpackage/newpackage_1.0-1.dsc

As you can see, we just need to provide the remote location of the dsc file, and Bazaar will do the rest. You’ve now got a Bazaar source branch.

### Работа с пакетом

Once you have the source package branch in a shared repository, you’ll want to create additional branches for the fixes or other work you plan to do. You’ll want to base your branch off the package source branch for the distro release that you plan to upload to. Usually this is the current development release, but it may be older releases if you’re backporting to an SRU for example.

#### Branching for a change

The first thing to do is to make sure your source package branch is up-to-date. It will be if you just checked it out, otherwise do this:

    $ cd tomboy.dev
    $ bzr pull

Any updates to the package that have uploaded since your checkout will now be pulled in. You do not want to make changes to this branch. Instead, create a branch that will contain just the changes you’re going to make. Let’s say you want to fix bug 12345 for the Tomboy project. When you’re in the shared repository you previously created for Tomboy, you can create your bug fix branch like this:

    $ bzr branch tomboy.dev bug-12345
    $ cd bug-12345

Now you can do all my work in the `bug-12345` directory. You make changes there as necessary, committing as you go along. This is just like doing any kind of software development with Bazaar. You can make intermediate commits as often as you like, and when your changes are finished, you will use the standard `dch` command (from the `devscripts` package):

    $ dch -i

Эта команда откроет редактор и добавит запись в файл debian/changelog.

При добавлении записи в `debian/changelog` вы должны включить тег исправления ошибки, который указывает, для какого сообщения об ошибке на Launchpad вы создали исправление. Этот текстовый тег имеет вполне определённый формат: `LP: #12345`. Пробел между `:` и `#` обязателен и, разумеется, вы должны указать номер реально существующей ошибке, которую вы исправляете. Ваш `debian/changelog` может выглядеть примерно так:

    tomboy (1.12.0-1ubuntu3) trusty; urgency=low

      * Don't fubar the frobnicator. (LP: #12345)

     -- Bob Dobbs <subgenius@example.com>  Mon, 10 Sep 2013 16:10:01 -0500

Commit with the normal:

    bzr commit

A hook in bzr-builddeb will use the debian/changelog text as the commit message and set the tag to mark bug #12345 as fixed.

Это работает только с bzr-builddeb 2.7.5 и bzr 2.4, для более старых версий используйте `debcommit`.

#### Сборка пакета

Along the way, you’ll want to build your branch so that you can test it to make sure it does actually fix the bug.

In order to build the package you can use the `bzr builddeb` command from the `bzr-builddeb` package. You can build a source package with:

    $ bzr builddeb -S

(`bd` — это псевдоним для `builddeb`.) Вы можете оставить пакет неподписанным, добавив к команде `-- -uc -us`.

Вы можете также использовать свои обычные инструменты, если они способны убирать каталоги `.bzr` из пакета, например:

    $ debuild -i -I

If you ever see an error related to trying to build a native package without a tarball, check to see if there is a `.bzr-builddeb/default.conf` file erroneously specifying the package as native. If the changelog version has a dash in it, then it’s not a native package, so remove the configuration file. Note that while `bzr builddeb` has a `--native` switch, it does not have a `--no-native` switch.

После того, как вы получили пакет исходного кода, можно собрать его как обычно, с помощью `pbuilder-dist` (или `pbuilder`, или sbuild).

### Seeking Review and Sponsorship

One of the biggest advantages to using the UDD workflow is to improve quality by seeking review of changes by your peers. This is true whether or not you have upload rights yourself. Of course, if you don’t have upload rights, you will need to seek sponsorship.

Once you are happy with your fix, and have a branch ready to go, the following steps can be used to publish your branch on Launchpad, link it to the bug issue, and create a merge proposal for others to review, and sponsors to upload.

#### Выгрузка на Launchpad

Ранее мы показали вам, как связать вашу ветку с ошибкой, используя команды `dch` и `bzr commit`. Однако ветка и ошибка в действительности не будут связаны, пока вы не выгрузите ветку на Launchpad командой push.

Создавать ссылку на ошибку для каждого вашего изменения не обязательно, но если вы исправляете ошибки, для которых имеется отчёт об ошибке, то ссылки на этот отчёт могут быть полезны.

Общий формат URL, на который вы должны выгрузить свою ветку, имеет следующий вид:

    lp:~<user-id>/ubuntu/<distroseries>/<package>/<branch-name>

For example, to push your fix for bug 12345 in the Tomboy package for Trusty, you’d use:

    $ bzr push lp:~subgenius/ubuntu/trusty/tomboy/bug-12345

Последний компонент пути в этом примере выбран произвольно, укажите вместо него реально существующую ошибку.

Но обычно этого недостаточно, чтобы разработчики Ubuntu проверили ваше изменение и взяли на себя поручительство над ним. Вам нужно отправить предложение слияния (merge proposal).

Для этого откройте страницу ошибки в браузере, например:

    $ bzr lp-open

Если сделать это не удалось, вы можете использовать:

    $ xdg-open https://code.launchpad.net/~subgenius/ubuntu/trusty/tomboy/bug-12345

где большая часть URL совпадает с тем URL, который вы указывали в команде bzr push. На этой странице вы увидите ссылку Propose for merging into another branch. Наберите описание вашего изменения в поле Initial Comment. Затем щёлкните Propose Merge, чтобы завершить процесс.

Merge proposals to package source branches will automatically subscribe the ~ubuntu-branches team, which should be enough to reach an Ubuntu developer who can review and sponsor your package change.

#### Создание debdiff

Как было указано выше, некоторые поручители предпочитают проверять debdiff, прикреплённый к отчёту об ошибке, вместо предложения слияния. Если вас попросили включить debdiff, вы можете создать его следующим образом (из вашей ветки bug-12345):

    $ bzr diff -rbranch:../tomboy.dev

Другой способ — открыть предложение слияния и загрузить diff.

Вы должны убедиться, что diff-файл содержит ожидаемые вами изменения, не больше и не меньше. Дайте ему подходящее имя, например, `foobar-12345.debdiff` и прикрепите к отчёту об ошибке.

#### Работа с обратной связью от поручителей

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

    $ bzr commit

Now when you push your branch to Launchpad, Bazaar will remembered where you pushed to, and will update the branch on Launchpad with your latest commits. All you need to do is:

    $ bzr push

You can then reply to the merge proposal review email explaining what you changed, and asking for re-review, or you can reply on the merge proposal page in Launchpad.

Note that if you are sponsored via a debdiff attached to a bug report you need to manually update by generating a new diff and attaching that to the bug report.

#### Ожидание

Разработчики Ubuntu составили расписание людей (так называемых “patch pilots”), которые регулярно проверяют очередь поручительства и предоставляют обратную связь по вопросам работы с ветками и патчами. Но, даже несмотря на это, может пройти несколько дней, пока вы получите ответ. Это зависит от их занятости, от состояния заморозки текущей версии и других факторов.

Если вы не получаете ответа в течение долгого времени, подключитесь к каналу #ubuntu-devel на irc.freenode.net и найдите кого-нибудь, кто может вам помочь.

Чтобы узнать больше о процессе поручительства, прочтите также нашу вики-документацию: https://wiki.ubuntu.com/SponsorshipProcess

### Uploading a package

После того, как предложение слияния проверено и утверждено, вы можете захотеть выгрузить свой пакетy либо в архив дистрибутива (если у вас есть соответствующие права), либо в ваш персональный архив пакетов (Personal Package Archive, или PPA). Вам также может понадобиться это сделать, если вы являетесь взяли на себя поручительство над чьими-нибудь изменениями.

#### Выгрузка изменений, сделанных вами

When you have a branch with a change that you would like to upload you need to get that change back on to the main source branch, build a source package, and then upload it.

First, you need to check that you have the latest version of the package in your checkout of the development package trunk:

    $ cd tomboy/tomboy.dev
    $ bzr pull

This pulls in any changes that may have been committed while you were working on your fix. From here, you have several options. If the changes on the trunk are large and you feel should be tested along with your change you can merge them into your bug fix branch and test there. If not, then you can carry on merging your bug fix branch into the development trunk branch. As of bzr 2.5 and bzr-builddeb 2.8.1, this works with just the standard `merge` command:

    $ bzr merge ../bug-12345

Для более старых версий bzr можно использовать взамен команду `merge-package`:

    $ bzr merge-package ../bug-12345

Эта команда сольёт два дерева и, возможно, сообщит о конфликтах, которые вам надо будет разрешить вручную.

Далее следует убедиться в правильности содержимого `debian/changelog`, то есть, что там правильно указан дистрибутив, номер версии и т.п.

Once that is done you should review the change you are about to commit with `bzr diff`. This should show you the same changes as a debdiff would before you upload the source package.

Следующий шаг — собрать и протестировать изменённый пакет исходного кода, как вы это обычно делаете:

    $ bzr builddeb -S

When you’re finally happy with your branch, make sure you’ve committed all your changes, then tag the branch with the changelog’s version number. The `bzr tag` command will do this for you automatically when given no arguments:

    $ bzr tag

This tag will tell the package importer that what is in the Bazaar branch is the same as in the archive.

Теперь вы можете выгрузить командой push изменения обратно на Launchpad:

    $ bzr push ubuntu:tomboy

(Измените место назначения, если вы выгружаете SRU или что-то подобное.)

Вам нужен один последний шаг, чтобы отправить свои изменения в Ubuntu или ваш PPA: вам нужно загрузить с помощью `dput` пакет исходного кода в соответствующее место. Например, чтобы загрузить изменения в PPA, сделайте следующее:

    $ dput ppa:imasponsor/myppa tomboy_1.5.2-1ubuntu5_source.changes

или, если у вас есть права загрузки в основной архив:

    $ dput tomboy_1.5.2-1ubuntu5_source.changes

You are now free to delete your feature branch, as it is merged, and can be re-downloaded from Launchpad if needed.

#### Поручительство над изменением

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

    $ bzr merge lp:~subgenius/ubuntu/trusty/tomboy/bug-12345

If there are lots of merge conflicts you would probably want to ask the contributor to fix them up. See the next section to learn how to cancel a pending merge.

But if the changes look good, commit and then follow the rest of the uploading process:

    $ bzr commit --author "Bob Dobbs <subgenius@example.com>"

#### Отмена выгрузки

At any time before you dput the source package you can decide to cancel an upload and revert the changes:

    $ bzr revert

You can do this if you notice something needs more work, or if you would like to ask the contributor to fix up conflicts when sponsoring something.

#### Поручительство над чем-нибудь и внесение своих собственных изменений

Если вы являетесь поручителем над чьей-нибудь работой, но хотите дополнить её несколькими собственными изменениями, то вы можете сначала выполнить слияние их работы в отдельную ветку.

If you already have a branch where you are working on the package and you would like to include their changes, then simply run the `bzr merge` from that branch, instead of the checkout of the development package. You can then make the changes and commit, and then carry on with your changes to the package.

If you don’t have an existing branch, but you know you would like to make changes based on what the contributor provides then you should start by grabbing their branch:

    $ bzr branch lp:~subgenius/ubuntu/trusty/tomboy/bug-12345

then work in this new branch, and then merge it in to the main one and upload as if it was your own work. The contributor will still be mentioned in the changelog, and Bazaar will correctly attribute the changes they made to them.

### Получение последних изменений

Если кто-нибудь ещё внёс изменения в пакет, вам может понадобиться получить эти изменения в ваши копии веток пакета.

#### Обновление вашей основной ветки

Обновить вашу копию ветки, соответствующей пакету в определённом выпуске, очень просто: выполните bzr pull из соответствующего каталога:

    $ cd tomboy/tomboy.dev
    $ bzr pull

This works wherever you have a checkout of a branch, so it will work for things like branches of saucy, trusty-proposed, etc.

#### Получение последних изменений в ваши рабочие ветки

Once you have updated your copy of a distroseries branch, then you may want to merge this in to your working branches as well, so that they are based on the latest code.

You don’t have to do this all the time though. You can work on slightly older code with no problems. The disadvantage would come if you were working on some code that someone else changed. If you are not working on the latest version then your changes may not be correct, and may even produce conflicts.

The merge does have to be done at some point though. The longer it is left, the harder may be, so doing it regularly should keep each merge simple. Even if there are many merges the total effort would hopefully be less.

To merge the changes you just need to use `bzr merge`, but you must have committed your current work first:

    $ cd tomboy/bug-12345
    $ bzr merge ../tomboy.dev

Any conflicts will be reported, and you can fix them up. To review the changes that you just merged use `bzr diff`. To undo the merge use `bzr revert`. Once you are happy with the changes then use `bzr commit`.

#### Referring to versions of a package

You will often think in terms of versions of a package, rather than the underlying Bazaar revision numbers. bzr-builddeb provides a revision specifier that makes this convenient. Any command that takes a `-r` argument to specify a revision or revision range will work with this specifier, e.g. `bzr log`, `bzr diff`, and so on. To view the versions of a package, use the `package:` specifier:

    $ bzr diff -r package:0.1-1..package:0.1-2

Эта команда покажет вам различия между версиями пакета 0.1-1 и 0.1-2.

### Слияние — обновления из Debian и апстрима

Слияние — это одна из сильнейших сторон Bazaar, и мы часто выполняем его в процессе разработки Ubuntu. Слияние может быть выполнено с обновлениями из Debian, из нового выпуска в апстриме и от других разработчиков Ubuntu. Сделать это в Bazaar очень просто, всё основано на команде `bzr merge` [1].

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

    $ bzr status

If that reports anything then you will either have to commit the changes, revert them, or shelve them to come back to later.

#### Слияние из Debian

Next run `bzr merge` passing the URL of the branch to merge from. For example, to merge from the version of the package in Debian Unstable run [2]:

    $ bzr merge lp:debian/tomboy

This will merge the changes since the last merge point and leave you with changes to review. This may cause some conflicts. You can see everything that the `merge` command did by running:

    $ bzr status
    $ bzr diff

If conflicts are reported then you need to edit those files to make them look how they should, removing the conflict markers. Once you have done this, run:

    $ bzr resolve
    $ bzr conflicts

This will resolve any conflicted files that you fixed, and then tell you what else you have to deal with.

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

    $ dch -i
    $ bzr commit

как было описано выше.

Однако перед фиксацией всегда желательно проверить все изменения, сделанные в Ubuntu, выполнив:

    $ bzr diff -r tag:0.6.10-5

Эта команда покажет различия между версиями в Debian (0.6.10-5) и Ubuntu (0.6.10-5ubuntu1). Подобным же способом вы можете выполнить сравнение с любыми другими версиями. Чтобы увидеть все доступные версии, выполните:

    $ bzr tags

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

If you are going to build the source package from this merged branch, you would use the `-S` option to the `bd` command. One other thing you’ll want to consider is also using the `--package-merge` option. This will add the appropriate `-v` and `-sa` options to the source package so that all the changelog entries since the last Ubuntu change will be included in your `_source.changes` file. For example:

    $ bzr builddeb -S --package-merge

#### Слияние с новой версией из апстрима

When upstream releases a new version (or you want to package a snapshot), you have to merge a tarball into your branch.

Это делается командой `bzr merge-upstream`. Если в вашем пакете имеется файл `debian/watch` с правильным содержимым, то из каталога ветки, в которую вы собираетесь слить изменения, просто наберите:

    $ bzr merge-upstream

Команда загрузит тарбол и сольёт его в вашу ветку, автоматически добавив запись в `debian/changelog`. `bzr-builddeb` просматривает файл `debian/watch`, чтобы определить местоположение тарбола из апстрима.

Если у вас отсутствует файл `debian/watch`, то вам нужно вручную указать местоположение тарбола из апстрима и версию:

    $ bzr merge-upstream --version 1.2 http://example.org/releases/foo-1.2.tar.gz

Опция `--version` используется для указания версии апстрима, из которой выполняется слияние, поскольку команда не способна (пока) узнать её самостоятельно.

Последний параметр — это местоположение тарбола, на который выполняется обновление: это может быть путь в локальной файловой системе, http, ftp, sftp или другой URI, как показано в примере. Команда автоматически загрузит тарбол для вас, переименует его соответствующим образом и, если требуется, преобразует в `.gz`.

Команда `merge-upstream` сообщит либо о своём удачном завершении, либо о том, что имеются конфликты. В любом случае у вас будет возможность проверить изменения перед их фиксацией обычным способом.

If you are merging an upstream release into an existing Bazaar branch that has not previously used the UDD layout, `bzr merge-upstream` will fail with an error that the tag for the previous upstream version is not available; the merge can’t be completed without knowing what base version to merge against. To work around this, create a tag in your existing repository for the last upstream version present there; e.g., if the last Ubuntu release was 1.1-0ubuntu3, create the tag upstream-1.1 pointing to the bzr revision you want to use as the tip of the upstream branch.

[1] | Для работы с командой `merge` вам понадобятся более новые версии `bzr` и `bzr-builddeb`. Используйте версии из Ubuntu 12.04 (Precise) или разрабатываемые версии из PPA `bzr`. Точнее говоря, вам понадобится `bzr` версии 2.5 beta 5 или более новой, а также `bzr-builddeb` версии 2.8.1 или более новой. Для старых версий используйте взамен команду `bzr merge-package`.

[2] | To check other available branches of a package in Debian, see package code page. E.g. https://code.launchpad.net/debian/+source/tomboy

### Использование chroot-окружений

Если вы пользуетесь одной из версий Ubuntu, но работаете над пакетами для другой версии, вы можете создать среду другой версии с помощью `chroot`.

Использование `chroot` позволит вам иметь в распоряжении полную файловую систему другого дистрибутива для удобства работы. Это позволяет избежать затрат, связанных с установкой виртуальной машины.

#### Создание chroot

Используйте команду `debootstrap`, чтобы создать новый chroot:

    $ sudo debootstrap trusty trusty/

This will create a directory `trusty` and install a minimal trusty system into it.

If your version of `debootstrap` does not know about Trusty you can try upgrading to the version in `backports`.

После этого вы можете работать внутри chroot:

    $ sudo chroot trusty

Где можно установить или удалить любой пакет, который вы хотите, без ущерба для основной системы.

Вы можете скопировать свои ключи GPG и SSH, а также конфигурацию Bazaar в chroot, чтобы получать доступ и подписывать пакеты непосредственно оттуда:

    $ sudo mkdir trusty/home/<username>
    $ sudo cp -r ~/.gnupg ~/.ssh ~/.bazaar trusty/home/<username>

Чтобы apt и другие программы не жаловались на отсутствующие локали, можно установить соответствующий языковой пакет:

    $ apt-get install language-pack-en

Если вам нужно запускать программы, использующие X-сервер, вам нужно добавить в chroot директорию /tmp, для этого снаружи chroot запустите:

    $ sudo mount -t none -o bind /tmp trusty/tmp
    $ xhost +

Для некоторых программ, возможно, понадобится привязать /dev или /proc.

Более подробную информацию о chroot вы можете найти на нашей странице Debootstrap Chroot wiki page.

#### Альтернативы

SBuild — система, похожая на PBuilder, также позволяет создать окружение и произвести тестовую сборку. Она более похожа на то, что используется на Launchpad для сборки пакетов, но подготовка такого окружения занимает больше времени по сравнению с PBuilder. Смотрите the Security Team Build Environment wiki page для подробного объяснения.

Полные виртуальные машины могут быть полезны для упаковки и тестирования программ. TestDrive — это программа, позволяющая автоматизировать синхронизацию и запуск ежедневных ISO-образов, смотрите вики-страницу TestDrive, чтобы узнать больше.

Можно также настроить pbuilder так, чтобы он приостанавливался при обнаружении ошибки сборки. Скопируйте C10shell из /usr/share/doc/pbuilder/examples в каталог и используйте аргумент `--hookdir=`, чтобы указать на него.

Облачные компьютеры EC2 Amazon позволяют нанимать компьютер за несколько центов в час. Вы можете установить на них Ubuntu любой поддерживаемой версии и пакеты. Это полезно, когда вам надо скомпилировать много пакетов одновременно или преодолеть ограничения пропускной способности.

### Традиционные методы создания пакетов

The majority of this guide deals with Ubuntu Distributed Development (UDD) which utilizes the distributed version control system (DVCS) Bazaar for retrieving package sources and submitting fixes with merge proposals. This article will discuss what we will call traditional packaging methods for lack of a better word. Before Bazaar was adopted for Ubuntu development, these were the typical methods for contributing to Ubuntu.

В некоторых случаях вам может понадобиться использовать эти инструменты вместо UDD. Поэтому не помешает познакомиться с ними. Перед тем, как продолжить, вам следует прочитать статью Подготовка.

#### Получение исходного кода

Чтобы получить пакет исходного кода, можно просто набрать:

    $ apt-get source <package_name>

Но у этого метода есть некоторые недостатки. Он скачивает версию исходного кода, которая доступна в вашей системе. Скорее всего, у вас установлен текущий стабильный выпуск, а вы собираетесь внести изменения в пакет в разрабатываемом выпуске. К счастью, пакет `ubuntu-dev-tools` предоставляет вспомогательный сценарий:

    $ pull-lp-source <package_name>

По умолчанию будет загружена самая свежая версия из разрабатываемого выпуска. Можно также указать версию выпуска Ubuntu следующим образом:

    $ pull-lp-source <package_name> trusty

to pull the source from the `trusty` release, or:

    $ pull-lp-source <package_name> 1.0-1ubuntu1

чтобы скачать версию пакета `1.0-1ubuntu1`. Для получения дополнительной информации о команде воспользуйтесь `man pull-lp-source`.

Для примера, давайте представим, что мы получили отчёт об ошибке, в котором говорится, что вместо “colour” в описании `xicc` должно быть “color,” и мы хотим это исправить. (Примечание: это просто пример чего-то, что можно изменить, а не реальная ошибка.) Чтобы получить исходный код, введите:

    $ pull-lp-source xicc 0.2-3

#### Создание Debdiff

Файл `debdiff` показывает различия между двумя пакетами Debian. Имя команды, используемой для его создания, тоже `debdiff`. Она является частью пакета `devscripts`. Смотрите `man debdiff` для подробной информации о ней. Чтобы сравнить два пакета исходного кода, передайте команде в качестве аргумента два файла `dsc`:

    $ debdiff <package_name>_1.0-1.dsc <package_name>_1.0-1ubuntu1.dsc

Чтобы продолжить наш пример, давайте отредактируем `debian/control` и «исправим» нашу «ошибку»:

    $ cd xicc-0.2
    $ sed -i 's/colour/color/g' debian/control

Мы также должны придерживаться Debian Maintainer Field Spec и отредактировать `debian/control`, заменив:

    Maintainer: Ross Burton <ross@debian.org>

на:

    Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
    XSBC-Original-Maintainer: Ross Burton <ross@debian.org>

Для этого можно воспользоваться инструментом `update-maintainer` (из пакета `ubuntu-dev-tools`).

Не забудьте задокументировать ваши изменения в `debian/changelog` с помощью `dch -i`, после чего мы можем сгенерировать новый пакет исходного кода:

    $ debuild -S

Теперь можно проверить наши изменения с помощью `debdiff`:

    $ cd ..
    $ debdiff xicc_0.2-3.dsc xicc_0.2-3ubuntu1.dsc | less

Чтобы создать файл патча, который можно отправить другим или приложить к отчёту об ошибке для одобрения, выполните:

    $ debdiff xicc_0.2-3.dsc xicc_0.2-3ubuntu1.dsc > xicc_0.2-3ubuntu1.debdiff

#### Применение Debdiff

Чтобы применить debdiff, нужно иметь исходный код версии, на основе которой он был создан:

    $ pull-lp-source xicc 0.2-3

Then in a terminal, change to the directory where the source was uncompressed:

    $ cd xicc-0.2

Фактически, debdiff похож на обычный файл патча. Примените его, как обычно, с помощью:

    $ patch -p1 < ../xicc_0.2.2ubuntu1.debdiff

### Создание пакетов для модулей и приложений Python

Наше руководство следует рекомендациям Debian Python policy. В качестве примера мы будем использовать пакет python-markdown, который можно загрузить с сайта PyPI. Вы можете посмотреть исходные коды сборки в репозитории Subversion.

Существует два типа пакетов Python — модули и приложения.

На момент написания руководства, Ubuntu содержала две несовместимых версии Python — 2.x и 3.x. `/usr/bin/python` является символической ссылкой на версию по умолчанию Python 2.x, а `/usr/bin/python3` — на версию по умолчанию Python 3.x. Модули Python нужно собирать со всеми поддерживаемыми версиями Python.

Чтобы создать пакет для нового модуля Python, вам может пригодиться инструмент `py2dsc` (доступный в пакете python-stdeb).

#### debian/control

Версии пакетов для Python 2.x и 3.x должны находиться в отдельных двоичных пакетах. Они должны иметь имена в формате `python{,3}-имя_модуля` (например: `python3-dbus.mainloop.qt`). В качестве примера в этой статье мы будем использовать для пакетов модуля имена `python-markdown` и `python3-markdown`, а также `python-markdown-doc` для пакета документации.

Специфичные для пакета Python особенности в файле `debian/control`:

- Секция пакетов модуля должна быть `python`, а для пакета документации `doc`. Для приложения будет достаточно одного двоичного пакета.

- Мы должны добавить зависимости сборки от `python-all (>= 2.6.6-3~)` и `python3-all (>= 3.1.2-7~)`, чтобы были доступны необходимые скрипты debhelper (подробнее в следующем разделе).

- Рекомендуется добавить поля `X-Python-Version` и `X-Python3-Version` — подробности смотрите в разделе Policy “Specifying Supported Versions”. Например:

      X-Python-Version: >= 2.6
      X-Python3-Version: >= 3.1

  Если ваш пакет работает только с Python 2.x или 3.x, сборка зависит только от одного пакета `-all` и использует только одно поле `-Version`.

- Пакеты модулей должны содержать подстановочные переменные `{python:Depends}` и `{python3:Depends}` (соответственно) в своих списках зависимостей.

#### debian/rules

The recommended helpers for python modules are `dh_python2` and `dh_python3`. Unfortunately, `debhelper` doesn’t yet build Python 3.x packages automatically (see bug 597105 in Debian BTS), so we’ll need to do that manually in override sections (skip this if your package doesn’t support Python 3.x).

Вот наш файл `debian/rules` (с комментариями):

    # These commands build the list of supported Python 3 versions
    # The last version should be just “python3” so that the scripts
    # get a correct shebang.
    # Use just “PYTHON3 := $(shell py3versions -r)” if your package
    # doesn’t contain scripts
    PY3REQUESTED := $(shell py3versions -r)
    PY3DEFAULT := $(shell py3versions -d)
    PYTHON3 := $(filter-out $(PY3DEFAULT),$(PY3REQUESTED)) python3

    %:
        # Adding the required helpers
        dh $@ --with python2,python3

    override_dh_auto_clean:
        dh_auto_clean
        rm -rf build/

    override_dh_auto_build:
        # Build for each Python 3 version
        set -ex; for python in $(PYTHON3); do \
            $$python setup.py build; \
        done
        dh_auto_build

    override_dh_auto_install:
        # The same for install; note the --install-layout=deb option
        set -ex; for python in $(PYTHON3); do \
            $$python setup.py install --install-layout=deb --root=debian/tmp; \
        done
        dh_auto_install

It is also a good practice to run tests during the build, if they are shipped by upstream. Usually tests can be invoked using `setup.py test` or `setup.py check`.

#### debian/*.install

Модули Python 2.устанавливаются в каталог `/usr/share/pyshared/` и для каждой версии интерпретатора создаётся символическая ссылка в `/usr/lib/python2.x/dist-packages/`, а все модули для Python 3.x устанавливаются в `/usr/lib/python3/dist-packages/`.

Если ваш пакет является приложением и имеет собственные модули Python, они должны быть установлены в `/usr/share/module` или `/usr/lib/module`, если модули не зависят от архитектуры (например, расширения) (смотрите раздел Policy “Programs Shipping Private Modules”).

Итак, наш файл `python-markdown.install` будет выглядеть следующим образом (мы также хотим установить исполняемый файл `markdown_py`):

    usr/lib/python2.*/
    usr/bin/

а `python3-markdown.install` будет содержать лишь одну строку:

    usr/lib/python3/

#### Пакет `-doc`

Инструмент, наиболее часто используемый для сборки документации для приложений на Python — это Sphinx. Чтобы добавить документацию Sphinx к вашему пакету (используя помощник `dh_sphinxdoc`), вам следует:

- Добавьте сборочные зависимости `python-sphinx` или `python3-sphinx` (в соответствии с версией Python, которую вы хотите использовать);

- Добавьте `sphinxdoc` к строке `dh --with`;

- Run `setup.py build_sphinx` in `override_dh_auto_build` (sometimes not needed);

- Добавьте `{sphinxdoc:Depends}` в список зависимостей вашего пакета `-doc`;

- Добавьте путь к каталогу сборки документации (обычно `build/sphinx/html`) в ваш файл `.docs`.

В нашем случае, документация автоматически собирается в каталоге `build/docs/` при запуске `setup.py build`, так что можно просто указать его в файле `python-markdown-doc.docs`:

    build/docs/

Поскольку документация также содержит исходные файлы``.txt``, нам нужно указать `dh_compress` не сжимать их — добавив в `debian/rules` следующее:

    override_dh_compress:
        dh_compress -X.txt

#### Проверка пакета на наличие ошибок

Наряду с `lintian`, есть специальный инструмент для проверки пакетов Python — `lintian4py`. Он доступен в пакете lintian4python. Например, эти две команды вызывают обе версии `lintian` и проверяют пакеты исходных кодов и двоичные пакеты:

    lintian -EI --pedantic *.dsc *.deb
    lintian4py -EI --pedantic *.dsc *.deb

Здесь опция `-EI` используется для включения экспериментальных и информационных тегов.

#### Смотрите также

- Python policy;

- Статью Python/Packaging на вики-страницах Debian;

- Статьи Python/LibraryStyleGuide и Python/AppStyleGuide на вики-страницах Debian;

- Команды Debian python-modules и python-apps.

### Работа с пакетами KDE

Создание пакетов приложений KDE в Ubuntu управляется командами Kubuntu и MOTU. Связаться с командой Kubuntu можно через список рассылки Kubuntu и Freenode IRC-канал `#kubuntu-devel`. Дополнительная информация о разработке Kubuntu находится на вики-странице Kubuntu.

Наша работа с пакетами следует практике команды Debian Qt/KDE и команды Debian KDE Extras. Большинство наших пакетов являются производными от пакетов этих команд Debian.

#### Политика создания патчей

Kubuntu добавляет патчи в приложения KDE, только если они исходят от оригинальных авторов, либо если они были отправлены в upstream и есть уверенность в их скором принятии, либо если мы обсудили проблемы с разработчиками KDE.

Kubuntu не меняет фирменного оформления пакетов, кроме случаев, когда этого требует апстрим (например, логотип в верхнем левом углу меню Kickoff) или для упрощения (например, удаление показываемых при запуске заставок).

#### debian/rules

Пакеты Debian включают некоторые дополнения к обычному использованию Debhelper. Они хранятся в пакете `pkg-kde-tools`.

Пакеты, использующие Debhelper 7, должны добавить опцию `--with=kde`. Это позволит убедиться в использовании правильных флагов сборки и опций, таких как обработка заданий kdeinit и файлов перевода.

    %:
        dh $@ --with=kde

Некоторые новые пакеты KDE используют систему `dhmk`, альтернативу `dh`, созданную командой Debian Qt/KDE. Прочесть о ней можно в /usr/share/pkg-kde-tools/qt-kde-team/2/README. Использующие её пакеты будут `включать /usr/share/pkg-kde-tools/qt-kde-team/2/debian-qt-kde.mk` вместо запуска `dh`.

#### Переводы

Переводы пакетов из репозитория main импортируются на Launchpad и экспортируются с Launchpad в языковые пакеты Ubuntu.

Итак, каждый KDE-пакет в main должен создавать шаблоны переводов, включать оригинальные переводы и обрабатывать переводимые строки в `.desktop`-файлах.

Для генерации шаблонов переводов пакет должен содержать файл `Messages.sh`; если его там нет, обратитесь в апстрим. Проверить его работу можно, выполнив сценарий `extract-messages.sh`, который должен создать один или несколько файлов `.pot` в каталоге `po/`. В процессе сборки это будет сделано автоматически, если вы используете опцию `--with=kde` для `dh`.

Апстрим обычно также помещает файлы перевода `.po` в каталог `po/`. Если их там нет, проверьте, не находятся ли они в отдельных языковых пакетах апстрима, таких как языковые пакеты KDE SC. Если они в отдельном языковом пакете, Launchpad нужно будет объединить их вручную, свяжитесь для этого с dpm.

Если пакет перемещён из universe в main, его следует перевыгрузить перед импортом переводов на Launchpad.

Файлы `.desktop` также требуют перевода. Мы добавили патч к KDELibs для чтения переводов из `.po`-файлов, указывающих на строку `X-Ubuntu-Gettext-Domain=`, добавляемую к файлам `.desktop` во время сборки пакета. Файл .pot для каждого пакета генерируется во время сборки и .po-файлы необходимо скачать из апстрима и включить в пакет или в наши языковые пакеты. Список .po-файлов, которые нужно скачать из репозиториев KDE, находится в `/usr/lib/kubuntu-desktop-i18n/desktop-template-list`.

#### Библиотечные символы

Библиотечные символы хранятся в файлах `.symbols`, для того чтобы при появлении новых версий не было отсутствующих символов. KDE использует библиотеки C++, которые немного отличаются от библиотек C. Команда Debian Qt/KDE имеет скрипты, обрабатывающие это. Смотрите страницу Working with symbols files для подробностей по созданию этих файлов и поддерживанию их в актуальном состоянии.

## Информация для дальнейшего чтения

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

Если вы желаете узнать больше о сборке пакетов Debian, вот несколько ресурсов Debian, которые могут быть вам полезны:

- Как создавать пакеты для Debian;

- Debian Policy Manual;

- Руководство начинающего разработчика Debian — доступно на многих языках;

- Учебник по сборке пакетов (также доступен в виде пакета).

Мы постоянно стремимся улучшить это руководство. Если вы нашли ошибку или у вас есть какие-то предложения, отправьте, пожалуйста, отчёт об ошибке на Launchpad. Если вы хотите помочь в работе над руководством, там же вы можете получить его исходный код.