#!/bin/bash set -x # This file format was stolen from devstack <3 # This method was stolen from devstack # git clone only if directory doesn't exist already. Since ``DEST`` might not # be owned by the installation user, we create the directory and change the # ownership to the proper user. # Set global RECLONE=yes to simulate a clone when dest-dir exists # git_clone remote dest-dir branch function git_clone { [[ "$OFFLINE" = "True" ]] && return GIT_REMOTE=$1 GIT_DEST=$2 GIT_BRANCH=$3 if echo $GIT_BRANCH | egrep -q "^refs"; then # If our branch name is a gerrit style refs/changes/... if [[ ! -d $GIT_DEST ]]; then git_timed clone $GIT_REMOTE $GIT_DEST fi cd $GIT_DEST git_timed fetch $GIT_REMOTE $GIT_BRANCH && git_timed checkout FETCH_HEAD else # do a full clone only if the directory doesn't exist if [[ ! -d $GIT_DEST ]]; then git_timed clone $GIT_REMOTE $GIT_DEST cd $GIT_DEST # This checkout syntax works for both branches and tags git_timed checkout $GIT_BRANCH elif [[ "$RECLONE" == "yes" ]]; then # if it does exist then simulate what clone does if asked to RECLONE cd $GIT_DEST # set the url to pull from and fetch git_timed remote set-url origin $GIT_REMOTE git_timed fetch origin # remove the existing ignored files (like pyc) as they cause breakage # (due to the py files having older timestamps than our pyc, so python # thinks the pyc files are correct using them) find $GIT_DEST -name '*.pyc' -delete git_timed checkout -f origin/$GIT_BRANCH # a local branch might not exist git_timed branch -D $GIT_BRANCH || true git_timed checkout -b $GIT_BRANCH fi fi } # Determinate is the given option present in the INI file # ini_has_option config-file section option function ini_has_option() { local file=$1 local section=$2 local option=$3 local line line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file") [ -n "$line" ] } # Get an option from an INI file # iniget config-file section option function iniget() { local file=$1 local section=$2 local option=$3 local line line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file") echo ${line#*=} } # Set an option in an INI file # iniset config-file section option value function iniset() { local file=$1 local section=$2 local option=$3 local value=$4 if ! grep -q "^\[$section\]" "$file"; then # Add section at the end echo -e "\n[$section]" >>"$file" fi if ! ini_has_option "$file" "$section" "$option"; then # Add it sed -i -e "/^\[$section\]/ a\\ $option = $value " "$file" else # Replace it sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=[ \t]*\).*$|\1$value|" "$file" fi } # Determine OS Vendor, Release and Update # Tested with OS/X, Ubuntu, RedHat, CentOS, Fedora # Returns results in global variables: # os_VENDOR - vendor name # os_RELEASE - release # os_UPDATE - update # os_PACKAGE - package type # os_CODENAME - vendor's codename for release # GetOSVersion GetOSVersion() { # Figure out which vendor we are if [[ -x "`which sw_vers 2>/dev/null`" ]]; then # OS/X os_VENDOR=`sw_vers -productName` os_RELEASE=`sw_vers -productVersion` os_UPDATE=${os_RELEASE##*.} os_RELEASE=${os_RELEASE%.*} os_PACKAGE="" if [[ "$os_RELEASE" =~ "10.7" ]]; then os_CODENAME="lion" elif [[ "$os_RELEASE" =~ "10.6" ]]; then os_CODENAME="snow leopard" elif [[ "$os_RELEASE" =~ "10.5" ]]; then os_CODENAME="leopard" elif [[ "$os_RELEASE" =~ "10.4" ]]; then os_CODENAME="tiger" elif [[ "$os_RELEASE" =~ "10.3" ]]; then os_CODENAME="panther" else os_CODENAME="" fi elif [[ -x $(which lsb_release 2>/dev/null) ]]; then os_VENDOR=$(lsb_release -i -s) os_RELEASE=$(lsb_release -r -s) os_UPDATE="" os_PACKAGE="rpm" if [[ "Debian,Ubuntu,LinuxMint" =~ $os_VENDOR ]]; then os_PACKAGE="deb" elif [[ "SUSE LINUX" =~ $os_VENDOR ]]; then lsb_release -d -s | grep -q openSUSE if [[ $? -eq 0 ]]; then os_VENDOR="openSUSE" fi elif [[ $os_VENDOR == "openSUSE project" ]]; then os_VENDOR="openSUSE" elif [[ $os_VENDOR =~ Red.*Hat ]]; then os_VENDOR="Red Hat" fi os_CODENAME=$(lsb_release -c -s) elif [[ -r /etc/redhat-release ]]; then # Red Hat Enterprise Linux Server release 5.5 (Tikanga) # Red Hat Enterprise Linux Server release 7.0 Beta (Maipo) # CentOS release 5.5 (Final) # CentOS Linux release 6.0 (Final) # Fedora release 16 (Verne) # XenServer release 6.2.0-70446c (xenenterprise) os_CODENAME="" for r in "Red Hat" CentOS Fedora XenServer; do os_VENDOR=$r if [[ -n "`grep \"$r\" /etc/redhat-release`" ]]; then ver=`sed -e 's/^.* \([0-9].*\) (\(.*\)).*$/\1\|\2/' /etc/redhat-release` os_CODENAME=${ver#*|} os_RELEASE=${ver%|*} os_UPDATE=${os_RELEASE##*.} os_RELEASE=${os_RELEASE%.*} break fi os_VENDOR="" done os_PACKAGE="rpm" elif [[ -r /etc/SuSE-release ]]; then for r in openSUSE "SUSE Linux"; do if [[ "$r" = "SUSE Linux" ]]; then os_VENDOR="SUSE LINUX" else os_VENDOR=$r fi if [[ -n "`grep \"$r\" /etc/SuSE-release`" ]]; then os_CODENAME=`grep "CODENAME = " /etc/SuSE-release | sed 's:.* = ::g'` os_RELEASE=`grep "VERSION = " /etc/SuSE-release | sed 's:.* = ::g'` os_UPDATE=`grep "PATCHLEVEL = " /etc/SuSE-release | sed 's:.* = ::g'` break fi os_VENDOR="" done os_PACKAGE="rpm" # If lsb_release is not installed, we should be able to detect Debian OS elif [[ -f /etc/debian_version ]] && [[ $(cat /proc/version) =~ "Debian" ]]; then os_VENDOR="Debian" os_PACKAGE="deb" os_CODENAME=$(awk '/VERSION=/' /etc/os-release | sed 's/VERSION=//' | sed -r 's/\"|\(|\)//g' | awk '{print $2}') os_RELEASE=$(awk '/VERSION_ID=/' /etc/os-release | sed 's/VERSION_ID=//' | sed 's/\"//g') fi export os_VENDOR os_RELEASE os_UPDATE os_PACKAGE os_CODENAME } # Translate the OS version values into common nomenclature # Sets ``DISTRO`` from the ``os_*`` values function GetDistro() { GetOSVersion if [[ "$os_VENDOR" =~ (Ubuntu) || "$os_VENDOR" =~ (Debian) ]]; then DISTRO_NAME=ubuntu DISTRO_RELEASE=$os_CODENAME elif [[ "$os_VENDOR" =~ (Fedora) ]]; then DISTRO_NAME=fedora DISTRO_RELEASE=$os_RELEASE elif [[ "$os_VENDOR" =~ (openSUSE) ]]; then DISTRO_NAME=opensuse DISTRO_RELEASE=$os_RELEASE elif [[ "$os_VENDOR" =~ (SUSE LINUX) ]]; then DISTRO_NAME=sle # For SLE, also use the service pack if [[ -z "$os_UPDATE" ]]; then DISTRO_RELEASE=$os_RELEASE else DISTRO_RELEASE="${os_RELEASE}sp${os_UPDATE}" fi elif [[ "$os_VENDOR" =~ (Red Hat) || "$os_VENDOR" =~ (CentOS) ]]; then # Drop the . release as we assume it's compatible DISTRO_NAME=rhel DISTRO_RELEASE=${os_RELEASE::1} elif [[ "$os_VENDOR" =~ (XenServer) ]]; then DISTRO_NAME=xs DISTRO_RELEASE=$os_RELEASE else # Catch-all for now is Vendor + Release + Update DISTRO_NAME=$os_VENDOR DISTRO_RELEASE=$os_RELEASE.$os_UPDATE fi export DISTRO_NAME export DISTRO_RELEASE } # Determine if current distribution is a Fedora-based distribution # (Fedora, RHEL, CentOS, etc). # is_fedora function is_fedora { if [[ -z "$os_VENDOR" ]]; then GetOSVersion fi [ "$os_VENDOR" = "Fedora" ] || [ "$os_VENDOR" = "Red Hat" ]\ || [ "$os_VENDOR" = "CentOS" ] || [ "$os_VENDOR" = "CentOSStream" ] } # Determine if current distribution is a SUSE-based distribution # (openSUSE, SLE). # is_suse function is_suse { if [[ -z "$os_VENDOR" ]]; then GetOSVersion fi [ "$os_VENDOR" = "openSUSE" ] || [ "$os_VENDOR" = "SUSE LINUX" ] } # Get the path to the directory where python executables are installed. # get_python_exec_prefix function get_python_exec_prefix() { if is_fedora || is_suse; then echo "/usr/bin" else echo "/usr/local/bin" fi } # Returns 'true' if 'true', 'yes', 'on' or '1' - false, otherwise. # Converts values to lower case first. # If no default is provided, assumes false. function get_bool() { local VARIABLE="$1" local DEFAULT=${2:-false} VALUE=${!VARIABLE:-$DEFAULT} VALUE=$(eval echo "$VALUE" | tr '[:upper:]' '[:lower:]') if [[ "1 yes true on" =~ "$VALUE" ]]; then VALUE=true else VALUE=false fi echo $VALUE } # Get the project branch to switch to. Uses PROJECT_BRANCH_NAME, # then BRANCH_DEFAULT, then 'master' function get_project_branch() { local PROJECT_BRANCH_NAME=$1 local BRANCH_DEFAULT=${2:-master} PROJECT_BRANCH_OVERRIDE=${!PROJECT_BRANCH_NAME} BRANCH=${PROJECT_BRANCH_OVERRIDE:-$BRANCH_DEFAULT} echo "$BRANCH" } # Try to switch to a branch or commit in a repo # Fails if the branch/commit doesn't exist function git_checkout() { local PROJECT=$1 local REPO_DIR=$2 local REPO_BRANCH=$3 local REPO_BRANCH_VAR_NAME=$4 if [ -n "$REPO_BRANCH" ]; then pushd "$REPO_DIR" if [ $PROJECT == "diskimage-builder" ]; then REPO_BRANCH=master fi CURRENT_BRANCH=$(git branch | grep "\*" | awk '{print $2}') GIT_STATUS=$(git checkout "$REPO_BRANCH" &> /dev/null || echo "failed") if [[ "$GIT_STATUS" = "failed" ]]; then exclaim "${COLOR_RED}Could not switch to branch/commit '$REPO_BRANCH' in $PROJECT, exiting${COLOR_NONE}" echo "Please set '$REPO_BRANCH_VAR_NAME' to a valid branch/commit and try again." if [[ "$CURRENT_BRANCH" != "master" ]]; then echo "Note: This repo is currently on branch ${CURRENT_BRANCH} - if this is correct," echo "you should set $REPO_BRANCH_VAR_NAME=${CURRENT_BRANCH} and re-run your command." else echo "Note: This error may also mean that there are modified files in $PROJECT." echo " If that is the case, please stash them and re-run your command." fi exit 1 else if [[ "$REPO_BRANCH" != "$CURRENT_BRANCH" ]]; then exclaim "${COLOR_BLUE}Switched to $PROJECT branch '$REPO_BRANCH'${COLOR_NONE}" else echo "Using $PROJECT branch '$REPO_BRANCH'" fi fi popd fi }