/managed-scripts/shell/provision_jenkins.sh
Shell | 502 lines | 404 code | 39 blank | 59 comment | 22 complexity | 2ef9a0cda27917b2e9c2a6d41b80206f MD5 | raw file
- #!/bin/bash
- #Created by Sam Gleske (https://github.com/samrocketman/home)
- #Wed May 20 11:09:18 EDT 2015
- #Mac OS X 10.9.5
- #Darwin 13.4.0 x86_64
- #GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin13)
- #curl 7.30.0 (x86_64-apple-darwin13.0) libcurl/7.30.0 SecureTransport zlib/1.2.5
- #awk version 20070501
- #java version "1.7.0_55"
- #Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
- #Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode)
- #DESCRIPTION
- # Provisions a fresh Jenkins on a local laptop, updates the plugins, and runs
- # it.
- # 1. Creates a JENKINS_HOME.
- # 2. Downloads Jenkins.
- # 3. Updates the Jenkins plugins to the latest version.
- #USAGE
- # Automatically provision and start Jenkins on your laptop.
- # mkdir ~/jenkins_testing
- # cd ~/jenkins_testing
- # provision_jenkins.sh bootstrap
- # Kill and completely delete your provisioned Jenkins.
- # cd ~/jenkins_testing
- # provision_jenkins.sh purge
- # Update all plugins to the latest version using jenkins-cli
- # cd ~/jenkins_testing
- # provision_jenkins.sh update-plugins
- # Start or restart Jenkins.
- # cd ~/jenkins_testing
- # provision_jenkins.sh start
- # provision_jenkins.sh restart
- # Stop Jenkins.
- # provision_jenkins.sh stop
- #
- # USER CUSTOMIZED VARIABLES
- #
- #Latest Release
- jenkins_url="${jenkins_url:-http://mirrors.jenkins-ci.org/war/latest/jenkins.war}"
- #LTS Jenkins URL
- #jenkins_url="${jenkins_url:-http://mirrors.jenkins-ci.org/war-stable/latest/jenkins.war}"
- JENKINS_HOME="${JENKINS_HOME:-my_jenkins_home}"
- JENKINS_WEB="${JENKINS_WEB:-http://localhost:8080/}"
- JENKINS_CLI="${JENKINS_CLI:-java -jar ./jenkins-cli.jar -s ${JENKINS_WEB} -noKeyAuth}"
- JENKINS_START="${JENKINS_START:-java -jar jenkins.war}"
- #remove trailing slash
- JENKINS_WEB="${JENKINS_WEB%/}"
- CURL="${CURL:-curl}"
- #Get JAVA_HOME for java on Mac OS X
- #will only run if OS X is detected
- if uname -rms | grep Darwin &> /dev/null; then
- JAVA_HOME="$(/usr/libexec/java_home)"
- PATH="${JAVA_HOME}/bin:${PATH}"
- echo "JAVA_HOME=${JAVA_HOME}"
- java -version
- fi
- export jenkins_url JENKINS_HOME JAVA_HOME PATH JENKINS_CLI CURL
- #
- # SCRIPT CONSOLE SCRIPTS
- #
- function script_skip_wizard() {
- cat <<'EOF'
- import hudson.util.PluginServletFilter
- def j=Jenkins.instance
- if('getSetupWizard' in j.metaClass.methods*.name.sort().unique()) {
- def w=j.getSetupWizard()
- if(w != null) {
- try {
- w.completeSetup()
- }
- catch(Exception e) {
- //pre Jenkins 2.6
- w.completeSetup(j)
- PluginServletFilter.removeFilter(w.FORCE_SETUP_WIZARD_FILTER)
- }
- j.save()
- println 'Wizard skipped.'
- }
- }
- EOF
- }
- function script_disable_usage_stats() {
- echo 'Jenkins.instance.setNoUsageStatistics(true)'
- }
- function script_upgrade_plugins() {
- cat <<'EOF'
- import hudson.model.UpdateSite
- def j = Jenkins.instance
- /*
- Install Jenkins plugins
- */
- def install(Collection c, Boolean dynamicLoad, UpdateSite updateSite) {
- c.each {
- println "Installing ${it} plugin."
- UpdateSite.Plugin plugin = updateSite.getPlugin(it)
- Throwable error = plugin.deploy(dynamicLoad).get().getError()
- if(error != null) {
- println "ERROR installing ${it}, ${error}"
- }
- }
- null
- }
- //upgrade plugins
- UpdateSite s = (UpdateSite) j.getUpdateCenter().getSite(UpdateCenter.ID_DEFAULT)
- //download latest JSON update data
- s.updateDirectlyNow(true)
- install(s.getUpdates()*.getInstalled()*.getShortName(), false, s)
- EOF
- }
- function script_install_plugins() {
- cat <<EOF
- def plugins = "$@".split('[, ]') as ArrayList
- /*
- Install Jenkins plugins
- */
- def install(Collection c, Boolean dynamicLoad, UpdateSite updateSite) {
- c.each {
- println "Installing \${it} plugin."
- UpdateSite.Plugin plugin = updateSite.getPlugin(it)
- Throwable error = plugin.deploy(dynamicLoad).get().getError()
- if(error != null) {
- println "ERROR installing \${it}, \${error}"
- }
- }
- null
- }
- def j = Jenkins.instance
- //upgrade plugins
- UpdateSite s = (UpdateSite) j.getUpdateCenter().getSite(UpdateCenter.ID_DEFAULT)
- //only install plugins if they're missing
- install(plugins - j.pluginManager.getPlugins()*.getShortName(), true, s)
- EOF
- }
- #
- # FUNCTIONS
- #
- function jenkins_script_console() {
- echo "Calling jenkins_script_console $1"
- ${CURL} --data-urlencode "script=$(eval "$@")" ${JENKINS_WEB}/scriptText
- }
- #CSRF protection support
- function is_crumbs_enabled() {
- use_crumbs="$( $CURL -s ${JENKINS_WEB}/api/json?pretty=true 2> /dev/null | python -c 'import sys,json;exec "try:\n j=json.load(sys.stdin)\n print str(j[\"useCrumbs\"]).lower()\nexcept:\n pass"' )"
- if [ "${use_crumbs}" = "true" ]; then
- return 0
- fi
- return 1
- }
- #CSRF protection support
- function get_crumb() {
- ${CURL} -s ${JENKINS_WEB}/crumbIssuer/api/json | python -c 'import sys,json;j=json.load(sys.stdin);print j["crumbRequestField"] + "=" + j["crumb"]'
- }
- #CSRF protection support
- function csrf_set_curl() {
- if is_crumbs_enabled; then
- if [ ! "${CSRF_CRUMB}" = "$(get_crumb)" ]; then
- if [ -n "${CSRF_CRUMB}" ]; then
- #remove existing crumb value from curl command
- CURL="$(echo "${CURL}" | sed "s/ -d ${CSRF_CRUMB}//")"
- fi
- export CSRF_CRUMB="$(get_crumb)"
- export CURL="${CURL} -d ${CSRF_CRUMB}"
- echo "Using crumbs for CSRF support."
- elif ! echo "${CURL}" | grep -F "${CSRF_CRUMB}" &> /dev/null; then
- export CURL="${CURL} -d ${CSRF_CRUMB}"
- echo "Using crumbs for CSRF support."
- fi
- fi
- }
- function is_auth_enabled() {
- no_authentication="$( $CURL -s ${JENKINS_WEB}/api/json?pretty=true 2> /dev/null | python -c 'import sys,json;exec "try:\n j=json.load(sys.stdin)\n print str(j[\"useSecurity\"]).lower()\nexcept:\n pass"' )"
- #check if authentication is required.;
- #if the value of no_authentication is anything but false; then assume authentication
- if [ ! "${no_authentication}" = "false" ]; then
- echo -n "Authentication required..."
- if [ -e "${JENKINS_HOME}/secrets/initialAdminPassword" ]; then
- echo "DONE"
- return 0
- else
- echo "FAILED"
- echo "Could not set authentication."
- echo "Missing file: ${JENKINS_HOME}/secrets/initialAdminPassword"
- exit 1
- fi
- fi
- return 1
- }
- function url_ready() {
- url="$1"
- echo -n "Waiting for ${url} to become available."
- while [ ! "200" = "$(curl -sLiI -w "%{http_code}\\n" -o /dev/null ${url})" ]; do
- echo -n '.'
- sleep 1
- done
- echo 'ready.'
- }
- function download_file() {
- #see bash man page and search for Parameter Expansion
- if [ "$#" = 1 ]; then
- url="$1"
- file="${1##*/}"
- else
- url="$1"
- file="$2"
- fi
- url_ready "${url}"
- if [ ! -e "${file}" ]; then
- curl -SLo "${file}" "${url}"
- fi
- }
- function jenkins_status() {
- #check to see if jenkins is running
- #will return exit status 0 if running or 1 if not running
- STATUS=1
- if [ -e "jenkins.pid" ]; then
- ps aux | grep -v 'grep' | grep 'jenkins\.war' | grep "$(cat jenkins.pid)" &> /dev/null
- STATUS=$?
- fi
- return ${STATUS}
- }
- function start_or_restart_jenkins() {
- #start Jenkins, if it's already running then stop it and start it again
- if [ -e "jenkins.pid" ]; then
- echo -n 'Jenkins might be running so attempting to stop it.'
- kill $(cat jenkins.pid)
- #wait for jenkins to stop
- while jenkins_status; do
- echo -n '.'
- sleep 1
- done
- rm jenkins.pid
- echo 'stopped.'
- fi
- echo 'Starting Jenkins.'
- ${JENKINS_START} >> console.log 2>&1 &
- echo "$!" > jenkins.pid
- }
- function stop_jenkins() {
- if [ -e "jenkins.pid" ]; then
- echo -n 'Jenkins might be running so attempting to stop it.'
- kill $(cat jenkins.pid)
- #wait for jenkins to stop
- while ps aux | grep -v 'grep' | grep "$(cat jenkins.pid)" &> /dev/null; do
- echo -n '.'
- sleep 1
- done
- rm jenkins.pid
- echo 'stopped.'
- fi
- }
- function update_jenkins_plugins() {
- #download the jenkins-cli.jar client
- download_file "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
- echo 'Updating Jenkins Plugins using jenkins-cli.'
- UPDATE_LIST="$( ${JENKINS_CLI} list-plugins | awk '$0 ~ /\)$/ { print $1 }' )"
- if [ ! -z "${UPDATE_LIST}" ]; then
- ${JENKINS_CLI} install-plugin ${UPDATE_LIST}
- fi
- }
- function jenkins_cli() {
- #download the jenkins-cli.jar client
- download_file "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
- echo "Executing: ${JENKINS_CLI} $@"
- ${JENKINS_CLI} $@
- }
- function force-stop() {
- if [ -e 'jenkins.pid' ]; then
- kill -9 $(cat jenkins.pid) 2> /dev/null
- rm -f jenkins.pid
- fi
- }
- #
- # main execution
- #
- case "$1" in
- bootstrap)
- shift
- skip_restart='false'
- while [ "$#" -gt '0' ]; do
- case $1 in
- --skip-restart)
- skip_restart='true'
- shift
- ;;
- *)
- echo "Error invalid arument provided to bootstrap command: $1"
- exit 1
- ;;
- esac
- done
- #provision Jenkins by default
- #download jenkins.war
- download_file ${jenkins_url} jenkins.war
- echo "JENKINS_HOME=${JENKINS_HOME}"
- start_or_restart_jenkins
- url_ready "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
- #try enabling authentication
- if is_auth_enabled; then
- export CURL="${CURL} -u admin:$(<${JENKINS_HOME}/secrets/initialAdminPassword)"
- fi
- #try enabling CSRF protection support
- csrf_set_curl
- jenkins_script_console script_skip_wizard
- jenkins_script_console script_disable_usage_stats
- jenkins_script_console script_upgrade_plugins
- jenkins_script_console script_install_plugins "credentials-binding,git,github,github-oauth,job-dsl,matrix-auth,matrix-project,pipeline-stage-view,ssh-slaves,workflow-aggregator"
- if ! ${skip_restart}; then
- start_or_restart_jenkins
- url_ready "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
- fi
- echo "Jenkins is ready. Visit ${JENKINS_WEB}/"
- if is_auth_enabled &> /dev/null; then
- echo "User: admin"
- echo "Password: $(<${JENKINS_HOME}/secrets/initialAdminPassword)"
- fi
- ;;
- download-file)
- shift
- download_file "$1"
- ;;
- clean)
- force-stop
- rm -f console.log jenkins.pid
- rm -rf "${JENKINS_HOME}"
- ;;
- cli)
- shift
- jenkins_cli $@
- ;;
- install-plugins)
- shift
- #try enabling authentication
- if is_auth_enabled; then
- export CURL="${CURL} -u admin:$(<${JENKINS_HOME}/secrets/initialAdminPassword)"
- fi
- #try enabling CSRF protection support
- csrf_set_curl
- jenkins_script_console script_install_plugins "$@"
- ;;
- update-plugins)
- update_jenkins_plugins
- echo 'Jenkins may need to be restarted.'
- ;;
- purge)
- force-stop
- rm -f console.log jenkins-cli.jar jenkins.pid jenkins.war
- rm -rf "${JENKINS_HOME}"
- ;;
- start|restart)
- start_or_restart_jenkins
- ;;
- status)
- if jenkins_status; then
- echo 'Jenkins is running.'
- exit 0
- else
- echo 'Jenkins is not running.'
- exit 1
- fi
- ;;
- stop)
- stop_jenkins
- ;;
- url-ready)
- shift
- url_ready "$1"
- ;;
- *)
- cat <<- "EOF"
- SYNOPSIS
- provision_jenkins.sh [command] [additional arguments]
- DESCRIPTION
- Additional arguments are only available for commands that support it.
- Otherwise, additional arguments will be ignored.
- Provisions a fresh Jenkins on a local laptop, updates the plugins, and runs
- it. Creates a JAVA_HOME. Downloads Jenkins. Updates the Jenkins plugins to
- the latest version.
- COMMANDS
- bootstrap The bootstrap behavior is to provision Jenkins.
- This command creates a JAVA_HOME, downloads
- Jenkins, and updates the plugins to the latest
- version. Additionally, it will install the git,
- github, and github-oauth plugins.
- cli [args] This command takes additional arguments. All
- arguments are passed through to jenkins-cli.jar.
- clean WARNING: destructive command. Kills the current
- instance of Jenkins, deletes JENKINS_HOME, removes
- the jenkins.pid file, and removes the console.log.
- Use this when you want start from scratch but don't
- want to download the latest Jenkins.
- download-file URL Wait for a file to become available and then
- download it. This command is useful for
- automation.
- install-plugins [args] This command takes additional arguments. The
- additional arguments are one or more Jenkins plugin
- IDs.
- purge WARNING: destructive command. Deletes all files
- related to the provisioned Jenkins including the
- war file and JENKINS_HOME. If Jenkins is running
- it will be sent SIGKILL.
- start or start and restart do the same thing. If Jenkins is
- restart not running then it will start it. If Jenkins is
- already running then it will stop Jenkins and start
- it again.
- stop Will gracefully shutdown Jenkins and leave the
- JENKINS_HOME intact.
- update-plugins Updates all unpinned plugins in Jenkins to their
- latest versions.
- url-ready URL Wait for a URL to become available. This command
- is useful for automation.
- EXAMPLE USAGE
- Automatically provision and start Jenkins on your laptop.
- mkdir ~/jenkins_testing
- cd ~/jenkins_testing
- provision_jenkins.sh bootstrap
- Kill and completely delete your provisioned Jenkins.
- cd ~/jenkins_testing
- provision_jenkins.sh purge
- Update all plugins to the latest version using jenkins-cli
- cd ~/jenkins_testing
- provision_jenkins.sh update-plugins
- Install additional plugins e.g. the slack plugin.
- cd ~/jenkins_testing
- provision_jenkins.sh install-plugins slack
- Start or restart Jenkins.
- cd ~/jenkins_testing
- provision_jenkins.sh start
- provision_jenkins.sh restart
- Stop Jenkins.
- provision_jenkins.sh stop
- See Jenkins CLI help documentation.
- provision_jenkins.sh cli help
- Create a Job using Jenkins CLI.
- provision_jenkins.sh cli create-job my_job < config.xml
- EOF
- esac