:build-node: The node to run build on.
:jenkins-ssh-credential: Credential to use for SSH. (Generally should
be configured in defaults.yaml)
+ :jenkins-urls: URLs to Jenkins systems to check for active builds.
:Optional parameters:
:branch: Git branch to fetch for the build. (default: master)
:build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
:build-timeout: Timeout in minutes before aborting build. (default: 90)
- :cron: Time when the packer image should be rebuilt (default: @daily)
+ :cron: Time when the packer image should be rebuilt (default: @hourly)
:git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
:openstack-cloud: OS_CLOUD setting to pass to openstack client.
(default: vex)
removal. (default: 30)
:openstack-image-protect: Whether or not to run the image protect script.
(default: true)
+ :openstack-stack-cleanup: Whether or not to run the stack cleanup script.
+ (default: true)
:openstack-volume-cleanup: Whether or not to run the volume cleanup script.
(default: true)
:stream: Keyword that can be used to represent a release code-name.
branch: master
build-days-to-keep: 7
build-timeout: 10
- cron: '@daily'
+ cron: '@hourly'
disable-job: false
git-url: '$GIT_URL/$PROJECT'
github-url: 'https://github.com'
openstack-image-cleanup: true
openstack-image-cleanup-age: 30
openstack-image-protect: true
+ openstack-stack-cleanup: true
openstack-volume-cleanup: true
stream: master
submodule-timeout: 10
stream: '{stream}'
branch: '{branch}'
lftools-version: '{lftools-version}'
+ - string:
+ name: JENKINS_URLS
+ default: '{jenkins-urls}'
+ description: |
+ Space separated list of Jenkins URLs to check for active builds.
wrappers:
- lf-infra-wrappers:
- lf-infra-pre-build
- inject:
properties-content: OS_CLOUD={openstack-cloud}
+ # Stacks
+ - conditional-step:
+ condition-kind: boolean-expression
+ condition-expression: '{openstack-stack-cleanup}'
+ steps:
+ - shell: !include-raw-escape: ../shell/openstack-cleanup-orphaned-stacks.sh
# Volumes
- conditional-step:
condition-kind: boolean-expression
--- /dev/null
+#!/bin/bash -l
+# SPDX-License-Identifier: EPL-1.0
+##############################################################################
+# Copyright (c) 2017, 2018 The Linux Foundation and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+##############################################################################
+# Scans OpenStack for orphaned stacks
+echo "---> Orphaned stacks"
+
+os_cloud="${OS_CLOUD:-vex}"
+jenkins_urls="${JENKINS_URLS:-}"
+
+stack_in_jenkins() {
+ # Usage: check_stack_in_jenkins STACK_NAME JENKINS_URL [JENKINS_URL...]
+ # Returns: 0 If stack is in Jenkins and 1 if stack is not in Jenkins.
+
+ STACK_NAME="${1}"
+
+ builds=()
+ for jenkins in "${@:2}"; do
+ JENKINS_URL="$jenkins/computer/api/json?tree=computer[executors[currentExecutable[url]],oneOffExecutors[currentExecutable[url]]]&xpath=//url&wrapper=builds"
+ resp=$(curl -s -w "\\n\\n%{http_code}" --globoff -H "Content-Type:application/json" "$JENKINS_URL")
+ json_data=$(echo "$resp" | head -n1)
+ #status=$(echo "$resp" | awk 'END {print $NF}')
+
+ if [[ "${jenkins}" == *"jenkins."*".org" ]] || [[ "${jenkins}" == *"jenkins."*".io" ]]; then
+ silo="production"
+ else
+ silo=$(echo "$jenkins" | sed 's/\/*$//' | awk -F'/' '{print $NF}')
+ fi
+ export silo
+ # We purposely want to wordsplit here to combine the arrays
+ # shellcheck disable=SC2206,SC2207
+ builds=(${builds[@]} $(echo "$json_data" | \
+ jq -r '.computer[].executors[].currentExecutable.url' \
+ | grep -v null | awk -F'/' '{print ENVIRON["silo"] "-" $6 "-" $7}')
+ )
+ done
+
+ if [[ "${builds[*]}" =~ $STACK_NAME ]]; then
+ return 0
+ fi
+
+ return 1
+}
+
+#########################
+## FETCH ACTIVE BUILDS ##
+#########################
+# Fetch stack list before fetching active builds to minimize race condition
+# where we might be try to delete stacks while jobs are trying to start
+
+mapfile -t OS_STACKS < <(openstack --os-cloud "$os_cloud" stack list \
+ -f value -c "Stack Name" -c "Stack Status" \
+ --property "stack_status=CREATE_COMPLETE" \
+ --property "stack_status=DELETE_FAILED" \
+ --property "stack_status=CREATE_FAILED" \
+ | awk '{print $1}')
+
+echo "-----> Active stacks"
+for stack in "${OS_STACKS[@]}"; do
+ echo "$stack"
+done
+
+
+##########################
+## DELETE UNUSED STACKS ##
+##########################
+echo "-----> Delete orphaned stacks"
+
+# Search for stacks not in use by any active Jenkins systems and remove them.
+for STACK_NAME in "${OS_STACKS[@]}"; do
+ # jenkins_urls intentially needs globbing to be passed a separate params.
+ # shellcheck disable=SC2153,SC2086
+ if stack_in_jenkins "$STACK_NAME" $jenkins_urls; then
+ # No need to delete stacks if there exists an active build for them
+ continue
+ else
+ echo "Deleting orphaned stack: $STACK_NAME"
+ lftools openstack --os-cloud "$os_cloud" stack delete "$STACK_NAME"
+ fi
+done