blob: ee198c51642702557ea454dd97e40809f990c4ea (
plain) (
tree)
|
|
#!/bin/bash
# Needs full bash
# region header
# Copyright Torben Sickert 16.12.2012
# License
# This library written by Torben Sickert stand under a creative commons
# naming 3.0 unported license.
# see http://creativecommons.org/licenses/by/3.0/deed.de
# vim: set tabstop=4 shiftwidth=4 expandtab:
# vim: foldmethod=marker foldmarker=region,endregion:
# Dependencies:
# vmware or virtualbox
# Notes:
# USE "sudo bin/vmware-vmx --new-sn JJ237-G52E2-08X0C-C3306-0WCQ1"
# To activate wmware workstation!
# Abbreviation for "createLinkedClone".
__NAME__='clc'
# endregion
# Provides the main module scope.
function clc() {
# region configuration
# region private properties
# region command line arguments
local _VERBOSE='no'
local _SUPPORTED_HYPERVISOR=('VMware' 'virtualBox')
# NOTE: This value will be determined automatically. If no hypervisor
# could be detected this value will be used as default.
# The first value from supported Machines is taken as default.
local _HYPERVISOR="$_SUPPORTED_HYPERVISOR"
local _PERSISTENT_SHORT_DESCRIPTION_SUFFIX=' --persistent--'
# endregion
local _STANDARD_OUTPUT=/dev/null
local _ERROR_OUTPUT=/dev/null
local _BASIC_IMAGE_CONFIGURATION_FILE_PATH=''
local _TARGET_PATH=''
local _CREATE_PERSISTENT_CONFIG='no'
# endregion
# endregion
# region functions
# region command line interface
# Prints a description about how to use this program.
function clcPrintUsageMessage() {
cat << EOF
$__NAME__ Generates a linked clone from given machine description file in
given target location.
EOF
return $?
}
# Prints a description about how to use this program by providing examples.
function clcPrintUsageExamples() {
cat << EOF
# Getting a help message.
>>> $0 --help
# Creating a linked clone.
>>> $0 /path/to/config.xml ~/.persistentLinkedClones/
# Creating a linked clone in verbose mode.
>>> $0 /path/to/config.xml ~/.persistentLinkedClones/ --verbose
# Creating a linked clone in verbose mode with debugging output.
>>> $0 /path/to/config.xml ~/.persistentLinkedClones/ --verbose --debug
# Creating a linked clone in verbose mode with debugging output.
>>> $0 /path/to/config.xml ~/.persistentLinkedClones/ -v -d
EOF
return $?
}
# Prints descriptions about each available command line option.
function clcPrintCommandLineOptionDescriptions() {
# NOTE; All letters are used for short options.
cat << EOF
-h --help Shows this help message.
-v --verbose Tells you what is going on (default: "$_VERBOSE").
-d --debug Gives you any output from all tools which are used
(default: "$_DEBUG").
-c --create-persistent-config If set an xml file for persistent openslx
boot will be created (default: "$_CREATE_PERSISTENT_CONFIG").
EOF
return $?
}
# Provides a help message for this module.
function clcPrintHelpMessage() {
echo -e \
"\nUsage: $0 BASIC_IMAGE_CONFIGURATION_FILE_PATH TARGET_PATH [options]\n" && \
clcPrintUsageMessage "$@" && \
echo -e '\nExamples:\n' && \
clcPrintUsageExamples "$@" && \
echo -e '\nOption descriptions:\n' && \
clcPrintCommandLineOptionDescriptions "$@" && \
echo && \
return $?
}
# Provides the command line interface and interactive questions.
function clcCommandLineInterface() {
while true; do
case "$1" in
-h|--help)
shift
clcPrintHelpMessage "$0"
exit 0
;;
-v|--verbose)
shift
_VERBOSE='yes'
;;
-d|--debug)
shift
_DEBUG='yes'
_STANDARD_OUTPUT=/dev/stdout
_ERROR_OUTPUT=/dev/stderr
;;
-c|--create-persistent-config)
shift
_CREATE_PERSISTENT_CONFIG='yes'
;;
'')
shift
break 2
;;
*)
if [[ ! "$_BASIC_IMAGE_CONFIGURATION_FILE_PATH" ]]; then
_BASIC_IMAGE_CONFIGURATION_FILE_PATH="$1"
elif [[ ! "$_TARGET_PATH" ]]; then
_TARGET_PATH="$1"
else
clcLog 'critical' \
"Given argument: \"$1\" is not available." '\n'
clcPrintHelpMessage "$0"
return 1
fi
shift
;;
esac
done
if [[ ! "$_BASIC_IMAGE_CONFIGURATION_FILE_PATH" ]] || \
[[ ! "$_TARGET_PATH" ]]; then
clcLog 'critical' \
"You have to provide a basic image configuration file and a destination path."
clcPrintHelpMessage "$0"
return 1
fi
local supportedVirtualMachine
for supportedVirtualMachine in ${_SUPPORTED_HYPERVISOR[*]}; do
if [[ "$(clcGetXMLValue 'virtualMachine' | \
grep --ignore-case "$supportedVirtualMachine")" ]]; then
_HYPERVISOR="$supportedVirtualMachine"
clcLog 'debug' "Detected \"$_HYPERVISOR\" as hypervisor."
break
fi
done
clcLog 'info' "Using \"$_HYPERVISOR\" as hypervisor." && \
return $?
}
# Grabs a value from currently loaded xml file.
function clcGetXMLValue() {
grep --ignore-case --only-matching "<$1 param=.*" \
"$_BASIC_IMAGE_CONFIGURATION_FILE_PATH" | awk -F '"' '{ print $2 }'
return $?
}
# Handles logging messages. Returns non zero and exit on log level error to
# support chaining the message into toolchain.
function clcLog() {
local loggingType='info'
local message="$1"
if [ "$2" ]; then
loggingType="$1"
message="$2"
fi
if [ "$_VERBOSE" == 'yes' ] || [ "$loggingType" == 'error' ] || \
[ "$loggingType" == 'critical' ]; then
if [ "$3" ]; then
echo -e -n "$3"
fi
echo -e "${loggingType}: $message"
fi
if [ "$loggingType" == 'error' ]; then
exit 1
fi
}
# endregion
# region tools
# Returns the minimal vmx vmware configuration file content to create a
# snapshot.
function clcGetTemporaryVMXContent() {
cat << EOF
.encoding = "UTF-8"
config.version = "8"
virtualHW.version = "7"
ide0:0.present = "TRUE"
ide0:0.fileName = "$1"
displayName = ""
EOF
return $?
}
# Creates a snapshot from VMware generated virtual machine.
function clcCreateVMwareSnapshot() {
local temporaryConfigurationPath="$(mktemp --directory)/" \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \
local temporaryConfigurationFilePath="$(mktemp --suffix '.vmx')" \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \
clcGetTemporaryVMXContent "/var/lib/virt/vmware/$(clcGetXMLValue 'image_name')" \
1>"$temporaryConfigurationFilePath" 2>"$_ERROR_OUTPUT" && \
mv "$temporaryConfigurationFilePath" "$temporaryConfigurationPath" \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \
clcLog "Needed files generated in \"$temporaryConfigurationPath\" generated." && \
vmrun snapshot "$temporaryConfigurationPath"*.vmx \
persistentUserSnapshot 1>"$_STANDARD_OUTPUT" \
2>"$_ERROR_OUTPUT" && \
mv "$temporaryConfigurationPath"*.vmdk "$_TARGET_PATH" \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT"
local result=$?
if [[ "$_DEBUG" == 'no' ]]; then
rm --recursive "$temporaryConfigurationPath" 1>"$_STANDARD_OUTPUT" \
2>"$_ERROR_OUTPUT"
fi
return $result
}
# Creates a snapshot from virtualBox generated virtual machine.
function clcCreateVirtualBoxSnapshot() {
local temporaryConfigurationPath="$(mktemp --directory)" \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \
VBoxManage clonevm TODO ->(VMNAME) --snapshot base --options link \\
--basefolder "$temporaryConfigurationPath" \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \
mv "${temporaryConfigurationPath}/Snapshots/"*.vmdk "$_TARGET_PATH" \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \
rm --recursive "$temporaryConfigurationPath" 1>"$_STANDARD_OUTPUT" \
2>"$_ERROR_OUTPUT" && \
return $?
}
# Creates a persistent version of given config file.
function clcCreatePersistentConfig() {
cp "$_BASIC_IMAGE_CONFIGURATION_FILE_PATH" "$_TARGET_PATH" && \
1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT" && \
sed --in-place --regexp-extended \
"s/(< *short_description[^>]*param=\"[^\"]*)(\")/\\1$_PERSISTENT_SHORT_DESCRIPTION_SUFFIX\\2/g" \
"$_TARGET_PATH" 1>"$_STANDARD_OUTPUT" 2>"$_ERROR_OUTPUT"
return $?
}
# endregion
# endregion
# region controller
clcCommandLineInterface "$@" || return $?
if [[ "$_CREATE_PERSISTENT_CONFIG" == 'yes' ]]; then
clcCreatePersistentConfig || \
clcLog 'error' 'Creating persitent config failed.'
else
"clcCreate${_HYPERVISOR}Snapshot" || \
clcLog 'error' 'Creating Linked Clone failed.'
fi
clcLog 'Program has successfully finished.' && \
return $?
# endregion
}
# region footer
if [[ "$0" == *"${__NAME__}.bash" ]]; then
"$__NAME__" "$@"
fi
# endregion
|