# Trendbox CI в Тулзах

> Ты либо в тренде, либо уходи.

Ванильный Trendbox (пока) не очень хорошо заточен под Docker. В частности, он не поддерживает запуск тестов через `docker-compose`. В этом репозитории собран набор хаков, которые обходят это ограничение.

Перед чтением этого мануала рекомендуется хотя бы поверхностно ознакомиться с [документацией Trendbox](https://github.yandex-team.ru/search-interfaces/trendbox-ci/blob/master/README.md).


## Quickstart

Чтобы запускать `docker` и `docker-compose` в Trendbox:

1. Используйте кастомный LXC-контейнер, указав в `.trendbox.yml`:

```
format: 0.2

language: python

cloud:
  type: sandbox
  owner: TOOLS

container:
  type: LXC
  storage: sandbox-resource
  resource: 2946980340
```

Последнюю версию и историю изменений смотрете в файле ChangeLog.rst.

2. В запускаемых скриптах замените `docker` и `docker-compose` на соответственно `trendocker` и `trendocker-compose`.
3. Не забудьте [авторизоваться](https://wiki.yandex-team.ru/qloud/docker-registry/#cli) если вы собираетесь работать с внутренним registry.
4. Добавьте вызов `restore-docker-layers` в секцию `before_install` и вызов `save-docker-layers` в секцию `after_script`, чтобы слои докера сохранялись между запусками тестов и работало кэширование.
5. ...
6. PROFIT

### Ограничения:
* Общий размер артефактов докера (= содержимого `/var/lib/docker`) не должен превышать 10 Гб ([пояснение](#storage-driver)).
* Для сборки и запуска сервисов `docker-compose` все программы в ваших контейнерах должны уважать переменные окружения `http_proxy` и `https_proxy` (см, например, замечение про [tox](#tox)). Для сборки через `docker build` это ограничение не актуально ([пояснение](#Сеть)).

### Примеры успешной настройки

* [django-pgaas](https://github.yandex-team.ru/tools/django_pgaas/blob/master/.trendbox.yml)

## Что в кастомном LXC-контейнере?

Ubuntu 16.04 (вместо 14.04 в стандартном) с минимальным количеством дополнительных пакетов и конфигов для работы с Trendbox. Кроме этого там установлены

* docker 17.09.1
* docker-compose 1.21.2
* releaser 0.38
* скрипты save-docker-layers и restore-docker-layers для кэширования слоёв докера

[Подробнее](./lxc) о сборке и содержимом кастомного контейнера.

## Как работает Docker?

### Сеть

Задачи в Trendbox используют локальный DNS-сервер для доступа к сети ([тикет](https://st.yandex-team.ru/FEI-9087#1518603403000)).

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

Проблема обходится двумя костылями:

#### docker

Скрипт `trendocker` модифицирует аргументы команды `build`, добавляя к ним `--network host`. Работая из хостовой сети, команды сборки могут ходить на внешние ресурсы.

#### docker-compose

Для docker-compose трюк с хостовой сетью применять нельзя: во-первых, это потребовало бы изменений в `docker-compose.yml`, во-вторых из-за этого сервисы не смогут общаться по сети используя свои имена.

Вместо этого, скрипт `trendocker-compose` модифицирует аргументы команд `build` и `run`, добавляя в их контекст переменные окружения `http_proxy` и `https_proxy`, указывающие на прокси-сервер, запущенный в хостовом LXC-контейнере.

**NB:** кроме вышеописанных сценариев, скрипты `trendocker` и `trendocker-compose` без изменений транслируют любые переданные им аргументы. Это позволяет использовать их для запуска любых команд, а не только `build` и `run`.

### Storage-driver

В LXC-контейнере используется overlayfs. Поверх неё получается использовать только [драйвер VFS](https://docs.docker.com/storage/storagedriver/vfs-driver/), самый медленный из доступных. Подробности в [тикете](https://st.yandex-team.ru/FEI-7559#1508143167000).

Чтобы использовать более эффективный `overlay2`, директория `/var/lib/docker` смонтирована на tmpfs с ограничением на размер 10 Гб.

**NB:** tmpfs не аллоцирует всю память сразу. Потребление памяти зависит исключительно от размера файлов в этой директории.


## Как отлаживать таски?

Если таску не получается запустить с первого раза, Sandbox позволяет запустить в LXC-контейнере интерактивный шелл.

1. Укажите в `.trendbox.yml` группу Sandbox, к которой у вас есть доступ. Вам всё равно придётся это сделать, если вы хотите использовать хранилище секретов. Подробности есть в соответствующей [инструкции](https://github.yandex-team.ru/search-interfaces/trendbox-ci/blob/master/docs/2-features/secrets/secrets.md).

2. В интерфейсе Sandbox нажмите Suspend во время исполнения вашей таски. Для удобства можно добавить в скрипт `sleep 100`.

3. Нажмите "Open shell"


## Известные проблемы

### [Tox](https://tox.readthedocs.io)

Tox по-умолчанию не передаёт все переменные окружения в процессы сборки и запуска тестов. Чтобы прокси заработал, необходимо явно настроить прокидывание переменных окружения в `tox.ini`:

```
passenv=http_proxy, https_proxy, no_proxy
```

### [vcrpy](https://vcrpy.readthedocs.io/en/latest/)

vcrpy [ломается](https://github.com/kevin1024/vcrpy/issues/214) при указании переменной `http_proxy`


### SSH

Внешние соединения по SSH не работает через прокси. В частности, не будет работать `git clone git@...` и зависимости вида `pip install git+ssh://`. Используйте клонирование по https.
