1
0

containerized Jenkins (#179)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/179
Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
Michael Hoennig
2025-06-18 13:51:38 +02:00
parent d351c9a2c1
commit ad1537b856
14 changed files with 283 additions and 142 deletions

15
Jenkins/Dockerfile Normal file
View File

@@ -0,0 +1,15 @@
FROM jenkins/jenkins:lts-jdk21
USER root
# Docker CLI installieren
RUN apt-get update && apt-get install -y docker.io && usermod -aG docker jenkins
# grant user jenkins access to /var/run/docker.sock
RUN usermod -aG messagebus jenkins
# install plugins
COPY Jenkins.plugins /usr/share/jenkins/ref/plugins.txt
RUN jenkins-plugin-cli --plugin-file /usr/share/jenkins/ref/plugins.txt
USER jenkins

8
Jenkins/Jenkins.plugins Normal file
View File

@@ -0,0 +1,8 @@
git
workflow-aggregator
pipeline-github-lib
docker-workflow
credentials
git-client
blueocean
coverage

138
Jenkins/Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,138 @@
pipeline {
parameters {
string(name: 'AGENT_CPUS', defaultValue: '2.5', description: 'CPU limit for the build agent')
string(name: 'AGENT_NETWORK', defaultValue: 'host', description: 'Network to be used for build agent')
booleanParam(name: 'QUICK_RUN', defaultValue: false, description: 'false: all stages but slow, true: just some stages and fast')
}
agent {
dockerfile {
filename 'Jenkins/agent/Dockerfile'
args """--user root --network ${params.AGENT_NETWORK}
--volume /var/run/docker.sock:/var/run/docker.sock
--memory=8g --cpus=${params.AGENT_CPUS}"""
}
}
environment {
GRADLE_USER_HOME = "${env.WORKSPACE}/.gradle-cache"
DOCKER_HOST = 'unix:///var/run/docker.sock'
HSADMINNG_POSTGRES_ADMIN_USERNAME = 'admin'
HSADMINNG_POSTGRES_RESTRICTED_USERNAME = 'restricted'
HSADMINNG_MIGRATION_DATA_PATH = 'migration'
TESTCONTAINERS_RYUK_DISABLED = true
TESTCONTAINERS_LOG_LEVEL = "DEBUG"
}
triggers {
pollSCM('H/1 * * * *')
}
stages {
stage('Detect Docker Environment') {
steps {
sh '''#!/bin/bash +x
if command -v docker >/dev/null 2>&1; then
if docker info --format '{{.SecurityOptions}}' 2>/dev/null | grep -q 'rootless'; then
echo "🟡 Docker daemon is running in ROOTLESS mode"
else
echo "🟢 Docker daemon is running in ROOTFUL mode"
fi
else
echo "❌ Docker CLI not found"
fi'''
}
}
stage('Checkout') {
steps {
checkout scm
}
}
stage('Compile') {
steps {
sh './gradlew clean processSpring compileJava compileTestJava --no-daemon --console=plain'
}
}
stage('Tests') {
parallel {
stage('Other Tests') {
stages {
stage('Unit-Tests') {
steps {
sh './gradlew unitTest --no-daemon --console=plain'
}
}
stage('Migration-Tests') {
steps {
sh './gradlew migrationTest --no-daemon --console=plain'
}
}
stage('Scenario-Tests') {
steps {
sh './gradlew scenarioTest --no-daemon --console=plain'
}
}
stage('General-Tests') {
when {
expression { !params.QUICK_RUN }
}
steps {
sh './gradlew generalIntegrationTest --no-daemon --console=plain'
}
}
stage('Booking+Hosting-Tests') {
when {
expression { !params.QUICK_RUN}
}
steps {
sh './gradlew bookingIntegrationTest hostingIntegrationTest --no-daemon --console=plain'
}
}
}
}
// in parallel because these tests take about as much time as all others combined
stage('Office-Tests') {
when {
expression { !params.QUICK_RUN }
}
steps {
sh './gradlew officeIntegrationTest --no-daemon --console=plain --fail-fast'
}
}
}
}
stage ('Checks') {
steps {
sh './gradlew check -x pitest -x test -x dependencyCheckAnalyze --no-daemon'
}
}
}
post {
always {
// archive test results
junit testResults: 'build/test-results/*/*.xml', allowEmptyResults: true, checksName: '', skipPublishingChecks: true
// archive the JaCoCo coverage report
// recordCoverage tools: [jacoco(pattern: 'build/reports/jacoco/test/jacocoTestReport.xml')]
sh 'find build -name jacocoTestReport.xml'
archiveArtifacts artifacts: 'build/reports/jacoco/**/jacocoTestReport.xml', allowEmptyArchive: true
// archive scenario-test reports in HTML format
sh './gradlew convertMarkdownToHtml'
archiveArtifacts artifacts:
'build/doc/scenarios/*.html, ' +
'build/reports/dependency-license/dependencies-without-allowed-license.json',
allowEmptyArchive: true
// cleanup workspace
cleanWs()
}
}
}

54
Jenkins/Makefile Normal file
View File

@@ -0,0 +1,54 @@
DOCKER := docker
SOCKET := /var/run/docker.sock
VOLUME := jenkins_home
.PHONY: build run bash init-pw unprotected protected start stop rm purge
# building the Jenkins image
build:
$(DOCKER) build -t jenkins-docker .
# initially running the Jenkins container
run:
$(DOCKER) run --detach \
--dns 8.8.8.8 \
--network bridge \
--publish 8080:8080 --publish 50000:50000 \
--volume $(SOCKET):/var/run/docker.sock \
--volume $(VOLUME):/var/jenkins_home \
--restart unless-stopped \
--name jenkins jenkins-docker
# (re-) starts the Jenkins container
start:
$(DOCKER) start jenkins
# opens a bash within the Jenkins container
bash:
$(DOCKER) exec -it jenkins bash
# prints the inital password of a newly setup Jenkins
init-pw:
$(DOCKER) exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
# disables security for the Jenkins, allows login without credentials
unprotected:
docker exec -it jenkins sed -i 's|<useSecurity>true</useSecurity>|<useSecurity>false</useSecurity>|' /var/jenkins_home/config.xml
docker exec -it jenkins grep useSecurity /var/jenkins_home/config.xml
# enables security for the Jenkins, requires login with credentials
protected:
docker exec -it jenkins sed -i 's|<useSecurity>true</useSecurity>|<useSecurity>true</useSecurity>|' /var/jenkins_home/config.xml
docker exec -it jenkins grep useSecurity /var/jenkins_home/config.xml
# stops the Jenkins container
stop:
$(DOCKER) stop jenkins
# removes the Jenkins container
rm: stop
$(DOCKER) rm jenkins
# purges the Jenkins volume (finally deletes the configuration)
purge: rm
$(DOCKER) volume rm $(VOLUME)

9
Jenkins/agent/Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
FROM eclipse-temurin:21-jdk
RUN apt-get update && \
apt-get install -y \
postgresql-client \
bind9-utils \
docker.io \
pandoc && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*