From 7710e7fc273dd9af6799ea565bbd21ce03745a44 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Wed, 27 Aug 2014 16:15:32 +1000 Subject: [PATCH] Only use lsb_release for distro tags The existing GetOSVersion has a lot of unused code which is wrong in several ways - the only path tested in upstream CI is with lsb_release, because it's pre-installed on all nodes - the /etc/redhat-release checking probably still works, but is unnecessary - If using lsb_release, os_UPDATE has never actually been set. - the /etc/SuSE-release branch checking is broken if the lsb package is actually installed. lsb checking does not set os_UPDATE but yet the SuSE DISTRO setting relies on this to set a patch level (and so does some of the rpm tags). SuSE 11 is up to update 3, but the rpm matching is stuck hard-coded to update 2. I'm guessing installation is actually broken there. - the debian checking branch is broken. The VERSION tags have been removed and were not supposed to be relied on anyway (see notes in [1]) This simplifies things: - remove OSX checking (moved here after discussions in I31d0fdd30928ecc8d959a95838b1d3affd28ac6f) - only use the output of lsb_release. - A small best-effort check to pre-install lsb packages if not detected (that avoids chicken-egg-problem of package-install wrappers relying on os_* flags). - The unset os_UPDATE is removed. It's only previous use was for setting separate suse versions in the DISTRO element for matching during package installs (since removed) - DISTRO setting is modified to use the parts of os_RELEASE it wants. Per-above, this is the correct place to parse out specifics. - Call out the is_* functions, which are a better way to detect platforms - Export the variables as read-only, since they shouldn't be reset [1] http://sources.debian.net/src/base-files/7.5/debian/changelog/ Change-Id: I46a2c36d95327087085df07cb797eb91249a893c --- clean.sh | 2 +- functions-common | 172 ++++++++++++++----------------------- stack.sh | 2 +- tools/create-stack-user.sh | 2 +- tools/info.sh | 4 - tools/install_prereqs.sh | 2 +- unstack.sh | 2 +- 7 files changed, 69 insertions(+), 117 deletions(-) diff --git a/clean.sh b/clean.sh index fc6f80dad4..57e3b5edf8 100755 --- a/clean.sh +++ b/clean.sh @@ -26,7 +26,7 @@ if [[ -r $TOP_DIR/.stackenv ]]; then fi # Determine what system we are running on. This provides ``os_VENDOR``, -# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME`` +# ``os_RELEASE``, ``os_PACKAGE``, ``os_CODENAME`` # and ``DISTRO`` GetDistro diff --git a/functions-common b/functions-common index dbf605cdd8..e6f081ce0a 100644 --- a/functions-common +++ b/functions-common @@ -274,112 +274,71 @@ function warn { # ================ # Determine OS Vendor, Release and Update -# Tested with OS/X, Ubuntu, RedHat, CentOS, Fedora -# Returns results in global variables: + +# +# NOTE : For portability, you almost certainly do not want to use +# these variables directly! The "is_*" functions defined below this +# bundle up compatible platforms under larger umbrellas that we have +# determinted are compatible enough (e.g. is_ubuntu covers Ubuntu & +# Debian, is_fedora covers RPM-based distros). Higher-level functions +# such as "install_package" further abstract things in better ways. +# # ``os_VENDOR`` - vendor name: ``Ubuntu``, ``Fedora``, etc # ``os_RELEASE`` - major release: ``14.04`` (Ubuntu), ``20`` (Fedora) -# ``os_UPDATE`` - update: ex. the ``5`` in ``RHEL6.5`` # ``os_PACKAGE`` - package type: ``deb`` or ``rpm`` -# ``os_CODENAME`` - vendor's codename for release: ``snow leopard``, ``trusty`` -os_VENDOR="" -os_RELEASE="" -os_UPDATE="" -os_PACKAGE="" -os_CODENAME="" +# ``os_CODENAME`` - vendor's codename for release: ``trusty`` + +declare os_VENDOR os_RELEASE os_PACKAGE os_CODENAME + +# Make a *best effort* attempt to install lsb_release packages for the +# user if not available. Note can't use generic install_package* +# because they depend on this! +function _ensure_lsb_release { + if [[ -x $(which lsb_release 2>/dev/null) ]]; then + return + fi + + if [[ -x $(which apt-get 2>/dev/null) ]]; then + sudo apt-get install -y lsb-release + elif [[ -x $(which zypper 2>/dev/null) ]]; then + # XXX: old code paths seem to have assumed SUSE platforms also + # had "yum". Keep this ordered above yum so we don't try to + # install the rh package. suse calls it just "lsb" + sudo zypper -y install lsb + elif [[ -x $(which dnf 2>/dev/null) ]]; then + sudo dnf install -y redhat-lsb-core + elif [[ -x $(which yum 2>/dev/null) ]]; then + # all rh patforms (fedora, centos, rhel) have this pkg + sudo yum install -y redhat-lsb-core + else + die $LINENO "Unable to find or auto-install lsb_release" + fi +} # GetOSVersion +# Set the following variables: +# - os_RELEASE +# - os_CODENAME +# - os_VENDOR +# - os_PACKAGE function GetOSVersion { + # We only support distros that provide a sane lsb_release + _ensure_lsb_release - # 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) - # Oracle Linux release 7 - # CloudLinux release 7.1 - os_CODENAME="" - for r in "Red Hat" CentOS Fedora XenServer CloudLinux; 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 - if [ "$os_VENDOR" = "Red Hat" ] && [[ -r /etc/oracle-release ]]; then - os_VENDOR=OracleLinux - fi - 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 + os_RELEASE=$(lsb_release -r -s) + os_CODENAME=$(lsb_release -c -s) + os_VENDOR=$(lsb_release -i -s) - 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" + if [[ $os_VENDOR =~ (Debian|Ubuntu|LinuxMint) ]]; then 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') + else + os_PACKAGE="rpm" fi - export os_VENDOR os_RELEASE os_UPDATE os_PACKAGE os_CODENAME + + typeset -xr os_VENDOR + typeset -xr os_RELEASE + typeset -xr os_PACKAGE + typeset -xr os_CODENAME } # Translate the OS version values into common nomenclature @@ -389,7 +348,8 @@ declare DISTRO function GetDistro { GetOSVersion if [[ "$os_VENDOR" =~ (Ubuntu) || "$os_VENDOR" =~ (Debian) ]]; then - # 'Everyone' refers to Ubuntu / Debian releases by the code name adjective + # 'Everyone' refers to Ubuntu / Debian releases by + # the code name adjective DISTRO=$os_CODENAME elif [[ "$os_VENDOR" =~ (Fedora) ]]; then # For Fedora, just use 'f' and the release @@ -397,26 +357,22 @@ function GetDistro { elif [[ "$os_VENDOR" =~ (openSUSE) ]]; then DISTRO="opensuse-$os_RELEASE" elif [[ "$os_VENDOR" =~ (SUSE LINUX) ]]; then - # For SLE, also use the service pack - if [[ -z "$os_UPDATE" ]]; then - DISTRO="sle${os_RELEASE}" - else - DISTRO="sle${os_RELEASE}sp${os_UPDATE}" - fi - elif [[ "$os_VENDOR" =~ (Red Hat) || \ + # just use major release + DISTRO="sle${os_RELEASE%.*}" + elif [[ "$os_VENDOR" =~ (Red.*Hat) || \ "$os_VENDOR" =~ (CentOS) || \ "$os_VENDOR" =~ (OracleLinux) ]]; then # Drop the . release as we assume it's compatible + # XXX re-evaluate when we get RHEL10 DISTRO="rhel${os_RELEASE::1}" elif [[ "$os_VENDOR" =~ (XenServer) ]]; then - DISTRO="xs$os_RELEASE" + DISTRO="xs${os_RELEASE%.*}" elif [[ "$os_VENDOR" =~ (kvmibm) ]]; then DISTRO="${os_VENDOR}${os_RELEASE::1}" else - # Catch-all for now is Vendor + Release + Update - DISTRO="$os_VENDOR-$os_RELEASE.$os_UPDATE" + die $LINENO "Unable to determine DISTRO" fi - export DISTRO + typeset -xr DISTRO } # Utility function for checking machine architecture diff --git a/stack.sh b/stack.sh index 5e4a4f8310..697dce156f 100755 --- a/stack.sh +++ b/stack.sh @@ -136,7 +136,7 @@ source $TOP_DIR/inc/meta-config source $TOP_DIR/lib/stack # Determine what system we are running on. This provides ``os_VENDOR``, -# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME`` +# ``os_RELEASE``, ``os_PACKAGE``, ``os_CODENAME`` # and ``DISTRO`` GetDistro diff --git a/tools/create-stack-user.sh b/tools/create-stack-user.sh index b49164b22a..c0b7ac70aa 100755 --- a/tools/create-stack-user.sh +++ b/tools/create-stack-user.sh @@ -24,7 +24,7 @@ TOP_DIR=$(cd $(dirname "$0")/.. && pwd) source $TOP_DIR/functions # Determine what system we are running on. This provides ``os_VENDOR``, -# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME`` +# ``os_RELEASE``, ``os_PACKAGE``, ``os_CODENAME`` # and ``DISTRO`` GetDistro diff --git a/tools/info.sh b/tools/info.sh index 433206e8ae..c056fa73f8 100755 --- a/tools/info.sh +++ b/tools/info.sh @@ -52,10 +52,6 @@ GetDistro echo "os|distro=$DISTRO" echo "os|vendor=$os_VENDOR" echo "os|release=$os_RELEASE" -if [ -n "$os_UPDATE" ]; then - echo "os|version=$os_UPDATE" -fi - # Repos # ----- diff --git a/tools/install_prereqs.sh b/tools/install_prereqs.sh index 031f8a8eca..8895e1e77c 100755 --- a/tools/install_prereqs.sh +++ b/tools/install_prereqs.sh @@ -28,7 +28,7 @@ if [[ -z "$TOP_DIR" ]]; then source $TOP_DIR/functions # Determine what system we are running on. This provides ``os_VENDOR``, - # ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME`` + # ``os_RELEASE``, ``os_PACKAGE``, ``os_CODENAME`` # and ``DISTRO`` GetDistro diff --git a/unstack.sh b/unstack.sh index 8eded837fd..c4dfdc8d9e 100755 --- a/unstack.sh +++ b/unstack.sh @@ -84,7 +84,7 @@ fi load_plugin_settings # Determine what system we are running on. This provides ``os_VENDOR``, -# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME`` +# ``os_RELEASE``, ``os_PACKAGE``, ``os_CODENAME`` GetOSVersion # Run extras