diff --git a/bitnami/jenkins/2/debian-11/Dockerfile b/bitnami/jenkins/2/debian-11/Dockerfile index 9dcc4d4d4723..968150a374fc 100644 --- a/bitnami/jenkins/2/debian-11/Dockerfile +++ b/bitnami/jenkins/2/debian-11/Dockerfile @@ -6,7 +6,7 @@ ARG TARGETARCH LABEL org.opencontainers.image.authors="https://bitnami.com/contact" \ org.opencontainers.image.description="Application packaged by Bitnami" \ org.opencontainers.image.licenses="Apache-2.0" \ - org.opencontainers.image.ref.name="2.375.2-debian-11-r10" \ + org.opencontainers.image.ref.name="2.375.2-debian-11-r11" \ org.opencontainers.image.source="https://github.com/bitnami/containers/tree/main/bitnami/jenkins" \ org.opencontainers.image.title="jenkins" \ org.opencontainers.image.vendor="VMware, Inc." \ @@ -20,7 +20,7 @@ ENV HOME="/" \ COPY prebuildfs / SHELL ["/bin/bash", "-o", "pipefail", "-c"] # Install required system packages and dependencies -RUN install_packages ca-certificates curl fontconfig git libfontconfig1 openssh-client procps unzip zlib1g +RUN install_packages ca-certificates curl fontconfig git jq libfontconfig1 openssh-client procps unzip zlib1g RUN mkdir -p /tmp/bitnami/pkg/cache/ && cd /tmp/bitnami/pkg/cache/ && \ COMPONENTS=( \ "render-template-1.0.5-0-linux-${OS_ARCH}-debian-11" \ diff --git a/bitnami/jenkins/2/debian-11/prebuildfs/opt/bitnami/licenses/licenses.txt b/bitnami/jenkins/2/debian-11/prebuildfs/opt/bitnami/licenses/licenses.txt index c76ba31f3b8a..8373a19703c6 100644 --- a/bitnami/jenkins/2/debian-11/prebuildfs/opt/bitnami/licenses/licenses.txt +++ b/bitnami/jenkins/2/debian-11/prebuildfs/opt/bitnami/licenses/licenses.txt @@ -1,3 +1,3 @@ -Bitnami containers ship with software bundles. You can find the licenses under: -/opt/bitnami/nami/COPYING +Bitnami containers ship with software bundles. You can find the licenses at: +https://bitnami.com/open-source /opt/bitnami/[name-of-bundle]/licenses/[bundle-version].txt diff --git a/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins-env.sh b/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins-env.sh index 55666557e43f..e859ef7c1725 100644 --- a/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins-env.sh +++ b/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins-env.sh @@ -23,6 +23,12 @@ export BITNAMI_DEBUG="${BITNAMI_DEBUG:-false}" # variable will be overridden with the value specified in that file jenkins_env_vars=( JENKINS_HOME + JENKINS_PLUGINS + JENKINS_PLUGINS_LATEST + JENKINS_PLUGINS_LATEST_SPECIFIED + JENKINS_SKIP_IMAGE_PLUGINS + JENKINS_OVERRIDE_PLUGINS + JENKINS_OVERRIDE_PATHS JENKINS_HTTP_LISTEN_ADDRESS JENKINS_HTTPS_LISTEN_ADDRESS JENKINS_HTTP_PORT_NUMBER @@ -34,6 +40,7 @@ jenkins_env_vars=( JENKINS_FORCE_HTTPS JENKINS_SKIP_BOOTSTRAP JENKINS_ENABLE_SWARM + JENKINS_CERTS_DIR JENKINS_KEYSTORE_PASSWORD JENKINS_USERNAME JENKINS_PASSWORD @@ -69,6 +76,12 @@ export JENKINS_TEMPLATES_DIR="${BITNAMI_ROOT_DIR}/scripts/jenkins/bitnami-templa export JENKINS_VOLUME_DIR="${BITNAMI_VOLUME_DIR}/jenkins" export JENKINS_HOME="${JENKINS_HOME:-${JENKINS_VOLUME_DIR}/home}" export JENKINS_MOUNTED_CONTENT_DIR="/usr/share/jenkins/ref" +export JENKINS_PLUGINS="${JENKINS_PLUGINS:-}" +export JENKINS_PLUGINS_LATEST="${JENKINS_PLUGINS_LATEST:-true}" +export JENKINS_PLUGINS_LATEST_SPECIFIED="${JENKINS_PLUGINS_LATEST_SPECIFIED:-false}" +export JENKINS_SKIP_IMAGE_PLUGINS="${JENKINS_SKIP_IMAGE_PLUGINS:-false}" +export JENKINS_OVERRIDE_PLUGINS="${JENKINS_OVERRIDE_PLUGINS:-false}" +export JENKINS_OVERRIDE_PATHS="${JENKINS_OVERRIDE_PATHS:-}" # System users (when running with a privileged user) export JENKINS_DAEMON_USER="jenkins" @@ -92,6 +105,7 @@ export JENKINS_FORCE_HTTPS="${JENKINS_FORCE_HTTPS:-no}" JENKINS_SKIP_BOOTSTRAP="${JENKINS_SKIP_BOOTSTRAP:-"${DISABLE_JENKINS_INITIALIZATION:-}"}" export JENKINS_SKIP_BOOTSTRAP="${JENKINS_SKIP_BOOTSTRAP:-no}" # only used during the first initialization export JENKINS_ENABLE_SWARM="${JENKINS_ENABLE_SWARM:-no}" +export JENKINS_CERTS_DIR="${JENKINS_CERTS_DIR:-${JENKINS_HOME}}" export JENKINS_KEYSTORE_PASSWORD="${JENKINS_KEYSTORE_PASSWORD:-bitnami}" # Jenkins credentials diff --git a/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins/run.sh b/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins/run.sh index d85dcaa386b6..ce4bc1caafbb 100755 --- a/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins/run.sh +++ b/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/jenkins/run.sh @@ -25,8 +25,8 @@ if is_boolean_yes "$JENKINS_FORCE_HTTPS"; then "--httpPort=-1" "--httpsPort=${JENKINS_HTTPS_PORT_NUMBER:-"$JENKINS_DEFAULT_HTTPS_PORT_NUMBER"}" "--httpsListenAddress=${JENKINS_HTTPS_LISTEN_ADDRESS:-"$JENKINS_DEFAULT_HTTPS_LISTEN_ADDRESS"}" - "--httpsKeyStore=${JENKINS_HOME}/jenkins.jks" - "--httpsKeyStorePassword=$JENKINS_KEYSTORE_PASSWORD" + "--httpsKeyStore=${JENKINS_CERTS_DIR}/jenkins.jks" + "--httpsKeyStorePassword=${JENKINS_KEYSTORE_PASSWORD}" ) else args+=( @@ -34,8 +34,8 @@ else "--httpListenAddress=${JENKINS_HTTP_LISTEN_ADDRESS:-"$JENKINS_DEFAULT_HTTP_LISTEN_ADDRESS"}" "--httpsPort=${JENKINS_HTTPS_PORT_NUMBER:-"$JENKINS_DEFAULT_HTTPS_PORT_NUMBER"}" "--httpsListenAddress=${JENKINS_HTTPS_LISTEN_ADDRESS:-"$JENKINS_DEFAULT_HTTPS_LISTEN_ADDRESS"}" - "--httpsKeyStore=${JENKINS_HOME}/jenkins.jks" - "--httpsKeyStorePassword=$JENKINS_KEYSTORE_PASSWORD" + "--httpsKeyStore=${JENKINS_CERTS_DIR}/jenkins.jks" + "--httpsKeyStorePassword=${JENKINS_KEYSTORE_PASSWORD}" ) fi args+=("$@") diff --git a/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/libjenkins.sh b/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/libjenkins.sh index 880620d93a03..70d13458e8bd 100644 --- a/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/libjenkins.sh +++ b/bitnami/jenkins/2/debian-11/rootfs/opt/bitnami/scripts/libjenkins.sh @@ -207,20 +207,14 @@ jenkins_initialize() { fi if is_mounted_dir_empty "$JENKINS_HOME"; then - # Plugins - if ! is_dir_empty "${JENKINS_BASE_DIR}/plugins"; then - debug "Moving plugins to $JENKINS_HOME" - ensure_dir_exists "${JENKINS_HOME}/plugins" - mv "${JENKINS_BASE_DIR}/plugins"/* "${JENKINS_HOME}/plugins" - am_i_root && configure_permissions_ownership "${JENKINS_HOME}/plugins" -d "755" -f "644" -u "$JENKINS_DAEMON_USER" -g "$JENKINS_DAEMON_GROUP" - else - debug "${JENKINS_BASE_DIR}/plugins is empty, assuming a restart" - fi + # Copy files from mounted directory, except for plugins if ! is_mounted_dir_empty "$JENKINS_MOUNTED_CONTENT_DIR"; then info "Moving custom mounted files to Jenkins home directory" echo "--- Copying files at $(date)" >>"${JENKINS_LOGS_DIR}/copy_reference_file.log" - find "$JENKINS_MOUNTED_CONTENT_DIR" \( -type f -o -type l \) | xargs -I % -P10 bash -c '. /opt/bitnami/scripts/libjenkins.sh && jenkins_add_custom_file %' + find "$JENKINS_MOUNTED_CONTENT_DIR" \( -type f -o -type l \) -and -not -path "$JENKINS_MOUNTED_CONTENT_DIR/plugins/*" | xargs -I % -P10 bash -c '. /opt/bitnami/scripts/libjenkins.sh && jenkins_add_custom_file %' fi + # Install Jenkins plugins defined in JENKINS_PLUGINS + jenkins_install_plugins # Initialize Jenkins if ! is_boolean_yes "$JENKINS_SKIP_BOOTSTRAP"; then # Create init groovy script and initialize Jenkins @@ -233,7 +227,7 @@ jenkins_initialize() { # Rotate the logs in Jenkins to clean the Jenkins warnings before actually configuring the app jenkins_stop # Generate jenkins.jks - "${JAVA_HOME}/bin/keytool" -genkey -keypass "${JENKINS_KEYSTORE_PASSWORD}" -storepass "${JENKINS_KEYSTORE_PASSWORD}" -keystore "${JENKINS_HOME}/jenkins.jks" -dname "CN=${JENKINS_HOST}, O=${JENKINS_HOST}" -alias "${JENKINS_HOST}" + "${JAVA_HOME}/bin/keytool" -genkey -keypass "${JENKINS_KEYSTORE_PASSWORD}" -storepass "${JENKINS_KEYSTORE_PASSWORD}" -keystore "${JENKINS_CERTS_DIR}/jenkins.jks" -dname "CN=${JENKINS_HOST}, O=${JENKINS_HOST}" -alias "${JENKINS_HOST}" mv "$JENKINS_LOG_FILE" "${JENKINS_LOGS_DIR}/jenkins.firstboot.log" rm "${JENKINS_HOME}/init.groovy.d/init-jenkins.groovy" else @@ -241,6 +235,12 @@ jenkins_initialize() { fi else info "Detected data from previous deployments" + jenkins_override_home_paths + # If JENKINS_OVERRIDE_PLUGINS is enabled, remove plugins from the volume if any and trigger new installation + if is_boolean_yes "$JENKINS_OVERRIDE_PLUGINS"; then + [[ -d "${JENKINS_HOME}/plugins" ]] && rm -rf "${JENKINS_HOME}/plugins" + jenkins_install_plugins + fi fi true @@ -320,13 +320,13 @@ jenkins_add_custom_file() { if [[ "$(get_sematic_version "$plugin_version" 1)" -gt "$(get_sematic_version "$current_version" 1)" ]]; then action="UPGRADED" reason="Installed version ($current_version) is older than installed version ($plugin_version)" + cp -pr "$(realpath "${filepath}")" "${JENKINS_HOME}/${relpath}" else action="SKIPPED" reason="Installed version ($current_version) is lower or equal than installed version ($plugin_version)" fi - fi - if [[ ! -f "${JENKINS_HOME}/${relpath}" || "$action" = "UPGRADED" ]]; then - action=${action:-"INSTALLED"} + else + action="INSTALLED" mkdir -p "${JENKINS_HOME}/$(dirname "$relpath")" cp -pr "$(realpath "${filepath}")" "${JENKINS_HOME}/${relpath}" fi @@ -349,7 +349,7 @@ jenkins_add_custom_file() { ######################## # Run custom initialization scripts # Globals: -# DB_* +# JENKINS_* # Arguments: # None # Returns: @@ -381,10 +381,103 @@ jenkins_custom_init_scripts() { rm "${JENKINS_HOME}/init.groovy.d/$(basename "$f")" ;; *) - warn "Skipping $f, supported formats are: .sh .sql .sql.gz" + warn "Skipping $f, supported formats are: .sh .groovy" ;; esac done touch "${JENKINS_VOLUME_DIR}/.user_scripts_initialized" fi } + +######################## +# Installs/upgrades plugins defined +# Globals: +# JENKINS_* +# Arguments: +# None +# Returns: +# None +######################### +jenkins_install_plugins() { + read -r -a plugins_list <<<"$(tr ',;' ' ' <<<"$JENKINS_PLUGINS")" + local -r plugin_manager_jar="${JENKINS_BASE_DIR}/jenkins-plugin-manager.jar" + local -r jenkins_war="${JENKINS_BASE_DIR}/jenkins.war" + local -r plugins_dir="${JENKINS_HOME}/plugins" + local -r tmp_plugins_file="${JENKINS_TMP_DIR}/plugins.txt" + local -a args=("-jar" "${plugin_manager_jar}" "--war" "$jenkins_war" "--plugin-file" "$tmp_plugins_file" "-d" "$plugins_dir" "--verbose") + + info "Installing Jenkins plugins" + # Copy built-in plugins included in the image + if ! is_dir_empty "${JENKINS_BASE_DIR}/plugins" && ! is_boolean_yes "$JENKINS_SKIP_IMAGE_PLUGINS"; then + debug "Moving image plugins to $JENKINS_HOME" + ensure_dir_exists "${JENKINS_HOME}/plugins" + mv "${JENKINS_BASE_DIR}/plugins"/* "${JENKINS_HOME}/plugins" + am_i_root && configure_permissions_ownership "${JENKINS_HOME}/plugins" -d "755" -f "644" -u "$JENKINS_DAEMON_USER" -g "$JENKINS_DAEMON_GROUP" + else + debug "${JENKINS_BASE_DIR}/plugins is empty" + fi + + # Copy plugins from mounted directory + if ! is_mounted_dir_empty "$JENKINS_MOUNTED_CONTENT_DIR/plugins"; then + debug "Moving custom mounted plugins to Jenkins home directory" + echo "--- Copying files at $(date)" >>"${JENKINS_LOGS_DIR}/copy_reference_file.log" + find "$JENKINS_MOUNTED_CONTENT_DIR/plugins" \( -type f -o -type l \) | xargs -I % -P10 bash -c '. /opt/bitnami/scripts/libjenkins.sh && jenkins_add_custom_file %' + else + debug "${JENKINS_MOUNTED_CONTENT_DIR}/plugins is empty" + fi + + # Install plugins from JENKINS_PLUGINS environment variable + if [[ "${#plugins_list[@]}" -gt 0 ]]; then + # Additional parameters + args+=("--latest" "$(is_boolean_yes "$JENKINS_PLUGINS_LATEST" && echo "true" || echo "false")") + if is_boolean_yes "$JENKINS_PLUGINS_LATEST_SPECIFIED"; then + args+=("--latest-specified") + fi + # Install plugins + debug "Installing plugins: ${plugins_list[*]}" + for i in "${plugins_list[@]}"; do + echo "$i" >> "$tmp_plugins_file" + done + if am_i_root; then + debug_execute gosu "$JENKINS_DAEMON_USER" java "${args[@]}" + else + debug_execute java "${args[@]}" + fi + rm "$tmp_plugins_file" + fi +} + +######################## +# Remove directories and files from Jenkins home and/or copy them from the mounted content dir +# Globals: +# JENKINS_* +# Arguments: +# None +# Returns: +# None +######################### +jenkins_override_home_paths() { + read -r -a paths_list <<<"$(tr ',;' ' ' <<<"$JENKINS_OVERRIDE_PATHS")" + # Skip if JENKINS_OVERRIDE_PATHS is empty + [[ "${#paths_list[@]}" -gt 0 ]] || return 0 + + info "The following relative paths will be removed from Jenkins home directory: ${paths_list[*]}" + for path in "${paths_list[@]}"; do + # Ensure no leading slash + relpath=${path#/} + # Remove file from Jenkins home + if [[ -d "${JENKINS_HOME}/${relpath}" ]]; then + rm -rf "${JENKINS_HOME:?}/${relpath}" + elif [[ -f "${JENKINS_HOME}/${relpath}" ]]; then + rm "${JENKINS_HOME}/${relpath}" + fi + # Mount relative path from mounted content dir + if ! is_mounted_dir_empty "$JENKINS_MOUNTED_CONTENT_DIR/${relpath}"; then + debug "Copying mounted directory ${relpath} to Jenkins home directory" + find "$JENKINS_MOUNTED_CONTENT_DIR/${relpath}" \( -type f -o -type l \) | xargs -I % -P10 bash -c '. /opt/bitnami/scripts/libjenkins.sh && jenkins_add_custom_file %' + elif [[ -f "$JENKINS_MOUNTED_CONTENT_DIR/${relpath}" ]]; then + debug "Copying mounted file ${relpath} to Jenkins home directory" + jenkins_add_custom_file "$JENKINS_MOUNTED_CONTENT_DIR/${relpath}" + fi + done +} diff --git a/bitnami/jenkins/2/debian-11/tags-info.yaml b/bitnami/jenkins/2/debian-11/tags-info.yaml index ef670b7e79d6..da853ec648fb 100644 --- a/bitnami/jenkins/2/debian-11/tags-info.yaml +++ b/bitnami/jenkins/2/debian-11/tags-info.yaml @@ -1,5 +1,5 @@ rolling-tags: - - "2" - - "2-debian-11" - - "2.375.2" - - "latest" +- "2" +- 2-debian-11 +- 2.375.2 +- latest diff --git a/bitnami/jenkins/README.md b/bitnami/jenkins/README.md index 84895685933a..e6520b9b3d7c 100644 --- a/bitnami/jenkins/README.md +++ b/bitnami/jenkins/README.md @@ -301,6 +301,14 @@ To download and install a set of plugins and their dependencies, use the [Plugin - [Getting Started with Plugin Installation Manager tool](https://github.com/jenkinsci/plugin-installation-manager-tool#getting-started) +Alternatively, it is possible to install plugins using the following env variables: + +- `JENKINS_PLUGINS`: Comma-separated list of Jenkins plugins to be installed during the first boot. +- `JENKINS_PLUGINS_LATEST`: If set to false, install the minimum required version of the plugins in `JENKINS_PLUGINS`. Default: **true** +- `JENKINS_PLUGINS_LATEST_SPECIFIED`: If set to true, install the latest dependencies of any plugin that is requested to have the latest version. Default: **false** +- `JENKINS_OVERRIDE_PLUGINS`: If set to true, existing plugins in the persisted volume will be removed and will force plugins to be reinstalled. Default: **false** +- `JENKINS_SKIP_IMAGE_PLUGINS`: If set to true, skip the installation of image built-in plugins. Default: **false** + ### Passing JVM parameters You might need to customize the JVM running Jenkins, typically to pass system properties or to tweak heap memory settings. Use the `JAVA_OPTS` environment variable for this purpose: