diff --git a/AUTHORS.rst b/AUTHORS.rst index 02bd0e6..cd7c28f 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -12,6 +12,7 @@ Adam Wright hipikat adam@hipikat.org Alec Koumjian akoumjian akoumjian@gmail.com Alex Van't Hof alexvh Alexander Krasnukhin themalkolm the.malkolm@gmail.com +Alexandru Avadanii alexandruavadanii Alexandru.Avadanii@enea.com Alexey dmitrievav Ali Rizvi-Santiago arizvisa amendlik amendlik @@ -69,6 +70,7 @@ Guillaume Derval GuillaumeDerval guillaume@guillaumederval.be gweis gweis Henrik Holmboe holmboe Howard Mei HowardMei howardleomei@gmail.com +Jan Heidbrink jheidbrink James Booth absolutejam vvalentine1337@gmail.com Jared E Stroud jaredestroud jaredestroud@gmail.com Jasper Lievisse Adriaanse jasperla jasper@humppa.nl @@ -80,6 +82,7 @@ Justin Anderson justinta justin.ta@outlook.com Justin Findlay jfindlay jfindlay@gmail.com Karl Grzeszczak karlgrz Kenneth Wilke KennethWilke +Ky-Anh Huynh icy lomeroe lomeroe Liu Xiaohui oreh herolxh@gmail.com Lorenzo Perone lopezio lorenzo.perone@yellowspace.net @@ -96,11 +99,13 @@ Matthew Mead-Briggs mattmb Matthew Richardson mrichar1 Matthew Willson ixela Matthieu Guegan mguegan +mfapouw mfapouw Michael A. Smith kojiromike michaels@syapse.com Michael Scherer mscherer Michele Bologna mbologna michele.bologna@gmail.com Mike Carlson m87carlson mike@bayphoto.com Mike Place cachedout mp@saltstack.com +N noelmcloughlin noel.maclochlainn@gmail.com nasenbaer13 nasenbaer13 nevins-b nevins-b Nicole Thomas rallytime nicole@saltstack.com diff --git a/ChangeLog b/ChangeLog index a396058..76195fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +Version TBD (In Progress on the Develop Branch): + +Version 2018.08.13: + * Fedora Py3 fixes (The-Loeki) #1273 + * Handle commented lines in the requirements files for pip pkgs (rallytime) #1271 + * Remove typo: extra 'c' was accidentally added in #1269 (rallytime) #1270 + * [Arch] Add python2-futures to list of pkgs on git install (rallytime) #1269 + * Fix undefined variable warn_msg on amd64 (alexandruavadanii) #1268 + * SLES12SP changed packages git to git-core and libzmq3 to libzmq4 (mfapouw) #1266 + * Add opensuse 15 specific installation functions (rallytime) #1263 + * Remove support for openSUSE Leap 42.2 (rallytime) #1262 + * Remove support for Fedora 26 (rallytime) #1261 + * Remove support for Ubuntu 17.10 (rallytime) #1260 + * Ensure pipe is absent before mkfifo/mknod (noelmcloughlin) #1256 + * fix for opensuse15 if no lsb_release pkg (noelmcloughlin) #1255 + * Fix Up ShellCheck errors/warnings for latest version of shellcheck (rallytime) #1253 + * Remove daily install option on Ubuntu system (icy) #1250 + * Add python 3 support for Ubuntu 18 (rallytime) #1248 + * Return immediately if apt-get fails (icy) #1247 + * Disable shell error about unbound variable during daily install (icy) #1246 + * OpenSuse_Leap_15.0 saltstack repo support (noelmcloughlin) #1244 + * Add Python3 package support for Debian 9 (rallytime) #1243 + * Add Python3 package support for CentOS 7 (rallytime) #1242 + * Shellcheck fixes found when running latest version (rallytime) #1239 + * Add Python3 package support for Ubuntu 16.04 (rallytime) #1238 + * Fix the variable ref from #803 (rallytime) #1229 + * Add Ubuntu 18.04 support (rallytime) #1228 + * Call __git_clone_and_checkout directly (jheidbrink) #1226 + * Fix for silently ignored version argument on CentOS/RHEL (pjcreath) #1210 + Version 2018.04.25: * Install py-tornado4 for FreeBSD. (abednarik) #1219 * Remove COPR repos configuration for Fedora (vutny ) #1211 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..b135966 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,114 @@ +import java.util.Random + +Random rand = new Random() + +// ONLY CHANGE THIS BIT PLEASE +def baseDistros = ["debian8", + "suse", + "centos6", + "arch", + "ubuntu-14.04", + "ubuntu-18.04", + "windows", + ] +def versions = ["stable", "git", "stable-old"] + +def basePrDistros = ["ubuntu-16.04", + "centos7"] + +def prVersions = ["stable", "git"] + +// You probably shouldn't be messing with this stuff down here + +def distros = (baseDistros + basePrDistros).unique() + +def notifySuccessful(String stageName) { + slackSend (color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})" + "\n Stage -- " + stageName) +} + +def notifyFailed(String stageName) { + slackSend (color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})" + "\n Stage -- " + stageName) +} + +def runKitchen(String distro) { + echo "kitchen create ${distro}" + echo "kitchen converge ${distro}" + echo "kitchen destroy ${distro}" +} + +def distroversions = [] +for (d in distros) { + for (v in versions) { + distroversions = distroversions + ["${d}-${v}"] + } +} + +def prDistros = (basePrDistros + distros[rand.nextInt(baseDistros.size())]).unique() + +def prDistroversions = [] +for (d in prDistros) { + for (v in prVersions) { + prDistroversions = prDistroversions + ["${d}-${v}"] + } +} + +def makeSetupRuns(dv) { + return { + node { + runKitchen("${dv}") + } + } +} + +def setupRuns = distroversions.collectEntries { + ["kitchen-${it}" : makeSetupRuns("${it}")] +} + +def prSetupRuns = prDistroversions.collectEntries { + ["kitchen-${it}" : makeSetupRuns("${it}")] +} + +node ('bootstrap') { + timestamps { + ansiColor('xterm') { + stage('checkout') { checkout scm } + stage('shellcheck') { + sh 'stack exec -- shellcheck -s sh -f checkstyle bootstrap-salt.sh | tee checkstyle.xml' + checkstyle canComputeNew: false, defaultEncoding: '', healthy: '', pattern: '**/checkstyle.xml', unHealthy: '', unstableTotalAll: '0' + archiveArtifacts artifacts: '**/checkstyle.xml' + } + // if (env.CHANGE_ID) { + // // Running for a PR only runs against 4 random distros from a shorter list + // stage('kitchen-pr') { + // parallel prSetupRuns + // } + // } else { + // // If we're not running for a pr we run *everything* + // stage('kitchen-all') { + // parallel setupRuns + // } + // } + } + } +} + +/* + * TODO: + * 1. Tests for each supported distro in bootstrap + branch shellcheck test (Shellcheck should be done) + * 2. Each distro needs a "stable" install (installs stable packages from our repo) and a "git" install (installs off of a git tag) + * 3. Running against each branch (stable, develop) + * 4. And probably a small subset against each pull request (similar to what we do in salt) + * + * Distros to check: + * Debian 8 + * Suse 42.1 + * CentOS 7 + * CentOS 6 + * Arch + * Ubuntu 16.04 + * Ubuntu 14.04 + * Windows + * + * Runs each against develop and stable + * + */ diff --git a/README.rst b/README.rst index ae5ca3f..ebe66ef 100644 --- a/README.rst +++ b/README.rst @@ -28,6 +28,7 @@ sum** of the downloaded ``bootstrap-salt.sh`` file. The SHA256 sum of the ``bootstrap-salt.sh`` file, per release, is: +- 2018.04.25: ``e2e3397d6642ba6462174b4723f1b30d04229b75efc099a553e15ea727877dfb`` - 2017.12.13: ``c127b3aa4a8422f6b81f5b4a40d31d13cec97bf3a39bca9c11a28f24910a6895`` - 2017.08.17: ``909b4d35696b9867b34b22ef4b60edbc5a0e9f8d1ed8d05f922acb79a02e46e3`` - 2017.05.24: ``8c42c2e5ad3d4384ddc557da5c214ba3e40c056ca1b758d14a392c1364650e89`` @@ -256,7 +257,7 @@ Red Hat family - Amazon Linux 2012.3 and later - CentOS 6/7 - Cloud Linux 6/7 -- Fedora 26/27/28 (install latest stable from standard repositories) +- Fedora 27/28 (install latest stable from standard repositories) - Oracle Linux 6/7 - Red Hat Enterprise Linux 6/7 - Scientific Linux 6/7 @@ -265,17 +266,26 @@ Red Hat family SUSE family ~~~~~~~~~~~ -- openSUSE Leap 42.2/42.3 +- openSUSE Leap 15 (see note below) +- openSUSE Leap 42.3 - openSUSE Tumbleweed 2015 - SUSE Linux Enterprise Server 11 SP4, 12 SP2 +**NOTE:** Leap 15 installs Python 3 Salt packages by default. Salt is packaged by SUSE, and +Leap 15 ships with Python 3. Salt with Python 2 can be installed using the the ``-x`` option +in combination with the ``git`` installation method. + +.. code:: console + + sh bootstrap-salt.sh -x python2 git v2018.3.2 + Ubuntu and derivatives ~~~~~~~~~~~~~~~~~~~~~~ - KDE neon (based on Ubuntu 16.04) - Linux Mint 17/18 -- Ubuntu 14.04/16.04 and subsequent non-TLS releases (see below) +- Ubuntu 14.04/16.04/18.04 and subsequent non-LTS releases (see below) Ubuntu Best Effort Support: Non-LTS Releases ******************************************** @@ -285,8 +295,11 @@ repositories are not provided on `SaltStack's Ubuntu repository`_ for the non-LT bootstrap script will attempt to install the packages for the most closely related LTS Ubuntu release instead. -For example, when installing Salt on Ubuntu 17.10, the bootstrap script will setup the repository -for Ubuntu 16.04 from `SaltStack's Ubuntu repository`_ and install the 16.04 packages. +For example, when installing Salt on Ubuntu 18.10, the bootstrap script will setup the repository +for Ubuntu 18.04 from `SaltStack's Ubuntu repository`_ and install the 18.04 packages. + +Non-LTS Ubuntu releases are not supported once the release reaches End-of-Life as defined by +`Ubuntu's release schedule`_. Other Linux distributions @@ -309,8 +322,8 @@ UNIX systems - SmartOS -Unsupported Distro ------------------- +Unsupported Distributions +------------------------- If you are running a Linux distribution that is not supported yet or is not correctly identified, please run the following commands and report their output when creating an issue: @@ -323,6 +336,28 @@ please run the following commands and report their output when creating an issue For information on how to add support for a currently unsupported distribution, please refer to the `Contributing Guidelines`_. +Python 3 Support +---------------- + +Some distributions support installing Salt to use Python 3 instead of Python 2. The availability of +this offering, while limited, is as follows: + +- CentOS 7 +- Debian 9 +- Fedora (only git installations) +- Ubuntu 16.04 +- Ubuntu 18.04 + +On Fedora 28, PIP installation must be allowed (-P) due to incompatibility with the shipped Tornado library. + +Installing the Python 3 packages for Salt is done via the ``-x`` option: + +.. code:: console + + sh bootstrap-salt.sh -x python3 + +See the ``-x`` option for more information. + Testing ------- @@ -381,6 +416,7 @@ Salt components, custom configurations, and even `pre-accepted Minion keys`_ alr .. _`SaltStack's corporate repository`: https://repo.saltstack.com/ .. _`SaltStack's Debian repository`: http://repo.saltstack.com/#debian .. _`SaltStack's Ubuntu repository`: http://repo.saltstack.com/#ubuntu +.. _`Ubuntu's release schedule`: https://wiki.ubuntu.com/Releases .. _Vagrant: http://www.vagrantup.com diff --git a/bootstrap-salt.sh b/bootstrap-salt.sh index f0727c6..9f7cf21 100755 --- a/bootstrap-salt.sh +++ b/bootstrap-salt.sh @@ -18,7 +18,7 @@ #====================================================================================================================== set -o nounset # Treat unset variables as an error -__ScriptVersion="2018.04.25" +__ScriptVersion="2018.08.13" __ScriptName="bootstrap-salt.sh" __ScriptFullName="$0" @@ -43,10 +43,6 @@ __ScriptArgs="$*" #====================================================================================================================== -#====================================================================================================================== -# LET THE BLACK MAGIC BEGIN!!!! -#====================================================================================================================== - # Bootstrap script truth values BS_TRUE=1 BS_FALSE=0 @@ -60,12 +56,13 @@ __DEFAULT_SLEEP=3 #---------------------------------------------------------------------------------------------------------------------- _COLORS=${BS_COLORS:-$(tput colors 2>/dev/null || echo 0)} __detect_color_support() { + # shellcheck disable=SC2181 if [ $? -eq 0 ] && [ "$_COLORS" -gt 2 ]; then - RC="\033[1;31m" - GC="\033[1;32m" - BC="\033[1;34m" - YC="\033[1;33m" - EC="\033[0m" + RC='\033[1;31m' + GC='\033[1;32m' + BC='\033[1;34m' + YC='\033[1;33m' + EC='\033[0m' else RC="" GC="" @@ -82,7 +79,7 @@ __detect_color_support # DESCRIPTION: Echo errors to stderr. #---------------------------------------------------------------------------------------------------------------------- echoerror() { - printf "${RC} * ERROR${EC}: %s\n" "$@" 1>&2; + printf "${RC} * ERROR${EC}: %s\\n" "$@" 1>&2; } #--- FUNCTION ------------------------------------------------------------------------------------------------------- @@ -90,7 +87,7 @@ echoerror() { # DESCRIPTION: Echo information to stdout. #---------------------------------------------------------------------------------------------------------------------- echoinfo() { - printf "${GC} * INFO${EC}: %s\n" "$@"; + printf "${GC} * INFO${EC}: %s\\n" "$@"; } #--- FUNCTION ------------------------------------------------------------------------------------------------------- @@ -98,7 +95,7 @@ echoinfo() { # DESCRIPTION: Echo warning information to stdout. #---------------------------------------------------------------------------------------------------------------------- echowarn() { - printf "${YC} * WARN${EC}: %s\n" "$@"; + printf "${YC} * WARN${EC}: %s\\n" "$@"; } #--- FUNCTION ------------------------------------------------------------------------------------------------------- @@ -107,7 +104,7 @@ echowarn() { #---------------------------------------------------------------------------------------------------------------------- echodebug() { if [ "$_ECHO_DEBUG" -eq $BS_TRUE ]; then - printf "${BC} * DEBUG${EC}: %s\n" "$@"; + printf "${BC} * DEBUG${EC}: %s\\n" "$@"; fi } @@ -289,7 +286,6 @@ __usage() { for packages available at repo.saltstack.com - stable [version] Install a specific version. Only supported for packages available at repo.saltstack.com - - daily Ubuntu specific: configure SaltStack Daily PPA - testing RHEL-family specific: configure EPEL testing repo - git Install from the head of the develop branch - git [ref] Install from any git ref (such as a branch, tag, or @@ -300,7 +296,6 @@ __usage() { - ${__ScriptName} stable - ${__ScriptName} stable 2017.7 - ${__ScriptName} stable 2017.7.2 - - ${__ScriptName} daily - ${__ScriptName} testing - ${__ScriptName} git - ${__ScriptName} git 2017.7 @@ -351,7 +346,7 @@ __usage() { -i Pass the salt-minion id. This will be stored under \${BS_SALT_ETC_DIR}/minion_id -p Extra-package to install while installing Salt dependencies. One package - per -p flag. You're responsible for providing the proper package name. + per -p flag. You are responsible for providing the proper package name. -H Use the specified HTTP proxy for all download URLs (including https://). For example: http://myproxy.example.com:3128 -b Assume that dependencies are already installed and software sources are @@ -385,11 +380,11 @@ __usage() { no ".bak" file will be created as either of those options will force a complete overwrite of the file. -q Quiet salt installation from git (setup.py install -q) - -x Changes the python version used to install a git version of salt. Currently - this is considered experimental and has only been tested on Centos 6. This - only works for git installations. + -x Changes the Python version used to install Salt. + For CentOS 6 git installations python2.7 is supported. + Fedora git installation, CentOS 7, Debian 9, Ubuntu 16.04 and 18.04 support python3. -y Installs a different python version on host. Currently this has only been - tested with Centos 6 and is considered experimental. This will install the + tested with CentOS 6 and is considered experimental. This will install the ius repo on the box if disable repo is false. This must be used in conjunction with -x . For example: sh bootstrap.sh -P -y -x python2.7 git v2017.7.2 @@ -400,7 +395,7 @@ EOT } # ---------- end of function __usage ---------- -while getopts ':hvnDc:g:Gyx:wk:s:MSNXCPFUKIA:i:Lp:dH:ZbflV:J:j:rR:aq' opt +while getopts ':hvnDc:g:Gyx:wk:s:MSNXCPFUKIA:i:Lp:dH:bflV:J:j:rR:aq' opt do case "${opt}" in @@ -462,11 +457,12 @@ shift $((OPTIND-1)) # Define our logging file and pipe paths LOGFILE="/tmp/$( echo "$__ScriptName" | sed s/.sh/.log/g )" LOGPIPE="/tmp/$( echo "$__ScriptName" | sed s/.sh/.logpipe/g )" +# Ensure no residual pipe exists +rm "$LOGPIPE" 2>/dev/null # Create our logging pipe # On FreeBSD we have to use mkfifo instead of mknod -mknod "$LOGPIPE" p >/dev/null 2>&1 || mkfifo "$LOGPIPE" >/dev/null 2>&1 -if [ $? -ne 0 ]; then +if ! (mknod "$LOGPIPE" p >/dev/null 2>&1 || mkfifo "$LOGPIPE" >/dev/null 2>&1); then echoerror "Failed to create the named pipe required to log" exit 1 fi @@ -567,7 +563,7 @@ if [ "$#" -gt 0 ];then fi # Check installation type -if [ "$(echo "$ITYPE" | egrep '(stable|testing|daily|git)')" = "" ]; then +if [ "$(echo "$ITYPE" | grep -E '(stable|testing|git)')" = "" ]; then echoerror "Installation type \"$ITYPE\" is not known..." exit 1 fi @@ -589,10 +585,10 @@ elif [ "$ITYPE" = "stable" ]; then if [ "$#" -eq 0 ];then STABLE_REV="latest" else - if [ "$(echo "$1" | egrep '^(latest|1\.6|1\.7|2014\.1|2014\.7|2015\.5|2015\.8|2016\.3|2016\.11|2017\.7|2018\.3)$')" != "" ]; then + if [ "$(echo "$1" | grep -E '^(latest|1\.6|1\.7|2014\.1|2014\.7|2015\.5|2015\.8|2016\.3|2016\.11|2017\.7|2018\.3)$')" != "" ]; then STABLE_REV="$1" shift - elif [ "$(echo "$1" | egrep '^([0-9]*\.[0-9]*\.[0-9]*)$')" != "" ]; then + elif [ "$(echo "$1" | grep -E '^([0-9]*\.[0-9]*\.[0-9]*)$')" != "" ]; then STABLE_REV="archive/$1" shift else @@ -657,6 +653,22 @@ if [ "$_CUSTOM_MINION_CONFIG" != "null" ]; then fi fi +# Check if we're installing via a different Python executable and set major version variables +if [ -n "$_PY_EXE" ]; then + _PY_PKG_VER=$(echo "$_PY_EXE" | sed -r "s/\\.//g") + + _PY_MAJOR_VERSION=$(echo "$_PY_PKG_VER" | cut -c 7) + if [ "$_PY_MAJOR_VERSION" != 3 ] && [ "$_PY_MAJOR_VERSION" != 2 ]; then + echoerror "Detected -x option, but Python major version is not 2 or 3." + echoerror "The -x option must be passed as python2, python27, or python2.7 (or use the Python '3' versions of examples)." + exit 1 + fi + + echoinfo "Detected -x option. Using $_PY_EXE to install Salt." +else + _PY_PKG_VER="" +fi + # If the configuration directory or archive does not exist, error out if [ "$_TEMP_CONFIG_DIR" != "null" ]; then _TEMP_CONFIG_DIR="$(__check_config_dir "$_TEMP_CONFIG_DIR")" @@ -775,8 +787,7 @@ __fetch_verify() { test "$(stat --format=%s "$fetch_verify_tmpf")" -eq "$fetch_verify_size" && \ test "$(md5sum "$fetch_verify_tmpf" | awk '{ print $1 }')" = "$fetch_verify_sum" && \ cat "$fetch_verify_tmpf" && \ - rm -f "$fetch_verify_tmpf" - if [ $? -eq 0 ]; then + if rm -f "$fetch_verify_tmpf"; then return 0 fi echo "Failed verification of $fetch_verify_url" @@ -875,6 +886,7 @@ __derive_debian_numeric_version() { # DESCRIPTION: Strip single or double quotes from the provided string. #---------------------------------------------------------------------------------------------------------------------- __unquote_string() { + # shellcheck disable=SC1117 echo "$*" | sed -e "s/^\([\"\']\)\(.*\)\1\$/\2/g" } @@ -907,7 +919,7 @@ __sort_release_files() { secondary_release_files="" # Sort know VS un-known files first for release_file in $(echo "${@}" | sed -r 's:[[:space:]]:\n:g' | sort -f | uniq); do - match=$(echo "$release_file" | egrep -i "${KNOWN_RELEASE_FILES}") + match=$(echo "$release_file" | grep -E -i "${KNOWN_RELEASE_FILES}") if [ "${match}" != "" ]; then primary_release_files="${primary_release_files} ${release_file}" else @@ -919,14 +931,14 @@ __sort_release_files() { max_prio="redhat-release centos-release oracle-release fedora-release" for entry in $max_prio; do if [ "$(echo "${primary_release_files}" | grep "$entry")" != "" ]; then - primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\(.*\)\($entry\)\(.*\):\2 \1 \3:g") + primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\\(.*\\)\\($entry\\)\\(.*\\):\\2 \\1 \\3:g") fi done # Now, least important goes last in the min_prio list min_prio="lsb-release" for entry in $min_prio; do if [ "$(echo "${primary_release_files}" | grep "$entry")" != "" ]; then - primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\(.*\)\($entry\)\(.*\):\1 \3 \2:g") + primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\\(.*\\)\\($entry\\)\\(.*\\):\\1 \\3 \\2:g") fi done @@ -945,6 +957,8 @@ __gather_linux_system_info() { # Let's test if the lsb_release binary is available rv=$(lsb_release >/dev/null 2>&1) + + # shellcheck disable=SC2181 if [ $? -eq 0 ]; then DISTRO_NAME=$(lsb_release -si) if [ "${DISTRO_NAME}" = "Scientific" ]; then @@ -959,6 +973,7 @@ __gather_linux_system_info() { [ "$n" = "$DISTRO_NAME" ] && DISTRO_NAME="" || DISTRO_NAME="$n" elif [ "${DISTRO_NAME}" = "openSUSE project" ]; then # lsb_release -si returns "openSUSE project" on openSUSE 12.3 + # lsb_release -si returns "openSUSE" on openSUSE 15.n DISTRO_NAME="opensuse" elif [ "${DISTRO_NAME}" = "SUSE LINUX" ]; then if [ "$(lsb_release -sd | grep -i opensuse)" != "" ]; then @@ -1015,11 +1030,11 @@ __gather_linux_system_info() { v=$(__parse_version_string "$rv") case $shortname in redhat ) - if [ "$(egrep 'CentOS' /etc/${rsource})" != "" ]; then + if [ "$(grep -E 'CentOS' /etc/${rsource})" != "" ]; then n="CentOS" - elif [ "$(egrep 'Scientific' /etc/${rsource})" != "" ]; then + elif [ "$(grep -E 'Scientific' /etc/${rsource})" != "" ]; then n="Scientific Linux" - elif [ "$(egrep 'Red Hat Enterprise Linux' /etc/${rsource})" != "" ]; then + elif [ "$(grep -E 'Red Hat Enterprise Linux' /etc/${rsource})" != "" ]; then n="ed at nterprise inux" else n="ed at inux" @@ -1031,7 +1046,7 @@ __gather_linux_system_info() { debian ) n="Debian" ;; ubuntu ) n="Ubuntu" ;; fedora ) n="Fedora" ;; - suse ) n="SUSE" ;; + suse|opensuse ) n="SUSE" ;; mandrake*|mandriva ) n="Mandriva" ;; gentoo ) n="Gentoo" ;; slackware ) n="Slackware" ;; @@ -1073,10 +1088,14 @@ __gather_linux_system_info() { n="Debian" v=$(__derive_debian_numeric_version "$v") ;; - sles ) + sles ) n="SUSE" v="${rv}" ;; + opensuse-leap ) + n="opensuse" + v="${rv}" + ;; * ) n=${nn} ;; @@ -1102,9 +1121,7 @@ __install_python() { exit 1 fi - PY_PKG_V=$(echo "$_PY_EXE" | sed -r "s/\.//g") - __PACKAGES="${PY_PKG_V}" - + __PACKAGES="$_PY_PKG_VER" if [ ${_DISABLE_REPOS} -eq ${BS_FALSE} ]; then echoinfo "Attempting to install a repo to help provide a separate python package" @@ -1145,25 +1162,24 @@ __gather_sunos_system_info() { case "$line" in *OpenIndiana*oi_[0-9]*) DISTRO_NAME="OpenIndiana" - DISTRO_VERSION=$(echo "$line" | sed -nr "s/OpenIndiana(.*)oi_([[:digit:]]+)(.*)/\2/p") + DISTRO_VERSION=$(echo "$line" | sed -nr "s/OpenIndiana(.*)oi_([[:digit:]]+)(.*)/\\2/p") break ;; *OpenSolaris*snv_[0-9]*) DISTRO_NAME="OpenSolaris" - DISTRO_VERSION=$(echo "$line" | sed -nr "s/OpenSolaris(.*)snv_([[:digit:]]+)(.*)/\2/p") + DISTRO_VERSION=$(echo "$line" | sed -nr "s/OpenSolaris(.*)snv_([[:digit:]]+)(.*)/\\2/p") break ;; *Oracle*Solaris*[0-9]*) DISTRO_NAME="Oracle Solaris" - DISTRO_VERSION=$(echo "$line" | sed -nr "s/(Oracle Solaris) ([[:digit:]]+)(.*)/\2/p") + DISTRO_VERSION=$(echo "$line" | sed -nr "s/(Oracle Solaris) ([[:digit:]]+)(.*)/\\2/p") break ;; *Solaris*) DISTRO_NAME="Solaris" # Let's make sure we not actually on a Joyent's SmartOS VM since some releases # don't have SmartOS in `/etc/release`, only `Solaris` - uname -v | grep joyent >/dev/null 2>&1 - if [ $? -eq 0 ]; then + if uname -v | grep joyent >/dev/null 2>&1; then DISTRO_NAME="SmartOS" fi break @@ -1258,7 +1274,7 @@ __ubuntu_derivatives_translation() { neon_16_ubuntu_base="16.04" # Translate Ubuntu derivatives to their base Ubuntu version - match=$(echo "$DISTRO_NAME_L" | egrep ${UBUNTU_DERIVATIVES}) + match=$(echo "$DISTRO_NAME_L" | grep -E ${UBUNTU_DERIVATIVES}) if [ "${match}" != "" ]; then case $match in @@ -1299,6 +1315,7 @@ __check_dpkg_architecture() { fi __REPO_ARCH="$DPKG_ARCHITECTURE" + __REPO_ARCH_DEB='deb' __return_code=0 case $DPKG_ARCHITECTURE in @@ -1310,6 +1327,18 @@ __check_dpkg_architecture() { "amd64") error_msg="" ;; + "arm64") + if [ "$_CUSTOM_REPO_URL" != "null" ]; then + warn_msg="Support for arm64 is experimental, make sure the custom repository used has the expected structure and contents." + else + # Saltstack official repository does not yet have arm64 metadata, + # use amd64 repositories on arm64, since all pkgs are arch-independent + __REPO_ARCH="amd64" + __REPO_ARCH_DEB="deb [arch=$__REPO_ARCH]" + warn_msg="Support for arm64 packages is experimental and might rely on architecture-independent packages from the amd64 repository." + fi + error_msg="" + ;; "armhf") if [ "$DISTRO_NAME_L" = "ubuntu" ] || [ "$DISTRO_MAJOR_VERSION" -lt 8 ]; then error_msg="Support for armhf packages at $_REPO_URL is limited to Debian/Raspbian 8 platforms." @@ -1324,6 +1353,11 @@ __check_dpkg_architecture() { ;; esac + if [ "${warn_msg:-}" != "" ]; then + # AArch64: Do not fail at this point, but warn the user about experimental support + # See https://github.com/saltstack/salt-bootstrap/issues/1240 + echowarn "${warn_msg}" + fi if [ "${error_msg}" != "" ]; then echoerror "${error_msg}" if [ "$ITYPE" != "git" ]; then @@ -1370,8 +1404,8 @@ __ubuntu_codename_translation() { "16") DISTRO_CODENAME="xenial" ;; - "17") - DISTRO_CODENAME="artful" + "18") + DISTRO_CODENAME="bionic" ;; *) DISTRO_CODENAME="trusty" @@ -1403,7 +1437,7 @@ __debian_derivatives_translation() { raspbian_9_debian_base="9.0" # Translate Debian derivatives to their base Debian version - match=$(echo "$DISTRO_NAME_L" | egrep ${DEBIAN_DERIVATIVES}) + match=$(echo "$DISTRO_NAME_L" | grep -E ${DEBIAN_DERIVATIVES}) if [ "${match}" != "" ]; then case $match in @@ -1491,11 +1525,11 @@ __check_end_of_life_versions() { # = 14.10 # = 15.04, 15.10 # = 16.10 - # = 17.04 + # = 17.04, 17.10 if [ "$DISTRO_MAJOR_VERSION" -lt 14 ] || \ [ "$DISTRO_MAJOR_VERSION" -eq 15 ] || \ - ([ "$DISTRO_MAJOR_VERSION" -eq 17 ] && [ "$DISTRO_MINOR_VERSION" -eq 04 ]) || \ - ([ "$DISTRO_MAJOR_VERSION" -lt 17 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]); then + [ "$DISTRO_MAJOR_VERSION" -eq 17 ] || \ + { [ "$DISTRO_MAJOR_VERSION" -eq 16 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; }; then echoerror "End of life distributions are not supported." echoerror "Please consider upgrading to the next stable. See:" echoerror " https://wiki.ubuntu.com/Releases" @@ -1507,9 +1541,9 @@ __check_end_of_life_versions() { # openSUSE versions not supported # # <= 13.X - # <= 42.1 - if [ "$DISTRO_MAJOR_VERSION" -le 13 ] || \ - ([ "$DISTRO_MAJOR_VERSION" -eq 42 ] && [ "$DISTRO_MINOR_VERSION" -le 1 ]); then + # <= 42.2 + if [ "$DISTRO_MAJOR_VERSION" -lt 15 ] || \ + { [ "$DISTRO_MAJOR_VERSION" -eq 42 ] && [ "$DISTRO_MINOR_VERSION" -le 2 ]; }; then echoerror "End of life distributions are not supported." echoerror "Please consider upgrading to the next stable. See:" echoerror " http://en.opensuse.org/Lifetime" @@ -1527,8 +1561,8 @@ __check_end_of_life_versions() { SUSE_PATCHLEVEL="00" fi if [ "$DISTRO_MAJOR_VERSION" -lt 11 ] || \ - ([ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$SUSE_PATCHLEVEL" -lt 04 ]) || \ - ([ "$DISTRO_MAJOR_VERSION" -eq 12 ] && [ "$SUSE_PATCHLEVEL" -lt 02 ]); then + { [ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$SUSE_PATCHLEVEL" -lt 04 ]; } || \ + { [ "$DISTRO_MAJOR_VERSION" -eq 12 ] && [ "$SUSE_PATCHLEVEL" -lt 02 ]; }; then echoerror "Versions lower than SuSE 11 SP4 or 12 SP2 are not supported." echoerror "Please consider upgrading to the next stable" echoerror " https://www.suse.com/lifecycle/" @@ -1537,8 +1571,8 @@ __check_end_of_life_versions() { ;; fedora) - # Fedora lower than 26 are no longer supported - if [ "$DISTRO_MAJOR_VERSION" -lt 26 ]; then + # Fedora lower than 27 are no longer supported + if [ "$DISTRO_MAJOR_VERSION" -lt 27 ]; then echoerror "End of life distributions are not supported." echoerror "Please consider upgrading to the next stable. See:" echoerror " https://fedoraproject.org/wiki/Releases" @@ -1608,7 +1642,8 @@ __check_end_of_life_versions() { freebsd) # FreeBSD versions lower than 9.1 are not supported. - if ([ "$DISTRO_MAJOR_VERSION" -eq 9 ] && [ "$DISTRO_MINOR_VERSION" -lt 01 ]) || [ "$DISTRO_MAJOR_VERSION" -lt 9 ]; then + if { [ "$DISTRO_MAJOR_VERSION" -eq 9 ] && [ "$DISTRO_MINOR_VERSION" -lt 01 ]; } || \ + [ "$DISTRO_MAJOR_VERSION" -lt 9 ]; then echoerror "Versions lower than FreeBSD 9.1 are not supported." exit 1 fi @@ -1710,18 +1745,14 @@ elif [ "${DISTRO_NAME_L}" = "debian" ]; then __debian_codename_translation fi -# Only Ubuntu has daily packages, let's let users know about that -if ([ "${DISTRO_NAME_L}" != "ubuntu" ] && [ "$ITYPE" = "daily" ]); then - echoerror "${DISTRO_NAME} does not have daily packages support" - exit 1 -elif ([ "$(echo "${DISTRO_NAME_L}" | egrep '(debian|ubuntu|centos|red_hat|oracle|scientific|amazon)')" = "" ] && [ "$ITYPE" = "stable" ] && [ "$STABLE_REV" != "latest" ]); then +if [ "$(echo "${DISTRO_NAME_L}" | grep -E '(debian|ubuntu|centos|red_hat|oracle|scientific|amazon)')" = "" ] && [ "$ITYPE" = "stable" ] && [ "$STABLE_REV" != "latest" ]; then echoerror "${DISTRO_NAME} does not have major version pegged packages support" exit 1 fi # Only RedHat based distros have testing support if [ "${ITYPE}" = "testing" ]; then - if [ "$(echo "${DISTRO_NAME_L}" | egrep '(centos|red_hat|amazon|oracle)')" = "" ]; then + if [ "$(echo "${DISTRO_NAME_L}" | grep -E '(centos|red_hat|amazon|oracle)')" = "" ]; then echoerror "${DISTRO_NAME} does not have testing packages support" exit 1 fi @@ -1729,13 +1760,13 @@ if [ "${ITYPE}" = "testing" ]; then fi # Only Ubuntu has support for installing to virtualenvs -if ([ "${DISTRO_NAME_L}" != "ubuntu" ] && [ "$_VIRTUALENV_DIR" != "null" ]); then +if [ "${DISTRO_NAME_L}" != "ubuntu" ] && [ "$_VIRTUALENV_DIR" != "null" ]; then echoerror "${DISTRO_NAME} does not have -V support" exit 1 fi # Only Ubuntu has support for pip installing all packages -if ([ "${DISTRO_NAME_L}" != "ubuntu" ] && [ $_PIP_ALL -eq $BS_TRUE ]); then +if [ "${DISTRO_NAME_L}" != "ubuntu" ] && [ $_PIP_ALL -eq $BS_TRUE ]; then echoerror "${DISTRO_NAME} does not have -a support" exit 1 fi @@ -1930,8 +1961,7 @@ __git_clone_and_checkout() { # HEAD; instead it will simply reset to itself. Check the ref to see # if it is a branch name, check out the branch, and pull in the # changes. - git branch -a | grep -q "${GIT_REV}" - if [ $? -eq 0 ]; then + if git branch -a | grep -q "${GIT_REV}"; then echodebug "Rebasing the cloned repository branch" git pull --rebase || return 1 fi @@ -1954,8 +1984,7 @@ __git_clone_and_checkout() { if [ "$(git clone 2>&1 | grep 'single-branch')" != "" ]; then # The "--single-branch" option is supported, attempt shallow cloning echoinfo "Attempting to shallow clone $GIT_REV from Salt's repository ${_SALT_REPO_URL}" - git clone --depth 1 --branch "$GIT_REV" "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME" - if [ $? -eq 0 ]; then + if git clone --depth 1 --branch "$GIT_REV" "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME"; then # shellcheck disable=SC2164 cd "${_SALT_GIT_CHECKOUT_DIR}" __SHALLOW_CLONE=$BS_TRUE @@ -2190,7 +2219,7 @@ __overwriteconfig() { fi # Convert json string to a yaml string and write it to config file. Output is dumped into tempfile. - $good_python -c "import json; import yaml; jsn=json.loads('$json'); yml=yaml.safe_dump(jsn, line_break='\n', default_flow_style=False); config_file=open('$target', 'w'); config_file.write(yml); config_file.close();" 2>$tempfile + "$good_python" -c "import json; import yaml; jsn=json.loads('$json'); yml=yaml.safe_dump(jsn, line_break='\\n', default_flow_style=False); config_file=open('$target', 'w'); config_file.write(yml); config_file.close();" 2>$tempfile # No python errors output to the tempfile if [ ! -s "$tempfile" ]; then @@ -2252,9 +2281,7 @@ __check_services_upstart() { echodebug "Checking if service ${servicename} is enabled" # Check if service is enabled to start at boot - initctl list | grep "${servicename}" > /dev/null 2>&1 - - if [ $? -eq 0 ]; then + if initctl list | grep "${servicename}" > /dev/null 2>&1; then echodebug "Service ${servicename} is enabled" return 0 else @@ -2280,7 +2307,7 @@ __check_services_sysvinit() { servicename=$1 echodebug "Checking if service ${servicename} is enabled" - if [ "$(LC_ALL=C /sbin/chkconfig --list | grep "\<${servicename}\>" | grep '[2-5]:on')" != "" ]; then + if [ "$(LC_ALL=C /sbin/chkconfig --list | grep "\\<${servicename}\\>" | grep '[2-5]:on')" != "" ]; then echodebug "Service ${servicename} is enabled" return 0 else @@ -2360,7 +2387,7 @@ __check_services_alpine() { echodebug "Checking if service ${servicename} is enabled" # shellcheck disable=SC2086,SC2046,SC2144 - if rc-status $(rc-status -r) | tail -n +2 | grep -q "\<$servicename\>"; then + if rc-status $(rc-status -r) | tail -n +2 | grep -q "\\<$servicename\\>"; then echodebug "Service ${servicename} is enabled" return 0 else @@ -2394,7 +2421,7 @@ __create_virtualenv() { __activate_virtualenv() { set +o nounset # Is virtualenv empty - if [ -z "$VIRTUAL_ENV" ]; then + if [ -z "$_VIRTUALENV_DIR" ]; then __create_virtualenv || return 1 # shellcheck source=/dev/null . "${_VIRTUALENV_DIR}/bin/activate" || return 1 @@ -2414,7 +2441,7 @@ __activate_virtualenv() { __install_pip_pkgs() { _pip_pkgs="$1" _py_exe="$2" - _py_pkg=$(echo "$_py_exe" | sed -r "s/\.//g") + _py_pkg=$(echo "$_py_exe" | sed -r "s/\\.//g") _pip_cmd="${_py_exe} -m pip" if [ "${_py_exe}" = "" ]; then @@ -2568,13 +2595,14 @@ __enable_universe_repository() { __install_saltstack_ubuntu_repository() { # Workaround for latest non-LTS ubuntu - if [ "$DISTRO_MAJOR_VERSION" -gt 16 ]; then - echowarn "Non-LTS Ubuntu detected, but stable packages requested. Trying packages from latest LTS release. You may experience problems." - UBUNTU_VERSION=16.04 - UBUNTU_CODENAME="xenial" + if [ "$DISTRO_MAJOR_VERSION" -gt 18 ] || \ + { [ "$DISTRO_MAJOR_VERSION" -eq 18 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; }; then + echowarn "Non-LTS Ubuntu detected, but stable packages requested. Trying packages for latest LTS release. You may experience problems." + UBUNTU_VERSION=18.04 + UBUNTU_CODENAME="bionic" else - UBUNTU_VERSION=$DISTRO_VERSION - UBUNTU_CODENAME=$DISTRO_CODENAME + UBUNTU_VERSION=${DISTRO_VERSION} + UBUNTU_CODENAME=${DISTRO_CODENAME} fi __PACKAGES='' @@ -2594,14 +2622,19 @@ __install_saltstack_ubuntu_repository() { # shellcheck disable=SC2086,SC2090 __apt_get_install_noinput ${__PACKAGES} || return 1 + __PY_VERSION_REPO="apt" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + __PY_VERSION_REPO="py3" + fi + # SaltStack's stable Ubuntu repository: - SALTSTACK_UBUNTU_URL="${HTTP_VAL}://${_REPO_URL}/apt/ubuntu/${UBUNTU_VERSION}/${__REPO_ARCH}/${STABLE_REV}" - echo "deb $SALTSTACK_UBUNTU_URL $UBUNTU_CODENAME main" > /etc/apt/sources.list.d/saltstack.list + SALTSTACK_UBUNTU_URL="${HTTP_VAL}://${_REPO_URL}/${__PY_VERSION_REPO}/ubuntu/${UBUNTU_VERSION}/${__REPO_ARCH}/${STABLE_REV}" + echo "$__REPO_ARCH_DEB $SALTSTACK_UBUNTU_URL $UBUNTU_CODENAME main" > /etc/apt/sources.list.d/saltstack.list __apt_key_fetch "$SALTSTACK_UBUNTU_URL/SALTSTACK-GPG-KEY.pub" || return 1 __wait_for_apt - apt-get update + apt-get update || return 1 } install_ubuntu_deps() { @@ -2614,7 +2647,7 @@ install_ubuntu_deps() { __enable_universe_repository || return 1 __wait_for_apt - apt-get update + apt-get update || return 1 fi __PACKAGES='' @@ -2624,7 +2657,7 @@ install_ubuntu_deps() { __PACKAGES="upstart" fi - if [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then + if [ "$DISTRO_MAJOR_VERSION" -ge 16 ] && [ -z "$_PY_EXE" ]; then __PACKAGES="${__PACKAGES} python2.7" fi @@ -2671,12 +2704,12 @@ install_ubuntu_stable_deps() { export DEBIAN_FRONTEND=noninteractive __wait_for_apt - apt-get update + apt-get update || return 1 if [ "${_UPGRADE_SYS}" -eq $BS_TRUE ]; then if [ "${_INSECURE_DL}" -eq $BS_TRUE ]; then __apt_get_install_noinput --allow-unauthenticated debian-archive-keyring && - apt-key update && apt-get update + apt-key update && apt-get update || return 1 fi __apt_get_upgrade_noinput || return 1 @@ -2690,27 +2723,9 @@ install_ubuntu_stable_deps() { install_ubuntu_deps || return 1 } -install_ubuntu_daily_deps() { - __wait_for_apt - install_ubuntu_stable_deps || return 1 - - if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then - __enable_universe_repository || return 1 - - add-apt-repository -y ppa:saltstack/salt-daily || return 1 - apt-get update - fi - - if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then - __apt_get_upgrade_noinput || return 1 - fi - - return 0 -} - install_ubuntu_git_deps() { __wait_for_apt - apt-get update + apt-get update || return 1 if ! __check_command_exists git; then __apt_get_install_noinput git-core || return 1 @@ -2740,12 +2755,25 @@ install_ubuntu_git_deps() { else install_ubuntu_stable_deps || return 1 - __PACKAGES="${__PACKAGES} python-crypto python-jinja2 python-m2crypto python-msgpack" - __PACKAGES="${__PACKAGES} python-requests python-tornado python-yaml python-zmq" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + PY_PKG_VER=3 + + __PACKAGES="${__PACKAGES} python3-setuptools" + else + PY_PKG_VER="" + + # There is no m2crypto package for Py3 at this time - only install for Py2 + __PACKAGES="${__PACKAGES} python-m2crypto" + fi + + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-crypto python${PY_PKG_VER}-jinja2" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-msgpack python${PY_PKG_VER}-requests" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-tornado python${PY_PKG_VER}-yaml" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-zmq" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then # Install python-libcloud if asked to - __PACKAGES="${__PACKAGES} python-libcloud" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-libcloud" fi # shellcheck disable=SC2086 @@ -2783,22 +2811,22 @@ install_ubuntu_stable() { return 0 } -install_ubuntu_daily() { - install_ubuntu_stable || return 1 - - return 0 -} - install_ubuntu_git() { # Activate virtualenv before install if [ "${_VIRTUALENV_DIR}" != "null" ]; then __activate_virtualenv || return 1 fi - if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then - python setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 + if [ -n "$_PY_EXE" ]; then + _PYEXE=${_PY_EXE} else - python setup.py ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 + _PYEXE=python2.7 + fi + + if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then + ${_PYEXE} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 + else + ${_PYEXE} setup.py ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 fi return 0 @@ -2904,8 +2932,7 @@ install_ubuntu_restart_daemons() { if [ -f /bin/systemctl ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then echodebug "There's systemd support while checking salt-$fname" systemctl stop salt-$fname > /dev/null 2>&1 - systemctl start salt-$fname.service - [ $? -eq 0 ] && continue + systemctl start salt-$fname.service && continue # We failed to start the service, let's test the SysV code below echodebug "Failed to start salt-$fname using systemd" fi @@ -2913,13 +2940,11 @@ install_ubuntu_restart_daemons() { if [ -f /sbin/initctl ]; then echodebug "There's upstart support while checking salt-$fname" - status salt-$fname 2>/dev/null | grep -q running - if [ $? -eq 0 ]; then + if status salt-$fname 2>/dev/null | grep -q running; then stop salt-$fname || (echodebug "Failed to stop salt-$fname" && return 1) fi - start salt-$fname - [ $? -eq 0 ] && continue + start salt-$fname && continue # We failed to start the service, let's test the SysV code below echodebug "Failed to start salt-$fname using Upstart" fi @@ -2979,6 +3004,11 @@ __install_saltstack_debian_repository() { DEBIAN_CODENAME="$DISTRO_CODENAME" fi + __PY_VERSION_REPO="apt" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + __PY_VERSION_REPO="py3" + fi + __PACKAGES='' # Install downloader backend for GPG keys fetching @@ -2997,13 +3027,13 @@ __install_saltstack_debian_repository() { __apt_get_install_noinput ${__PACKAGES} || return 1 # amd64 is just a part of repository URI, 32-bit pkgs are hosted under the same location - SALTSTACK_DEBIAN_URL="${HTTP_VAL}://${_REPO_URL}/apt/debian/${DEBIAN_RELEASE}/${__REPO_ARCH}/${STABLE_REV}" - echo "deb $SALTSTACK_DEBIAN_URL $DEBIAN_CODENAME main" > "/etc/apt/sources.list.d/saltstack.list" + SALTSTACK_DEBIAN_URL="${HTTP_VAL}://${_REPO_URL}/${__PY_VERSION_REPO}/debian/${DEBIAN_RELEASE}/${__REPO_ARCH}/${STABLE_REV}" + echo "$__REPO_ARCH_DEB $SALTSTACK_DEBIAN_URL $DEBIAN_CODENAME main" > "/etc/apt/sources.list.d/saltstack.list" __apt_key_fetch "$SALTSTACK_DEBIAN_URL/SALTSTACK-GPG-KEY.pub" || return 1 __wait_for_apt - apt-get update + apt-get update || return 1 } install_debian_deps() { @@ -3015,23 +3045,29 @@ install_debian_deps() { export DEBIAN_FRONTEND=noninteractive __wait_for_apt - apt-get update + apt-get update || return 1 if [ "${_UPGRADE_SYS}" -eq $BS_TRUE ]; then # Try to update GPG keys first if allowed if [ "${_INSECURE_DL}" -eq $BS_TRUE ]; then __apt_get_install_noinput --allow-unauthenticated debian-archive-keyring && - apt-key update && apt-get update + apt-key update && apt-get update || return 1 fi __apt_get_upgrade_noinput || return 1 fi + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + PY_PKG_VER=3 + else + PY_PKG_VER="" + fi + # Additionally install procps and pciutils which allows for Docker bootstraps. See 366#issuecomment-39666813 __PACKAGES='procps pciutils' # YAML module is used for generating custom master/minion configs - __PACKAGES="${__PACKAGES} python-yaml" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-yaml" # shellcheck disable=SC2086 __apt_get_install_noinput ${__PACKAGES} || return 1 @@ -3167,13 +3203,24 @@ install_debian_9_git_deps() { __git_clone_and_checkout || return 1 - __PACKAGES="libzmq5 lsb-release python-apt python-backports-abc python-crypto" - __PACKAGES="${__PACKAGES} python-jinja2 python-m2crypto python-msgpack python-requests" - __PACKAGES="${__PACKAGES} python-systemd python-tornado python-yaml python-zmq" + __PACKAGES="libzmq5 lsb-release" + + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + PY_PKG_VER=3 + else + PY_PKG_VER="" + + # These packages are PY2-ONLY + __PACKAGES="${__PACKAGES} python-backports-abc python-m2crypto" + fi + + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-apt python${PY_PKG_VER}-crypto python${PY_PKG_VER}-jinja2" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-msgpack python${PY_PKG_VER}-requests python${PY_PKG_VER}-systemd" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-tornado python${PY_PKG_VER}-yaml python${PY_PKG_VER}-zmq" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then # Install python-libcloud if asked to - __PACKAGES="${__PACKAGES} python-libcloud" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-libcloud" fi # shellcheck disable=SC2086 @@ -3231,10 +3278,16 @@ install_debian_9_stable() { } install_debian_git() { - if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then - python setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 + if [ -n "$_PY_EXE" ]; then + _PYEXE=${_PY_EXE} else - python setup.py ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 + _PYEXE=python + fi + + if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then + ${_PYEXE} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 + else + ${_PYEXE} setup.py ${SETUP_PY_INSTALL_ARGS} install --install-layout=deb || return 1 fi } @@ -3265,7 +3318,7 @@ install_debian_git_post() { # Configure SystemD for Debian 8 "Jessie" and later if [ -f /bin/systemctl ]; then if [ ! -f /lib/systemd/system/salt-${fname}.service ] || \ - ([ -f /lib/systemd/system/salt-${fname}.service ] && [ $_FORCE_OVERWRITE -eq $BS_TRUE ]); then + { [ -f /lib/systemd/system/salt-${fname}.service ] && [ $_FORCE_OVERWRITE -eq $BS_TRUE ]; }; then if [ -f "${_SALT_GIT_CHECKOUT_DIR}/pkg/salt-${fname}.service" ]; then __copyfile "${_SALT_GIT_CHECKOUT_DIR}/pkg/salt-${fname}.service" /lib/systemd/system __copyfile "${_SALT_GIT_CHECKOUT_DIR}/pkg/salt-${fname}.environment" "/etc/default/salt-${fname}" @@ -3284,7 +3337,7 @@ install_debian_git_post() { # Install initscripts for Debian 7 "Wheezy" elif [ ! -f "/etc/init.d/salt-$fname" ] || \ - ([ -f "/etc/init.d/salt-$fname" ] && [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]); then + { [ -f "/etc/init.d/salt-$fname" ] && [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; }; then if [ -f "${_SALT_GIT_CHECKOUT_DIR}/pkg/salt-$fname.init" ]; then __copyfile "${_SALT_GIT_CHECKOUT_DIR}/pkg/salt-${fname}.init" "/etc/init.d/salt-${fname}" __copyfile "${_SALT_GIT_CHECKOUT_DIR}/pkg/salt-${fname}.environment" "/etc/default/salt-${fname}" @@ -3362,16 +3415,23 @@ install_debian_check_services() { # install_fedora_deps() { - - __PACKAGES="libyaml m2crypto PyYAML python-crypto python-jinja2" - __PACKAGES="${__PACKAGES} python2-msgpack python2-requests python-zmq" - - if [ "$DISTRO_MAJOR_VERSION" -lt 26 ]; then - __PACKAGES="${__PACKAGES} yum-utils" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + # Packages are named python3- + PY_PKG_VER=3 + __PACKAGES="python3-m2crypto python3-PyYAML" else - __PACKAGES="${__PACKAGES} dnf-utils" + PY_PKG_VER=2 + __PACKAGES="m2crypto" + if [ "$DISTRO_MAJOR_VERSION" -ge 28 ]; then + __PACKAGES="${__PACKAGES} python2-pyyaml" + else + __PACKAGES="${__PACKAGES} PyYAML" + fi fi + __PACKAGES="${__PACKAGES} dnf-utils libyaml python${PY_PKG_VER}-crypto python${PY_PKG_VER}-jinja2" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-msgpack python${PY_PKG_VER}-requests python${PY_PKG_VER}-zmq" + # shellcheck disable=SC2086 dnf install -y ${__PACKAGES} || return 1 @@ -3427,6 +3487,12 @@ install_fedora_stable_post() { } install_fedora_git_deps() { + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + # Packages are named python3- + PY_PKG_VER=3 + else + PY_PKG_VER=2 + fi if [ "$_INSECURE_DL" -eq $BS_FALSE ] && [ "${_SALT_REPO_URL%%://*}" = "https" ]; then dnf install -y ca-certificates || return 1 @@ -3440,10 +3506,19 @@ install_fedora_git_deps() { __git_clone_and_checkout || return 1 - __PACKAGES="python2-tornado systemd-python" + __PACKAGES="python${PY_PKG_VER}-systemd" + if [ "${PY_PKG_VER}" -eq 3 ] && [ "$DISTRO_MAJOR_VERSION" -ge 28 ]; then + __check_pip_allowed "You need to allow pip based installations (-P) for Tornado <5.0 in order to install Salt on Python 3" + grep tornado "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt" | while IFS=' +' read -r dep; do + "${_PY_EXE}" -m pip install "${dep}" || return 1 + done + else + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-tornado" + fi if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} python-libcloud python-netaddr" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-libcloud python${PY_PKG_VER}-netaddr" fi # shellcheck disable=SC2086 @@ -3459,10 +3534,17 @@ install_fedora_git_deps() { } install_fedora_git() { - if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then - python setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install || return 1 + if [ "${_PY_EXE}" != "" ]; then + _PYEXE=${_PY_EXE} + echoinfo "Using the following python version: ${_PY_EXE} to install salt" else - python setup.py ${SETUP_PY_INSTALL_ARGS} install || return 1 + _PYEXE='python2' + fi + + if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then + ${_PYEXE} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --prefix=/usr || return 1 + else + ${_PYEXE} setup.py ${SETUP_PY_INSTALL_ARGS} install --prefix=/usr || return 1 fi return 0 } @@ -3534,8 +3616,7 @@ __install_epel_repository() { fi # Check if epel repo is already enabled and flag it accordingly - yum repolist | grep -q "^[!]\?${_EPEL_REPO}/" - if [ $? -eq 0 ]; then + if yum repolist | grep -q "^[!]\\?${_EPEL_REPO}/"; then _EPEL_REPOS_INSTALLED=$BS_TRUE return 0 fi @@ -3556,9 +3637,14 @@ __install_saltstack_rhel_repository() { repo_rev="latest" fi + __PY_VERSION_REPO="yum" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + __PY_VERSION_REPO="py3" + fi + # Avoid using '$releasever' variable for yum. # Instead, this should work correctly on all RHEL variants. - base_url="${HTTP_VAL}://${_REPO_URL}/yum/redhat/${DISTRO_MAJOR_VERSION}/\$basearch/${repo_rev}/" + base_url="${HTTP_VAL}://${_REPO_URL}/${__PY_VERSION_REPO}/redhat/${DISTRO_MAJOR_VERSION}/\$basearch/${repo_rev}/" gpg_key="SALTSTACK-GPG-KEY.pub" repo_file="/etc/yum.repos.d/saltstack.repo" @@ -3574,7 +3660,7 @@ enabled=1 enabled_metadata=1 _eof - fetch_url="${HTTP_VAL}://${_REPO_URL}/yum/redhat/${DISTRO_MAJOR_VERSION}/${CPU_ARCH_L}/${repo_rev}/" + fetch_url="${HTTP_VAL}://${_REPO_URL}/${__PY_VERSION_REPO}/redhat/${DISTRO_MAJOR_VERSION}/${CPU_ARCH_L}/${repo_rev}/" __rpm_import_gpg "${fetch_url}${gpg_key}" || return 1 yum clean metadata || return 1 elif [ "$repo_rev" != "latest" ]; then @@ -3590,7 +3676,14 @@ install_centos_stable_deps() { yum -y update || return 1 fi - if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then + if [ "$_DISABLE_REPOS" -eq "$BS_TRUE" ] && [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + echoerror "Detected -r or -R option while installing Salt packages for Python 3." + echoerror "Python 3 packages for Salt require the EPEL repository to be installed." + echoerror "The -r and -R options are incompatible with -x and Python 3 bootstrap installs." + return 1 + fi + + if [ "$_DISABLE_REPOS" -eq "$BS_FALSE" ]; then __install_epel_repository || return 1 __install_saltstack_rhel_repository || return 1 fi @@ -3602,8 +3695,14 @@ install_centos_stable_deps() { __install_saltstack_rhel_repository || return 1 fi + __PACKAGES="yum-utils chkconfig" + # YAML module is used for generating custom master/minion configs - __PACKAGES="yum-utils chkconfig PyYAML" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + __PACKAGES="${__PACKAGES} python34-PyYAML" + else + __PACKAGES="${__PACKAGES} PyYAML" + fi # shellcheck disable=SC2086 __yum_install_noinput ${__PACKAGES} || return 1 @@ -3684,15 +3783,29 @@ install_centos_git_deps() { __git_clone_and_checkout || return 1 - __PACKAGES="m2crypto python-crypto python-futures python-jinja2 python-msgpack" - __PACKAGES="${__PACKAGES} python-requests python-tornado python-zmq" + __PACKAGES="m2crypto" - if [ "$DISTRO_MAJOR_VERSION" -ge 7 ]; then - __PACKAGES="${__PACKAGES} systemd-python" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 3 ]; then + # Packages are named python34- + PY_PKG_VER=34 + else + PY_PKG_VER="" + + # Only Py2 needs python-futures + __PACKAGES="${__PACKAGES} python-futures" + + # There is no systemd-python3 package as of this writing + if [ "$DISTRO_MAJOR_VERSION" -ge 7 ]; then + __PACKAGES="${__PACKAGES} systemd-python" + fi fi + __PACKAGES="python${PY_PKG_VER}-crypto python${PY_PKG_VER}-jinja2" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-msgpack python${PY_PKG_VER}-requests" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-tornado python${PY_PKG_VER}-zmq" + if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} python-libcloud" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-libcloud" fi if [ "${_INSTALL_PY}" -eq "${BS_TRUE}" ]; then @@ -3700,7 +3813,7 @@ install_centos_git_deps() { __install_python || return 1 fi - if [ "${_PY_EXE}" != "" ]; then + if [ "${_PY_EXE}" != "" ] && [ "$_PIP_ALLOWED" -eq "$BS_TRUE" ]; then # If "-x" is defined, install dependencies with pip based on the Python version given. _PIP_PACKAGES="m2crypto jinja2 msgpack-python pycrypto PyYAML tornado<5.0 zmq" @@ -3710,8 +3823,10 @@ install_centos_git_deps() { fi if [ -f "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt" ]; then - for SINGLE_PACKAGE in $_PIP_PACKAGES; do - __REQUIRED_VERSION="$(grep "${SINGLE_PACKAGE}" "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt")" + # Filter out any commented lines from the requirements file + _REQ_LINES="$(grep '^[^#]' "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt")" + for SINGLE_PACKAGE in ${_PIP_PACKAGES}; do + __REQUIRED_VERSION="$(grep "${SINGLE_PACKAGE}" "${_REQ_LINES}")" if [ "${__REQUIRED_VERSION}" != "" ]; then _PIP_PACKAGES=$(echo "$_PIP_PACKAGES" | sed "s/${SINGLE_PACKAGE}/${__REQUIRED_VERSION}/") fi @@ -3767,13 +3882,13 @@ install_centos_git_post() { if [ -f /bin/systemctl ]; then if [ ! -f "/usr/lib/systemd/system/salt-${fname}.service" ] || \ - ([ -f "/usr/lib/systemd/system/salt-${fname}.service" ] && [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]); then + { [ -f "/usr/lib/systemd/system/salt-${fname}.service" ] && [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; }; then __copyfile "${_SALT_GIT_CHECKOUT_DIR}/pkg/rpm/salt-${fname}.service" /usr/lib/systemd/system fi SYSTEMD_RELOAD=$BS_TRUE elif [ ! -f "/etc/init.d/salt-$fname" ] || \ - ([ -f "/etc/init.d/salt-$fname" ] && [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]); then + { [ -f "/etc/init.d/salt-$fname" ] && [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; }; then __copyfile "${_SALT_GIT_CHECKOUT_DIR}/pkg/rpm/salt-${fname}" /etc/init.d chmod +x /etc/init.d/salt-${fname} fi @@ -3802,8 +3917,7 @@ install_centos_restart_daemons() { if [ -f /sbin/initctl ] && [ -f /etc/init/salt-${fname}.conf ]; then # We have upstart support and upstart knows about our service - /sbin/initctl status salt-$fname > /dev/null 2>&1 - if [ $? -ne 0 ]; then + if ! /sbin/initctl status salt-$fname > /dev/null 2>&1; then # Everything is in place and upstart gave us an error code? Fail! return 1 fi @@ -3811,9 +3925,8 @@ install_centos_restart_daemons() { # upstart knows about this service. # Let's try to stop it, and then start it /sbin/initctl stop salt-$fname > /dev/null 2>&1 - /sbin/initctl start salt-$fname > /dev/null 2>&1 # Restart service - if [ $? -ne 0 ]; then + if ! /sbin/initctl start salt-$fname > /dev/null 2>&1; then # Failed the restart?! return 1 fi @@ -4344,6 +4457,7 @@ install_alpine_linux_post() { script_url="${_SALTSTACK_REPO_URL%.git}/raw/develop/pkg/alpine/salt-$fname" [ -f "/etc/init.d/salt-$fname" ] || __fetch_url "/etc/init.d/salt-$fname" "$script_url" + # shellcheck disable=SC2181 if [ $? -eq 0 ]; then chmod +x "/etc/init.d/salt-$fname" else @@ -4438,13 +4552,13 @@ install_amazon_linux_ami_deps() { repo_rev="latest" fi - if echo $repo_rev | egrep -q '^archive'; then + if echo $repo_rev | grep -E -q '^archive'; then year=$(echo "$repo_rev" | cut -d '/' -f 2 | cut -c1-4) else year=$(echo "$repo_rev" | cut -c1-4) fi - if echo "$repo_rev" | egrep -q '^(latest|2016\.11)$' || \ + if echo "$repo_rev" | grep -E -q '^(latest|2016\.11)$' || \ [ "$year" -gt 2016 ]; then _USEAWS=$BS_TRUE pkg_append="python27" @@ -4646,7 +4760,7 @@ install_arch_linux_git_deps() { fi pacman -R --noconfirm python2-distribute pacman -Su --noconfirm --needed python2-crypto python2-setuptools python2-jinja \ - python2-m2crypto python2-markupsafe python2-msgpack python2-psutil \ + python2-m2crypto python2-futures python2-markupsafe python2-msgpack python2-psutil \ python2-pyzmq zeromq python2-requests python2-systemd || return 1 __git_clone_and_checkout || return 1 @@ -4968,7 +5082,7 @@ install_freebsd_git_deps() { if [ ! -f salt/syspaths.py ]; then # We still can't provide the system paths, salt 0.16.x # Let's patch salt's source and adapt paths to what's expected on FreeBSD - echodebug "Replacing occurrences of '/etc/salt' with \'${_SALT_ETC_DIR}\'" + echodebug "Replacing occurrences of '/etc/salt' with ${_SALT_ETC_DIR}" # The list of files was taken from Salt's BSD port Makefile for file in conf/minion conf/master salt/config.py salt/client.py \ salt/modules/mysql.py salt/utils/parsers.py salt/modules/tls.py \ @@ -5017,7 +5131,7 @@ install_freebsd_11_stable() { install_freebsd_git() { # /usr/local/bin/python2 in FreeBSD is a symlink to /usr/local/bin/python2.7 - __PYTHON_PATH=$(readlink -f "$(which python2)") + __PYTHON_PATH=$(readlink -f "$(command -v python2)") __ESCAPED_PYTHON_PATH=$(echo "${__PYTHON_PATH}" | sed 's/\//\\\//g') # Install from git @@ -5408,9 +5522,9 @@ __set_suse_pkg_repo() { # Set distro repo variable if [ "${DISTRO_MAJOR_VERSION}" -gt 2015 ]; then DISTRO_REPO="openSUSE_Tumbleweed" - elif [ "${DISTRO_MAJOR_VERSION}" -ge 42 ]; then + elif [ "${DISTRO_MAJOR_VERSION}" -ge 42 ] || [ "${DISTRO_MAJOR_VERSION}" -eq 15 ]; then DISTRO_REPO="openSUSE_Leap_${DISTRO_MAJOR_VERSION}.${DISTRO_MINOR_VERSION}" - elif [ "${DISTRO_MAJOR_VERSION}" -lt 42 ]; then + else DISTRO_REPO="SLE_${DISTRO_MAJOR_VERSION}_SP${SUSE_PATCHLEVEL}" fi @@ -5472,7 +5586,8 @@ __zypper_install() { fi } -install_opensuse_stable_deps() { +__opensuse_prep_install() { + # DRY function for common installation preparatory steps for SUSE if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then # Is the repository already known __set_suse_pkg_repo @@ -5481,21 +5596,27 @@ install_opensuse_stable_deps() { fi __zypper --gpg-auto-import-keys refresh + + # shellcheck disable=SC2181 if [ $? -ne 0 ] && [ $? -ne 4 ]; then # If the exit code is not 0, and it's not 4 (failed to update a # repository) return a failure. Otherwise continue. return 1 fi + if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then + __zypper --gpg-auto-import-keys update || return 1 + fi +} + +install_opensuse_stable_deps() { + __opensuse_prep_install || return 1 + if [ "$DISTRO_MAJOR_VERSION" -eq 12 ] && [ "$DISTRO_MINOR_VERSION" -eq 3 ]; then # Because patterns-openSUSE-minimal_base-conflicts conflicts with python, lets remove the first one __zypper remove patterns-openSUSE-minimal_base-conflicts fi - if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then - __zypper --gpg-auto-import-keys update || return 1 - fi - # YAML module is used for generating custom master/minion configs # requests is still used by many salt modules # Salt needs python-zypp installed in order to use the zypper module @@ -5617,7 +5738,7 @@ install_opensuse_git_post() { if [ -f /bin/systemctl ]; then use_usr_lib=$BS_FALSE - if [ "${DISTRO_MAJOR_VERSION}" -gt 13 ] || ([ "${DISTRO_MAJOR_VERSION}" -eq 13 ] && [ "${DISTRO_MINOR_VERSION}" -ge 2 ]); then + if [ "${DISTRO_MAJOR_VERSION}" -ge 15 ]; then use_usr_lib=$BS_TRUE fi @@ -5691,24 +5812,112 @@ install_opensuse_check_services() { # ####################################################################################################################### +####################################################################################################################### +# +# openSUSE Leap 15 +# + +install_opensuse_15_stable_deps() { + __opensuse_prep_install || return 1 + + # SUSE only packages Salt for Python 3 on Leap 15 + # Py3 is the default bootstrap install for Leap 15 + # However, git installs might specify "-x python2" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 2 ]; then + PY_PKG_VER=2 + else + PY_PKG_VER=3 + fi + + # YAML module is used for generating custom master/minion configs + # requests is still used by many salt modules + __PACKAGES="python${PY_PKG_VER}-PyYAML python${PY_PKG_VER}-requests" + + # shellcheck disable=SC2086 + __zypper_install ${__PACKAGES} || return 1 + + if [ "${_EXTRA_PACKAGES}" != "" ]; then + echoinfo "Installing the following extra packages as requested: ${_EXTRA_PACKAGES}" + # shellcheck disable=SC2086 + __zypper_install ${_EXTRA_PACKAGES} || return 1 + fi + + return 0 +} + +install_opensuse_15_git_deps() { + install_opensuse_15_stable_deps || return 1 + + if ! __check_command_exists git; then + __zypper_install git || return 1 + fi + + __git_clone_and_checkout || return 1 + + # Py3 is the default bootstrap install for Leap 15 + # However, git installs might specify "-x python2" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 2 ]; then + PY_PKG_VER=2 + + # This is required by some of the python2 packages below + __PACKAGES="libpython2_7-1_0" + else + PY_PKG_VER=3 + __PACKAGES="" + fi + + __PACKAGES="${__PACKAGES} libzmq5 python${PY_PKG_VER}-Jinja2 python${PY_PKG_VER}-msgpack" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-pycrypto python${PY_PKG_VER}-pyzmq" + + if [ -f "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt" ]; then + # We're on the develop branch, install whichever tornado is on the requirements file + __REQUIRED_TORNADO="$(grep tornado "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt")" + if [ "${__REQUIRED_TORNADO}" != "" ]; then + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-tornado" + fi + fi + + if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-apache-libcloud" + fi + + # shellcheck disable=SC2086 + __zypper_install ${__PACKAGES} || return 1 + + # Let's trigger config_salt() + if [ "$_TEMP_CONFIG_DIR" = "null" ]; then + _TEMP_CONFIG_DIR="${_SALT_GIT_CHECKOUT_DIR}/conf/" + CONFIG_SALT_FUNC="config_salt" + fi + + return 0 +} + +install_opensuse_15_git() { + + # Py3 is the default bootstrap install for Leap 15 + if [ -n "$_PY_EXE" ]; then + _PYEXE=${_PY_EXE} + else + _PYEXE=python3 + fi + + ${_PYEXE} setup.py ${SETUP_PY_INSTALL_ARGS} install --prefix=/usr || return 1 + return 0 +} + +# +# End of openSUSE Leap 15 +# +####################################################################################################################### + ####################################################################################################################### # # SUSE Enterprise 12 # install_suse_12_stable_deps() { - if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then - # Is the repository already known - __set_suse_pkg_repo - # Check zypper repos and refresh if necessary - __check_and_refresh_suse_pkg_repo - fi - - __zypper --gpg-auto-import-keys refresh || return 1 - - if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then - __zypper --gpg-auto-import-keys update || return 1 - fi + __opensuse_prep_install || return 1 # YAML module is used for generating custom master/minion configs # requests is still used by many salt modules @@ -5727,7 +5936,6 @@ install_suse_12_stable_deps() { # Let's try to install the higher version first and then the lower one in case of failure __zypper_install 'python-M2Crypto>=0.22' || __zypper_install 'python-M2Crypto>=0.21' || return 1 - if [ "${_EXTRA_PACKAGES}" != "" ]; then echoinfo "Installing the following extra packages as requested: ${_EXTRA_PACKAGES}" # shellcheck disable=SC2086 @@ -5741,14 +5949,14 @@ install_suse_12_git_deps() { install_suse_12_stable_deps || return 1 if ! __check_command_exists git; then - __zypper_install git || return 1 + __zypper_install git-core || return 1 fi __git_clone_and_checkout || return 1 __PACKAGES="" # shellcheck disable=SC2089 - __PACKAGES="${__PACKAGES} libzmq3 python-Jinja2 python-msgpack-python python-pycrypto" + __PACKAGES="${__PACKAGES} libzmq4 python-Jinja2 python-msgpack-python python-pycrypto" __PACKAGES="${__PACKAGES} python-pyzmq python-xml" if [ -f "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt" ]; then @@ -5811,18 +6019,7 @@ install_suse_12_restart_daemons() { # install_suse_11_stable_deps() { - if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then - # Is the repository already known - __set_suse_pkg_repo - # Check zypper repos and refresh if necessary - __check_and_refresh_suse_pkg_repo - fi - - __zypper --gpg-auto-import-keys refresh || return 1 - - if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then - __zypper --gpg-auto-import-keys update || return 1 - fi + __opensuse_prep_install || return 1 # YAML module is used for generating custom master/minion configs __PACKAGES="python-PyYAML" @@ -6356,7 +6553,7 @@ preseed_master() { SEED_DEST="$_PKI_DIR/master/minions" [ -d "$SEED_DEST" ] || (mkdir -p "$SEED_DEST" && chmod 700 "$SEED_DEST") || return 1 - for keyfile in $_TEMP_KEYS_DIR/*; do + for keyfile in "$_TEMP_KEYS_DIR"/*; do keyfile=$(basename "${keyfile}") src_keyfile="${_TEMP_KEYS_DIR}/${keyfile}" dst_keyfile="${SEED_DEST}/${keyfile}" @@ -6416,6 +6613,7 @@ daemons_running() { #====================================================================================================================== # Let's get the dependencies install function +DEP_FUNC_NAMES="" if [ ${_NO_DEPS} -eq $BS_FALSE ]; then DEP_FUNC_NAMES="install_${DISTRO_NAME_L}${PREFIXED_DISTRO_MAJOR_VERSION}_${ITYPE}_deps" DEP_FUNC_NAMES="$DEP_FUNC_NAMES install_${DISTRO_NAME_L}${PREFIXED_DISTRO_MAJOR_VERSION}${PREFIXED_DISTRO_MINOR_VERSION}_${ITYPE}_deps" @@ -6423,10 +6621,6 @@ if [ ${_NO_DEPS} -eq $BS_FALSE ]; then DEP_FUNC_NAMES="$DEP_FUNC_NAMES install_${DISTRO_NAME_L}${PREFIXED_DISTRO_MAJOR_VERSION}${PREFIXED_DISTRO_MINOR_VERSION}_deps" DEP_FUNC_NAMES="$DEP_FUNC_NAMES install_${DISTRO_NAME_L}_${ITYPE}_deps" DEP_FUNC_NAMES="$DEP_FUNC_NAMES install_${DISTRO_NAME_L}_deps" -elif [ "${ITYPE}" = "git" ]; then - DEP_FUNC_NAMES="__git_clone_and_checkout" -else - DEP_FUNC_NAMES="" fi DEPS_INSTALL_FUNC="null" @@ -6571,17 +6765,26 @@ if [ "$INSTALL_FUNC" = "null" ]; then exit 1 fi + # Install dependencies if [ ${_NO_DEPS} -eq $BS_FALSE ] && [ $_CONFIG_ONLY -eq $BS_FALSE ]; then # Only execute function is not in config mode only echoinfo "Running ${DEPS_INSTALL_FUNC}()" - $DEPS_INSTALL_FUNC - if [ $? -ne 0 ]; then + if ! ${DEPS_INSTALL_FUNC}; then echoerror "Failed to run ${DEPS_INSTALL_FUNC}()!!!" exit 1 fi fi + +if [ "${ITYPE}" = "git" ] && [ ${_NO_DEPS} -eq ${BS_TRUE} ]; then + if ! __git_clone_and_checkout; then + echo "Failed to clone and checkout git repository." + exit 1 + fi +fi + + # Triggering config_salt() if overwriting master or minion configs if [ "$_CUSTOM_MASTER_CONFIG" != "null" ] || [ "$_CUSTOM_MINION_CONFIG" != "null" ]; then if [ "$_TEMP_CONFIG_DIR" = "null" ]; then @@ -6591,8 +6794,7 @@ if [ "$_CUSTOM_MASTER_CONFIG" != "null" ] || [ "$_CUSTOM_MINION_CONFIG" != "null if [ ${_NO_DEPS} -eq $BS_FALSE ] && [ $_CONFIG_ONLY -eq $BS_TRUE ]; then # Execute function to satisfy dependencies for configuration step echoinfo "Running ${DEPS_INSTALL_FUNC}()" - $DEPS_INSTALL_FUNC - if [ $? -ne 0 ]; then + if ! ${DEPS_INSTALL_FUNC}; then echoerror "Failed to run ${DEPS_INSTALL_FUNC}()!!!" exit 1 fi @@ -6602,8 +6804,7 @@ fi # Configure Salt if [ "$CONFIG_SALT_FUNC" != "null" ] && [ "$_TEMP_CONFIG_DIR" != "null" ]; then echoinfo "Running ${CONFIG_SALT_FUNC}()" - $CONFIG_SALT_FUNC - if [ $? -ne 0 ]; then + if ! ${CONFIG_SALT_FUNC}; then echoerror "Failed to run ${CONFIG_SALT_FUNC}()!!!" exit 1 fi @@ -6612,7 +6813,7 @@ fi # Drop the master address if passed if [ "$_SALT_MASTER_ADDRESS" != "null" ]; then [ ! -d "$_SALT_ETC_DIR/minion.d" ] && mkdir -p "$_SALT_ETC_DIR/minion.d" - cat <<_eof > $_SALT_ETC_DIR/minion.d/99-master-address.conf + cat <<_eof > "$_SALT_ETC_DIR/minion.d/99-master-address.conf" master: $_SALT_MASTER_ADDRESS _eof fi @@ -6626,8 +6827,7 @@ fi # Pre-seed master keys if [ "$PRESEED_MASTER_FUNC" != "null" ] && [ "$_TEMP_KEYS_DIR" != "null" ]; then echoinfo "Running ${PRESEED_MASTER_FUNC}()" - $PRESEED_MASTER_FUNC - if [ $? -ne 0 ]; then + if ! ${PRESEED_MASTER_FUNC}; then echoerror "Failed to run ${PRESEED_MASTER_FUNC}()!!!" exit 1 fi @@ -6637,8 +6837,7 @@ fi if [ "$_CONFIG_ONLY" -eq $BS_FALSE ]; then # Only execute function is not in config mode only echoinfo "Running ${INSTALL_FUNC}()" - $INSTALL_FUNC - if [ $? -ne 0 ]; then + if ! ${INSTALL_FUNC}; then echoerror "Failed to run ${INSTALL_FUNC}()!!!" exit 1 fi @@ -6647,8 +6846,7 @@ fi # Run any post install function. Only execute function if not in config mode only if [ "$POST_INSTALL_FUNC" != "null" ] && [ "$_CONFIG_ONLY" -eq $BS_FALSE ]; then echoinfo "Running ${POST_INSTALL_FUNC}()" - $POST_INSTALL_FUNC - if [ $? -ne 0 ]; then + if ! ${POST_INSTALL_FUNC}; then echoerror "Failed to run ${POST_INSTALL_FUNC}()!!!" exit 1 fi @@ -6657,8 +6855,7 @@ fi # Run any check services function, Only execute function if not in config mode only if [ "$CHECK_SERVICES_FUNC" != "null" ] && [ "$_CONFIG_ONLY" -eq $BS_FALSE ]; then echoinfo "Running ${CHECK_SERVICES_FUNC}()" - $CHECK_SERVICES_FUNC - if [ $? -ne 0 ]; then + if ! ${CHECK_SERVICES_FUNC}; then echoerror "Failed to run ${CHECK_SERVICES_FUNC}()!!!" exit 1 fi @@ -6669,8 +6866,7 @@ if [ "$STARTDAEMONS_INSTALL_FUNC" != "null" ] && [ ${_START_DAEMONS} -eq $BS_TRU echoinfo "Running ${STARTDAEMONS_INSTALL_FUNC}()" echodebug "Waiting ${_SLEEP} seconds for processes to settle before checking for them" sleep ${_SLEEP} - $STARTDAEMONS_INSTALL_FUNC - if [ $? -ne 0 ]; then + if ! ${STARTDAEMONS_INSTALL_FUNC}; then echoerror "Failed to run ${STARTDAEMONS_INSTALL_FUNC}()!!!" exit 1 fi @@ -6681,8 +6877,7 @@ if [ "$DAEMONS_RUNNING_FUNC" != "null" ] && [ ${_START_DAEMONS} -eq $BS_TRUE ]; echoinfo "Running ${DAEMONS_RUNNING_FUNC}()" echodebug "Waiting ${_SLEEP} seconds for processes to settle before checking for them" sleep ${_SLEEP} # Sleep a little bit to let daemons start - $DAEMONS_RUNNING_FUNC - if [ $? -ne 0 ]; then + if ! ${DAEMONS_RUNNING_FUNC}; then echoerror "Failed to run ${DAEMONS_RUNNING_FUNC}()!!!" for fname in api master minion syndic; do diff --git a/tests/bootstrap/test_install.py b/tests/bootstrap/test_install.py index 5f52aa9..b06d4cf 100644 --- a/tests/bootstrap/test_install.py +++ b/tests/bootstrap/test_install.py @@ -270,39 +270,6 @@ class InstallationTestCase(BootstrapTestCase): ) ) - def test_install_daily(self): - args = [] - if requires_pip_based_installations(): - args.append('-P') - - args.append('daily') - - rc, out, err = self.run_script( - args=args, timeout=15 * 60, stream_stds=True - ) - if GRAINS['os'] in ('Ubuntu', 'Trisquel', 'Mint'): - self.assert_script_result( - 'Failed to install daily', - 0, (rc, out, err) - ) - - # Try to get the versions report - self.assert_script_result( - 'Failed to get the versions report (\'--versions-report\')', - 0, - self.run_script( - script=None, - args=('salt-minion', '--versions-report'), - timeout=15 * 60, - stream_stds=True - ) - ) - else: - self.assert_script_result( - 'Although system is not Ubuntu, we managed to install', - 1, (rc, out, err) - ) - def test_install_testing(self): args = [] if requires_pip_based_installations():