Просмотр поста

.
reaper

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

Для начала хорошо было бы знать, что такое build server.
Это специальное ПО, предназначенное для обеспечения непрерывной интеграции.

Непрерывная интеграция (Continuous Integration, CI) - практика разработки ПО, при которой выполняются частые сборки проектов, что позволяет быстро выявить и решить различные проблемы.

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

- Получить исходный код из репозитория.
- Собрать проект (установить сторонние библиотеки, используемые в нём, скомпилировать и т.п.).
- Выполнить тесты.
- Задеплоить готовый проект.

Так как я не собираюсь делать убийцу TeamCity или Travis CI, то остановимся на этом:

- Клонирование из git репозитория.
- Выполнение шагов, описанных в конфигурации проекта.
- Просмотр лога сборки.

Что нам понадобится:

- Python
- Buildout
- Flask
- Tornado
- psycopg2
- PyZMQ

Python, я думаю, в представлении не нуждается.

Buildout. Позволяет устанавливать сторонние библиотеки, не прибегая к virtualenv и не засоряя систему.
А ещё у него есть куча рецептов, которые позволяют вытворять всякие прикольные штуки
вроде генерации скриптов, конфигов из шаблонов, интеграции с различными библиотеками и т.п.
Можно написать какой-нибудь свой рецепт. Всё ограничено только полётом фантазии.

Flask -- это микро-фреймворк, предназначенный для написания веб-приложений.
Tornado -- неблокирующий веб-сервер и веб-фреймворк.
psycopg2 -- питоновские биндинги для PostgreSQL.
PyZMQ -- обеспечивает поддержку ZMQ.

ZMQ -- библиотека, позволяющая создать систему очереди сообщений.
Подробнее о ZMQ можно узнать например здесь http://habrahabr.ru/post/198578/

Подготовка проекта и установка зависимостей

Первым делом создаём директорий для проекта:

$ mkdir buildserver
$ cd buildserver

Создаём файл setup.py со следующим содержимым:

$ editor setup.py

from setuptools import setup, find_packages

setup(
    name='buildserver',
    version='0.1',
    description='Simple buildserver',
    packages=find_packages('src'),
    package_dir={'': 'src'},
    install_requires=[
        'flask',
        'psycopg2',
        'pyzmq',
        'tornado'
    ]
)


Создаём файл buildout.cfg:

$ editor buildout.cfg

[buildout]
develop = .
parts = buildserver

[buildserver]
recipe = zc.recipe.egg
eggs = buildserver
interpreter = py


Создаём пакет buildserver:

$ mkdir src/buildserver -p
$ touch src/buildserver/__init__.py

Перед установкой зависимостей проекта, в систему придётся поставить некоторые пакеты,
которые требуются сборки этих зависимостей.
А именно:

python-dev
libzmq3-dev
postgresql-server-dev-9.3

Ну и сам постгрес надо будет поставить, если не стоит.

В убунте и прочих debian-based дистрибутивах достаточно выполнить:

$ sudo apt-get install python-dev libzmq3-dev postgresql-9.3 postgresql-server-dev-9.3

Ставим buildout и зависимости для проекта:

$ wget http://downloads.buildout.org/2/bootstrap.py
$ python bootstrap.py
$ bin/buildout

Настройка PostgreSQL

Устанавливаем пароль для пользователя postgres:

$ sudo passwd postgres

Эта команда запросит ваш пароль, новый пароль для postgres, и повтор нового пароля.

Логинимся:

$ su postgres

Создаём юзера:

$ createuser -sdrP kilte

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

Выходим:
$ exit

Заходим в psql:

$ psql postgres

Создаём базу данных для нашего приложения:

create database buildserver owner kilte;

На этом настройку postgres можно считать оконченой.


Bower

Bower - это менеджер зависимостей для фронтенда.

http://bower.io/ - Оф. сайт
http://nano.sapegin.ru/all/bower - Инфа на русском.

Для того, чтобы установить bower, нужно поставить nodejs и npm.
Я недолюбливаю npm и всё, что с ним связано, потому что оно выкачивает десятки мегабайт непонятно чего.
Мы пойдём более простым путём.
Bower портирован на PHP и мы спокойно можем скачать один файл, и начать пользоваться.

$ wget http://bowerphp.org/bowerphp.phar

Можете теперь сделать с ним всё, что угодно.
У меня же для подобных штук в домашнем директории есть директорий bin, куда я складываю все бинарники.
~/bin прописан в $PATH, что позволяет мне запускать все файлы из ~/bin, не набирая абсолютный путь до исполняемого файла.

Кому-то может такое и не понравится, потому можно сделать вот что:

$ sudo mv bowerphp.phar /usr/local/bin/bowerphp

Конечно нужно не забыть сделать этот файл исполняемым:

$ sudo chmod +x /usr/local/bin/bowerphp

Теперь пробуем выполнить:

$ bowerphp

Создаём в корне проекта два файла .bowerrc и bower.json

В .bowerrc пишем:
{
    "directory": "web/vendor"
}


Здесь мы определили путь к директорию, куда будут установлены зависимости, описанные в bower.json

В bower.json:
{
    "name": "buildserver",
    "private": true,
    "dependencies": {
        "angular": "1.3.*",
        "angular-route": "1.3.*",
        "angular-websocket": "*"
    }
}


Ну здесь всё понятно, а что не понятно, смотрите доку на офф сайте.

Выполняем:

$ bowerphp install

После чего получим в корне проекта директорий web/vendor, в котором лежат описанные в конфиге зависимости.


Настройка Nginx

Ещё не стоит? Почему? А ну быстро ставим. Хе-хе.

$ sudo apt-get install nginx

Пишем конфиг для него:

$ sudo editor /etc/nginx/sites-available/buildserver.conf

Содержимое конфига (+/-)

server {
    listen 80;
    server_name buildserver;
    root /home/kilte/projects/buildserver/web;
    index index.html;

    location / {
        try_files $uri $uri/ @app;
    }

    # REST API
    location @app {
         proxy_pass http://127.0.0.1:5000;
    }

    # проксируем WebSockets
    location /broadcast/ {
        proxy_pass http://127.0.0.1:8888;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host buildserver;  
        proxy_read_timeout 950s;
    }

}


Путь к проекту не забудьте заменить.

Врубаем хост:

$ sudo ln -s /etc/nginx/sites-available/buildserver.conf /etc/nginx/sites-enabled/
$ sudo service nginx restart

В /etc/hosts: 127.0.0.1 buildserver