BAYZR и SONARQUBE пример работы с проектом

Имею:

  1. IP: 192.168.0.116, необходим для демонстрации работы через веб
  2. ОС: CentOS Linux release 7.3, так же подойдет RHEL 7, Fedora 25. CentOS 6 и подобные тоже подойдут, но возможности будут серьезно ограничены, т.к https://build.opensuse.org/project/show/home:bayrepo репозиторий для 7-й версии имеет намного больше пакетов для аналитики.
  3. Архитектура: x86_64
  4. Объем памяти: 3Гб + 2Гб swap
  5. Объем HDD: 8Гб + 2Гб на каждую параллельную задачу, т.е если планируется 4 параллельных анализа то 4*2=8гб+8Гб=16Гб.

Установка описана здесь: bayzr и continue integration

yum install wget -y
wget http://download.opensuse.org/repositories/home:/bayrepo/CentOS_7/home:bayrepo.repo -O /etc/yum.repos.d/home:bayrepo.repo
yum install bayzr-citool -y
citool -setup-run

Сервер для установки абсолютно чистый. Команда citool -setup-run спросит:

[root@localhost ~]# citool -setup-run
Welcome to management script of continue integration system
Chose what should to do next:
  1) Install all needed components
  2) Create backups of installed components
  3) Restore from backup(bkp.zip)
1/2/3 or q(quit) or e(exit) for next step

Выбираю - 1. Второй вопрос при установке:

Chose version of SonarQube will be installed:
   1. SonarQube 6.0
   2. SonarQube 5.6
Press 1 or 2

Выбираю снова - 1. Далее скрипт просит пароль задать для нового пользователя базы данных:

Set password for sonarqube database:

Выбираю для примера Test1234567890

Загружается SonarQube, JDK, MySQL и прочие пакеты.

Данные пакеты, указывают на то, что установка прошла успешно:

# rpm -qa | egrep "yumbootstrap|^java-|mysql-community|bayzr" | sort
bayzr-0.2-28.1.x86_64
bayzr-citool-0.2-28.1.x86_64
java-1.8.0-openjdk-1.8.0.131-3.b12.el7_3.x86_64
java-1.8.0-openjdk-devel-1.8.0.131-3.b12.el7_3.x86_64
java-1.8.0-openjdk-headless-1.8.0.131-3.b12.el7_3.x86_64
mysql-community-bench-5.6.36-2.el7.x86_64
mysql-community-client-5.6.36-2.el7.x86_64
mysql-community-common-5.6.36-2.el7.x86_64
mysql-community-devel-5.6.36-2.el7.x86_64
mysql-community-libs-5.6.36-2.el7.x86_64
mysql-community-server-5.6.36-2.el7.x86_64
yumbootstrap-0.0.3-7.2.noarch

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

# ps aux | egrep "citool|SonarQube"
root      1223  0.0  0.0  17808   744 ?        Sl   May26   0:00 /usr/local/sonar/bin/linux-x86-64/wrapper /usr/local/sonar/conf/wrapper.conf wrapper.syslog.ident=SonarQube wrapper.pidfile=/var/run/SonarQube.pid wrapper.daemonize=TRUE wrapper.lockfile=/var/lock/subsys/SonarQube
checker   2315  0.0  0.3 182676  6176 tty2     Ssl+ May26   0:00 /usr/sbin/citool -server-run
checker   2325  0.0  0.3 190872  7220 tty2     Sl+  May26   0:00 /usr/sbin/citool -job-runner 10
root      2615  0.0  0.0 112648   976 pts/1    R+   00:01   0:00 grep -E --color=auto citool|SonarQube
# cat /etc/citool.ini
[mysql]
connect=bayzr:Test1234567890@tcp(127.0.0.1:3306)/bayzr?charset=utf8
clean=10
timetoclean=59 59 23 * * *

[server]
workers=10
wait=30
  • mysql→connect - строка соединения с базой данных, база уже создана установщиком
  • mysql→clean - время жизни результата в базе, по умолчанию 10 дней
  • mysql→timetoclean - строка в формате крон, для указания времени когда будет запускаться планировщиком задача по очистке базы
  • server→workers - число обработчиков очереди
  • server→wait - время в секундах на перечитывание задач и переинициализацию таймеров

CI система с bayzr и SonarQube состоит из двух частей, это планировщик задач по анализированию кода и сам SonarQube. Планировщик содержит список проектов с параметрами, что проверять, какими анализаторами и какими файлами, куда сохранять результат, когда и как запускаться.

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

syetemtcl restart citool

введу в адресной строке браузера: http://192.168.0.116:11000. Логин: su_admin, Пароль: su_admin

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

  • Admin Group - самые широкие права, может изменять сведения о пользователях, создавать задачи, создавать процессы, смотреть результат выполнения процессов.
  • Developer Group -
  • User Group - не доступно ничего, кроме входа и информационной странички
  • Viewer Group - может просматривать результат выполнения процессов и создавать новые процессы.

Задача - это описание параметров анализа, конфигурация анализируемых утилит, сведения откуда брать исходники, что из пакетов доустанавливать, когда запускать Процесс - это постановка выбранной задачи в очередь на выполнение с указанием какой коммит, ветку или ref-change взять, для анализа Из очереди процессов свободные воркеры выхватывают наиболее приоритетный и начинают выполенение. Приоритетов очередей аж 5. Приоритет выбирается при создании процесса.

Для регистрации нового пользователя необходимо зайти в форму Login и выбрать ссылку "Зарегистрироваться". В предложенной форме ввести: Для примера - создам пользователя jovanny. При входе от пользователя jovanny, ему не доступно ничего, т.к он получает роль по умолчанию - User Group. Зайду от пользователя su_admin и поменяю его права на более высокие, например Developer Group. В открывшейся форме выберем Developer Group, потом нажмем кнопку "Отправить", сохраним параметры. Эта форма позволяет изменить параметры пользователя, изменить его пароль и даже удалить пользователя.

Теперь перелогинимся вновь под пользователем jovanny, для этого жмем меню "Выход". Пунктов меню стало больше. Создадим задачу. Сразу оговорюсь, что сборка и установка пакетов необходимых для сборки происходит в chroot, управление chroot происходит посредством yumbootstrap. По умолчанию, доступные среды для сборки хранятся в каталоге: /etc/yumbootstrap/suites/, но citool использует centos-7-mod.suite, этот сьют можно перенастроить на любую rpm подобную среду, например добавить epel репозитории и пр. Описание сьюта будет приведено ниже.

suite

# cat /etc/yumbootstrap/suites/centos-7-mod.suite
name = CentOS
release = 7

gpg_key =  gpg/RPM-GPG-KEY-CentOS-7
gpg_key ?= gpg/RPM-GPG-KEY-CentOS-Security-7
gpg_key ?= gpg/repomd.xml.key

packages = packages/${suite}.list

[main]
cachedir=/yumbootstrap/cache
logfile=/yumbootstrap/log/yum.log
keepcache=0
debuglevel=2
exactarch=1
obsoletes=1
installonly_limit=5
proxy=http://127.0.0.1:3128

[post_install]
finalize = scripts/addbayzr.py
finalize = scripts/fix_rpmdb.py
finalize = scripts/clean_yumbootstrap.py

[repositories]
centos         = http://mirror.centos.org/centos/7/os/$basearch/
centos-updates = http://mirror.centos.org/centos/7/updates/$basearch/
home_repo      = http://download.opensuse.org/repositories/home:/bayrepo/CentOS_7/
centos-extras  = http://mirror.centos.org/centos/7/extras/$basearch/


[environment]
HOME=/root
TERM="$TERM"
PS1='\u:\w\$ '
PATH=/bin:/usr/bin:/sbin:/usr/sbin
OUT_USER=checker

[cache]
cache_dir = /usr/share/yumbotstrapcache
cache_expire = 2592000

# vim:ft=dosini
  • в секции [main] вписываются ключи, которые помещаются в yum.conf внутри /etc в изолированном окружении. Из строки конфигурации видно, что настроен proxy параметр, для кеширования пакетов прокси сервером.
  • в секции [post_install] содержится список скриптов, которые будут выполнены после подготовки окружения и внутри окружения.
  • в секции [repositories] представлен список подключаемых URL репозиториев
  • в секции [environment] описаны переменные окружения внутри среды
  • в секции [cache] описан путь к кэшу и время жизни кеша в секундах, когда кэш считать просроченным. Это для ускорения подготовки среды. При наличии кэша, структура и скелет chroot окружения просто копируется без доп. подготовки.

list

# cat /etc/yumbootstrap/suites/packages/centos-7-mod.list
# subset from @Core
coreutils
bash
grep
gawk
basesystem
rpm
initscripts
iproute
sudo
shadow-utils

# subset from @Base
less
make
mktemp
vim-minimal
yum
which
#authconfig
#dhclient
chkconfig
# graphical boot helper (used by initscripts)
plymouth
# ~root/.*
rootfiles

#utils
bayzr
pylint
java-1.8.0-openjdk
~/usr/local/sonar-scanner
~/etc/resolv.conf
~/usr/bin/shellcheck
gcc
gcc-c++
make
cmake
git
bay-gcc61
clang
clang-analyzer
cppcheck
oclint
rats
splint
pylint
rpmlint
frama-c
+/var/lib/mysql
+/usr/local/sonar
+/dev
+/proc

# redhat-release
centos-release

# required to fix RPM DB
/usr/bin/db_load

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

Записи типа aaaa:

bayzr
pylint
java-1.8.0-openjdk

говорят, что указанные пакеты должны быть установлены

Записи типа ~aaaa:

~/usr/local/sonar-scanner
~/etc/resolv.conf
~/usr/bin/shellcheck

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

Записи типа +aaaa:

+/var/lib/mysql
+/usr/local/sonar
+/dev
+/proc

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

Выбираю меню "Задания"→"Создать новую задачу".

Задача - это список параметров и действий будущего процесса

  • Название - название задачи(name[:key[:version]]) key и version необязательны, при их отсутсвии они будут созданы из name
  • Тип результата - CommitCheck не отправлять результат в SonarQube; SonarQube - отправить результат в SonarQube
  • Использовать коммит или ветку - использовать в качестве идентификатора изменений коммит или имя ветки или патчсет для gerrit
  • Команда клонирования - полная команда клонирования проекта. git clone … без git clone
  • Пакеты для сборки проекта и Пакеты для сборки проекта ранее используемые - список пакетов, которые должны быть доустановлены в окружение для успешного анализа или сборки проекта(если сборка необходима)
  • Команды сборки - список команд, каждая с новой строки, которые необходимо выполнить чтоб получить корректные исходные коды для анализа. Например для си-это может быть команда сборки проекта make VERBOSE=1 и т.д
  • Тип периода - тип задачи, если Крон - то это периодическая задача, которую запускает сам сервис, иначе, Задача запускается вручную или по событию извне
  • Время периода - описание крон задачи в крон формате https://godoc.org/github.com/robfig/cron
  • Кто может запускать - список пользователей которым разрешен запуск, распространяется только на WEB API
  • Конфигурация для анализаторов кода - bzr.conf со списком анализаторов и настроек игнорирования. Больше информации по файлу: http://bayrepo.net/ru/bayzrdscr#bzrconf
  • Файл результата - имя файла результата проверки и путь к нему, если путь к нему не в корне git проекта, такое может быть если в пункте "Команды сборки" есть команды смены каталога
  • Ветка для периодических задач - в какую ветку переключаться планировщику, при выполнении задачи по крону (только для Cron задач)
  • Список проверяемых файлов - в результирующий отчет могут попасть либо все файлы исходных кодов из проверяемого коммита(ветки) или только те файлы которые были найдены в разнице двух коммитов указанных при создании процесса через запятую
  • Команды выполняемые после аналитики - команды для shell скрипта, которые выполняются после анализа, в shell скрипт передаются параметры - 1 - параметр число найденных ошибок, 2 - путь к файлу отчета, 3 - вывод команд, 4 - id задачи, для извлечения дополнительных параметров из bayzr_JOBADDP. Данные команды могут быть использованы для нотификации и пр.
  • Рабочий каталог в проекте - каталог относительно корня git проекта, где будет запущен sonar-scanner
  • Команды выполняемые перед аналитикой от root - это уже не установка пакетов, это может быть yum update или установка модулей питона pip install … и т.д

Пример заполнения: для проекта mod_performance, периодическая проверка всего проекта с сохранением результата в SonarQube

Название поляЗначение
Название(name[:key[:version]])mod_performance:0.4:0.4
Тип результатаSonarQube
Использовать коммит или веткуВетку
Команда клонированияhttps://github.com/bayrepo/mod_performance.git
Пакеты для сборки проектаhttpd-devel,apr-devel,gd-devel,sqlite3 для каждого пакета нужно нажать + и вписать имя пакета
Пакеты для сборки проекта ранее используемыеНичего, т.к это первая задача
Команды сборки (новая команда с новой строки) {{CHECK}} для вставки команды анализа исходников{{CHECK}} make - {{CHECK}} это служебное слово, которое говорит, что в этой команде нужен анализ, до команды {{CHECK}} можно делать подготовительные для сборки или анализа команды, если проект только на питоне или на bash, то {{CHECK}} все равно нужно вызвать, но с командой {{CHECK}} echo 1, чтоб запустить событие проверки исходников
Тип периодаКрон
Время периода00 30 01 * * *
Кто может запускатьВыбираем всех доступных пользователей
Конфигурация для анализаторов кодаТ.к у меня в примере C-проект, то конфигурация по-умолчанию подходит, оставляю без изменений, проверка cppcheck
Файл результатаreport.html - из предыдущей настройки
Ветка для периодических задачmaster - т.к исходники беру из ветки master
Список проверяемых файловПолный список
Команды выполняемые после аналитики(записываются в скрипт). 1 - параметр число найденных ошибок, 2 - путь к файлу отчета, 3 - вывод командпусто, ничего не запускаем
Рабочий каталог в проектепусто, т.к никуда при подготовке не переходим
Команды выполняемые перед аналитикой от rootпусто, т.к никаких действий требующих прав суперпользователя не нужно, здесь можно вставить yum install, pip install и прочее

Сохраняем. Получаем вывод:

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

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

Название поляЗначение
Название(name[:key[:version]])mod_performance:manual:0.4
Тип результатаCommit check
Использовать коммит или веткуКоммит
Пакеты для сборки проекта ранее используемыеhttpd-devel,apr-devel,gd-devel,sqlite3
Тип периодаБез периода
Время периодапусто
Ветка для периодических задачпусто
Список проверяемых файловТолько измененные файлы

Теперь первая задача при запуске репортует в SonarQube, вторая оставляет только внутрений результат проверки. Каждая созданная задача может быть удалена "Удалить" или изменена "Изменить" напротив имени указанной задачи. Внимание!!! Подтверждение на удаление не спрашивается.

Перейдем в меню "Процессы". На картинке видно, что было запущено несколько процессов, один - это созданная ранее крон задача. Красным квадратом выделена область статуса - если она пустая, то задача или выполняется или уже успешно выполнена. Если там изображение перевернутой руки - это значит, что во время анализа произошли проблемы. Лог сборки и анализа можно найти по ссылке обведенной зеленым квадратом на рисунке. Синий квадрат содержит ссылку на результат анализа или сообщение "Нет результата".

Создадим задачу, появится окно с параметрами:

Процесс - это запущенная Задача с заданными параметрами. Результатом работы процесса является отчет о результатах проверки кода или сообщение об ошибке

  • Название - название процесса, уникальное имя выполняемого задания
  • Приоритет - приоритет выполнения процесса. При запросе анализа, процесс запускается не мгновенно, а попадает в очередь процессов. Из каждой очереди выбирается запрос на процесс с меньшим идентификатором. Порядок и очередность пересмотра очередей: первой пересматривается очередь с приоритетом Экстремальный, потом Высокий, потом Стандартный и наконец - Низкий
  • Идентификатор изменения - идентификатор изменения в системе контроля версий (имя ветки, коммит, или разница между коммитами). Для разницы коммитов два коммита должны быть указаны через запятую. В качестве идентификатора может быть: имя ветки без remotes и origin(для задачити типа Ветка), или коммит или два коммита через запятую(для задачи типа Коммит)
  • Задача - название задачи, параметры которой будут использованы
  • Дополнительное описание - любой комментарий, может быть пустым

Запустим процесс вручную для задачи mod_performance:manual:0.4

Название поляЗначение
Названиепервый ручной процесс
ПриоритетСтандартный
Идентификатор изменения в системе контроля версий (имя ветки, коммит, или разница между коммитами). Для разницы коммитов два коммита должны быть указаны через запятуюa50002ecbd1644478e3153a1d1dcc1218a43c333
Задачаmod_performance:manual:0.4
Дополнительное описаниепервый ручной процесс

Вывод каждой задачи логирует stderr и stdout каждой выполняемой команды. Для просмотра вывода, нужно нажать на ссылку напротив требуемого процесса. Пример вывода: Красным цветом подсвечены строки из stderr, былые строки - из stdout, зеленые - это команда которая выполнялась.

Результат проверки выглядит следующим образом:

Страница разбита на секции:

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

  • Сиреневая - список ошибок, каждая строка разворачивается и содержит вырезку кода с подсвеченной ошибкой

Красным цветом подсвечиваются критические ошибки, желтым - предупреждения, синим - информационные.

Для запуска процесса через web-api или из автоматизированных утилит необходимо сформировать запрос вида:

curl -u {LOGIN}:{USER_TOKEN} --data "user_token={USER_TOKEN}&task_token={TASK_TOKEN}&commit={CHANGE_ID}&descr={DESCRIPTION}&{ADDPARAMS}" http://{SERVER_IP}:11000/api/jobjson

где: {LOGIN}:{USER_TOKEN} это: перейти по ссылке: требуемый {LOGIN}:{USER_TOKEN} выделены красным:

{TASK_TOKEN} - переходим в меню "Задания", нажимаем "Изменить" напротив требуемого задания и в открывшемся окне берем идентификатор выделенный красным:

{CNANGE_ID} - имя ветки, номер коммита, ref change для геррит

{DESCRIPTION} - описание процесса

{ADDPARAMS} - любое число дополнительных параметров в виде param1=value1&param2=value2&… Эти параметры будут сохранены в базе данных и могут быть использованы пост скриптом.

Пример:

curl -u jovanny:9c8cf1c285136d631c2df03c9e051c --data "user_token=9c8cf1c285136d631c2df03c9e051c&task_token=1c418fa991b46dd0b53f69b4e3b916&commit=b9c744bde897764ce6b71161d38ed02650157e22&descr=Task1&currentdate=UNUSE" http://192.168.0.116:11000/api/jobjson

Ежедневно планировщиком задач запускается задача по очистке базы данных. Задача проверяет все старые сборки старше mysql→clean=10 дней, а также сборки никому не принадлежащие, ошибочные и прочее и удаляет их. Такая запись выглядит как: и содержит такой вывод: Записи в выводе показывают цифры удаленных строк в базе данных.

Для сбора информации в SonarQube необходимо активировать правила плагина bayzr. Для этого необходимо: 1. Зайти по адресу 192.168.0.116:9000 и залогиниться как администратор: admin:admin 2. Перейти в пункт меню: Правила, выбрать фильтр bayzr и выбрать Язык - Cpp.Нажать на кнопку "Массовое изменение" 3. В выпавшем меню выбрать - Активировать в …, согласиться с предложенным вариантом

Все

Пример результата анализа в SonarQube: 1. 2. 3.