Carthago delenda est!
Настройка GitLab Runner-а
Проект Нибелунги содержит в себе всё необходимое для интеграции остальных
проектов в процесс CI используя технологию GitLab Runner Docker Executor.
Большое значение имеет данная инструкция описывающая весь процесс, пожалуйста ознакомьтесь с ней.
Данный проект так же содержит демонстративный подпроект Nibelungen
описывающий весь процесс взаимодействия с GitLab CI. Взяв внутренний проект
Nibelungen в качестве шаблона, вы сможете легко адаптировтаь свой проект под
интеграцию.
Итак, содержимое данного проекта:
ci: Папка с общими скриптами, которые должны входить во все образыDocker-аdocs: Диаграммы для данногоREADMEimages: ОбразыDocker-а для разных типов сборокnibelungen: Внутренний проект демонстрирующий принципыGitLab CI.gitlab-ci.yml: Файл конфигурацииCIдля внутреннего проектаnibelungendocker-compose.yml: Файл содержащий описание главное контейнераGitLab Runner-аREADME.md: Инструкция описывающая разворачивание серверной и клиентской частейreg.ini: Файл содержащий информацию для регистрацииexecuter-а для проектаNibelungenregister.py: Скрипт регистрирующийexecuter-ы клиентских проектовrunner.code-workspace:workspaceфайлIDEVisual Code
- Нибелунги
- О данном проекте
- Оглавление
- Концепция
- Настройка на сервере
- Docker
- Иструкция настроки для каждого проекта
- Создание образов Docker-а
- Локальная сборка мобильных приложений
- Некоторые заметки
Небольшая ремарка: в дальнейшем термин runner может быть использован как
касательно главного контейнера GitLab Runner-а, так и в отношении
конкретного executer-а, запускаемого для сборки целевого проекта. Точное
значение истекает из контекста.
На следующей диаграме изображена общая концепция GitLab Runner-а с
executer-ами Docker-а:
Все шаги нижеследующей инструкции расписанны ниже.
- Установите
Docker - Настройте
Docker Registry - Создайте папку
/srv/nibelungen/config/certs/на хосте - Загрузите корневой сертификат
- Из корня проекта запустите
runnerкомандой./deploy.sh - Настройте параллельность для главного
runner-а
Инфраструктура докера нужна для разработки контейнера в рамках которого
GitLab CI будет собирать проект на сервере сборки.
Тут описывается установка
Docker-а на хостеOpenSuse
Установка Docker-а:
# To install the docker and docker-compose packages
$ sudo zypper install docker python3-docker-compose
# To start the docker daemon during boot
$ sudo systemctl enable docker
# To join the docker group that is allowed to use the docker daemon
$ sudo usermod -G docker -a $USER
# Restart the docker daemon
$ sudo systemctl restart dockerТут очень важно сделать logout и login, что бы права группы применились к
вашему пользователю.
# Verify docker is running
docker version
# This will pull down and run the, "Hello World" docker container from
# dockerhub
docker run --rm hello-worldИнициализируйте Swarm:
docker swarm initВ связи с избыточной сложностью рекомендуется НЕ устанавливать
Docker Registryна станциях разработки
Установка реестра необходима для воспроизведения штатного режима работы
сервера на котором будет крутиться образ. В штатном режиме образ будет
скачиваться стеком swarm-а с реестра.
Данные registry находятся в /opt/docker/data.
Добавьте метку на наш едиственный узел:
docker node update --label-add registry=true $HOSTNAMEСоздайте самиздатный сертефикат, если не распологаете иным, изменив пути и данные на необходимые:
mkdir $HOME/certs/
cd $HOME/certs/
openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout ilmarinen.key \
-x509 -days 365 -out ilmarinen.crt \
-subj "/C=RU/ST=Vologda/L=Vologda/O=Kalevala/OU=NIT/CN=Ilmarinen"Установите сертификат в системе:
sudo cp ilmarinen.crt /usr/share/ca-certificates
sudo update-ca-certificates ca-certificatesА так же конкретно для Docker-а:
# Убедитесь, что требуемая папка существует
sudo cp ilmarinen.crt /etc/docker/certs.d/ilmarinen\:8443/Удалите сервис и секреты, если они уже настроены и настроены неудовлетворительно:
docker service rm registry
docker secret rm ilmarinen.key
docker secret rm ilmarinen.crtДобавим секреты Docker-а:
docker secret create ilmarinen.key ilmarinen.key
docker secret create ilmarinen.crt ilmarinen.crtСоздайте сервис командой:
sudo docker service create \
--name registry \
--secret ilmarinen.crt \
--secret ilmarinen.key \
--constraint 'node.labels.registry==true' \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/ilmarinen.crt \
-e REGISTRY_HTTP_TLS_KEY=/run/secrets/ilmarinen.key \
--publish published=8443,target=443 \
--replicas 1 \
registry:2Если необходимо примонтировать хранилище реестра на видимую папку, добавьте
--mount type=bind,src=/opt/docker/data,dst=/var/lib/registry в опции вызова.
Для того, что бы посмотреть состояние репозитория, вы можете воспользоваться следующими командами:
# Проверка статуса сервиса
docker service inspect registry --pretty
# Просмотр содержимого репозитория
curl -k -X GET https://$HOSTNAME:8443/v2/_catalog | python -m json.tool
# Просмотр тегов конкретного образа
curl -k -X GET https://$HOSTNAME:8443/v2/<image>/tags/list | \
python -m json.toolВ связи со сложностью активации реестра
Docker-а с самописным артефактом, взаимодействие с реестром пока не налажено
Docker при сборках может начать не-по-детски зависать. Это значит, что
скопилось много мусора. Очистить его мы сможем, с помощью команды:
docker system prune -aОчень рекомендуется компановать команды оболочки в одну дериктиву RUN
используя два амперсанда и слеш, к примеру:
RUN mkdir /opt/qt4 && \
cd /opt/qt4 && \
/root/qt4config.sh $QT_VER && \
make -j$(nproc)
Требуется переписать данный мануал в ключе переноса сертификатов в сам образ; необходимо минимизировать количество томов связанных непосредственно с хостом, в идеале обеспечить возможность контейнреа пуститься в полёт по улью
Подключитесь к хосту на котором будут бежать GitLab Runner и дочерние
Executor-ы. OS хоста должна относиться к семейству Linux.
Создайте папку:
sudo mkdir -p /srv/nibelungen/config/certs/SERVER=gitlab.kalevala.ru
PORT=443
CERTIFICATE=${SERVER}.crt
openssl s_client \
-connect ${SERVER}:${PORT} \
-showcerts </dev/null 2>/dev/null | \
sed -e '/-----BEGIN/,/-----END/!d' | \
sudo tee "$CERTIFICATE" >/dev/null
sudo mv $CERTIFICATE /srv/nibelungen/config/certs/
sudo cat /srv/nibelungen/config/certs/gitlab.kalevala.ruУбедитесь, что сертификат скачался.
Runner запускается в виде сервиса Docker-а методом deploy-я описанного в
docker-compose файле в улей swarm.
В свете необходимости привязки сервиса к определённому узлу, в рамках
docker service используется механизм меток (labels) и реплик
(replicas). Сервисы позволяют системе автоматически реанимировать контейнеры
в случае их падения. Метки и реплики необходимы, что бы держать сервис на
определённом узле, так как сервис монтирует папку которой не будет на иных
узлах.
Для главного узла, мы используем метку main.
В ещё более далёком будущем, можно будет выпустить сервис в свободный полёт по
улею (swarm) монтируя папку с конфигурацией через nfs. Так же будет
необходимо решить проблему с монтированием сокета: /var/run/docker.sock.
Задайте метку необходимому узлу (node), если она не задана. Сначала
проверьте, задана ли метка:
docker node ls
docker node inspect self --prettyОбратите внимание на секцию labels
Если метки main нет, задайте:
docker node update --label-add main=true <host_name>Убедитесь, что метка (label) выставлена.
docker node inspect self --prettyПерейдём к разворачиванию нашего сервиса в улей. Выполните команду из корня данного репозитория:
sh deploy.shЧто бы получить информацию о сервисах в общем и нашем в частности, выполните
следующие команды. В частности в выводе первой команды, проверьте, что в
строчке нашего сервиса, значение колонки REPLICAS - 1/1:
docker service ls
docker service inspect gitlab_runner --prettyЧто бы получить информацию об ограничениях на расположение сервиса по меткам, выполните:
docker service inspect \
--format='{{json .Spec.TaskTemplate.Placement.Constraints}}' \
gitlab_runnerНЕ Запустите контейнер командой docker-compose up -d, так как мы
запускаем сервис через улей:
Что бы мониторить лолги контейнера, выполните:
docker service logs gitlab_runnerОткройте config.toml с правами root-а:
sudo vim /srv/nibelungen/config/config.tomlНастройте на корневом уровне следующие опции:
oncurrent = 10
check_interval = 1
Все шаги нижеследующей инструкции расписанны ниже.
- Настройте CI/CD для каждого проекта на сервере GitLab
- Создайте необходимый образ
Dockerдля каждого проекта - Зарегестрируйте
Dockerобраз - Зарегестрируйте
runnerдля каждого проекта - Настройте
volumesдля переиспользования скаченных библиотек - Реализуйте этап загрузки артифактов на сервер
- Создайте папку
ciсо скриптами интеграции - Проверьте скрипт очистки старых
pipeline-ов - Заполните файл
.gitlab-ci.yml - Запустите
pipline-ы в настроенных проектах
Создайте файл .gitlab-ci.yml в репозитории и загрузите изменения на сервер.
В рамках проекта активируйте опцию или убедитесь, что она активна по следующему пути:
Settings -> General -> Visibility, project features, permissions -> Expand -> Repository -> Pipeline
Сохраните изменения.
В случае если у вас ещё нет личного токена, или вы хотите создать отдельный личный токен для каждого проекта, перейдите по пути:
Ваша иконка сверху справа -> Access Tokens
Дайте имя токену, поставьте галочку на api.
Нажмите Create personal access token.
Сохраните Личный токен.
Перейдите по пути:
Settings -> CI/CD -> Auto DevOps -> Expand
Снимите галочку с Default to Auto DevOps pipeline
Сохраните изменения.
Далее, на той же странице:
Runners -> Expand -> Specific runners -> Set up a specific runner manually
Скопируйте токен runner-а после фразы And this registration token.
Далее, на той же странице:
Variables -> Expand -> Add variable
Добавьте необходимую переменную PRIVATE_TOKEN указав значение личного
токена из прошлого этапа.
Поставьте галочку на опции Mask variable.
Сохраните изменения.
Далее: Settings -> General -> Project ID
Запомните идентификатор проекта.
Все образы Docker-а создаются в рамках данного (nibelungen) репозитория и
используются в целевых проектах.
Скрипты для всех образов находятся в папке images. Для того, что бы
пересобрать конкретный образ, вы можете перейти в нужную подпапку и запустить
скрипт ./docker.sh. Так же вы можете за раз собрать все образы, запустив
команду ./build.sh в папке images.
Сборка образов должна происходить на хосте, где располагается основной
gitlab-runner.
Рабочие варианты создания и отладки Docker образов описанны в секциях
посвящённых Docker-у ниже, воспользуйтесь ими, если нужно будет создавать
новые образы.
Создайте тег и залейте образ:
docker tag nibelungen Ilmarinen:8443/kalevala/nibelungen:latest
docker push Ilmarinen:8443/kalevala/nibelungen:latestПроверьте, что образ доступен:
docker pull Ilmarinen:8443/kalevala/nibelungenЗапустите несколько запросов к API:
curl -k -X GET https://Ilmarinen:8443/v2/_catalog | python -m json.tool
curl -k -X GET https://Ilmarinen:8443/v2/nibelungen/tags/list | \
python -m json.toolУдалите репозиторий, если необходимо:
$ ls /srv/registry/docker/registry/v2/repositories/kalevala/
$ sudo rm -rf /srv/registry/docker/registry/v2/repositories/kalevala/nibelungen
Не забывайте добавлять ilmarinen:8443/kalevala в имя образа, чтобы он брался из корпоративного реестра Docker-а
Этот момент нужно учитывать при составлении reg.ini, в случае изменения
имени образа, меняйте нужные записи в config.toml.
На ilmarinen префикс будет: ilmarinen:5000/kalevala.
Чтобы массово зарегистрировать все образы, можно воспользоваться чем то вроде:
sh build.sh | grep tagged
docker tag ...
docker push ...
docker pull ...После того, как мы получили и зарегистрировали все необходимые образы, очистите систему:
docker rmi $(docker images -f "dangling=true" -q)В корне каждого проекта который интегрируется в GitLab CI/CD должен быть
файл reg.ini по образцу подобного файла содержащегося в корне данного
проекта. Этот файл парсится скриптом register.py, так же находящемся в корне
данного проекта. Файл включает в себя слудующую информацию:
desc- Описаниеrunner-аtags- Теги, которые вы будете использовать в.gitlab-ci.ymlцелевого проектаimage- Образ докера, который будет вызыватьсяexecuter-омrunner-а для сборки целевого проекта
Как уже сказанно выше, для регистрации runner-а нужно использовать скрипт
register.py из корня данного репозитория, передав ему соответствующие
параметры:
- Путь к целевому проекту сожедржащему файл
reg.ini - Скопированный токен
runner-а - Внутренняя команда
Внутренняя команда может быть:
register- собственно говоря, зарегистрироватьdryrun- вывести на экран созданную команду регистрации, но не запустить её
Если команда вызвана без параметров, будет выведена подсказка. Пример запуска скрипта:
sh /register.py /home/crm/repos/androidts2/ <RUNNER_TOKEN> registerДалее откройте config.toml с правами root-а:
sudo vim /srv/gitlab-runner/config/config.tomlВ случае (а скорее всего это так), если у вас есть свой образ Docker-а для
сборки проекта, установите политику if-not-present для опции pull_policy в
секции [runners.docker] runner-а целевого проекта.
Вот пример секции:
[[runners]]
name = "Nibelungen"
..
[runners.docker]
..
pull_policy = ["if-not-present"]GitLab Runner обнаруживает изменения в файле config.toml и сам перегружает
конфигурацию о чём с радостью рассказывает нам в своём логе, который можно
получить, как мы помним, командой docker service logs gitlab_runner:
gitlab_runner | Checking for jobs... received job=927
gitlab_runner | Job succeeded duration=6.157507035s
gitlab_runner | Configuration loaded builds=0
Если GitLab Runner не перегрузил конфигурацию, это можно сделать вручную:
docker stack ls
NAME SERVICES ORCHESTRATOR
Nibelungen 1 Swarm
$ docker stack services Nibelungen
ID NAME MODE REPLICAS IMAGE
jigjofz8jlxe gitlab_runner replicated 1/1 gitlab/...
docker service update --force gitlab_runner
gitlab_runner
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
docker service logs gitlab_runner
gitlab_runner | Configuration loaded builds=0
gitlab_runner | WARNING: [runWait] received stop signal builds=0
stop-signal=quit
gitlab_runner | WARNING: Starting graceful shutdown, waiting for builds to
finish StopSignal=quit builds=0
gitlab_runner | All workers stopped. Can exit now builds=0В рамках контейнера executor-а необходимо кешировать все скаченные
библиотеки, для этого, для каждой системы сборки нужно найти свой локальный
репозиторий.
В рамках отладки, вы можете запустить необходимые команды через файл
gitlab-ci.yml и увидеть результат в интерфейсе GitLab-а на страницах
проекта.
К примеру, что бы получить путь к локальному репозиторию maven-а, установите
следующую команду на выполнение:
test_job:
script:
- mvn help:evaluate -Dexpression=settings.localRepositoryДля gradle как мы знаем, в качестве кеша используется $USER_HOME/.gradle.
Из прошлого примера, мы уже поняли что $USER_HOME в рамках контейнера, это
/root.
Так же стоит кешировать ANDROID_SDK_ROOT и путь к локальному кешу
gradle-а. volumes для этих папок лучше всего указывать в config.toml, не
стоит указывать их в самом Dockerfile-е.
Для кэширования локального кеша gradle-а необходимо синхронизировать его
папки с отдельной папкой после завешения сборки и в обратно перед самой
сборкой. Используйте для этого команду rsync.
Обязательно ознакомьтесь с документацией
GitLab Runner-а.
Для сложных схем кеширования с перекидыванием артифактов из папки репозитория, используйте монтирование на папку хоста, для отладки и выявления проблем в соответствующих фазах.
Вот пример такого монтирования:
volumes = [ ... "/srv/kalevala_cache:/kalevala_cache"]Как это уже понятно, используемый нами способ кеширования это монтирование
папок хоста или просто кеширование папок контейнера через установку путей в
массиве опции volumes в config.toml.
Описание стратегии
Добавьте полученные пути в массив путей в опции volumes в нужном runner-е
в config.toml. К примеру, для executor-ов использующих maven и gradle,
конфигурация будет как указанно ниже.
Обратите внимание, что в рамках Dockerfile-а мы указали домашнюю папку
gradle-а, как /root/gradle, за место /root/.gradle.
Не стоит монтировать в виде volume-а /usr/local/android-sdk так как файлы
в этой папке статичны, и сам Android SDK уже скачан в образе.
[[runners]]
name = "AndroidTS2"
..
[runners.docker]
..
volumes = ["/cache",
"/srv/android_keys:/data",
"/srv/gradle:/root/gradle",
"/srv/kalevala_cache:/kalevala_cache"]
[[runners]]
name = "Changelogs"
..
[runners.docker]
..
volumes = ["/cache", "/root/.m2/repository"]Файл .gitlab-ci.yml каждого проекта должен использовать скрипт upload.sh
для загрузки артифактов. Скопируйте upload.sh из папки nibelungen данного
проекта в свой, и настройте пути к нужным файлам. Все необходимые параметры
будут передаваться из фазы загрузки в файле .gitlab-ci.yml.
Убедитесь, что у проекта есть возможность принимать артифакты.
Платформа интеграции обладает общим скриптом upload.sh предназначенным для
загрузки артефактов зборки в репозиторий артефактов на GitLab-е.
Скрипт находится в папке ci в корне проекта и может работать в трёх режимах:
- Отладка
- Режим личного токена
- Режим токена задачи
Личный токен и идентификатор проекта вы получили в предыдущих этапах.
Если по какой то причине у вас нет доступа к настройкам проекта, но при этом
есть токен API, вы можете получить идентификатор проекта вызовом REST
запроса:
curl -k -XGET --header "PRIVATE-TOKEN: <PRIVATE-TOKEN>" \
"https://gitlab.kalevala.ru/api/v4/projects"В выводе команды, вы получите идентификатор проекта, который сможете использовать в дальнейшем.
Режим токена задачи это непосредсвенно режим в котором находится скрипт по
время выполнения workflow на GitLab-е.
Без параметров скрипт выдаст подсказку:
upload.sh
Загрузка артефактов на GitLab:
./upload token_type token pid package version arch_path arch_name
token_type: тип токена: JOB или PRIVATE
token : debug для отладочного запуска или token
pid : идентификатор проекта
package : имя пакета
version : версия
arch_path : путь к архиву
arch_name : имя архиваДля отладки, запустите скрипт с параметром debug в позиции token. В этом
режиме скрипт напечатает вызываемый url:
upload.sh PRIVATE debug 265 brunhilde 2.0.0 \
nibelungen/output/nibelungen.txt nibelungen.txt
TN TYPE: PRIVATE
PROJ ID: 265
PACKAGE: brunhilde
VERSION: 2.0.0
AR_PATH: nibelungen/output/nibelungen.txt
AR_NAME: nibelungen.txt
# api/v4/projects/265/packages/generic
# 2.0.0-brunhilde-2021-05-21_18-59-29
URL: https://gitlab.kalevala.ru/.../.../2.0.0/nibelungen.txt
JSON: {"message":"201 Created"}
CODE: 201
UploadedЧто бы запустить скрипт в режиме личного токена, создайте необходимые файлы
у себя и используя личный токен и идентификатор проекта выполните команду
ниже. Вы так же можете сконструировать имя пакета используюя timestamp:
KALEVALA_VERSION=$(sh ci/version.sh)
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
PACKAGE=$KALEVALA_VERSION-brunhilde-$TIMESTAMP
upload.sh PRIVATE <PRIVATE-TOKEN> 265 $PACKAGE 2.0.0 \
nibelungen/output/nibelungen.txt nibelungen.txt
TN TYPE: PRIVATE
PROJ ID: 265
PACKAGE: 2.0.0-brunhilde-2021-05-21_19-02-42
VERSION: 2.0.0
AR_PATH: nibelungen/output/nibelungen.txt
AR_NAME: nibelungen.txt
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 14793 100 25 100 14768 34 20454 --:--:-- --:--:-- --:--:-- 20460
JSON: {"message":"201 Created"}
CODE: 201
UploadedПерейдите в GitLab и убедитесь, что файл загрузился.
Далее, добавьте фазу в .gitlab-ci.yml по примеру указанному в данном файле в
данном проекте. Для того, что бы фаза загрузки приняла артефакты с предыдущей
фазы, используйте секциb artifacts и dependencies. Данная секция должна
использоваться в каждой фазе, которая хочет что то передать следующей фазе.
Так же очень рекомендуется задавать время просрочки артифактов с помощью опции
expire_in как в примере:
pack_job:
artifacts:
expire_in: 10 min
paths:
- nibelungen/output/nibelungen.txtСоздайте в проекте папку ci и добавьте туда все скрипты необходимые для
workflow процесса интеграции данного проекта.
Платформа предоставляет вам скрипт clean.py для очистки старых
pipeline-ов, который находится по исполняемому пути PATH во всех образах.
Скрипт принимает идентификатор проекта, личный токен и количество дней и
часов для вычисления времянной метки за которой все pipeline-ы проекта будут
удалены.
Не смотря на временную метку, скрипт не оставит более 30-и pipeline-ов, даже
если они будут в рамках указанной времянной метки.
Целеесообразно иметь возможность отладить данный скрипт вручную.
Запустите из корня проекта:
ci/clean.py -h
usage: clean.py [-h] [-d] pid token days hours
Очистка старых pipeline-ов
positional arguments:
pid Идентификатор проекта
token Персональный токен владельца проекта
days Количество дней
hours Количество часов
optional arguments:
-h, --help show this help message and exit
-d, --dryrun Сухая прогонкаПопробуйте очистить несколько старый pipeline-ов вручную:
python ci/clean.py 265 xxxxxxxxxxxxxxxxxxxx 0 1 -d
PID: 265
Days: 0
Hours: 1
To keep : 2021-06-01T15:41:42:514
To delete: 2021-06-01T15:19:14:504
To delete: 2021-06-01T14:55:17:499Если опустить опцию -d, то будут удалены два pipeline-а старге одного часа
у проекта под номером 265.
Добавьте и адаптируйте следующий отрывок в каждый .gitlab-ci.yml каждого
проекта:
clean_job:
stage: clean
needs: []
when: always
variables:
PRIVATE_TOKEN: "~token~"
DAYS: 30
HOURS: 0
tags:
- nibelungen
script:
- clean.py $CI_PROJECT_ID $PRIVATE_TOKEN $DAYS $HOURSЗамените тэг nibelungen на тэг проекта.
Как уже писалось выше, вам необходимо создать переменную PRIVATE_TOKEN в
настройках CD/CI проекта. Таким же образом вы можете переписать значения
DAYS и HOURS.
Как уже сказанно, при любых значениях дней и часов, после выполнения скрипта
останется не более 30-и pipeline-ов.
Заполните файл .gitlab-ci.yml в своём проекте по образцу данного файла в
данном проекте создавая необходимые фазы сборки/тестирования/загрузки и тд.
Pipeline-ы с заданиями (jobs) будут выполняться на каждый push в
репозиторий, а так же при ручном merge request-е. Кроме того, вы можете
запустить процесс вручную, перейдя в опцию CI/CD -> Pipelines
В общем, если всё настроено правильно, простой запуск ./build.sh из папки
images/ создаст все необходимые образы.
Для сборок на maven необходимо собрать специальный образ Docker-а
kalevala_maven.
Установите JDK 1.8, так как более поздие JDK не содержат пакет
javax.xml.bind.DatatypeConverter необходимый для наших проектов.
Склонируйте следующие репозитории в соседнии папки с данным репозиторием.
Соберите их командой mvn package:
git@gitlab.kalevala.ru:devs/app_server/core.gitgit@gitlab.kalevala.ru:devs/app_server/dependencies.git
Перейдите в папку images/maven.
Если все репозитории у вас лежат в одной папке, то простой запуск скрипта
sh docker.sh скопирует все зависимости. Если репозитории не в одной папке,
следуйте следующей инструкции.
Создайте папку deps в нынешнем местоположении (images/maven), и скопируйте
в неё следующие файлы:
core/target/core.jardependencies/lib/ojdbc8.jar
Далее продолжим в штатном режиме.
Запустите файл ./docker.sh.
Образ готов, и называется kalevala_maven, именно его используйте в файле
reg.ini для команды регистрации executer-а который использует maven как
средство сборки.
Для сборок на gradle необходимо собрать специальный образ Docker-а
kalevala_gradle.
В образ импортируются имена файлов необходимых для подписывания apk:
- Имя файла хранилища ключей
- Имя файла содержащего пароль от хранилища
Оба файла должны быть в определённой папке на хосте и монтироваться через
config.toml к папке /data/ в контейнере.
Как уже сказанно keystore - хранилище ключей и файл с паролем создаются на
хосте или копируются на хост.
По умолчанию, скрипт создания образа будет искать следующие пути:
/srv/android_keys/KalevalaAPPKey.jks/srv/android_keys/password.txt
Если этих файлов нет по данным путям, система ожидает их в виде параметров
вызова. В таком случае, перейдите в папку images/gradle и запустите файл
sh docker.sh передав путь к хранилищу ключей и путь к файлу с паролем от
хранилища:
ls /srv/android_keys/
keystore.jks password.txt
sh docker.sh /srv/android_keys/keystore.jks /srv/android_keys/password.txtЕсли же вы положили данные файлы по нужным путям, просто запустите файл
sh docker.sh
Система будет просить вас подтвердить установку сертификатов, отвечайте y.
Образ готов, и называется kalevala_gradle, именно его используйте в файле
reg.ini для команды регистрации executer-а который использует gradle как
средство сборки.
Для создания образа gradle вам нужно суметь собрать проект локально.
Установите Android SDK. Краткое описание действий скрипта:
- Скачивает Android SDK
- Подтверждает лицензии
SDK_URL=https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
ANDROID_HOME=/path/to/android-sdk
ANDROID_VERSION=28
ANDROID_BUILD_TOOLS_VERSION=28.0.3
sudo mkdir -p "$ANDROID_HOME"
cd "$ANDROID_HOME"
curl -o sdk.zip $SDK_URL
unzip sdk.zip
rm sdk.zip
mkdir -p "$ANDROID_HOME/licenses"
echo "24333f8a63b6825ea9c5514f83c2829b004d1" | tee \
"$ANDROID_HOME/licenses/android-sdk-license"
echo "84831b9409646a918e30573bab4c9c91346d8" | tee \
"$ANDROID_HOME/licenses/android-sdk-preview-license"
$ANDROID_HOME/tools/bin/sdkmanager --update
$ANDROID_HOME/tools/bin/sdkmanager \
"build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
"platforms;android-${ANDROID_VERSION}" \
"platform-tools"Собирите к примеру проект AndroidTS2. Перейдите в корень проекта, не
забудьте дать права запуска скрипту: chmod u+x gradlew
Краткое описание действий скрипта:
- Установливает переменную среды
ANDROID_SDK_ROOTв значениеANDROID_HOMEизDockerfile-а - Запускает:
./gradlew build
export ANDROID_SDK_ROOT="/usr/local/android-sdk"
sh gradlew --console=plain buildСначала единоразово создайте keystore, затем каждый раз подписывайте с его
помощью apk.
Обратите внимание, что нам нужна установленная переменная
ANDROID_BUILD_TOOLS_VERSION с прошлого этапа.
Краткое описание действий скрипта:
- Создаём хранитель ключей
- Подписываем
USER_NAME=[name]
PASSWORD=[password]
mkdir /path/to/keystore
cd /path/to/keystore
keytool \
-genkey \
-v \
-keystore $USER_NAME.jks \
-alias $USER_NAME \
-keyalg RSA \
-keysize 2048 \
-validity 10000
cd /path/to/repo/app/build/output/apr/release
echo $PASSWORD | \
$ANDROID_SDK_ROOT/build-tools/$ANDROID_BUILD_TOOLS_VERSION/apksigner \
sign \
--ks /path/to/keystore/$USER_NAME.jks \
app-release-unsigned.apk
mv app-release-unsigned.apk app-release.apk
$ANDROID_SDK_ROOT/build-tools/$ANDROID_BUILD_TOOLS_VERSION/apksigner \
verify app-release.apkС помощью последней команды убедитесь, что apk подписан.
Во время линии сборки используется скрипт subscribe.sh, целесообразно иметь
возможность отлаживать его на хосте.
Заметки:
/path/to/nibelungenпуть к корню данного проекта/path/to/repoпуть к проектуgradleapkкоторого предстоит подписать- Файл с паролем должен именоваться
/data/password.txt
cd /path/to/repo
sudo mkdir /data
sudo cp /path/to/<keystore.jks> /data/keystore.jks
sudo cp /path/to/<password.txt> /data/password.txt
export ANDROID_SDK_ROOT=</path/to/android/sdk>
export ANDROID_BUILD_TOOLS_VERSION=<android_build_tools_version>
export KEYSTORE=keystore.jks
export PASSWORD=password.jksЧто бы проверить образ локально, до интеграции в линию сборки, вы можете запустить его в интрактивном режиме. Обратите внимание на следующие вещи:
- Папка
/data/с хранилищем ключей и файлом с паролем монтируются в образ с хоста - Хранилище ключей при загрузке контейнера оказывается по пути:
/data/$KEYSTORE - Файл с паролем при загрузке контейнера оказывается по пути:
/data/$PASSWORD - Переменные среда
ANDROID_SDK_ROOTиANDROID_BUILD_TOOLS_VERSIONтак же задаются во время создания образа <home>/.gradleв рамках образа это/root/gradle/path/to/repoпуть к проектуgradle
cd /path/to/repo
ANDROID_KEYS=/path/to/android_keys
docker run \
--rm \
-it \
--mount type=bind,source="$(pwd)",target=/app \
--mount type=bind,source=$(echo $HOME/.gradle),target=/root/gradle \
--mount type=bind,source=$ANDROID_KEYS,target=/data \
kalevala_gradle \
/bin/bash
# Находясь в терминале контейнера
cd /app
sh gradlew build -x lintДля подписи APK вы можете использовать скрипт subscribe.sh являющийся частью
образа или, в целях отладки, пройти весь процесс вручную.
Используя скрипт, вам надо передать путь к папке содержажей
app-release-unsigned.apk:
subscribe.sh app/build/outputs/apk/release/
echo $?Вручную:
PASSWORD=$(cat /data/$PASSWORD)
echo $PASSWORD
ls /data/$KEYSTORE
cd app/build/outputs/apk/release/
echo $PASSWORD | \
$ANDROID_SDK_ROOT/build-tools/$ANDROID_BUILD_TOOLS_VERSION/apksigner \
sign \
--ks /data/$KEYSTORE \
app-release-unsigned.apk
mv app-release-unsigned.apk app-release.apk
$ANDROID_SDK_ROOT/build-tools/$ANDROID_BUILD_TOOLS_VERSION/apksigner \
verify app-release.apkНе забудьте вернуть права на все файлы в папке репозитория и кеша после монтирования папок в контейнер:
sudo chown -R <user>:<group> /path/to/repo
sudo chown -R <user>:<group> /home/<user>/.gradleЕсли у вас не получается создать образ на определённом хосте, вы можете портировать его сохранением/переносом/загрузкой на другой, к примеру:
docker save -o gradle.img kalevala_gradle
csp gradle.img crm@appsrv-1:/home/crm/images/
ssh crm@appsrv-1
cd ~/images
docker load -i gradle.imgПолезные команды openssl
# Подключиться к серверу
openssl s_client -connect gitlab.kalevala.ru:443
# Слепок сертификата [-sha256|-sha1]
openssl x509 -noout -fingerprint -sha1 -inform pem -in ilmarinen.pem
# Информация о сертификате
openssl x509 -text -noout -in ilmarinen.pemВажно помнить при составлении скриптов для alpine: Не пишите в shebang-е
/bin/bash, так как в alpine его нет, пишите только /bin/sh.
Вот пример:
#!/bin/sh
sh build.shУстановка git-а в Docker-е:
ARG GIT_URL=https://mirrors.edge.kernel.org/pub/software/scm/git
RUN set -o errexit -o nounset \
&& perl -MCPAN -e "ExtUtils::MakeMaker" \
&& wget --no-verbose --no-check-certificate --output-document=git.tar.xz \
$GIT_URL/git-${GIT_VERSION}.tar.xz > /dev/null 2>&1 \
&& mkdir /opt/git \
&& tar -xvf git.tar.xz > /dev/null \
&& rm git.tar.xz \
&& mv git-${GIT_VERSION} /opt/gitsrc \
&& cd /opt/gitsrc \
&& ./configure \
--prefix=/opt/git \
--with-curl \
--with-openssl \
--with-expat \
CFLAGS=-m32 > /dev/null 2>&1 \
&& make install > /dev/null 2>&1 \
&& rm /usr/bin/git \
&& ln -s /opt/git/bin/git /usr/bin/git \
&& git --versionПо поводу контейнеров. Не переживайте, контейнеры executer-ов исчезают после
выполения каждой фазы.