Following on from my Blog entry "Scripted
Template Generation from an existing vServer" I have built a
wrapper script that can be used to execute the Template Generation
script or Clone a specific vServer. This script was not
incorporated into the original script because it must be executed
on a Compute Node with access to the /OVS/Repositories directory
and the Compute Node are a minimal install and hence do not have
all the required software available. As part of the Cloning
process this new script will create an Assets input file that can
be used with the CreateAssets.sh describe in the blog "Scripting
Asset Creation" and optionally execute the result to create
the clone.
To successfully run the script you will need the following 3 scripts located in the same directory on a machine with the EMOC cli/api rms installed.
During execute, of the CloneOrTemplateVServer.sh, the script will connect to EMOC and stop the specified vServer before scping the CreateTemplateFromVServer.sh to the specified Compute Node and executing it. Once the vServer has been converted to a Template the script will restart the specified vServer and then retrieve the following information for the vServers and build the Clone Asset file.
If the opt to execute has been specified, "-e" the CreateAsset.sh script will be executed passing in the Clone Asset file thus importing the template and creating the server.
To successfully run the script you will need the following 3 scripts located in the same directory on a machine with the EMOC cli/api rms installed.
During execute, of the CloneOrTemplateVServer.sh, the script will connect to EMOC and stop the specified vServer before scping the CreateTemplateFromVServer.sh to the specified Compute Node and executing it. Once the vServer has been converted to a Template the script will restart the specified vServer and then retrieve the following information for the vServers and build the Clone Asset file.
- Connected Networks
- VServer Type
If the opt to execute has been specified, "-e" the CreateAsset.sh script will be executed passing in the Clone Asset file thus importing the template and creating the server.
Usage
usage: ./CloneOrTemplateVServer.sh -a-n -u -p -t|-b|-c [-e] -i [-r ] [-w ] [-d ] [-f ] -a Name of the Account that contains the Specified vServer. -u User that is allowed to access the specified account the default is root -p password of the specified user -n vServer to be templatised or cloned. -f (Default is CreateAssets.in) Defines the file that will be built during the clode operation. -t|-b|-c Indicates if only a template should be created (-t) or if the cloning file should be generated as well (-c). Specifying -b will cause the current IP Addresses to be used in the Asset File -e If the action is to clone then the presence of this flag indicates that the resulting AssetsFile should be executed -r Location of the repository the default is /OVS/Repositories/* -w Working directory where intermediate files will be copied. -d Directory where the template tgz will be created. Default is current directory -i Address of Compute Node to run the Template functionality from.
Script
Download
#!/bin/bash
################################################################################
#
# Exalogic EL X2-2 2.0.0.4 (Linux x86-64) Configuration Script.
#
# HEADER START
#
# THIS SCRIPT IS PROVIDED ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT
# THE COVERED SCRIPT IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
# PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
# OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE
# DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER
# CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION.
# NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
# DISCLAIMER.
#
# When distributing this Code, include this HEADER in each file.
# If applicable, add the following below this this HEADER, with the fields
# enclosed by brackets "[]" replaced with your own identifying information:
# Portions Copyright [yyyy] [name of copyright owner]
#
# HEADER END
#
#
# Copyright 2011 Andrew Hopkinson, Oracle Corporation UK Ltd.
#
################################################################################
export OCCLI=/opt/sun/occli/bin
export IAAS_HOME=/opt/oracle/iaas/cli
export IAAS_BASE_URL=https://localhost
export BASE_IAAS_ACCESS_KEY_FILE=iaas_access.key
export BASE_KEY_NAME=cli.asset.create
export BASE_KEY_FILE=iaas_access.pub
export RUN_DATE=`date +"%Y%m%d-%H%M"`
#CloudUser used to create vServers & Volumes
export IAAS_USER=root
export IAAS_PASSWORD_FILE=root.pwd
export INPUT_FILE=CreateAssets.in
export ACCOUNTS_FILE=accounts.out
export VOLUMES_FILE=volumes.out
export DISTGRPS_FILE=distgrp.out
export VNETS_FILE=vnets.out
export VSERVER_TYPES_FILE=vstype.out
export VSERVER_FILE=vserver.out
export VSERVER_TEMPLATES=template.out
export NETWORK_STATIC_IPS=staticips.out
export KEY_PAIRS=keypairs.out
## **********************************************************
PROCESSING_ACCOUNT=""
function connectToAccount() {
if [[ "$ACCOUNT" != "$PROCESSING_ACCOUNT" ]]
then
if [[ "" != "$PROCESSING_ACCOUNT" ]]
then
$IAAS_HOME/bin/iaas-delete-key-pair --key-name $KEY_NAME --access-key-file $IAAS_ACCESS_KEY_FILE
$IAAS_HOME/bin/akm-delete-access-key $AK
fi
# Set run specific key information
export IAAS_ACCESS_KEY_FILE=$ACCOUNT"."$RUN_DATE"."$BASE_IAAS_ACCESS_KEY_FILE
export KEY_NAME=$ACCOUNT"."$RUN_DATE"."$BASE_KEY_NAME
export KEY_FILE=$ACCOUNT"."$RUN_DATE"."$BASE_KEY_FILE
#echo "IAAS_ACCESS_KEY_FILE=$IAAS_ACCESS_KEY_FILE"
#echo "KEY_NAME=$KEY_NAME"
echo "KEY_FILE=$KEY_FILE"
# Save current processing account
PROCESSING_ACCOUNT=$ACCOUNT
IAAS_USER=$ACCOUNT_USER
echo "$ACCOUNT_PASSWORD" > $IAAS_PASSWORD_FILE
$IAAS_HOME/bin/akm-describe-accounts --sep "|" > $ACCOUNTS_FILE
while read line
do
ACCOUNT_ID=${line%%|*}
line=${line#*|}
ACCOUNT_NAME=${line%%|*}
# echo "Id = $ACCOUNT_ID"
# echo "Name = $ACCOUNT_NAME"
if [[ "$ACCOUNT_NAME" == "$ACCOUNT" ]]
then
#echo "Found Account $line"
AK=`$IAAS_HOME/bin/akm-create-access-key --account $ACCOUNT_ID --access-key-file $IAAS_ACCESS_KEY_FILE`
KEYPAIR=`$IAAS_HOME/bin/iaas-create-key-pair --key-name $KEY_NAME --key-file $KEY_FILE`
echo "Connected to $ACCOUNT_NAME"
#cp $IAAS_ACCESS_KEY_FILE $ACCOUNT_NAME$IAAS_ACCESS_KEY_FILE
#cp $KEY_FILE $ACCOUNT_NAME$KEY_FILE
break
fi
done < $ACCOUNTS_FILE
fi
}
function disconnectFromAccount() {
$IAAS_HOME/bin/iaas-delete-key-pair --key-name $KEY_NAME --access-key-file $IAAS_ACCESS_KEY_FILE
$IAAS_HOME/bin/akm-delete-access-key $AK
PROCESSING_ACCOUNT=""
}
function getDistributionGroups() {
$IAAS_HOME/bin/iaas-describe-distribution-groups --sep "|" > $DISTGRPS_FILE
}
function getNetworks() {
$IAAS_HOME/bin/iaas-describe-vnets --sep "|" > $VNETS_FILE
}
function getVSTypes() {
$IAAS_HOME/bin/iaas-describe-vserver-types --sep "|" > $VSERVER_TYPES_FILE
}
function getTemplates() {
$IAAS_HOME/bin/iaas-describe-server-templates --sep "|" > $VSERVER_TEMPLATES
}
function getVolumes() {
$IAAS_HOME/bin/iaas-describe-volumes --sep "|" > $VOLUMES_FILE
}
function getVServers() {
$IAAS_HOME/bin/iaas-describe-vservers --sep "|" > $VSERVER_FILE
}
function getVServerId() {
while read line
do
VSERVER_ID=${line%%|*}
line=${line#*|}
NAME=${line%%|*}
if [[ "$VSERVER_NAME" == "$NAME" ]]
then
break;
fi
VSERVER_ID=""
done < $VSERVER_FILE
}
function getVServerState() {
getVServers
while read line
do
VSERVER_ID=${line%%|*}
line=${line#*|}
NAME=${line%%|*}
line=${line#*|}
line=${line#*|}
VSERVER_STATE=${line%%|*}
if [[ "$VSERVER_NAME" == "$NAME" ]]
then
break;
fi
done < $VSERVER_FILE
}
function pauseUntilVServerRunning() {
# Wait until the Server is running before creating the next
echo "Pausing until vServer is Running"
getVServerState
while [[ "$VSERVER_STATE" != "RUNNING" ]]
do
echo "$NAME $VSERVER_STATE"
if [[ "$VSERVER_STATE" != "RUNNING" ]]
then
echo "Sleeping......."
sleep 30
fi
getVServerState
done
echo "$NAME $VSERVER_STATE"
# Lets pause for a minute or two
echo "Just Chilling......"
sleep 30
}
## **********************************************************
function pauseUntilVServerShutdown() {
# Wait until the Server is running before creating the next
echo "Pausing until vServer has Shutdown"
getVServerState
while [[ "$VSERVER_STATE" != "SHUTDOWNDETACHED" ]]
do
echo "$NAME $VSERVER_STATE"
if [[ "$VSERVER_STATE" != "SHUTDOWNDETACHED" ]]
then
echo "Sleeping......."
sleep 30
fi
getVServerState
done
echo "$NAME $VSERVER_STATE"
# Lets pause for a minute or two
echo "Just Chilling......"
sleep 30
}
#############################################################
##
## stopVServer
## ===========
##
## Find and stop a vServer.
##
#############################################################
function stopVServer() {
echo "Stopping vServer $VSERVER_NAME"
getVServers
getVServerId
$IAAS_HOME/bin/iaas-stop-vservers --vserver-ids $VSERVER_ID --force
pauseUntilVServerShutdown
}
#############################################################
##
## startVServer
## ============
##
## Find and stop a vServer.
##
#############################################################
function startVServer() {
echo "Starting vServer $VSERVER_NAME"
getVServers
getVServerId
$IAAS_HOME/bin/iaas-start-vservers --vserver-ids $VSERVER_ID
pauseUntilVServerRunning
}
#############################################################
##
## executeRemoteCreateTemplate
## ===========================
##
## Execute the CreateTemplateFromVServer.sh on the specified
## Compute Node. This is required because the Repository is
## not accessible from the EC VM. It's assumed we will not
## need to enter a password.
##
#############################################################
function executeRemoteCreateTemplate() {
echo "Executing Remote Functions"
if [[ "$CN_IP_ADDRESS" != "" ]]
then
#ssh root@$CN_IP_ADDRESS "bash -s" < CreateTemplateFromVServer.sh -n $VSERVER_NAME -r $REPOSITORY_DIR -w $WORKING_DIR -d $DESTINATION_DIR
#ssh root@$CN_IP_ADDRESS "bash -s -n $VSERVER_NAME -r $REPOSITORY_DIR -w $WORKING_DIR -d $DESTINATION_DIR" < CreateTemplateFromVServer.sh
#cat CreateTemplateFromVServer.sh | ssh root@$CN_IP_ADDRESS "bash -s -n $VSERVER_NAME -r $REPOSITORY_DIR -w $WORKING_DIR -d $DESTINATION_DIR"
echo "Copying script to $CN_IP_ADDRESS"
scp CreateTemplateFromVServer.sh root@$CN_IP_ADDRESS:/tmp
ssh root@$CN_IP_ADDRESS "chmod a+x /tmp/CreateTemplateFromVServer.sh"
ssh root@$CN_IP_ADDRESS "/tmp/CreateTemplateFromVServer.sh -n $VSERVER_NAME -r $REPOSITORY_DIR -w $WORKING_DIR -d $DESTINATION_DIR"
ssh root@$CN_IP_ADDRESS "rm -f /tmp/CreateTemplateFromVServer.sh"
TEMPLATE_TGZ=$DESTINATION_DIR/el_template_$VSERVER_NAME.tgz
fi
}
#############################################################
##
## createTemplate
## ==============
##
## High level template creation function that will call the
## required processing function in the necessary sequence.
##
#############################################################
function createTemplate() {
stopVServer
executeRemoteCreateTemplate
startVServer
echo ""
echo ""
echo "****************************************************"
echo "**"
echo "** $TEMPLATE_TGZ has been created from"
echo "** vServer $VSERVER_NAME "
echo "**"
echo "****************************************************"
echo ""
echo ""
}
#############################################################
##
## getNetworkName
## ==============
##
## Gets the name of a network based on the Id.
##
#############################################################
function getNetworkName() {
NETWORK_NAME=""
while read line
do
ID=${line%%|*}
line=${line#*|}
NAME=${line%%|*}
if [[ "$ID" == "$NETWORK_ID" ]]
then
NETWORK_NAME=$NAME
break
fi
done < $VNETS_FILE
}
#############################################################
##
## getVSTypeName
## =============
##
## Gets the name of a vServer Type based on the Id.
##
#############################################################
function getVSTypeName() {
VSTYPE_NAME=""
while read line
do
ID=${line%%|*}
line=${line#*|}
NAME=${line%%|*}
if [[ "$ID" == "$VSTYPE_ID" ]]
then
VSTYPE_NAME=$NAME
break
fi
done < $VSERVER_TYPES_FILE
}
#############################################################
##
## generateAssetFile
## =================
##
## Generates a Input script that can be used with the
## CreateAssets.sh to create a server based on the new
## template.
##
#############################################################
function generateAssetFile() {
echo "Generating Clones CreateAsset input file"
if [[ "$ASSET_FILE" == "" ]]
then
if [[ "$BACKUP" == "true" ]]
then
ASSET_FILE=$VSERVER_NAME"BackupAsset.in"
else
ASSET_FILE=$VSERVER_NAME"CreateCloneAsset.in"
fi
fi
echo "$ACCOUNT:Connect|$ACCOUNT_USER|$ACCOUNT_PASSWORD" > $ASSET_FILE
# Here we are assuming that we have used the recommended mount
SN_TEMPLATE_FILE=${TEMPLATE_TGZ/u01/export}
echo "$ACCOUNT:Upload|ServerTemplate|$VSERVER_NAME-Template|http://$SN_IP_ADDRESS/shares$SN_TEMPLATE_FILE" >> $ASSET_FILE
# Get VServer specific information
getVServers
getNetworks
getVSTypes
while read line
do
VSERVER_ID=${line%%|*}
line=${line#*|}
NAME=${line%%|*}
line=${line#*|}
if [[ "$NAME" == "$VSERVER_NAME" ]]
then
URL=${line%%|*}
line=${line#*|}
STATE=${line%%|*}
line=${line#*|}
NETWORK_IDS=${line%%|*}
line=${line#*|}
NETWORK_IPS=${line%%|*}
line=${line#*|}
TEMPLATE_ID=${line%%|*}
line=${line#*|}
SSH_KEY=${line%%|*}
line=${line#*|}
VSTYPE_ID=${line%%|*}
line=${line#*|}
NETWORK_NAMES=""
#NETWORK_IPS=""
for NETWORK_ID in ${NETWORK_IDS//,/ }
do
getNetworkName
if [[ "$NETWORK_NAMES" == "" ]]
then
NETWORK_NAMES=$NETWORK_NAME
if [[ "$BACKUP" != "true" ]]
then
NETWORK_IPS="*"
fi
else
NETWORK_NAMES=$NETWORK_NAMES","$NETWORK_NAME
if [[ "$BACKUP" != "true" ]]
then
NETWORK_IPS=$NETWORK_IPS",*"
fi
fi
done
# Get VServer Type Name
getVSTypeName
echo "$ACCOUNT:Create|vServer|$VSERVER_NAME-Clone|$VSTYPE_NAME|$VSERVER_NAME-Template|$NETWORK_NAMES|$NETWORK_IPS" >> $ASSET_FILE
break
fi
done < $VSERVER_FILE
echo "$ACCOUNT:Disconnect" >> $ASSET_FILE
echo "Generated Asset File $ASSET_FILE"
}
#############################################################
##
## executeAssetFile
## =================
##
## Execute the CreateAssets.sh script using the generated
## Asset file. We assume it is in the same directory.
##
#############################################################
function executeAssetFile() {
echo "Executing the Generated $ASSET_FILE file"
echo ""
./CreateAssets.sh -f $ASSET_FILE -r
}
#############################################################
##
## usage
## =====
##
## Show usage.
##
#############################################################
function usage() {
echo ""
echo >&2 "usage: $0 -a <Account Name> -n <vServer Name> -u <Account User> -p <Account Password> -t|-b|-c [-e] -i <Compute Node IP> [-r <Repository Directory>] [-w <Working Directory>] [-d <Destination Directory>] [-f <Asset Definition File>]"
echo >&2 " -a <Account Name> Name of the Account that contains the Specified vServer."
echo >&2 " -u <Account User> User that is allowed to access the specified account the default is root"
echo >&2 " -p <Account Password> password of the specified user"
echo >&2 " -n <vServer Name> vServer to be templatised or cloned."
echo >&2 " -f <Asset Definition File> (Default is CreateAssets.in) Defines the file that will be built during the clode operation."
echo >&2 " -t|-b|-c Indicates if only a template should be created (-t) or if the cloning file should be generated as well (-c). Specifying -b will cause the current IP Addresses to be used in the Asset File"
echo >&2 " -e If the action is to clone then the presence of this flag indicates that the resulting AssetsFile should be executed"
echo >&2 " -r <Repository Directory> Location of the repository the default is /OVS/Repositories/*"
echo >&2 " -w <Working Directory> Working directory where intermediate files will be copied."
echo >&2 " -d <Destination Directory> Directory where the template tgz will be created. Default is current directory"
echo >&2 " -i <Compute Node IP> Address of Compute Node to run the Template functionality from."
echo""
exit 1
}
###############################################################
##
## Simple start for the script that will extract the parameters
## and call the appriate start function.
##
###############################################################
export CLONE=""
export BACKUP=""
export TEMPLATE=""
export EXECUTE=""
export WORKING_DIR="/u01/common/images/vServerTemplateWIP"
export DESTINATION_DIR="/u01/common/images/vServerTemplates"
export REPOSITORY_DIR="/OVS/Repositories/*"
export ACCOUNT_USER="root"
export ACCOUNT_PASSWORD="welcome1"
export SYSTEMIMGDIR=/mnt/elsystem
export CN_IP_ADDRESS=""
export SN_IP_ADDRESS="172.17.0.9"
while [ $# -gt 0 ]
do
case "$1" in
-f) ASSET_FILE="$2"; shift;;
-a) ACCOUNT="$2"; shift;;
-n) VSERVER_NAME="$2"; shift;;
-r) REPOSITORY_DIR="$2"; shift;;
-d) DESTINATION_DIR="$2"; shift;;
-u) ACCOUNT_USER="$2"; shift;;
-p) ACCOUNT_PASSWORD="$2"; shift;;
-w) WORKING_DIR="$2"; shift;;
-i) CN_IP_ADDRESS="$2"; shift;;
-s) SN_IP_ADDRESS="$2"; shift;;
-c) CLONE=true;;
-b) BACKUP=true;;
-t) TEMPLATE=true;;
-e) EXECUTE=true;;
*) usage;;
*) break;;
esac
shift
done
# Check if the JAVA_HOME is set
if [[ "$JAVA_HOME" == "" ]]
then
export JAVA_HOME=/usr/java/latest
echo "JAVA_HOME is not defined using $JAVA_HOME"
fi
# Processing function call
if [[ "$VSERVER_NAME" == "" || "$REPOSITORY_DIR" == "" || "$CN_IP_ADDRESS" == "" ]]
then
usage
elif [[ "$TEMPLATE" == "true" || "$CLONE" == "true" || "$BACKUP" == "true" ]]
then
connectToAccount
createTemplate
if [[ "$CLONE" == "true" || "$BACKUP" == "true" ]]
then
generateAssetFile
fi
disconnectFromAccount
if [[ "$EXECUTE" == "true" && "$BACKUP" != "true" ]]
then
executeAssetFile
fi
fi
echo "****************************************"
echo "***** Finished Processing Assets *****"
echo "****************************************"
No comments:
Post a Comment