Compare commits
2 commits
64e34c8b97
...
fa356847d3
Author | SHA1 | Date | |
---|---|---|---|
fa356847d3 | |||
b72c476834 |
12 changed files with 20 additions and 758 deletions
|
@ -1,79 +0,0 @@
|
||||||
FROM adoptopenjdk/openjdk11:alpine
|
|
||||||
# add ca-certificates package
|
|
||||||
RUN apk add --no-cache ca-certificates
|
|
||||||
# Copy masked.name root cert
|
|
||||||
COPY files/MaskedName_Root_CA.crt /usr/local/share/ca-certificates/MaskedName_Root_CA.crt
|
|
||||||
# update ca certs
|
|
||||||
RUN update-ca-certificates 2>/dev/null
|
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
|
||||||
bash \
|
|
||||||
coreutils \
|
|
||||||
curl \
|
|
||||||
expect \
|
|
||||||
git \
|
|
||||||
git-lfs \
|
|
||||||
openssh-client \
|
|
||||||
openssl \
|
|
||||||
tini \
|
|
||||||
ttf-dejavu \
|
|
||||||
tzdata \
|
|
||||||
unzip
|
|
||||||
|
|
||||||
ARG user=jenkins
|
|
||||||
ARG group=jenkins
|
|
||||||
ARG uid=15000
|
|
||||||
ARG gid=15000
|
|
||||||
ARG http_port=8080
|
|
||||||
ARG agent_port=50000
|
|
||||||
ARG JENKINS_HOME=/var/jenkins_home
|
|
||||||
ARG REF=/usr/share/jenkins/ref
|
|
||||||
|
|
||||||
ENV JENKINS_HOME $JENKINS_HOME
|
|
||||||
ENV JENKINS_SLAVE_AGENT_PORT ${agent_port}
|
|
||||||
ENV REF $REF
|
|
||||||
|
|
||||||
RUN mkdir -p $JENKINS_HOME \
|
|
||||||
&& chown ${uid}:${gid} $JENKINS_HOME \
|
|
||||||
&& addgroup -g ${gid} ${group} \
|
|
||||||
&& adduser -h "$JENKINS_HOME" -u ${uid} -G ${group} -s /bin/bash -D ${user}
|
|
||||||
|
|
||||||
VOLUME $JENKINS_HOME
|
|
||||||
|
|
||||||
RUN mkdir -p ${REF}/init.groovy.d
|
|
||||||
|
|
||||||
ARG JENKINS_VERSION
|
|
||||||
ENV JENKINS_VERSION ${JENKINS_VERSION:-2.249.1}
|
|
||||||
|
|
||||||
ARG JENKINS_SHA=a38ca485b3e2bae6ec69a34b6b34b674f4dd4baf04f20f8dce2d838d08ed5bd6
|
|
||||||
ARG JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war
|
|
||||||
RUN curl -fsSL ${JENKINS_URL} -o /usr/share/jenkins/jenkins.war \
|
|
||||||
&& echo "${JENKINS_SHA} /usr/share/jenkins/jenkins.war" | sha256sum -c -
|
|
||||||
|
|
||||||
ENV JENKINS_UC https://updates.jenkins.io
|
|
||||||
ENV JENKINS_UC_EXPERIMENTAL=https://updates.jenkins.io/experimental
|
|
||||||
ENV JENKINS_INCREMENTALS_REPO_MIRROR=https://repo.jenkins-ci.org/incrementals
|
|
||||||
RUN chown -R ${user} "$JENKINS_HOME" "$REF"
|
|
||||||
|
|
||||||
ARG PLUGIN_CLI_URL=https://github.com/jenkinsci/plugin-installation-manager-tool/releases/download/plugin-management-parent-pom-2.0.0/jenkins-plugin-manager-2.0.0.jar
|
|
||||||
RUN curl -fsSL ${PLUGIN_CLI_URL} -o /usr/lib/jenkins-plugin-manager.jar
|
|
||||||
|
|
||||||
# for main web interface:
|
|
||||||
EXPOSE ${http_port}
|
|
||||||
|
|
||||||
# will be used by attached slave agents:
|
|
||||||
EXPOSE ${agent_port}
|
|
||||||
|
|
||||||
ENV COPY_REFERENCE_FILE_LOG $JENKINS_HOME/copy_reference_file.log
|
|
||||||
|
|
||||||
USER ${user}
|
|
||||||
|
|
||||||
COPY files/jenkins-support /usr/local/bin/jenkins-support
|
|
||||||
COPY files/jenkins.sh /usr/local/bin/jenkins.sh
|
|
||||||
COPY files/tini-shim.sh /bin/tini
|
|
||||||
COPY files/jenkins-plugin-cli.sh /bin/jenkins-plugin-cli
|
|
||||||
|
|
||||||
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/jenkins.sh"]
|
|
||||||
|
|
||||||
# from a derived Dockerfile, can use `RUN install-plugins.sh active.txt` to setup $REF/plugins from a support bundle
|
|
||||||
COPY files/install-plugins.sh /usr/local/bin/install-plugins.sh
|
|
|
@ -1,43 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDNTCCAh2gAwIBAgIUYp8xo5t2lJFP3SiD1fJirgGUQJ0wDQYJKoZIhvcNAQEL
|
|
||||||
BQAwFjEUMBIGA1UEAxMLbWFza2VkLm5hbWUwHhcNMjAwODI5MTkyMzEyWhcNMzAw
|
|
||||||
ODI3MTkyMzQyWjAWMRQwEgYDVQQDEwttYXNrZWQubmFtZTCCASIwDQYJKoZIhvcN
|
|
||||||
AQEBBQADggEPADCCAQoCggEBAMI7oR+KHvvznfnaAXDMO5qpSTCAYCyfjFEohYJf
|
|
||||||
lOcnLONXb3f6sP5d1eltL+UTq0RVU5UP0aNW7hqDTa41MRw0JCDtB68yKdYq2hZf
|
|
||||||
97gA+lj3MEJU6RTAKLrg75GRh/AbNEIgwvPuHKW6hMbtwOyM9DFU//W3xpusalXy
|
|
||||||
RMFzAHfSDj9ci+UygUt9HINWd/SmMGG/8PghaRhfE44wRFMqYezeliIt2JIs43BV
|
|
||||||
7HqG0Oev9WPeXmiaZUYKQetHiQqR14Mxiv1IGzCmwwN+9b4tZtZTa58oM5dPXfbb
|
|
||||||
lrELQE5OsPaNtMtER3MgxovDN3VSCGH/O/GyaEWVanY5UF8CAwEAAaN7MHkwDgYD
|
|
||||||
VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBY8jW3fDVUp
|
|
||||||
URt1prhmDMjkVikgMB8GA1UdIwQYMBaAFBY8jW3fDVUpURt1prhmDMjkVikgMBYG
|
|
||||||
A1UdEQQPMA2CC21hc2tlZC5uYW1lMA0GCSqGSIb3DQEBCwUAA4IBAQAWQz4d3QzE
|
|
||||||
W8NGA16ZPamlVubOLB5DtZz2qrSrn3DeObLIDShInV3qtRlDx9HYJLTCA75Ket0J
|
|
||||||
NTsyMcTy2txd4I8hgdF30XJeEciN9wZ0mKEeP/YKDwe8V2XwWq4XYkDechlWHpZo
|
|
||||||
PfWcoLprKwVUI4HzaqkNmwcmMUI4xAsC+SLe1mrebseKm49oOwdQs/oPVLK+0nEp
|
|
||||||
RvD0aOvohILIa/2ZtKczvhB/L3fo5pg9Ex/0JDBdDHIedMabD3qn8Idse+P5Dfwa
|
|
||||||
Ju2Ctyb+n1TTPxRDMxs2cFbA5irr+2ARJd8jtGS+1fyxogjOWS1RR523F+qIS3su
|
|
||||||
KibGel+gFPpq
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIID0zCCArugAwIBAgIUM52uhXSeTCim1pmzucm/cnIgNp8wDQYJKoZIhvcNAQEL
|
|
||||||
BQAwFjEUMBIGA1UEAxMLbWFza2VkLm5hbWUwHhcNMjAwODI5MTkyNzAwWhcNMjUw
|
|
||||||
ODI4MTkyNzMwWjAtMSswKQYDVQQDEyJtYXNrZWQubmFtZSBJbnRlcm1lZGlhdGUg
|
|
||||||
QXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8LuGo+As
|
|
||||||
ICYWdJjBCY0snF/X+jF1tdcrQzNiRKESEb5dsDiy979bugCblPQDQ+g5WGqXX4pj
|
|
||||||
UyZZE3ZwhOufISlGK0ow1aMjqS+pFlQ85KRD/jUtLPRUJuQF+m2YwId/Mg6/B7Qk
|
|
||||||
d166uJkNxS+MGZCi2OYXeoivnOY7Q0Kj/0vIbc5Vt3kCRVg2ljLSQhoBd+85AHMR
|
|
||||||
jeRjZMeYEYF2HTVwrg4DrC/r00MVtDcNqs6+M7YZ/rzny73GvfJWfWoB1C4piZlg
|
|
||||||
fvUcSDL5HAhjiu5cSeIR7DTuVx7t4PoK6AqUkPygDtq1ZaLybXT7X6d072dR5AXO
|
|
||||||
nWFLPaaGJ979iwIDAQABo4IBADCB/TAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
|
|
||||||
BAUwAwEB/zAdBgNVHQ4EFgQUIkhVYBaK9CcvXG8FM2jKVZ16oZAwHwYDVR0jBBgw
|
|
||||||
FoAUFjyNbd8NVSlRG3WmuGYMyORWKSAwUQYIKwYBBQUHAQEERTBDMEEGCCsGAQUF
|
|
||||||
BzAChjVodHRwOi8vdmF1bHQuY29sdW1iaWEubWFza2VkLm5hbWU6ODIwMC92MS9w
|
|
||||||
a2lfcm9vdC9jYTBHBgNVHR8EQDA+MDygOqA4hjZodHRwOi8vdmF1bHQuY29sdW1i
|
|
||||||
aWEubWFza2VkLm5hbWU6ODIwMC92MS9wa2lfcm9vdC9jcmwwDQYJKoZIhvcNAQEL
|
|
||||||
BQADggEBAK6HMgR+hpwjZCmf5NszDSHr7dYKZXP4LrcHPWs94nLM33UZ572ubGHs
|
|
||||||
dKjRw8YD0cncrsypsYmEgR57U+DHkys394wkb7UOwy1Zvd5IIRXdP0cDylz0QzqM
|
|
||||||
APnQYN+ismkoljhk9ey0Qbo3CmPjM+UQcAxuZQtA4M+riC1+jkude1uYL0szC6Y9
|
|
||||||
4KetfvbNkedSaV5yJaRKCBhRcC4/GjpBG/odQ/5AfBPAFjZqhcIJWBrVYbTQVC79
|
|
||||||
hMA1iwWJPmT9LsjMSUfxFTPzxRnNXQiKFz5kT2OiS1nqh8aOcyU9YC928pkifNJV
|
|
||||||
KokuDezJFM7ie3d+EcBk1V9lHwOWdto=
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,291 +0,0 @@
|
||||||
#!/bin/bash -eu
|
|
||||||
|
|
||||||
# Resolve dependencies and download plugins given on the command line
|
|
||||||
#
|
|
||||||
# FROM jenkins
|
|
||||||
# RUN install-plugins.sh docker-slaves github-branch-source
|
|
||||||
#
|
|
||||||
# Environment variables:
|
|
||||||
# REF: directory with preinstalled plugins. Default: /usr/share/jenkins/ref/plugins
|
|
||||||
# JENKINS_WAR: full path to the jenkins.war. Default: /usr/share/jenkins/jenkins.war
|
|
||||||
# JENKINS_UC: url of the Update Center. Default: ""
|
|
||||||
# JENKINS_UC_EXPERIMENTAL: url of the Experimental Update Center for experimental versions of plugins. Default: ""
|
|
||||||
# JENKINS_INCREMENTALS_REPO_MIRROR: url of the incrementals repo mirror. Default: ""
|
|
||||||
# JENKINS_UC_DOWNLOAD: download url of the Update Center. Default: JENKINS_UC/download
|
|
||||||
# CURL_OPTIONS When downloading the plugins with curl. Curl options. Default: -sSfL
|
|
||||||
# CURL_CONNECTION_TIMEOUT When downloading the plugins with curl. <seconds> Maximum time allowed for connection. Default: 20
|
|
||||||
# CURL_RETRY When downloading the plugins with curl. Retry request if transient problems occur. Default: 3
|
|
||||||
# CURL_RETRY_DELAY When downloading the plugins with curl. <seconds> Wait time between retries. Default: 0
|
|
||||||
# CURL_RETRY_MAX_TIME When downloading the plugins with curl. <seconds> Retry only within this period. Default: 60
|
|
||||||
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
echo "WARN: install-plugins.sh is deprecated, please switch to jenkins-plugin-cli"
|
|
||||||
|
|
||||||
JENKINS_WAR=${JENKINS_WAR:-/usr/share/jenkins/jenkins.war}
|
|
||||||
|
|
||||||
. /usr/local/bin/jenkins-support
|
|
||||||
|
|
||||||
REF_DIR="${REF}/plugins"
|
|
||||||
FAILED="$REF_DIR/failed-plugins.txt"
|
|
||||||
|
|
||||||
getLockFile() {
|
|
||||||
printf '%s' "$REF_DIR/${1}.lock"
|
|
||||||
}
|
|
||||||
|
|
||||||
getArchiveFilename() {
|
|
||||||
printf '%s' "$REF_DIR/${1}.jpi"
|
|
||||||
}
|
|
||||||
|
|
||||||
download() {
|
|
||||||
local plugin originalPlugin version lock ignoreLockFile url
|
|
||||||
plugin="$1"
|
|
||||||
version="${2:-latest}"
|
|
||||||
ignoreLockFile="${3:-}"
|
|
||||||
url="${4:-}"
|
|
||||||
lock="$(getLockFile "$plugin")"
|
|
||||||
|
|
||||||
if [[ $ignoreLockFile ]] || mkdir "$lock" &>/dev/null; then
|
|
||||||
if ! doDownload "$plugin" "$version" "$url"; then
|
|
||||||
# some plugin don't follow the rules about artifact ID
|
|
||||||
# typically: docker-plugin
|
|
||||||
originalPlugin="$plugin"
|
|
||||||
plugin="${plugin}-plugin"
|
|
||||||
if ! doDownload "$plugin" "$version" "$url"; then
|
|
||||||
echo "Failed to download plugin: $originalPlugin or $plugin" >&2
|
|
||||||
echo "Not downloaded: ${originalPlugin}" >> "$FAILED"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! checkIntegrity "$plugin"; then
|
|
||||||
echo "Downloaded file is not a valid ZIP: $(getArchiveFilename "$plugin")" >&2
|
|
||||||
echo "Download integrity: ${plugin}" >> "$FAILED"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
resolveDependencies "$plugin"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
doDownload() {
|
|
||||||
local plugin version url jpi
|
|
||||||
plugin="$1"
|
|
||||||
version="$2"
|
|
||||||
url="$3"
|
|
||||||
jpi="$(getArchiveFilename "$plugin")"
|
|
||||||
|
|
||||||
# If plugin already exists and is the same version do not download
|
|
||||||
if test -f "$jpi" && unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | grep "^Plugin-Version: ${version}$" > /dev/null; then
|
|
||||||
echo "Using provided plugin: $plugin"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n $url ]] ; then
|
|
||||||
echo "Will use url=$url"
|
|
||||||
elif [[ "$version" == "latest" && -n "$JENKINS_UC_LATEST" ]]; then
|
|
||||||
# If version-specific Update Center is available, which is the case for LTS versions,
|
|
||||||
# use it to resolve latest versions.
|
|
||||||
url="$JENKINS_UC_LATEST/latest/${plugin}.hpi"
|
|
||||||
elif [[ "$version" == "experimental" && -n "$JENKINS_UC_EXPERIMENTAL" ]]; then
|
|
||||||
# Download from the experimental update center
|
|
||||||
url="$JENKINS_UC_EXPERIMENTAL/latest/${plugin}.hpi"
|
|
||||||
elif [[ "$version" == incrementals* ]] ; then
|
|
||||||
# Download from Incrementals repo: https://jenkins.io/blog/2018/05/15/incremental-deployment/
|
|
||||||
# Example URL: https://repo.jenkins-ci.org/incrementals/org/jenkins-ci/plugins/workflow/workflow-support/2.19-rc289.d09828a05a74/workflow-support-2.19-rc289.d09828a05a74.hpi
|
|
||||||
local groupId incrementalsVersion
|
|
||||||
# add a trailing ; so the \n gets added to the end
|
|
||||||
readarray -t "-d;" arrIN <<<"${version};";
|
|
||||||
unset 'arrIN[-1]';
|
|
||||||
groupId=${arrIN[1]}
|
|
||||||
incrementalsVersion=${arrIN[2]}
|
|
||||||
url="${JENKINS_INCREMENTALS_REPO_MIRROR}/$(echo "${groupId}" | tr '.' '/')/${plugin}/${incrementalsVersion}/${plugin}-${incrementalsVersion}.hpi"
|
|
||||||
else
|
|
||||||
JENKINS_UC_DOWNLOAD=${JENKINS_UC_DOWNLOAD:-"$JENKINS_UC/download"}
|
|
||||||
url="$JENKINS_UC_DOWNLOAD/plugins/$plugin/$version/${plugin}.hpi"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Downloading plugin: $plugin from $url"
|
|
||||||
# We actually want to allow variable value to be split into multiple options passed to curl.
|
|
||||||
# This is needed to allow long options and any options that take value.
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
retry_command curl ${CURL_OPTIONS:--sSfL} --connect-timeout "${CURL_CONNECTION_TIMEOUT:-20}" --retry "${CURL_RETRY:-3}" --retry-delay "${CURL_RETRY_DELAY:-0}" --retry-max-time "${CURL_RETRY_MAX_TIME:-60}" "$url" -o "$jpi"
|
|
||||||
return $?
|
|
||||||
}
|
|
||||||
|
|
||||||
checkIntegrity() {
|
|
||||||
local plugin jpi
|
|
||||||
plugin="$1"
|
|
||||||
jpi="$(getArchiveFilename "$plugin")"
|
|
||||||
|
|
||||||
unzip -t -qq "$jpi" >/dev/null
|
|
||||||
return $?
|
|
||||||
}
|
|
||||||
|
|
||||||
resolveDependencies() {
|
|
||||||
local plugin jpi dependencies
|
|
||||||
plugin="$1"
|
|
||||||
jpi="$(getArchiveFilename "$plugin")"
|
|
||||||
|
|
||||||
dependencies="$(unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | tr '\n' '|' | sed -e 's#| ##g' | tr '|' '\n' | grep "^Plugin-Dependencies: " | sed -e 's#^Plugin-Dependencies: ##')"
|
|
||||||
|
|
||||||
if [[ ! $dependencies ]]; then
|
|
||||||
echo " > $plugin has no dependencies"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " > $plugin depends on $dependencies"
|
|
||||||
|
|
||||||
IFS=',' read -r -a array <<< "$dependencies"
|
|
||||||
|
|
||||||
for d in "${array[@]}"
|
|
||||||
do
|
|
||||||
plugin="$(cut -d':' -f1 - <<< "$d")"
|
|
||||||
if [[ $d == *"resolution:=optional"* ]]; then
|
|
||||||
echo "Skipping optional dependency $plugin"
|
|
||||||
else
|
|
||||||
local pluginInstalled
|
|
||||||
if pluginInstalled="$(echo -e "${bundledPlugins}\n${installedPlugins}" | grep "^${plugin}:")"; then
|
|
||||||
pluginInstalled="${pluginInstalled//[$'\r']}"
|
|
||||||
local versionInstalled; versionInstalled=$(versionFromPlugin "${pluginInstalled}")
|
|
||||||
local minVersion; minVersion=$(versionFromPlugin "${d}")
|
|
||||||
if versionLT "${versionInstalled}" "${minVersion}"; then
|
|
||||||
echo "Upgrading bundled dependency $d ($minVersion > $versionInstalled)"
|
|
||||||
download "$plugin" &
|
|
||||||
else
|
|
||||||
echo "Skipping already installed dependency $d ($minVersion <= $versionInstalled)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
download "$plugin" &
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
wait
|
|
||||||
}
|
|
||||||
|
|
||||||
bundledPlugins() {
|
|
||||||
if [ -f "$JENKINS_WAR" ]
|
|
||||||
then
|
|
||||||
TEMP_PLUGIN_DIR=/tmp/plugintemp.$$
|
|
||||||
for i in $(jar tf "$JENKINS_WAR" | grep -E '[^detached-]plugins.*\..pi' | sort)
|
|
||||||
do
|
|
||||||
rm -fr $TEMP_PLUGIN_DIR
|
|
||||||
mkdir -p $TEMP_PLUGIN_DIR
|
|
||||||
PLUGIN=$(basename "$i"|cut -f1 -d'.')
|
|
||||||
(cd $TEMP_PLUGIN_DIR;jar xf "$JENKINS_WAR" "$i";jar xvf "$TEMP_PLUGIN_DIR/$i" META-INF/MANIFEST.MF >/dev/null 2>&1)
|
|
||||||
VER=$(grep -E -i Plugin-Version "$TEMP_PLUGIN_DIR/META-INF/MANIFEST.MF"|cut -d: -f2|sed 's/ //')
|
|
||||||
echo "$PLUGIN:$VER"
|
|
||||||
done
|
|
||||||
rm -fr $TEMP_PLUGIN_DIR
|
|
||||||
else
|
|
||||||
echo "war not found, installing all plugins: $JENKINS_WAR"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
versionFromPlugin() {
|
|
||||||
local plugin=$1
|
|
||||||
if [[ $plugin =~ .*:.* ]]; then
|
|
||||||
echo "${plugin##*:}"
|
|
||||||
else
|
|
||||||
echo "latest"
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
installedPlugins() {
|
|
||||||
for f in "$REF_DIR"/*.jpi; do
|
|
||||||
echo "$(basename "$f" | sed -e 's/\.jpi//'):$(get_plugin_version "$f")"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
jenkinsMajorMinorVersion() {
|
|
||||||
if [[ -f "$JENKINS_WAR" ]]; then
|
|
||||||
local version major minor
|
|
||||||
version="$(java -jar "$JENKINS_WAR" --version)"
|
|
||||||
major="$(echo "$version" | cut -d '.' -f 1)"
|
|
||||||
minor="$(echo "$version" | cut -d '.' -f 2)"
|
|
||||||
echo "$major.$minor"
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
local plugin jenkinsVersion
|
|
||||||
local plugins=()
|
|
||||||
|
|
||||||
mkdir -p "$REF_DIR" || exit 1
|
|
||||||
rm -f "$FAILED"
|
|
||||||
|
|
||||||
# Read plugins from stdin or from the command line arguments
|
|
||||||
if [[ ($# -eq 0) ]]; then
|
|
||||||
while read -r line || [ "$line" != "" ]; do
|
|
||||||
# Remove leading/trailing spaces, comments, and empty lines
|
|
||||||
plugin=$(echo "${line}" | tr -d '\r' | sed -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ \t]*#.*$//g' -e '/^[ \t]*$/d')
|
|
||||||
|
|
||||||
# Avoid adding empty plugin into array
|
|
||||||
if [ ${#plugin} -ne 0 ]; then
|
|
||||||
plugins+=("${plugin}")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
|
||||||
plugins=("$@")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create lockfile manually before first run to make sure any explicit version set is used.
|
|
||||||
echo "Creating initial locks..."
|
|
||||||
for plugin in "${plugins[@]}"; do
|
|
||||||
mkdir "$(getLockFile "${plugin%%:*}")"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Analyzing war $JENKINS_WAR..."
|
|
||||||
bundledPlugins="$(bundledPlugins)"
|
|
||||||
|
|
||||||
echo "Registering preinstalled plugins..."
|
|
||||||
installedPlugins="$(installedPlugins)"
|
|
||||||
|
|
||||||
# Get the update center URL based on the jenkins version
|
|
||||||
jenkinsVersion="$(jenkinsMajorMinorVersion)"
|
|
||||||
jenkinsUcJson=$(curl "${CURL_OPTIONS:--sSfL}" -o /dev/null -w "%{url_effective}" "${JENKINS_UC}/update-center.json?version=${jenkinsVersion}")
|
|
||||||
if [ -n "${jenkinsUcJson}" ]; then
|
|
||||||
JENKINS_UC_LATEST=${jenkinsUcJson//update-center.json/}
|
|
||||||
echo "Using version-specific update center: $JENKINS_UC_LATEST..."
|
|
||||||
else
|
|
||||||
JENKINS_UC_LATEST=
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Downloading plugins..."
|
|
||||||
for plugin in "${plugins[@]}"; do
|
|
||||||
local reg='^([^:]+):?([^:]+)?:?([^:]+)?:?(http.+)?'
|
|
||||||
if [[ $plugin =~ $reg ]]; then
|
|
||||||
local pluginId="${BASH_REMATCH[1]}"
|
|
||||||
local version="${BASH_REMATCH[2]}"
|
|
||||||
local lock="${BASH_REMATCH[3]}"
|
|
||||||
local url="${BASH_REMATCH[4]}"
|
|
||||||
download "$pluginId" "$version" "${lock:-true}" "${url}" &
|
|
||||||
else
|
|
||||||
echo "Skipping the line '${plugin}' as it does not look like a reference to a plugin"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
wait
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "WAR bundled plugins:"
|
|
||||||
echo "${bundledPlugins}"
|
|
||||||
echo
|
|
||||||
echo "Installed plugins:"
|
|
||||||
installedPlugins
|
|
||||||
|
|
||||||
if [[ -f $FAILED ]]; then
|
|
||||||
echo "Some plugins failed to download!" "$(<"$FAILED")" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Cleaning up locks"
|
|
||||||
find "$REF_DIR" -regex ".*.lock" | while read -r filepath; do
|
|
||||||
rm -r "$filepath"
|
|
||||||
done
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
java -jar /usr/lib/jenkins-plugin-manager.jar "$@"
|
|
|
@ -1,183 +0,0 @@
|
||||||
#!/bin/bash -eu
|
|
||||||
|
|
||||||
: "${REF:="/usr/share/jenkins/ref"}"
|
|
||||||
|
|
||||||
# compare if version1 < version2
|
|
||||||
versionLT() {
|
|
||||||
local v1; v1=$(echo "$1" | cut -d '-' -f 1 )
|
|
||||||
local q1; q1=$(echo "$1" | cut -s -d '-' -f 2- )
|
|
||||||
local v2; v2=$(echo "$2" | cut -d '-' -f 1 )
|
|
||||||
local q2; q2=$(echo "$2" | cut -s -d '-' -f 2- )
|
|
||||||
if [ "$v1" = "$v2" ]; then
|
|
||||||
if [ "$q1" = "$q2" ]; then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
if [ -z "$q1" ]; then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
if [ -z "$q2" ]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
[ "$q1" = "$(echo -e "$q1\n$q2" | sort -V | head -n1)" ]
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
[ "$v1" = "$(echo -e "$v1\n$v2" | sort -V | head -n1)" ]
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# returns a plugin version from a plugin archive
|
|
||||||
get_plugin_version() {
|
|
||||||
local archive; archive=$1
|
|
||||||
local version; version=$(unzip -p "$archive" META-INF/MANIFEST.MF | grep "^Plugin-Version: " | sed -e 's#^Plugin-Version: ##')
|
|
||||||
version=${version%%[[:space:]]}
|
|
||||||
echo "$version"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Copy files from /usr/share/jenkins/ref into $JENKINS_HOME
|
|
||||||
# So the initial JENKINS-HOME is set with expected content.
|
|
||||||
# Don't override, as this is just a reference setup, and use from UI
|
|
||||||
# can then change this, upgrade plugins, etc.
|
|
||||||
copy_reference_file() {
|
|
||||||
f="${1%/}"
|
|
||||||
b="${f%.override}"
|
|
||||||
rel="${b#"$REF/"}"
|
|
||||||
version_marker="${rel}.version_from_image"
|
|
||||||
dir=$(dirname "${rel}")
|
|
||||||
local action;
|
|
||||||
local reason;
|
|
||||||
local container_version;
|
|
||||||
local image_version;
|
|
||||||
local marker_version;
|
|
||||||
local log; log=false
|
|
||||||
if [[ ${rel} == plugins/*.jpi ]]; then
|
|
||||||
container_version=$(get_plugin_version "$JENKINS_HOME/${rel}")
|
|
||||||
image_version=$(get_plugin_version "${f}")
|
|
||||||
if [[ -e $JENKINS_HOME/${version_marker} ]]; then
|
|
||||||
marker_version=$(cat "$JENKINS_HOME/${version_marker}")
|
|
||||||
if versionLT "$marker_version" "$container_version"; then
|
|
||||||
if ( versionLT "$container_version" "$image_version" && [[ -n $PLUGINS_FORCE_UPGRADE ]]); then
|
|
||||||
action="UPGRADED"
|
|
||||||
reason="Manually upgraded version ($container_version) is older than image version $image_version"
|
|
||||||
log=true
|
|
||||||
else
|
|
||||||
action="SKIPPED"
|
|
||||||
reason="Installed version ($container_version) has been manually upgraded from initial version ($marker_version)"
|
|
||||||
log=true
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ "$image_version" == "$container_version" ]]; then
|
|
||||||
action="SKIPPED"
|
|
||||||
reason="Version from image is the same as the installed version $image_version"
|
|
||||||
else
|
|
||||||
if versionLT "$image_version" "$container_version"; then
|
|
||||||
action="SKIPPED"
|
|
||||||
log=true
|
|
||||||
reason="Image version ($image_version) is older than installed version ($container_version)"
|
|
||||||
else
|
|
||||||
action="UPGRADED"
|
|
||||||
log=true
|
|
||||||
reason="Image version ($image_version) is newer than installed version ($container_version)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ -n "$TRY_UPGRADE_IF_NO_MARKER" ]]; then
|
|
||||||
if [[ "$image_version" == "$container_version" ]]; then
|
|
||||||
action="SKIPPED"
|
|
||||||
reason="Version from image is the same as the installed version $image_version (no marker found)"
|
|
||||||
# Add marker for next time
|
|
||||||
echo "$image_version" > "$JENKINS_HOME/${version_marker}"
|
|
||||||
else
|
|
||||||
if versionLT "$image_version" "$container_version"; then
|
|
||||||
action="SKIPPED"
|
|
||||||
log=true
|
|
||||||
reason="Image version ($image_version) is older than installed version ($container_version) (no marker found)"
|
|
||||||
else
|
|
||||||
action="UPGRADED"
|
|
||||||
log=true
|
|
||||||
reason="Image version ($image_version) is newer than installed version ($container_version) (no marker found)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ ! -e $JENKINS_HOME/${rel} || "$action" == "UPGRADED" || $f = *.override ]]; then
|
|
||||||
action=${action:-"INSTALLED"}
|
|
||||||
log=true
|
|
||||||
mkdir -p "$JENKINS_HOME/${dir}"
|
|
||||||
cp -pr "${f}" "$JENKINS_HOME/${rel}";
|
|
||||||
# pin plugins on initial copy
|
|
||||||
touch "$JENKINS_HOME/${rel}.pinned"
|
|
||||||
echo "$image_version" > "$JENKINS_HOME/${version_marker}"
|
|
||||||
reason=${reason:-$image_version}
|
|
||||||
else
|
|
||||||
action=${action:-"SKIPPED"}
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ ! -e $JENKINS_HOME/${rel} || $f = *.override ]]
|
|
||||||
then
|
|
||||||
action="INSTALLED"
|
|
||||||
log=true
|
|
||||||
mkdir -p "$JENKINS_HOME/${dir}"
|
|
||||||
cp -pr "$(realpath "${f}")" "$JENKINS_HOME/${rel}";
|
|
||||||
else
|
|
||||||
action="SKIPPED"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ -n "$VERBOSE" || "$log" == "true" ]]; then
|
|
||||||
if [ -z "$reason" ]; then
|
|
||||||
echo "$action $rel" >> "$COPY_REFERENCE_FILE_LOG"
|
|
||||||
else
|
|
||||||
echo "$action $rel : $reason" >> "$COPY_REFERENCE_FILE_LOG"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Retries a command a configurable number of times with backoff.
|
|
||||||
#
|
|
||||||
# The retry count is given by ATTEMPTS (default 60), the initial backoff
|
|
||||||
# timeout is given by TIMEOUT in seconds (default 1.)
|
|
||||||
#
|
|
||||||
function retry_command() {
|
|
||||||
local max_attempts=${ATTEMPTS-3}
|
|
||||||
local timeout=${TIMEOUT-1}
|
|
||||||
local success_timeout=${SUCCESS_TIMEOUT-1}
|
|
||||||
local max_success_attempt=${SUCCESS_ATTEMPTS-1}
|
|
||||||
local attempt=0
|
|
||||||
local success_attempt=0
|
|
||||||
local exitCode=0
|
|
||||||
|
|
||||||
while (( attempt < max_attempts ))
|
|
||||||
do
|
|
||||||
set +e
|
|
||||||
"$@"
|
|
||||||
exitCode=$?
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [[ $exitCode == 0 ]]
|
|
||||||
then
|
|
||||||
success_attempt=$(( success_attempt + 1 ))
|
|
||||||
if (( success_attempt >= max_success_attempt))
|
|
||||||
then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
sleep "$success_timeout"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$(date -u '+%T') Failure ($exitCode) Retrying in $timeout seconds..." 1>&2
|
|
||||||
sleep "$timeout"
|
|
||||||
success_attempt=0
|
|
||||||
attempt=$(( attempt + 1 ))
|
|
||||||
timeout=$(( timeout ))
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ $exitCode != 0 ]]
|
|
||||||
then
|
|
||||||
echo "$(date -u '+%T') Failed in the last attempt ($*)" 1>&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
return $exitCode
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
#! /bin/bash -e
|
|
||||||
|
|
||||||
# cert prep
|
|
||||||
for i in /secrets/jenkins.crt /etc/ssl/certs/ca-cert-MaskedName_Root_CA.pem; do
|
|
||||||
cat $i >> /tmp/jenkins_bundle.crt
|
|
||||||
echo >> /tmp/jenkins_bundle.crt
|
|
||||||
done
|
|
||||||
|
|
||||||
expect <(cat <<EOH
|
|
||||||
spawn openssl pkcs12 -inkey /secrets/jenkins.key -in /tmp/jenkins_bundle.crt -export -out /secrets/jenkins.jks
|
|
||||||
expect "Enter Export Password:"
|
|
||||||
send -- "password\r"
|
|
||||||
expect "Verifying - Enter Export Password:"
|
|
||||||
send -- "password\r"
|
|
||||||
interact
|
|
||||||
EOH
|
|
||||||
)
|
|
||||||
|
|
||||||
# defaultish jenkins stuff
|
|
||||||
: "${JENKINS_WAR:="/usr/share/jenkins/jenkins.war"}"
|
|
||||||
: "${JENKINS_HOME:="/var/jenkins_home"}"
|
|
||||||
: "${COPY_REFERENCE_FILE_LOG:="${JENKINS_HOME}/copy_reference_file.log"}"
|
|
||||||
: "${REF:="/usr/share/jenkins/ref"}"
|
|
||||||
touch "${COPY_REFERENCE_FILE_LOG}" || { echo "Can not write to ${COPY_REFERENCE_FILE_LOG}. Wrong volume permissions?"; exit 1; }
|
|
||||||
echo "--- Copying files at $(date)" >> "$COPY_REFERENCE_FILE_LOG"
|
|
||||||
find "${REF}" \( -type f -o -type l \) -exec bash -c '. /usr/local/bin/jenkins-support; for arg; do copy_reference_file "$arg"; done' _ {} +
|
|
||||||
|
|
||||||
# if `docker run` first argument start with `--` the user is passing jenkins launcher arguments
|
|
||||||
if [[ $# -lt 1 ]] || [[ "$1" == "--"* ]]; then
|
|
||||||
|
|
||||||
# read JAVA_OPTS and JENKINS_OPTS into arrays to avoid need for eval (and associated vulnerabilities)
|
|
||||||
java_opts_array=()
|
|
||||||
while IFS= read -r -d '' item; do
|
|
||||||
java_opts_array+=( "$item" )
|
|
||||||
done < <([[ $JAVA_OPTS ]] && xargs printf '%s\0' <<<"$JAVA_OPTS")
|
|
||||||
|
|
||||||
readonly agent_port_property='jenkins.model.Jenkins.slaveAgentPort'
|
|
||||||
if [ -n "${JENKINS_SLAVE_AGENT_PORT:-}" ] && [[ "${JAVA_OPTS:-}" != *"${agent_port_property}"* ]]; then
|
|
||||||
java_opts_array+=( "-D${agent_port_property}=${JENKINS_SLAVE_AGENT_PORT}" )
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$DEBUG" ]] ; then
|
|
||||||
java_opts_array+=( \
|
|
||||||
'-Xdebug' \
|
|
||||||
'-Xrunjdwp:server=y,transport=dt_socket,address=5005,suspend=y' \
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
|
|
||||||
jenkins_opts_array=( )
|
|
||||||
while IFS= read -r -d '' item; do
|
|
||||||
jenkins_opts_array+=( "$item" )
|
|
||||||
done < <([[ $JENKINS_OPTS ]] && xargs printf '%s\0' <<<"$JENKINS_OPTS")
|
|
||||||
|
|
||||||
exec java -Duser.home="$JENKINS_HOME" "${java_opts_array[@]}" -jar ${JENKINS_WAR} "${jenkins_opts_array[@]}" "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# As argument is not jenkins, assume user want to run his own process, for example a `bash` shell to explore this image
|
|
||||||
exec "$@"
|
|
|
@ -1,17 +0,0 @@
|
||||||
#! /bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
***************************************************************************
|
|
||||||
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING *
|
|
||||||
***************************************************************************
|
|
||||||
Please update your scripts to use /sbin/tini or simply tini going forward.
|
|
||||||
Previous path has been preserved for backwards compatibility,
|
|
||||||
but WILL BE REMOVED in the future. (around Jenkins >= 2.107.2+)
|
|
||||||
|
|
||||||
Now sleeping 2 minutes...
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sleep 120
|
|
||||||
|
|
||||||
exec tini "$@"
|
|
|
@ -3,6 +3,11 @@ job "freshrss" {
|
||||||
region = "global"
|
region = "global"
|
||||||
type = "service"
|
type = "service"
|
||||||
|
|
||||||
|
constraint {
|
||||||
|
attribute = "${meta.storage_optimized}"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
|
||||||
update {
|
update {
|
||||||
stagger = "30s"
|
stagger = "30s"
|
||||||
max_parallel = 1
|
max_parallel = 1
|
||||||
|
|
|
@ -3,6 +3,11 @@ job "gitea" {
|
||||||
region = "global"
|
region = "global"
|
||||||
type = "service"
|
type = "service"
|
||||||
|
|
||||||
|
constraint {
|
||||||
|
attribute = "${meta.storage_optimized}"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
|
||||||
update {
|
update {
|
||||||
stagger = "30s"
|
stagger = "30s"
|
||||||
max_parallel = 1
|
max_parallel = 1
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
job "jenkins" {
|
|
||||||
datacenters = ["columbia"]
|
|
||||||
region = "global"
|
|
||||||
type = "service"
|
|
||||||
|
|
||||||
update {
|
|
||||||
stagger = "30s"
|
|
||||||
max_parallel = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
constraint {
|
|
||||||
attribute = "${meta.long_lived}"
|
|
||||||
value = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
vault {
|
|
||||||
policies = ["default", "ansible"]
|
|
||||||
change_mode = "restart"
|
|
||||||
}
|
|
||||||
group "jenkins" {
|
|
||||||
count = 1
|
|
||||||
|
|
||||||
task "jenkins" {
|
|
||||||
driver = "docker"
|
|
||||||
config {
|
|
||||||
image = "docker.service.masked.name:8082/jenkins"
|
|
||||||
ports = ["https"]
|
|
||||||
volumes = [
|
|
||||||
"/opt/jenkins_home:/var/jenkins_home"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
template {
|
|
||||||
data = <<EOH
|
|
||||||
{{- with secret "pki_int/issue/masked-dot-name" "common_name=jenkins.service.masked.name" "alt_names=jenkins.service.columbia.masked.name" -}}
|
|
||||||
{{- .Data.certificate -}}
|
|
||||||
{{- end -}}
|
|
||||||
EOH
|
|
||||||
destination = "${NOMAD_SECRETS_DIR}/jenkins.crt"
|
|
||||||
change_mode = "restart"
|
|
||||||
}
|
|
||||||
|
|
||||||
template {
|
|
||||||
data = <<EOH
|
|
||||||
{{- with secret "pki_int/issue/masked-dot-name" "common_name=jenkins.service.masked.name" "alt_names=jenkins.service.columbia.masked.name" -}}
|
|
||||||
{{- .Data.private_key -}}
|
|
||||||
{{- end -}}
|
|
||||||
EOH
|
|
||||||
destination = "${NOMAD_SECRETS_DIR}/jenkins.key"
|
|
||||||
change_mode = "restart"
|
|
||||||
}
|
|
||||||
|
|
||||||
env {
|
|
||||||
ROOT_URL = "${NOMAD_ADDR_https}"
|
|
||||||
JAVA_ARGS = "-Xmx2048m"
|
|
||||||
JENKINS_OPTS = "--httpsPort=8443 --httpsKeyStore=/secrets/jenkins.jks --httpsKeyStorePassword=password --httpPort=-1"
|
|
||||||
}
|
|
||||||
|
|
||||||
resources {
|
|
||||||
cpu = 2000
|
|
||||||
memory = 2560
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
network {
|
|
||||||
port "https" {
|
|
||||||
to = 8443
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
service {
|
|
||||||
name = "jenkins"
|
|
||||||
port = "https"
|
|
||||||
|
|
||||||
check {
|
|
||||||
name = "jenkins"
|
|
||||||
type = "tcp"
|
|
||||||
interval = "10s"
|
|
||||||
timeout = "2s"
|
|
||||||
address_mode = "driver"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,11 @@ job "nextcloud" {
|
||||||
region = "global"
|
region = "global"
|
||||||
type = "service"
|
type = "service"
|
||||||
|
|
||||||
|
constraint {
|
||||||
|
attribute = "${meta.storage_optimized}"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
|
||||||
update {
|
update {
|
||||||
stagger = "30s"
|
stagger = "30s"
|
||||||
max_parallel = 1
|
max_parallel = 1
|
||||||
|
|
|
@ -3,6 +3,11 @@ job "radicale" {
|
||||||
region = "global"
|
region = "global"
|
||||||
type = "service"
|
type = "service"
|
||||||
|
|
||||||
|
constraint {
|
||||||
|
attribute = "${meta.storage_optimized}"
|
||||||
|
value = "true"
|
||||||
|
}
|
||||||
|
|
||||||
update {
|
update {
|
||||||
stagger = "30s"
|
stagger = "30s"
|
||||||
max_parallel = 1
|
max_parallel = 1
|
||||||
|
|
Loading…
Reference in a new issue