ezbuild/libraries/common

482 wiersze
17 KiB
Bash

#!/bin/bash
# Copyright 2010-2012, Asio Software Technologies
# Distributed under the terms of the GNU General Public License v3
#-------------------------------------------------------------------------------
# Checks if system running EzBuild meets its requirements
#-------------------------------------------------------------------------------
function checkPrerequisites() {
if [ "$(uname -s)" != "Linux" ]; then
printError "You are trying to launch ${EZNAME} on non-Linux system!"
return 1
fi
if [ "${EUID}" != "0" ] && [ "${USER}" != "root" ]; then
printError "The ${EZNAME} needs to be launched from root account!"
return 1
fi
if [ ! -e /dev/null ]; then
printError "The /dev directory seems to be not mounted!"
return 1
fi
if [ ! -e /proc/mounts ]; then
printError "The /proc directory seems to be not mounted!"
return 1
fi
ping -c 1 google.com &> /dev/null
if [ ${?} -ne 0 ]; then
printError "There seems to be no Internet conectivity!"
return 1
fi
return 0
}
#-------------------------------------------------------------------------------
# Tests for a minimum version level by comparing version numbers
# Parameters: %min_version% %test_version%
#-------------------------------------------------------------------------------
function checkVersion() {
local BEST REF TST
REF=$(echo "${1}" | \
sed -u -e "s/-r/_z/g" -e "s/_p/_z/g" -e "s/_zre/_pre/" -e "s/$/_z0/")
TST=$(echo "${2}" | \
sed -u -e "s/-r/_z/g" -e "s/_p/_z/g" -e "s/_zre/_pre/" -e "s/$/_z0/")
BEST=$(echo -e "${REF}\n${TST}" | sed "/^$/d" | sort -Vr | head -1)
[[ "${BEST}" = "${TST}" ]] && return 0
return 1
}
#-------------------------------------------------------------------------------
# Outputs formatted error message and aborts script execution with given status
# Parameters: %message% [%status%]
#-------------------------------------------------------------------------------
function die() {
local STATUS=${2:-1}
notify ${STATUS} "${1}"
printError "${1}"
echo -ne "\n"
exit ${STATUS}
}
#-------------------------------------------------------------------------------
# Failure handler; outputs warning or error depending on user settings
# Parameters: %message% [%status%]
#-------------------------------------------------------------------------------
function fail() {
local STATUS=${2:-1}
if isEnabled ${FATALERRORS}; then
die "${1}" ${STATUS}
else
pushNotification ${STATUS} "${1}"
printWarn "${1}"
fi
}
#-------------------------------------------------------------------------------
# Checks if the given function has been defined
# Parameters: %function%
#-------------------------------------------------------------------------------
function functionExists() {
type ${1} 2>/dev/null | grep -q "is a function"
return ${?}
}
#-------------------------------------------------------------------------------
# Checks whether a defined variable contain specified element or not
# Parameters: %element% %variable%
#-------------------------------------------------------------------------------
function hasElement() {
local NEEDLE=${1}
shift
local X
for X in "${@}"; do
[ "${X}" = "${NEEDLE}" ] && return 0
done
return 1
}
#-------------------------------------------------------------------------------
# Checks whether a supplied variable is defined or not
# Parameters: %variable%
#-------------------------------------------------------------------------------
function isDefined() {
[[ ${!1-X} == ${!1-Y} ]]
}
#-------------------------------------------------------------------------------
# Checks whether a supplied variable is enabled or not
# Parameters: %variable%
#-------------------------------------------------------------------------------
function isEnabled() {
case "${1}" in
[Ee][Nn][Aa][Bb][Ll][Ee][Dd])
return 0
;;
[Tt][Rr][Uu][Ee])
return 0
;;
[Yy][Ee][Ss])
return 0
;;
1)
return 0
;;
esac
return 1
}
#-------------------------------------------------------------------------------
# Checks whether a variable is defined and if value's length > 0
# Parameters: %variable%
#-------------------------------------------------------------------------------
function isSet() {
if isDefined ${1}; then
if [[ -n ${!1} ]]; then
return 0
fi
fi
return 1
}
#-------------------------------------------------------------------------------
# Prints a list of available built-in modules
#-------------------------------------------------------------------------------
function listModules() {
local MODULE
echo -e "Modules can be used to enhance EzBuild functionality by handling"
echo -e "triggered events. They can be easily enabled and/or disabled in"
echo -e "configuration files. Every event has its own list of modules."
echo -e "List of built-in modules available for ${EZNAME}:\n"
for MODULE in ${EZROOT}/modules/*.ezmod; do
source ${MODULE} &> /dev/null
if [ ${?} -ne 0 ] || ! hasElement ${EZNAME} ${EZMOD_COMPATIBILITY}; then
unloadModule
continue
fi
MODULE=$(basename "${MODULE}" .ezmod)
EZMOD_AUTHOR=${EZMOD_AUTHOR:-Unknown}
EZMOD_DESCRIPTION=${EZMOD_DESCRIPTION:-No description provided}
EZMOD_VERSION=${EZMOD_VERSION:-N/A}
echo -e "${COLOR_CYAN}${COLOR_BOLD} ${MODULE}${COLOR_NORMAL}"
echo -e "\t${COLOR_RED}Description:\t${COLOR_CYAN}${EZMOD_DESCRIPTION}"
echo -e "\t${COLOR_RED}Version:\t${COLOR_CYAN}${EZMOD_VERSION}"
echo -e "\t${COLOR_RED}Author:\t\t${COLOR_CYAN}${EZMOD_AUTHOR}\n"
unloadModule
done
echo -e "${COLOR_WHITE}"
exit 0
}
#-------------------------------------------------------------------------------
# Loads EzBuild configuration
#-------------------------------------------------------------------------------
function loadConfiguration() {
source ${EZROOT}/config/common.conf &> /dev/null || panic
source ${EZROOT}/config/${EZNAME}.conf &> /dev/null || panic
source ${EZROOT}/config/layout.conf &> /dev/null || panic
source /etc/ezbuild/common.conf &> /dev/null || panic
source /etc/ezbuild/${EZNAME}.conf &> /dev/null || panic
source /etc/ezbuild/layout.conf &> /dev/null || panic
}
#-------------------------------------------------------------------------------
# Loads all EzBuild Libraries
#-------------------------------------------------------------------------------
function loadLibraries() {
source ${EZROOT}/libraries/constants &> /dev/null || panic
source ${EZROOT}/libraries/filesystem &> /dev/null || panic
source ${EZROOT}/libraries/repositories &> /dev/null || panic
}
#-------------------------------------------------------------------------------
# Loads and executes given EzBuild module
# Parameters: %module% %step%
#-------------------------------------------------------------------------------
function loadModule() {
local MODULE="${1}"
local FUNCTION="${EZNAME}_${2}"
if [ -e ${MODULESCUSTOMDIR}/${MODULE}.ezmod ]; then
source ${MODULESCUSTOMDIR}/${MODULE}.ezmod &> /dev/null
else
source ${EZROOT}/modules/${MODULE}.ezmod &> /dev/null
fi
if [ ${?} -eq 0 ] && hasElement ${EZNAME} ${EZMOD_COMPATIBILITY}; then
if [ -e ${MODULESCUSTOMDIR}/${MODULE}.conf ]; then
source ${EZROOT}/config/modules/${MODULE}.conf &> /dev/null
source ${MODULESCUSTOMDIR}/${MODULE}.conf &> /dev/null
elif [ -e /etc/ezbuild/modules/${MODULE}.conf ]; then
source ${EZROOT}/config/modules/${MODULE}.conf &> /dev/null
source /etc/ezbuild/modules/${MODULE}.conf &> /dev/null
fi
if [ ${?} -eq 0 ]; then
if functionExists ${FUNCTION}; then
eval ${FUNCTION}
return ${?}
else
return 255
fi
fi
fi
return 1
}
#-------------------------------------------------------------------------------
# Saves specified message into a log file
# Parameters: %message% [%level%]
#-------------------------------------------------------------------------------
function logMessage() {
local DATE MESSAGE TYPE
if isEnabled ${LOGGING}; then
MESSAGE="${1}"
TYPE="${2}"
DATE=$(date +"${LOGDATEFORMAT}")
if [ -z ${TYPE} ]; then
TYPE=" - "
fi
{ echo -e "[${DATE}][${TYPE}] ${MESSAGE}" >> ${LOGFILE}; } 2> /dev/null
fi
}
#-------------------------------------------------------------------------------
# Saves executed command multiline output into a log file
# Parameters: %command_output%
#-------------------------------------------------------------------------------
function logOutput() {
if isEnabled ${LOGGING}; then
if [ -z "${@}" ]; then
echo -e " )> (NO OUTPUT)" >> ${LOGFILE}
else
echo -e "${@}" | awk '{ print " )> ", $0; }' >> ${LOGFILE}
fi
fi
}
#-------------------------------------------------------------------------------
# Sends an e-mail notification about occured error
# Parameters: %status% %message%
#-------------------------------------------------------------------------------
function notify() {
if isEnabled ${LOGGING} && isSet NOTIFY && isEnabled ${EZNOTIFY}; then
local MESG=""
local SEND=0
if [ ${1} -ne 0 ]; then
MESG="The ${EZNAME} has failed with code: ${1} and message: ${2}"
SEND=1
if [ ${#NOTIFICATIONS[@]} -ne 0 ]; then
MESG="${MESG}\nThere were also some non-fatal errors that has \
been treated as warnings:"
fi
elif [ ${#NOTIFICATIONS[@]} -ne 0 ]; then
MESG="The ${EZNAME} process has ended its job without any fatal \
error, but there still were some non-fatal errors that has \
been treated as warnings:"
SEND=1
fi
MESG=$(echo -e "${MESG}" | awk -v OFS=" " '$1=$1')
if [ ${SEND} -eq 1 ]; then
if [ ${#NOTIFICATIONS[@]} -ne 0 ]; then
for NOTIFICATION in "${NOTIFICATIONS[@]}"; do
MESG="${MESG}\n * ${NOTIFICATION}"
done
fi
local LOGS="Full output from log file:\n\n$(cat ${LOGFILE})"
local TOPIC="The ${EZNAME} process has produced an error!"
echo -e "${MESG}\n\n\n${LOGS}" | mailx -s "${TOPIC}" "${NOTIFY}"
fi
fi
}
#-------------------------------------------------------------------------------
# Outputs error message and aborts program execution
#-------------------------------------------------------------------------------
function panic() {
echo -e "FATAL ERROR: Unable to load necessary files!"
echo -e "Your EzBuild installation seems to be broken..."
exit 1
}
#-------------------------------------------------------------------------------
# Outputs formatted error message to both display and log file
# Parameters: %message%
#-------------------------------------------------------------------------------
function printError() {
logMessage "${1}" "ERROR"
echo -e " ${MESSAGE_ERROR} ${@}"
}
#-------------------------------------------------------------------------------
# Outputs formatted information to both display and log file
# Parameters: %message%
#-------------------------------------------------------------------------------
function printInfo() {
logMessage "${1}" "INFO"
echo -e " ${MESSAGE_INFO} ${@}"
}
#-------------------------------------------------------------------------------
# Outputs formatted information about EzBuild version and copyrights
#-------------------------------------------------------------------------------
function printNotice() {
echo -e "\n${COLOR_BOLD}EzBuild v${EZVERSION} (${EZNAME} launched)"
echo -e "${EZCOPYRIGHT}${COLOR_NORMAL}"
echo -e "${BORDER_STAR}\n"
}
#-------------------------------------------------------------------------------
# Outputs formatted warning to both display and log file
# Parameters: %message%
#-------------------------------------------------------------------------------
function printWarn() {
logMessage "${1}" "WARN"
echo -e " ${MESSAGE_WARN} ${@}"
}
#-------------------------------------------------------------------------------
# Adds new non-fatal error notification message to the queue
# Parameters: %status% %message%
#-------------------------------------------------------------------------------
function pushNotification() {
local NUM=${#NOTIFICATIONS[@]}
NOTIFICATIONS[${NUM}]="Code: ${1} Message: ${2}"
}
#-------------------------------------------------------------------------------
# Optionally sends all notifications from queue and aborts program execution
#-------------------------------------------------------------------------------
function quit() {
notify 0
echo -e "${COLOR_BOLD}ALL DONE!\n${COLOR_NORMAL}"
exit 0
}
#-------------------------------------------------------------------------------
# Restores original Internal Field Separator (IFS)
#-------------------------------------------------------------------------------
function restoreIFS() {
if [ "${ORGIFS:-unset}" != "unset" ]; then
IFS="${ORGIFS}"
unset ORGIFS
else
unset IFS
fi
}
#-------------------------------------------------------------------------------
# Silently executes given command and saves its output to log file if enabled
# Parameters: %command%
#-------------------------------------------------------------------------------
function run() {
local COMMAND OUTPUT RESULT
COMMAND="${@}"
logMessage "Executing: \`${COMMAND}\`" "DEBUG"
OUTPUT=$(eval ${COMMAND} 2>&1)
RESULT=${?}
logOutput "${OUTPUT}"
return ${RESULT}
}
#-------------------------------------------------------------------------------
# Saves original Internal Field Separator (IFS) and optionally sets new value
# Parameters: %new_ifs%
#-------------------------------------------------------------------------------
function saveIFS() {
local NEWIFS
if [ "${IFS:-unset}" != "unset" ]; then
ORGIFS="${IFS}"
fi
NEWIFS="${1}"
if isSet NEWIFS; then
IFS="${NEWIFS}"
fi
}
#-------------------------------------------------------------------------------
# Prints EzBuild usage information
#-------------------------------------------------------------------------------
function showEzbuildUsage() {
echo -e "EzBuild is release building metatool used by reGen2 developers for"
echo -e "building a custom Linux releases and templates.\n"
echo -e "USAGE: ezsync [parameters]"
echo -e " -c\t--cleanlog\tclears log file; not working with -p and -P"
echo -e " -D\t--tarballdate\toverrides produced image version/date format"
echo -e " -h\t--help\t\tdisplays this screen and exits immediately"
echo -e " -l\t--listmods\tshows the list of available built-in modules"
echo -e " -p\t--purge\t\tclears temporary folder"
echo -e " -P\t--purgeonly\tclears temporary folder and exits"
echo -e " -s\t--syscheck\tperforms prerequisites check only"
echo -e " -t\t--notrigger\tdisables all build triggers and modules"
echo -e " -T\t--tarballformat\toverrides default compression algorithm"
echo -e "\n"
exit 0
}
#-------------------------------------------------------------------------------
# Prints EzSync usage information
#-------------------------------------------------------------------------------
function showEzsyncUsage() {
echo -e "\tEzSync is a part of EzBuild release building metatool used by"
echo -e "\treGen2 Linux for synchronizing Portage Tree with mainline.\n"
echo -e "USAGE: ezsync [parameters]"
echo -e " -c\t--cleanlog\tclears log file; not working with -p and -P"
echo -e " -D\t--tarballdate\toverrides produced image version/date format"
echo -e " -h\t--help\t\tdisplays this screen and exits immediately"
echo -e " -l\t--listmods\tshows the list of available built-in modules"
echo -e " -n\t--nosync\tspecifies the ebuilds source that will be omitted"
echo -e " -N\t--nopush\tavoids automatic commits into repositories"
echo -e " -p\t--purge\t\tclears temporary folder"
echo -e " -P\t--purgeonly\tclears temporary folder and exits"
echo -e " -s\t--syscheck\tperforms prerequisites check only"
echo -e " -t\t--notrigger\tdisables all build triggers and modules"
echo -e " -T\t--tarballformat\toverrides default compression algorithm"
echo -e "\nEXAMPLES:"
echo -e " ezsync -c -n mainline"
echo -e " ezsync -n mainline -n my_repo1"
echo -e "\n"
exit 0
}
#-------------------------------------------------------------------------------
# Returns a UNIX timestamp
#-------------------------------------------------------------------------------
function timestamp() {
echo $(date +%s)
}
#-------------------------------------------------------------------------------
# Returns lowercase string
# Parameters: %string%
#-------------------------------------------------------------------------------
function toLower() {
echo "${@}" | tr '[:upper:]' '[:lower:]'
}
#-------------------------------------------------------------------------------
# Returns uppercase string
# Parameters: %string%
#-------------------------------------------------------------------------------
function toUpper() {
echo "${@}" | tr '[:lower:]' '[:upper:]'
}
#-------------------------------------------------------------------------------
# Returns only the first part of a string, delimited by tabs or spaces
# Parameters: %string%
#-------------------------------------------------------------------------------
function trim() {
echo ${1}
}
#-------------------------------------------------------------------------------
# Silently unloads any previously loaded module
#-------------------------------------------------------------------------------
function unloadModule() {
unset EZMOD_AUTHOR
unset EZMOD_COMPATIBILITY
unset EZMOD_DESCRIPTION
unset EZMOD_VERSION
unset ezsync_precommit
unset ezsync_presync
unset ezsync_postcommit
unset ezsync_postsync
}