diff --git a/.gitattributes b/.gitattributes index fe21a8c..dd185af 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ *.sh eol=lf +*.bat eol=crlf client/configs/** eol=lf client-vnc/configs/** eol=lf swarm-jenkins-agent/configs/** eol=lf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7a0e54a..9d27384 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - script: [ 'build-base-k8s-jenkins-agent.sh', 'build-base-k8s-jenkins-coverage-agent.sh', 'build-base-swarm-jenkins-agent.sh', 'build-base-swarm-jenkins-coverage-agent.sh', 'build-edt-swarm-agent.sh', 'build-edt-k8s-agent.sh', 'build-oscript-k8s-agent.sh', 'build-oscript-swarm-agent.sh', 'build-server.sh', 'build-executor.sh'] + script: [ 'build-base-k8s-jenkins-agent.sh', 'build-base-k8s-jenkins-coverage-agent.sh', 'build-base-swarm-jenkins-agent.sh', 'build-base-swarm-jenkins-coverage-agent.sh', 'build-edt-swarm-agent.sh', 'build-edt-k8s-agent.sh', 'build-oscript-k8s-agent.sh', 'build-oscript-swarm-agent.sh', 'build-server.sh', 'build-executor.sh', 'build-sonar-scanner.sh'] steps: - name: Maximize build space diff --git a/Layers.md b/Layers.md index be2a406..d5c0f7a 100644 --- a/Layers.md +++ b/Layers.md @@ -23,6 +23,17 @@ * oscript * test-utils +## SonarScanner (анализ кода, без vnc) + +* client +* jdk +* sonar-scanner + +Реализовано в скриптах: + +* [build-sonar-scanner.sh](build-sonar-scanner.sh) +* [build-sonar-scanner.bat](build-sonar-scanner.bat) + ## 1C как Jenkins агент * client diff --git a/README.md b/README.md index 613b08d..891aafb 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ - [Клиент](#клиент) - [Клиент с поддержкой VNC](#клиент-с-поддержкой-vnc) - [Клиент с дополнительными языками](#клиент-с-дополнительными-языками) + - [SonarScanner](#sonarscanner) - [Тонкий клиент](#тонкий-клиент) - [Тонкий клиент с дополнительными языками](#тонкий-клиент-с-дополнительными-языками) - [Хранилище конфигурации](#хранилище-конфигурации) @@ -86,6 +87,13 @@ env.bat - build-edt-k8s-agent.sh - build-oscript-k8s-agent.sh +3. Отдельные образы: + + - build-server.sh + - build-crs.sh + - build-executor.sh + - build-sonar-scanner.sh + ## Как использовать готовые дистрибутивы Вы можете использовать готовые дистрибутивы платформы, для этого достаточно разместить их в папке `distr`. Скрипты будут автоматически использовать их для сборки образа. @@ -167,6 +175,31 @@ docker build --build-arg ONEC_USERNAME=${ONEC_USERNAME} \ -f client/Dockerfile . ``` +## SonarScanner + +[(Наверх)](#оглавление) + +Образ с [SonarScanner CLI](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/) поверх слоёв `client` + `jdk` (без поддержки VNC). Java предоставляется слоем `jdk`, автоскачивание JRE с сервера отключено (`SONAR_SCANNER_SKIP_JRE_PROVISIONING=true`). SonarScanner CLI 8.x требует Java 21+, поэтому скрипт сборки собирает слой `jdk` с JDK 25 (`SONAR_JDK_VERSION`, по умолчанию `25`). Для сборки всей цепочки слоёв (`client` → `jdk` → `sonar-scanner`) используйте скрипт `build-sonar-scanner.sh` (или `build-sonar-scanner.bat` в Windows). + +Либо вручную, поверх уже собранного образа `onec-client` (см. раздел [Клиент](#клиент)) — сначала слой `jdk`, затем `sonar-scanner`: + +```bash +# слой jdk поверх client +docker build --build-arg DOCKER_REGISTRY_URL=${DOCKER_REGISTRY_URL} \ + --build-arg BASE_IMAGE=onec-client \ + --build-arg BASE_TAG=${ONEC_VERSION} \ + --build-arg OPENJDK_VERSION=25 \ + -t ${DOCKER_REGISTRY_URL}/onec-client-jdk:${ONEC_VERSION} \ + -f jdk/Dockerfile . + +# слой sonar-scanner поверх client + jdk +docker build --build-arg DOCKER_REGISTRY_URL=${DOCKER_REGISTRY_URL} \ + --build-arg BASE_IMAGE=onec-client-jdk \ + --build-arg BASE_TAG=${ONEC_VERSION} \ + -t ${DOCKER_REGISTRY_URL}/onec-sonar-scanner:${ONEC_VERSION} \ + -f sonar-scanner/Dockerfile . +``` + ## Тонкий клиент [(Наверх)](#оглавление) diff --git a/build-oscript-k8s-agent.sh b/build-oscript-k8s-agent.sh index 84ad6f7..57a74ca 100755 --- a/build-oscript-k8s-agent.sh +++ b/build-oscript-k8s-agent.sh @@ -23,7 +23,7 @@ docker build \ --pull \ --build-arg DOCKER_REGISTRY_URL=library \ --build-arg BASE_IMAGE=eclipse-temurin \ - --build-arg BASE_TAG=17 \ + --build-arg BASE_TAG=17-jdk-focal \ -t ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}oscript-jdk:latest \ -f oscript/Dockerfile \ $last_arg diff --git a/build-oscript-swarm-agent.bat b/build-oscript-swarm-agent.bat index cbcc3dc..f733337 100644 --- a/build-oscript-swarm-agent.bat +++ b/build-oscript-swarm-agent.bat @@ -14,7 +14,7 @@ docker build ^ --pull ^ --build-arg DOCKER_REGISTRY_URL=%DOCKER_REGISTRY_URL% ^ --build-arg BASE_IMAGE=eclipse-temurin ^ - --build-arg BASE_TAG=17 ^ + --build-arg BASE_TAG=17-jdk-focal ^ -t %DOCKER_REGISTRY_URL%/oscript-jdk:latest ^ -f oscript/Dockerfile ^ %last_arg% diff --git a/build-oscript-swarm-agent.sh b/build-oscript-swarm-agent.sh index dcdb7d5..b28f474 100755 --- a/build-oscript-swarm-agent.sh +++ b/build-oscript-swarm-agent.sh @@ -23,7 +23,7 @@ docker build \ --pull \ --build-arg DOCKER_REGISTRY_URL=library \ --build-arg BASE_IMAGE=eclipse-temurin \ - --build-arg BASE_TAG=17 \ + --build-arg BASE_TAG=17-jdk-focal \ -t ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}oscript-jdk:latest \ -f oscript/Dockerfile \ $last_arg diff --git a/build-sonar-scanner.bat b/build-sonar-scanner.bat new file mode 100644 index 0000000..1e8d127 --- /dev/null +++ b/build-sonar-scanner.bat @@ -0,0 +1,75 @@ +@echo off + +docker login -u %DOCKER_LOGIN% -p %DOCKER_PASSWORD% %DOCKER_REGISTRY_URL% + +if %ERRORLEVEL% neq 0 goto end + +if "%DOCKER_SYSTEM_PRUNE%"=="true" docker system prune -af + +if %ERRORLEVEL% neq 0 goto end + +if "%NO_CACHE%"=="true" (SET last_arg="--no-cache .") else (SET last_arg=".") + +rem SonarScanner CLI 8.x требует Java 21+, поэтому слой jdk собираем с JDK 25 +if "%SONAR_JDK_VERSION%"=="" set SONAR_JDK_VERSION=25 + +docker build ^ + --pull ^ + --build-arg DOCKER_REGISTRY_URL=library ^ + --build-arg BASE_IMAGE=ubuntu ^ + --build-arg BASE_TAG=20.04 ^ + --build-arg ONESCRIPT_PACKAGES="yard" ^ + -t %DOCKER_REGISTRY_URL%/oscript-downloader:latest ^ + -f oscript/Dockerfile ^ + %last_arg% + +if %ERRORLEVEL% neq 0 goto end + +docker build ^ + --build-arg ONEC_USERNAME=%ONEC_USERNAME% ^ + --build-arg ONEC_PASSWORD=%ONEC_PASSWORD% ^ + --build-arg ONEC_VERSION=%ONEC_VERSION% ^ + --build-arg DOCKER_REGISTRY_URL=%DOCKER_REGISTRY_URL% ^ + --build-arg BASE_IMAGE=oscript-downloader ^ + --build-arg BASE_TAG=latest ^ + -t %DOCKER_REGISTRY_URL%/onec-client:%ONEC_VERSION% ^ + -f client/Dockerfile ^ + %last_arg% + +if %ERRORLEVEL% neq 0 goto end + +docker push %DOCKER_REGISTRY_URL%/onec-client:%ONEC_VERSION% + +if %ERRORLEVEL% neq 0 goto end + +docker build ^ + --build-arg DOCKER_REGISTRY_URL=%DOCKER_REGISTRY_URL% ^ + --build-arg BASE_IMAGE=onec-client ^ + --build-arg BASE_TAG=%ONEC_VERSION% ^ + --build-arg OPENJDK_VERSION=%SONAR_JDK_VERSION% ^ + -t %DOCKER_REGISTRY_URL%/onec-client-jdk:%ONEC_VERSION% ^ + -f jdk/Dockerfile ^ + %last_arg% + +if %ERRORLEVEL% neq 0 goto end + +docker push %DOCKER_REGISTRY_URL%/onec-client-jdk:%ONEC_VERSION% + +if %ERRORLEVEL% neq 0 goto end + +docker build ^ + --build-arg DOCKER_REGISTRY_URL=%DOCKER_REGISTRY_URL% ^ + --build-arg BASE_IMAGE=onec-client-jdk ^ + --build-arg BASE_TAG=%ONEC_VERSION% ^ + -t %DOCKER_REGISTRY_URL%/onec-sonar-scanner:%ONEC_VERSION% ^ + -f sonar-scanner/Dockerfile ^ + %last_arg% + +if %ERRORLEVEL% neq 0 goto end + +docker push %DOCKER_REGISTRY_URL%/onec-sonar-scanner:%ONEC_VERSION% + +if %ERRORLEVEL% neq 0 goto end + +:end +echo End of program. diff --git a/build-sonar-scanner.sh b/build-sonar-scanner.sh new file mode 100755 index 0000000..d65c586 --- /dev/null +++ b/build-sonar-scanner.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +set -eo pipefail + +if [ -n "${DOCKER_LOGIN}" ] && [ -n "${DOCKER_PASSWORD}" ] && [ -n "${DOCKER_REGISTRY_URL}" ]; then + if ! docker login -u "${DOCKER_LOGIN}" -p "${DOCKER_PASSWORD}" "${DOCKER_REGISTRY_URL}"; then + echo "Docker login failed" + exit 1 + fi +else + echo "Skipping Docker login due to missing credentials" +fi + +if [ "${DOCKER_SYSTEM_PRUNE}" = 'true' ] ; then + docker system prune -af +fi + +last_arg='.' +if [ "${NO_CACHE}" = 'true' ] ; then + last_arg='--no-cache .' +fi + +for var in ONEC_USERNAME ONEC_PASSWORD ONEC_VERSION; do + if [ -z "${!var}" ]; then + echo "Required environment variable $var is not set" >&2 + exit 1 + fi +done + +# SonarScanner CLI 8.x требует Java 21+, поэтому слой jdk собираем с JDK 25 +SONAR_JDK_VERSION="${SONAR_JDK_VERSION:-25}" + +docker build \ + --pull \ + --build-arg DOCKER_REGISTRY_URL=library \ + --build-arg BASE_IMAGE=ubuntu \ + --build-arg BASE_TAG=20.04 \ + --build-arg ONESCRIPT_PACKAGES="yard" \ + -t ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}oscript-downloader:latest \ + -f oscript/Dockerfile \ + $last_arg + +docker build \ + --build-arg ONEC_USERNAME=$ONEC_USERNAME \ + --build-arg ONEC_PASSWORD=$ONEC_PASSWORD \ + --build-arg ONEC_VERSION=$ONEC_VERSION \ + --build-arg DOCKER_REGISTRY_URL=$DOCKER_REGISTRY_URL \ + --build-arg BASE_IMAGE=oscript-downloader \ + --build-arg BASE_TAG=latest \ + -t ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}onec-client:$ONEC_VERSION \ + -f client/Dockerfile \ + $last_arg + +if [[ -n "$DOCKER_REGISTRY_URL" ]]; then + docker push $DOCKER_REGISTRY_URL/onec-client:$ONEC_VERSION +else + echo "DOCKER_REGISTRY_URL not set, skipping docker push." +fi + +docker build \ + --build-arg DOCKER_REGISTRY_URL=$DOCKER_REGISTRY_URL \ + --build-arg BASE_IMAGE=onec-client \ + --build-arg BASE_TAG=$ONEC_VERSION \ + --build-arg OPENJDK_VERSION=$SONAR_JDK_VERSION \ + -t ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}onec-client-jdk:$ONEC_VERSION \ + -f jdk/Dockerfile \ + $last_arg + +if [[ -n "$DOCKER_REGISTRY_URL" ]]; then + docker push $DOCKER_REGISTRY_URL/onec-client-jdk:$ONEC_VERSION +else + echo "DOCKER_REGISTRY_URL not set, skipping docker push." +fi + +docker build \ + --build-arg DOCKER_REGISTRY_URL=$DOCKER_REGISTRY_URL \ + --build-arg BASE_IMAGE=onec-client-jdk \ + --build-arg BASE_TAG=$ONEC_VERSION \ + -t ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}onec-sonar-scanner:$ONEC_VERSION \ + -f sonar-scanner/Dockerfile \ + $last_arg + +if [[ -n "$DOCKER_REGISTRY_URL" ]]; then + docker push $DOCKER_REGISTRY_URL/onec-sonar-scanner:$ONEC_VERSION +else + echo "DOCKER_REGISTRY_URL not set, skipping docker push." +fi diff --git a/jdk/Dockerfile b/jdk/Dockerfile index ed324d8..a79e38e 100644 --- a/jdk/Dockerfile +++ b/jdk/Dockerfile @@ -6,6 +6,9 @@ FROM ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}${BASE_IMAGE}:${BASE_TAG} LABEL maintainer="Nikita Gryzlov , FirstBit" +# Установка JDK требует root (например, когда базовый слой client завершается USER usr1cv8) +USER root + # Install OpenJDK ARG OPENJDK_VERSION=17 diff --git a/oscript/Dockerfile b/oscript/Dockerfile index 556fe47..8b1fc84 100644 --- a/oscript/Dockerfile +++ b/oscript/Dockerfile @@ -15,15 +15,22 @@ RUN apt-get update \ wget \ libicu-dev \ pkg-config \ - && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \ - && echo "deb http://download.mono-project.com/repo/debian stable-buster main" > /etc/apt/sources.list.d/mono-official-stable.list \ + && mkdir -p -m 0755 /etc/apt/keyrings \ + && wget -qO- 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF' | \ + gpg --dearmor -o /etc/apt/keyrings/mono-official-stable.gpg \ + # Mono публикует отдельные репозитории под дистрибутив: Debian -> stable-buster, Ubuntu -> stable-focal. + # Подбираем подходящий по фактическому базовому образу (BASE_IMAGE/BASE_TAG могут быть любыми). + && . /etc/os-release \ + && if [ "$ID" = "debian" ]; then mono_repo="debian stable-buster"; else mono_repo="ubuntu stable-focal"; fi \ + && echo "deb [signed-by=/etc/apt/keyrings/mono-official-stable.gpg] https://download.mono-project.com/repo/$mono_repo main" \ + > /etc/apt/sources.list.d/mono-official-stable.list \ && apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ mono-runtime \ ca-certificates-mono \ libmono-i18n4.0-all \ libmono-system-runtime-serialization4.0-cil \ - && rm -rf /etc/apt/sources.list.d/mono-official-stable.list \ + && rm -rf /etc/apt/sources.list.d/mono-official-stable.list /etc/apt/keyrings/mono-official-stable.gpg \ && apt-get update \ && cert-sync --user /etc/ssl/certs/ca-certificates.crt \ && rm -rf \ diff --git a/sonar-scanner/Dockerfile b/sonar-scanner/Dockerfile new file mode 100644 index 0000000..13b476e --- /dev/null +++ b/sonar-scanner/Dockerfile @@ -0,0 +1,41 @@ +ARG DOCKER_REGISTRY_URL +ARG BASE_IMAGE +ARG BASE_TAG + +# Версия SonarScanner CLI. Java предоставляется слоем jdk. +# SonarScanner CLI 8.x требует Java 21+, слой jdk собирается с JDK 25 (см. build-sonar-scanner.sh). +ARG SONAR_SCANNER_VERSION=8.1.0.6389 + +# Стадия загрузки: скачиваем и распаковываем SonarScanner CLI +FROM ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}${BASE_IMAGE}:${BASE_TAG} AS downloader + +ARG SONAR_SCANNER_VERSION +USER root + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + unzip \ + && wget -q -O /tmp/sonar-scanner.zip \ + "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}.zip" \ + && unzip -q /tmp/sonar-scanner.zip -d /opt \ + && mv "/opt/sonar-scanner-${SONAR_SCANNER_VERSION}" /opt/sonar-scanner + +# Финальный образ: SonarScanner CLI поверх слоя client + jdk (Java из слоя jdk) +FROM ${DOCKER_REGISTRY_URL:+"$DOCKER_REGISTRY_URL/"}${BASE_IMAGE}:${BASE_TAG} + +LABEL maintainer="Nikita Fedkin " + +ENV SONAR_SCANNER_HOME=/opt/sonar-scanner + +COPY --from=downloader /opt/sonar-scanner ${SONAR_SCANNER_HOME} + +ENV PATH="${SONAR_SCANNER_HOME}/bin:${PATH}" + +# Java берётся из слоя jdk, поэтому отключаем автоскачивание JRE с сервера +ENV SONAR_SCANNER_SKIP_JRE_PROVISIONING=true + +USER usr1cv8 + +WORKDIR /usr/src + +CMD ["sonar-scanner"]