Skip to content

Instantly share code, notes, and snippets.

@rjminsha
Last active August 29, 2015 14:15
Show Gist options
  • Select an option

  • Save rjminsha/ee3666e33865dcd10e21 to your computer and use it in GitHub Desktop.

Select an option

Save rjminsha/ee3666e33865dcd10e21 to your computer and use it in GitHub Desktop.
Sample deploy script for deploying a group of containers to the IBM Container Service
#!/bin/bash
#********************************************************************************
# Copyright 2014 IBM
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
#********************************************************************************
dump_info () {
echo -e "${label_color}Container Information: ${no_color}"
echo -e "${label_color}Information about this organization and space${no_color}:"
echo "Summary:"
ice info
export CONTAINER_LIMIT=$(ice info | grep "Containers limit" | awk '{print $4}')
export IP_LIMIT=$(ice info | grep "Floating IPs limit" | awk '{print $5}')
export CONTAINER_COUNT=$(ice info | grep "Containers usage" | awk '{print $4}')
export IP_COUNT=$(ice info | grep "Floating IPs usage" | awk '{print $5}')
local WARNING_LEVEL="$(echo "$CONTAINER_LIMIT - 2" | bc)"
if [ ${CONTAINER_COUNT} -ge ${CONTAINER_LIMIT} ]; then
echo -e "${red}You have ${CONTAINER_COUNT} containers running, and may reached the default limit on the number of containers ${no_color}"
elif [ ${CONTAINER_COUNT} -ge ${WARNING_LEVEL} ]; then
echo -e "${label_color}There are ${CONTAINER_COUNT} containers running, which is approaching the limit of ${CONTAINER_LIMIT}${no_color}"
fi
local AVAILABLE="$(echo "$IP_LIMIT - $IP_COUNT" | bc)"
if [ ${AVAILABLE} -le 0 ]; then
echo -e "${red}You have reached the default limit for the number of available public IP addresses${no_color}"
else
echo -e "${label_color}You have ${AVAILABLE} public IP addresses remaining${no_color}"
fi
echo "Groups: "
ice group list
echo "Routes: "
cf routes
echo "Running Containers: "
ice ps
echo "All floating IP addresses"
ice ip list --all
return 0
}
update_inventory(){
local TYPE=$1
local NAME=$2
local ACTION=$3
if [ $# -ne 3 ]; then
echo -e "${red}updating inventory expects a three inputs: 1. type 2. name 3. action. Where type is either group or container, and the name is the name of the container being added to the inventory.${no_color}"
return 1
fi
local ID="undefined"
# find the container or group id
if [ "$TYPE" == "ibm_containers" ]; then
ID=$(ice inspect ${NAME} | grep "\"Id\":" | awk '{print $2}')
RESULT=$?
if [ $RESULT -ne 0 ] || [ -z "${ID}" ]; then
echo -e "${red}Could not find container called $NAME${no_color}"
ice ps
return 1
fi
elif [ "${TYPE}" == "ibm_containers_group" ]; then
ID=$(ice group inspect ${NAME} | grep "\"Id\":" | awk '{print $2}')
if [ $RESULT -ne 0 ] || [ -z "${ID}" ]; then
echo -e "${red}Could not find group called $NAME${no_color}"
ice group list
return 1
fi
else
echo -e "${red}Could not update inventory with unknown type: ${TYPE}${no_color}"
return 1
fi
local JOB_TYPE=""
# trim off junk
local temp="${ID%\",}"
ID="${temp#\"}"
echo "The ID of the $TYPE is: $ID"
# find other inventory information
echo -e "${label_color}Updating inventory with $TYPE of $NAME ${no_color}"
IDS_INV_URL="${IDS_URL%/}"
IDS_REQUEST=$TASK_ID
IDS_DEPLOYER=${JOB_NAME##*/}
if [ ! -z "$COPYARTIFACT_BUILD_NUMBER" ] ; then
IDS_VERSION_TYPE="JENKINS_BUILD_ID"
IDS_VERSION=$COPYARTIFACT_BUILD_NUMBER
elif [ ! -z "$CS_BUILD_SELECTOR" ] ; then
IDS_VERSION_TYPE="JENKINS_BUILD_ID"
IDS_VERSION=$CS_BUILD_SELECTOR
else
IDS_VERSION_TYPE="SCM_REV_ID"
if [ ! -z "$GIT_COMMIT" ] ; then
IDS_VERSION=$GIT_COMMIT
elif [ ! -z "$RTCBuildResultUUID" ] ; then
IDS_VERSION=$RTCBuildResultUUID
fi
fi
if [ -z "$IDS_RESOURCE" ]; then
local IDS_RESOURCE="https://hub.jazz.net/pipeline"
fi
if [ -z "$IDS_VERSION" ]; then
local IDS_RESOURCE="1"
fi
IDS_RESOURCE=$CF_SPACE_ID
if [ -z "$IDS_RESOURCE" ]; then
echo -e "${red}Could not find CF SPACE in environment, using production space id${no_color}"
else
# call IBM DevOps Service Inventory CLI to update the entry for this deployment
echo "bash ids-inv -a ${ACTION} -d $IDS_DEPLOYER -q $IDS_REQUEST -r $IDS_RESOURCE -s $ID -t ${TYPE} -u $IDS_INV_URL -v $IDS_VERSION"
bash ids-inv -a ${ACTION} -d $IDS_DEPLOYER -q $IDS_REQUEST -r $IDS_RESOURCE -s $ID -t ${TYPE} -u $IDS_INV_URL -v $IDS_VERSION
fi
}
insert_inventory(){
update_inventory $1 $2 "insert"
}
delete_inventory(){
update_inventory $1 $2 "delete"
}
# function to wait for a container to start
# takes a container name as the only parameter
wait_for_group (){
local WAITING_FOR=$1
if [ -z ${WAITING_FOR} ]; then
echo "${red}Expected container name to be passed into wait_for${no_color}"
return 1
fi
COUNTER=0
STATE="unknown"
while [[ ( $COUNTER -lt 60 ) && ("${STATE}" != "\"CREATE_COMPLETE\"") ]]; do
let COUNTER=COUNTER+1
STATE=$(ice group inspect $WAITING_FOR | grep "Status" | awk '{print $2}' | sed 's/,//g')
if [ -z "${STATE}" ]; then
STATE="being placed"
fi
echo "${WAITING_FOR} is ${STATE}"
sleep 3
done
if [ "$STATE" != "\"CREATE_COMPLETE\"" ]; then
echo -e "${red}Failed to start group ${no_color}"
return 1
fi
return 0
}
deploy_group() {
local MY_GROUP_NAME=$1
echo "deploying group ${MY_GROUP_NAME}"
if [ -z MY_GROUP_NAME ];then
echo "${red}No container name was provided${no_color}"
return 1
fi
# check to see if that group name is already in use
ice group inspect ${MY_GROUP_NAME} > /dev/null
local FOUND=$?
if [ ${FOUND} -eq 0 ]; then
echo -e "${red}${MY_GROUP_NAME} already exists.${no_color}"
exit 1
fi
# create the group and check the results
if [ -z "${BIND_TO}" ]; then
echo "creating group: ice group create --name ${MY_GROUP_NAME} --publish ${PORT} --desired ${GROUP_DESIRED} ${IMAGE_NAME} "
ice group create --name ${MY_GROUP_NAME} --publish ${PORT} --desired ${GROUP_DESIRED} ${IMAGE_NAME}
RESULT=$?
else
echo "Binding to ${BIND_TO}"
local APP=$(cf env ${BIND_TO})
local APP_FOUND=$?
if [ $APP_FOUND -ne 0 ]; then
echo -e "${red}${BIND_TO} application not found in space. Please confirm that you wish to bind the container to the application, and that the application exists${no_color}"
fi
local VCAP_SERVICES=$(echo "${APP}" | grep "VCAP_SERVICES")
local SERVICES_BOUND=$?
if [ $SERVICES_BOUND -ne 0 ]; then
echo -e "${label_color}No services appear bound to ${BIND_TO}. Please confirm that you have bound the intended services to the application.${no_color}"
fi
ice group create --name ${MY_GROUP_NAME} --bind ${BIND_TO} --publish ${PORT} --desired ${GROUP_DESIRED} ${IMAGE_NAME}
echo "creating group: ice group create --name ${MY_GROUP_NAME} --bind ${BIND_TO} --publish ${PORT} --desired ${GROUP_DESIRED} ${IMAGE_NAME}"
RESULT=$?
fi
if [ $RESULT -ne 0 ]; then
echo -e "${red}Failed to deploy ${MY_GROUP_NAME} using ${IMAGE_NAME}${no_color}"
return 1
fi
# wait for group to start
wait_for_group ${MY_GROUP_NAME}
RESULT=$?
if [ $RESULT -eq 0 ]; then
insert_inventory "ibm_containers_group" ${MY_GROUP_NAME}
if [[ ( -n "${ROUTE_DOMAIN}" ) && ( -n "${ROUTE_HOSTNAME}" ) ]]; then
ice route map --hostname $ROUTE_HOSTNAME --domain $ROUTE_DOMAIN $MY_GROUP_NAME
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo -e "${red}Failed to map $ROUTE_HOSTNAME $ROUTE_DOMAIN to $MY_GROUP_NAME. Please ensure that the routes are setup correctly. You can see this with cf routes when targetting the space for this stage.${no_color}"
cf routes
fi
else
echo "${label_color}No route defined to be mapped to the container group. If you wish to provide a Route please define ROUTE_HOSTNAME and ROUTE_DOMAIN on the Stage environment${no_color}"
fi
else
echo -e "${red}Failed to deploy group${no_color}"
fi
return ${RESULT}
}
deploy_simple () {
local MY_GROUP_NAME="${CONTAINER_NAME}_${BUILD_NUMBER}"
deploy_group ${MY_GROUP_NAME}
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo -e "${red}Error encountered with simple build strategy for ${CONTAINER_NAME}_${BUILD_NUMBER}${no_color}"
exit $RESULT
fi
}
deploy_red_black () {
echo -e "${label_color}Example red_black container deploy ${no_color}"
# deploy new version of the application
local MY_GROUP_NAME="${CONTAINER_NAME}_${BUILD_NUMBER}"
deploy_group ${MY_GROUP_NAME}
RESULT=$?
if [ $RESULT -ne 0 ]; then
exit $RESULT
fi
if [ -z "$REMOVE_FROM" ]; then
clean
RESULT=$?
if [ $RESULT -ne 0 ]; then
exit $RESULT
fi
else
echo "Not removing previous instances until after testing"
fi
return 0
}
clean() {
echo "Cleaning up previous deployments. Will keep ${CONCURRENT_VERSIONS} versions active."
if [ -z "$REMOVE_FROM" ]; then
COUNTER=${BUILD_NUMBER}
else
COUNTER=$REMOVE_FROM
fi
local FOUND=0
until [ $COUNTER -lt 1 ]; do
echo "Looking for and inspecting ${CONTAINER_NAME}_${COUNTER}"
ice group inspect ${CONTAINER_NAME}_${COUNTER} > inspect.log
local RESULT=$?
if [ $RESULT -eq 0 ]; then
echo "Found previous container ${CONTAINER_NAME}_${COUNTER}"
let FOUND+=1
if [ $FOUND -le $CONCURRENT_VERSIONS ]; then
# this is the previous version so keep it around
echo "keeping deployment: ${CONTAINER_NAME}_${COUNTER}"
elif [[ ( -n "${ROUTE_DOMAIN}" ) && ( -n "${ROUTE_HOSTNAME}" ) ]]; then
# remove this group
echo "removing route $ROUTE_HOSTNAME $ROUTE_DOMAIN from ${CONTAINER_NAME}_${COUNTER}"
ice route unmap --hostname $ROUTE_HOSTNAME --domain $ROUTE_DOMAIN ${CONTAINER_NAME}_${COUNTER}
sleep 2
echo "removing group ${CONTAINER_NAME}_${COUNTER}"
ice group rm ${CONTAINER_NAME}_${COUNTER}
delete_inventory "ibm_containers_group" ${CONTAINER_NAME}_${COUNTER}
else
echo "removing group ${CONTAINER_NAME}_${COUNTER}"
ice group rm ${CONTAINER_NAME}_${COUNTER}
delete_inventory "ibm_containers_group" ${CONTAINER_NAME}_${COUNTER}
fi
fi
let COUNTER-=1
done
echo "Cleaned up previous deployments"
return 0
}
##################
# Initialization #
##################
# Check to see what deployment type:
# simple: simply deploy a container and set the inventory
# red_black: deploy new container, assign floating IP address, keep original container
echo "Deploying using ${DEPLOY_TYPE} strategy, for ${CONTAINER_NAME}, deploy number ${BUILD_NUMBER}"
if [ -z "$GROUP_DESIRED" ]; then
export GROUP_DESIRED=1
fi
if [ -z "$PORT" ]; then
export PORT=80
fi
if [ -z "$ROUTE_HOSTNAME" ]; then
echo -e "${label_color}ROUTE_HOSTNAME not set. Please set the desired or existing route hostname as an environment property on the stage.${no_color}"
fi
if [ -z "$ROUTE_DOMAIN" ]; then
echo -e "${label_color}ROUTE_DOMAIN not set, defaulting to mybluemix.net${no_color}"
export ROUTE_DOMAIN="mybluemix.net"
fi
if [ -z "$CONCURRENT_VERSIONS" ];then
export CONCURRENT_VERSIONS=1
fi
if [ "${DEPLOY_TYPE}" == "simple" ]; then
deploy_simple
elif [ "${DEPLOY_TYPE}" == "simple_public" ]; then
deploy_public
elif [ "${DEPLOY_TYPE}" == "clean" ]; then
clean
elif [ "${DEPLOY_TYPE}" == "red_black" ]; then
deploy_red_black
else
echo -e "${label_color}Defaulting to red_black deploy${no_color}"
deploy_red_black
fi
dump_info
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment