diff --git a/bitnami/jenkins/2/debian-10/Dockerfile b/bitnami/jenkins/2/debian-10/Dockerfile new file mode 100644 index 000000000000..7a74be32ef58 --- /dev/null +++ b/bitnami/jenkins/2/debian-10/Dockerfile @@ -0,0 +1,33 @@ +FROM bitnami/minideb:buster +LABEL maintainer "Bitnami " + +ENV PATH="/opt/bitnami/java/bin:/opt/bitnami/git/bin:/opt/bitnami/nami/bin:$PATH" + +COPY prebuildfs / +# Install required system packages and dependencies +RUN install_packages ca-certificates curl dirmngr fontconfig fonts-dejavu-extra gnupg libc6 libcom-err2 libcurl4 libffi6 libgcc1 libgcrypt20 libgmp10 libgnutls30 libgpg-error0 libgssapi-krb5-2 libhogweed4 libidn2-0 libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 libldap-2.4-2 libnettle6 libnghttp2-14 libp11-kit0 libpsl5 librtmp1 libsasl2-2 libssh2-1 libssl1.1 libtasn1-6 libunistring2 openssh-client procps sudo unzip zlib1g +RUN /build/bitnami-user.sh && \ + /build/install-nami.sh +RUN bitnami-pkg install java-1.8.242-0 --checksum 3a70f3d1c3cd9bc6ec581b2a10373a2b323c0b9af40402ce8d19aeb0b3d02400 +RUN bitnami-pkg install git-2.25.0-0 --checksum 392bea1a8c3607f8ebce5403ec22819915ab8a5cc2245a5249568660b4ed07df +RUN bitnami-pkg unpack jenkins-2.204.1-0 --checksum e352877123c5328c2dfd26f02c28e1fe4e3fc035334b264713ca894770f6c13a +RUN apt-get update && apt-get upgrade && \ + rm -r /var/lib/apt/lists /var/cache/apt/archives +RUN /build/install-gosu.sh +RUN /build/install-tini.sh +RUN mkdir -p /usr/share/jenkins/ref + +COPY rootfs / +RUN ln -sf /install-plugins.sh /usr/local/bin/install-plugins.sh +ENV BITNAMI_APP_NAME="jenkins" \ + BITNAMI_IMAGE_VERSION="2.204.1-debian-10-r0" \ + DISABLE_JENKINS_INITIALIZATION="no" \ + JAVA_OPTS="" \ + JENKINS_HOME="/opt/bitnami/jenkins/jenkins_home" \ + JENKINS_PASSWORD="bitnami" \ + JENKINS_USERNAME="user" + +EXPOSE 8080 8443 50000 + +ENTRYPOINT [ "/app-entrypoint.sh" ] +CMD [ "/run.sh" ] diff --git a/bitnami/jenkins/2/debian-10/docker-compose.yml b/bitnami/jenkins/2/debian-10/docker-compose.yml new file mode 100644 index 000000000000..207be66b876a --- /dev/null +++ b/bitnami/jenkins/2/debian-10/docker-compose.yml @@ -0,0 +1,13 @@ +version: '2' +services: + jenkins: + image: 'bitnami/jenkins:2' + ports: + - '80:8080' + - '443:8443' + - '50000:50000' + volumes: + - 'jenkins_data:/bitnami' +volumes: + jenkins_data: + driver: local diff --git a/bitnami/jenkins/2/debian-10/prebuildfs/build/bitnami-user.sh b/bitnami/jenkins/2/debian-10/prebuildfs/build/bitnami-user.sh new file mode 100755 index 000000000000..ab84296bcdfa --- /dev/null +++ b/bitnami/jenkins/2/debian-10/prebuildfs/build/bitnami-user.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +useradd -ms /bin/bash bitnami +mkdir -p /opt/bitnami && chown bitnami:bitnami /opt/bitnami +sed -i -e 's/\s*Defaults\s*secure_path\s*=/# Defaults secure_path=/' /etc/sudoers +echo 'bitnami ALL=NOPASSWD: ALL' >> /etc/sudoers diff --git a/bitnami/jenkins/2/debian-10/prebuildfs/build/install-gosu.sh b/bitnami/jenkins/2/debian-10/prebuildfs/build/install-gosu.sh new file mode 100755 index 000000000000..1756700daa89 --- /dev/null +++ b/bitnami/jenkins/2/debian-10/prebuildfs/build/install-gosu.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +VERSION="1.11" +SHA256="0b843df6d86e270c5b0f5cbd3c326a04e18f4b7f9b8457fa497b0454c4b138d7" + +curl --silent -L "https://github.com/tianon/gosu/releases/download/${VERSION}/gosu-amd64" > "/usr/local/bin/gosu" +echo "$SHA256" "/usr/local/bin/gosu" | sha256sum --check +chmod u+x "/usr/local/bin/gosu" +mkdir -p "/opt/bitnami/licenses" +curl --silent -L "https://raw.githubusercontent.com/tianon/gosu/master/LICENSE" > "/opt/bitnami/licenses/gosu-${VERSION}.txt" diff --git a/bitnami/jenkins/2/debian-10/prebuildfs/build/install-nami.sh b/bitnami/jenkins/2/debian-10/prebuildfs/build/install-nami.sh new file mode 100755 index 000000000000..d8a59c381f6d --- /dev/null +++ b/bitnami/jenkins/2/debian-10/prebuildfs/build/install-nami.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +curl --silent -L https://nami-prod.s3.amazonaws.com/tools/nami/releases/nami-1.0.0-1-linux-x64.tar.gz > /tmp/nami-linux-x64.tar.gz +echo "80488279b056d5e9c183fe34097c5f496715ab16a602afcc9f78d59f15139a16 /tmp/nami-linux-x64.tar.gz" | sha256sum --check +mkdir -p /opt/bitnami/nami /opt/bitnami/licenses +tar xzf /tmp/nami-linux-x64.tar.gz --strip 1 -C /opt/bitnami/nami && rm /tmp/nami-linux-x64.tar.gz +curl --silent -L https://raw.githubusercontent.com/bitnami/nami/master/COPYING > /opt/bitnami/licenses/nami-1.0.0-1.txt diff --git a/bitnami/jenkins/2/debian-10/prebuildfs/build/install-tini.sh b/bitnami/jenkins/2/debian-10/prebuildfs/build/install-tini.sh new file mode 100755 index 000000000000..8376a36aee5f --- /dev/null +++ b/bitnami/jenkins/2/debian-10/prebuildfs/build/install-tini.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +GPG_KEY="595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7" +GPG_KEY_FINGERPRINT="6380 DC42 8747 F6C3 93FE ACA5 9A84 159D 7001 A4E5" +SERVERS=("ha.pool.sks-keyservers.net" "hkp://p80.pool.sks-keyservers.net:80" "keyserver.ubuntu.com" "hkp://keyserver.ubuntu.com:80" "pgp.mit.edu") +VERSION="0.13.2" + +for server in "${SERVERS[@]}"; do + gpg --keyserver "$server" --recv-keys "$GPG_KEY" && break || : +done +gpg --fingerprint "$GPG_KEY" | grep -q "$GPG_KEY_FINGERPRINT" +curl --silent -L "https://github.com/krallin/tini/releases/download/v${VERSION}/tini.asc" > "/tmp/tini.asc" +curl --silent -L "https://github.com/krallin/tini/releases/download/v${VERSION}/tini" > "/usr/local/bin/tini" +gpg --verify "/tmp/tini.asc" "/usr/local/bin/tini" +chmod +x "/usr/local/bin/tini" +mkdir -p "/opt/bitnami/licenses" +curl --silent -L "https://raw.githubusercontent.com/krallin/tini/master/LICENSE" > "/opt/bitnami/licenses/tini-${VERSION}.txt" diff --git a/bitnami/jenkins/2/debian-10/prebuildfs/opt/bitnami/base/functions b/bitnami/jenkins/2/debian-10/prebuildfs/opt/bitnami/base/functions new file mode 100644 index 000000000000..6e9168c5577b --- /dev/null +++ b/bitnami/jenkins/2/debian-10/prebuildfs/opt/bitnami/base/functions @@ -0,0 +1,121 @@ +#!/bin/bash + +[[ ${BASH_DEBUG:-false} = true ]] && set -x + +# Constants +MODULE="$(basename "$0")" +BITNAMI_PREFIX=/opt/bitnami + +# Color Palette +RESET='\033[0m' +BOLD='\033[1m' + +## Foreground +BLACK='\033[38;5;0m' +RED='\033[38;5;1m' +GREEN='\033[38;5;2m' +YELLOW='\033[38;5;3m' +BLUE='\033[38;5;4m' +MAGENTA='\033[38;5;5m' +CYAN='\033[38;5;6m' +WHITE='\033[38;5;7m' + +## Background +ON_BLACK='\033[48;5;0m' +ON_RED='\033[48;5;1m' +ON_GREEN='\033[48;5;2m' +ON_YELLOW='\033[48;5;3m' +ON_BLUE='\033[48;5;4m' +ON_MAGENTA='\033[48;5;5m' +ON_CYAN='\033[48;5;6m' +ON_WHITE='\033[48;5;7m' + +# Functions + +######################## +# Print to STDERR +# Arguments: +# Message to print +# Returns: +# None +######################### +stderr_print() { + printf "%b\\n" "${*}" >&2 +} + +######################## +# Log message +# Arguments: +# Message to log +# Returns: +# None +######################### +log() { + stderr_print "${NAMI_DEBUG:+${CYAN}${MODULE:-} ${MAGENTA}$(date "+%T.%2N ")}${RESET}${*}" +} +######################## +# Log an 'info' message +# Arguments: +# Message to log +# Returns: +# None +######################### +info() { + log "${GREEN}INFO ${RESET} ==> ${*}" +} +######################## +# Log message +# Arguments: +# Message to log +# Returns: +# None +######################### +warn() { + log "${YELLOW}WARN ${RESET} ==> ${*}" +} +######################## +# Log an 'error' message +# Arguments: +# Message to log +# Returns: +# None +######################### +error() { + log "${RED}ERROR${RESET} ==> ${*}" +} +######################## +# Print the welcome page +# Globals: +# DISABLE_WELCOME_MESSAGE +# BITNAMI_APP_NAME +# Arguments: +# None +# Returns: +# None +######################### +print_welcome_page() { + if [[ -z "${DISABLE_WELCOME_MESSAGE:-}" ]]; then + if [[ -n "$BITNAMI_APP_NAME" ]]; then + print_image_welcome_page + fi + fi +} +######################## +# Print the welcome page for a Bitnami Docker image +# Globals: +# BITNAMI_APP_NAME +# Arguments: +# None +# Returns: +# None +######################### +print_image_welcome_page() { + local github_url="https://github.com/bitnami/bitnami-docker-${BITNAMI_APP_NAME}" + + log "" + log "${BOLD}Welcome to the Bitnami ${BITNAMI_APP_NAME} container${RESET}" + log "Subscribe to project updates by watching ${BOLD}${github_url}${RESET}" + log "Submit issues and feature requests at ${BOLD}${github_url}/issues${RESET}" + log "Send us your feedback at ${BOLD}containers@bitnami.com${RESET}" + log "" +} diff --git a/bitnami/jenkins/2/debian-10/prebuildfs/opt/bitnami/base/helpers b/bitnami/jenkins/2/debian-10/prebuildfs/opt/bitnami/base/helpers new file mode 100644 index 000000000000..da35a1975ec6 --- /dev/null +++ b/bitnami/jenkins/2/debian-10/prebuildfs/opt/bitnami/base/helpers @@ -0,0 +1,40 @@ +#!/bin/bash + +. /opt/bitnami/base/functions + +######################## +# Helper function to initialize a single nami module +# Arguments: +# Module to initialize +# Returns: +# None +# Description: +# Initialize an unpacked nami module with the `nami initialize` command. +# Command arguments can be specified as function argumnts after the module name. +# `--log-level trace` flag is added to the command if `NAMI_DEBUG` env variable exists. +# The log level can be overriden using the `NAMI_LOG_LEVEL` env variable. +######################### +nami_initialize_one() { + local module="${1:?module not specified}" + if nami inspect $module | grep -q '"lifecycle": "unpacked"'; then + local inputs= + if [[ -f "/${module}-inputs.json" ]]; then + inputs="--inputs-file=/${module}-inputs.json" + fi + nami ${NAMI_DEBUG:+--log-level ${NAMI_LOG_LEVEL:-trace}} initialize $module $inputs "${@:2}" + fi +} + +######################## +# Helper function to initialize one or more nami modules +# Arguments: +# Module to initialize +# Returns: +# None +######################### +nami_initialize() { + local module="${1:?module not specified}" + for module in "${@}"; do + nami_initialize_one $module + done +} diff --git a/bitnami/jenkins/2/debian-10/prebuildfs/usr/sbin/bitnami-pkg b/bitnami/jenkins/2/debian-10/prebuildfs/usr/sbin/bitnami-pkg new file mode 100755 index 000000000000..3d934df5585a --- /dev/null +++ b/bitnami/jenkins/2/debian-10/prebuildfs/usr/sbin/bitnami-pkg @@ -0,0 +1,211 @@ +#!/bin/bash -e +. /opt/bitnami/base/functions + +print_usage() { + log "Usage: bitnami-pkg - [OPTIONS] -- [ARGS]" + log "" + log "Download and install Bitnami packages" + log "" + log "Commands:" + log " install Download and install a package." + log " unpack Download and unpack a package." + log "" + log "Options:" + log " -b, --bucket Package release bucket (default: stacksmith)." + log " -c, --checksum SHA256 verification checksum." + log " -h, --help Show this help message and exit." + log "" + log "If the package is already available in the /tmp/bitnami/pkg/cache/" + log "directory, the download will be skipped. If there is a corresponding" + log "file of the same name post-fixed with .sha256 in the directory," + log "that sha will be used instead of the --checksum option." + log "" + log "Examples:" + log " - Unpack package" + log " \$ bitnami-pkg unpack nginx-1.9.10-0" + log "" + log " - Verify and Install package" + log " \$ bitnami-pkg install nginx-1.9.10-0 --checksum 15565d06b18c2e3710fc08e579ddb3d0e39aa663264a0f7404f0743cb4cdb58d" + log "" + log " - Install package with arguments" + log " \$ bitnami-pkg install mariadb-10.1.11-0 -- --password bitnami" + log "" + log " - Install package from testing" + log " \$ bitnami-pkg install mariadb-10.1.11-0 --bucket testing" + log "" +} + +identify_distro() { + distro="${IMAGE_OS:-unknown}" + if [ "${distro}" == "unknown" -a -f /etc/os-release ]; then + distro="$(grep "^ID=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2)-$(grep "^VERSION_ID=" /etc/os-release | cut -d'=' -f2 | cut -d'"' -f2 | cut -d'.' -f1)" + fi + echo "$distro" +} + +identify_arch() { + local arch=$(uname -m) + + case "${arch}" in + ppc64le) + ;; # no-op + x86_64) + case $(identify_distro) in + debian-*) + arch=amd64 + ;; + ol-*) + arch=x86_64 + ;; + centos-*) + arch=x86_64 + ;; + rhel-*) + arch=x86_64 + ;; + photon-*) + arch=x86_64 + ;; + esac + ;; + *) + arch="unknown" + ;; + esac + echo $arch +} + +# break up command line for easy parsing and check legal options +ARGS=$(getopt -o b:c:h -l "bucket:,checksum:,help" -n "bitnami-pkg" -- "$@") +if [ $? -ne 0 ]; +then + exit 1 +fi + +eval set -- "$ARGS"; +while true; do + case "$1" in + -b|--bucket) + shift + if [ -n "$1" ]; then + RELEASE_BUCKET=$1 + shift + fi + ;; + -c|--checksum) + shift + if [ -n "$1" ]; then + PACKAGE_SHA256=$1 + shift + fi + ;; + -h|--help) + print_usage + exit 0 + ;; + --) + shift + break + ;; + esac +done + +# weed out unrecognized commands +case "$1" in + install|unpack) ;; + *) + error "Unrecognized command: $1" + print_usage + exit 1 + ;; +esac + +# install/unpack command need to be supplied a package name +if [ $# -lt 2 ]; then + print_usage + exit 1 +fi + +INSTALL_ROOT=/tmp/bitnami/pkg/install +CACHE_ROOT=/tmp/bitnami/pkg/cache + +PACKAGE="$2-linux-$(identify_arch)-$(identify_distro)" +PACKAGE_ARGS=${@:3} +PACKAGE_NAME=$(echo $PACKAGE | sed 's/-[0-9].*//') +RELEASE_BUCKET=${RELEASE_BUCKET:-stacksmith} + +mkdir -p $INSTALL_ROOT +cd $INSTALL_ROOT + +info "Downloading $PACKAGE package" +if [ -f $CACHE_ROOT/$PACKAGE.tar.gz ]; then + info "$CACHE_ROOT/$PACKAGE.tar.gz already exists, skipping download." + cp $CACHE_ROOT/$PACKAGE.tar.gz . + if [ -f $CACHE_ROOT/$PACKAGE.tar.gz.sha256 ]; then + info "Using the local sha256 from $CACHE_ROOT/$PACKAGE.tar.gz.sha256" + PACKAGE_SHA256=$(cat $CACHE_ROOT/$PACKAGE.tar.gz.sha256) + fi +else + # display cURL progress bar when a tty is attached + if tty -s; then + CURL_ARGS="-#" + else + CURL_ARGS="-sS" + fi + if ! curl $CURL_ARGS -LOf "https://downloads.bitnami.com/files/$RELEASE_BUCKET/$PACKAGE.tar.gz"; then + warn "Package name '$PACKAGE' does not exist, will try '${PACKAGE%-$(identify_distro)}'..." + if curl $CURL_ARGS -LOf "https://downloads.bitnami.com/files/$RELEASE_BUCKET/${PACKAGE%-$(identify_distro)}.tar.gz"; then + PACKAGE="${PACKAGE%-$(identify_distro)}" + else + error "Could not find the requested package..." + exit 1 + fi + fi +fi + +if ! tar tzf $PACKAGE.tar.gz >/dev/null 2>&1; then + error "Invalid or corrupt '$PACKAGE' package." + exit 1 +fi + +if [ "$PACKAGE_SHA256" ]; then + info "Verifying package integrity" + echo "$PACKAGE_SHA256 $PACKAGE.tar.gz" | sha256sum -c - +fi + +# If the tarball has too many files, it can trigger a bug +# in overlayfs when using tar. Install bsdtar in the container image +# to workaround it. As the overhead is too big (~40 MB), it is not added by +# default. Source: https://github.com/coreos/bugs/issues/1095 +if which bsdtar > /dev/null; then + bsdtar -xf $PACKAGE.tar.gz +else + tar xzf $PACKAGE.tar.gz +fi + +case "$1" in + install) info "Installing $PACKAGE" ;; + unpack) info "Unpacking $PACKAGE" ;; +esac +nami $1 $PACKAGE $PACKAGE_ARGS + +rm -rf $INSTALL_ROOT + +if [ "$BITNAMI_PKG_EXTRA_DIRS" ]; then + info "Creating extra directories" + for i in ${BITNAMI_PKG_EXTRA_DIRS}; do + mkdir -p $i + done +fi + +if [ "$BITNAMI_PKG_CHMOD" ]; then + DIRS="/.nami /bitnami $BITNAMI_PKG_EXTRA_DIRS" + if ! [[ $PACKAGE_NAME =~ .*-client ]]; then + mkdir -p /bitnami/$PACKAGE_NAME + fi + # We need to be in $HOME in order to nami inspect works + cd $HOME + DIRS+=" $(nami inspect $PACKAGE_NAME | grep -e 'installdir' | cut -f4 -d\")" + info "Fixing permissions: chmod $BITNAMI_PKG_CHMOD $DIRS" + chmod $BITNAMI_PKG_CHMOD $DIRS +fi diff --git a/bitnami/jenkins/2/debian-10/rootfs/app-entrypoint.sh b/bitnami/jenkins/2/debian-10/rootfs/app-entrypoint.sh new file mode 100755 index 000000000000..ce68566f52aa --- /dev/null +++ b/bitnami/jenkins/2/debian-10/rootfs/app-entrypoint.sh @@ -0,0 +1,19 @@ +#!/bin/bash -e + +. /opt/bitnami/base/functions +. /opt/bitnami/base/helpers + +print_welcome_page + +if [[ "$1" == "nami" && "$2" == "start" ]] || [[ "$1" == "/run.sh" ]]; then + ## Copy custom files to home + readonly copy_log="/opt/bitnami/jenkins/copy_reference_file.log" + touch "${copy_log}" || { echo "Can not write to ${copy_log}. Wrong volume permissions?"; exit 1; } + echo "--- Copying files at $(date)" >> "$copy_log" + find /usr/share/jenkins/ref/ \( -type f -o -type l \) | xargs -I % -P10 bash -c '. /jenkins-support; copy_reference_file %' + + nami_initialize jenkins + info "Starting jenkins... " +fi + +exec tini -- "$@" diff --git a/bitnami/jenkins/2/debian-10/rootfs/install-plugins.sh b/bitnami/jenkins/2/debian-10/rootfs/install-plugins.sh new file mode 100755 index 000000000000..1b5d2689394a --- /dev/null +++ b/bitnami/jenkins/2/debian-10/rootfs/install-plugins.sh @@ -0,0 +1,247 @@ +#!/bin/bash -eu + +## Based on https://github.com/jenkinsci/docker/blob/610f266227fcda2aa2c409998690607da1dc6c4a/install-plugins.sh + +set -o pipefail + +REF_DIR="/usr/share/jenkins/ref/plugins/" +FAILED="$REF_DIR/failed-plugins.txt" +JENKINS_WAR=/opt/bitnami/jenkins/jenkins.war + +. /jenkins-support + +getLockFile() { + printf '%s' "$REF_DIR/${1}.lock" +} + +getArchiveFilename() { + printf '%s' "$REF_DIR/${1}.jpi" +} + +download() { + local plugin originalPlugin version lock ignoreLockFile + plugin="$1" + version="${2:-latest}" + ignoreLockFile="${3:-}" + lock="$(getLockFile "$plugin")" + + if [[ $ignoreLockFile ]] || mkdir "$lock" &>/dev/null; then + if ! doDownload "$plugin" "$version"; then + # some plugin don't follow the rules about artifact ID + # typically: docker-plugin + originalPlugin="$plugin" + plugin="${plugin}-plugin" + if ! doDownload "$plugin" "$version"; 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" + 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 [[ "$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" + else + JENKINS_UC_DOWNLOAD="https://updates.jenkins.io/download" + url="$JENKINS_UC_DOWNLOAD/plugins/$plugin/$version/${plugin}.hpi" + fi + + echo "Downloading plugin: $plugin from $url" + curl -sSfL --connect-timeout 20 --retry 5 --retry-delay 0 --retry-max-time 60 "$url" -o "$jpi" + return $? +} + +bundledPlugins() { + if [ -f $JENKINS_WAR ] + then + TEMP_PLUGIN_DIR=/tmp/plugintemp.$$ + for i in $(unzip -lf $JENKINS_WAR | grep -E '[^detached-]plugins.*\..pi' | awk '{print $4}' | sort) + do + rm -fr $TEMP_PLUGIN_DIR + mkdir -p $TEMP_PLUGIN_DIR + PLUGIN=$(basename "$i"|cut -f1 -d'.') + (cd $TEMP_PLUGIN_DIR;unzip -x "$JENKINS_WAR" "$i" >/dev/null;unzip -x "$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 "ERROR file not found: $JENKINS_WAR" + exit 1 + fi +} + +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 +} + +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="$(/opt/bitnami/java/bin/java -jar $JENKINS_WAR --version)" + major="$(echo "$version" | cut -d '.' -f 1)" + minor="$(echo "$version" | cut -d '.' -f 2)" + echo "$major.$minor" + else + echo "ERROR file not found: $JENKINS_WAR" + return 1 + fi +} + +main() { + local plugin pluginVersion 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..." + bundledPlugins="$(bundledPlugins)" + + echo "Registering preinstalled plugins..." + installedPlugins="$(installedPlugins)" + + # Check if there's a version-specific update center, which is the case for LTS versions + jenkinsVersion="$(jenkinsMajorMinorVersion)" + if curl -fsL -o /dev/null "https://updates.jenkins.io/$jenkinsVersion"; then + JENKINS_UC_LATEST="https://updates.jenkins.io/$jenkinsVersion" + echo "Using version-specific update center: $JENKINS_UC_LATEST..." + else + JENKINS_UC_LATEST= + fi + + echo "Downloading plugins..." + for plugin in "${plugins[@]}"; do + pluginVersion="" + + if [[ $plugin =~ .*:.* ]]; then + pluginVersion=$(versionFromPlugin "${plugin}") + plugin="${plugin%%:*}" + fi + + download "$plugin" "$pluginVersion" "true" & + done + wait + + echo + echo "Plugins included in the WAR:" + echo "${bundledPlugins}" + echo + echo "Plugins installed:" + installedPlugins + + if [[ -f $FAILED ]]; then + echo "Some plugins failed to download!" "$(<"$FAILED")" >&2 + exit 1 + fi + + echo "Cleaning up locks" + rm -r "$REF_DIR"/*.lock +} + +main "$@" diff --git a/bitnami/jenkins/2/debian-10/rootfs/jenkins-inputs.json b/bitnami/jenkins/2/debian-10/rootfs/jenkins-inputs.json new file mode 100644 index 000000000000..53a34e97e3e6 --- /dev/null +++ b/bitnami/jenkins/2/debian-10/rootfs/jenkins-inputs.json @@ -0,0 +1,7 @@ +{ + "disableInitialization": "{{$global.env.DISABLE_JENKINS_INITIALIZATION}}", + "homeDir": "{{$global.env.JENKINS_HOME}}", + "javaOpts": "{{$global.env.JAVA_OPTS}}", + "password": "{{$global.env.JENKINS_PASSWORD}}", + "username": "{{$global.env.JENKINS_USERNAME}}" +} \ No newline at end of file diff --git a/bitnami/jenkins/2/debian-10/rootfs/jenkins-support b/bitnami/jenkins/2/debian-10/rootfs/jenkins-support new file mode 100644 index 000000000000..5bc251113a35 --- /dev/null +++ b/bitnami/jenkins/2/debian-10/rootfs/jenkins-support @@ -0,0 +1,178 @@ +#!/bin/bash -eu + +## Based on https://github.com/jenkinsci/docker/blob/8e33e547a43d248bbb3cf403fe908dbf11d4ae45/jenkins-support + +# 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:23}" + version_marker="${rel}.version_from_image" + dir=$(dirname "${b}") + 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 + action="SKIPPED" + reason="Installed version ($container_version) has been manually upgraded from initial version ($marker_version)" + log=true + 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:23}" + 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:23}" + cp -pr "$(realpath ${f})" "$JENKINS_HOME/${rel}"; + else + action="SKIPPED" + fi + fi + if [[ -n "$VERBOSE" || "$log" == "true" ]]; then + copy_log="/opt/bitnami/jenkins/copy_reference_file.log" + if [ -z "$reason" ]; then + echo "$action $rel" >> "$copy_log" + else + echo "$action $rel : $reason" >> "$copy_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-60} + 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 +} diff --git a/bitnami/jenkins/2/debian-10/rootfs/run.sh b/bitnami/jenkins/2/debian-10/rootfs/run.sh new file mode 100755 index 000000000000..c68f53405108 --- /dev/null +++ b/bitnami/jenkins/2/debian-10/rootfs/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +USER=jenkins +START_COMMAND="java ${JAVA_OPTS} -jar /opt/bitnami/jenkins/jenkins.war" + +exec gosu ${USER} bash -c "${START_COMMAND}" + diff --git a/bitnami/jenkins/README.md b/bitnami/jenkins/README.md index 3b901359a381..9bb7bd14f7ba 100644 --- a/bitnami/jenkins/README.md +++ b/bitnami/jenkins/README.md @@ -39,7 +39,7 @@ Learn more about the Bitnami tagging policy and the difference between rolling t * [`2-ol-7`, `2.204.1-ol-7-r38` (2/ol-7/Dockerfile)](https://github.com/bitnami/bitnami-docker-jenkins/blob/2.204.1-ol-7-r38/2/ol-7/Dockerfile) -* [`2-debian-10`, `0.0.0-debian-10-r0`, `2`, `0.0.0`, `0.0.0-r0`, `latest` (2/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-jenkins/blob/0.0.0-debian-10-r0/2/debian-10/Dockerfile) +* [`2-debian-10`, `2.204.1-debian-10-r0`, `2`, `2.204.1`, `2.204.1-r0`, `latest` (2/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-jenkins/blob/2.204.1-debian-10-r0/2/debian-10/Dockerfile) Subscribe to project updates by watching the [bitnami/jenkins GitHub repo](https://github.com/bitnami/bitnami-docker-jenkins).