From 86aad5459a52905c6f57c93b5738bfb7dcd42ec7 Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Mon, 17 Apr 2017 03:07:03 -0400 Subject: [PATCH 1/8] Avoid using variables in printf format strings This can potentially cause security issues. --- .travis/dispatch.sh | 8 ++++---- .travis/install_salt.sh | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis/dispatch.sh b/.travis/dispatch.sh index 1da063f2..7564cda4 100755 --- a/.travis/dispatch.sh +++ b/.travis/dispatch.sh @@ -14,12 +14,12 @@ salt_call() { } travis_fold_start () { - printf "travis_fold:start:$1\n" - printf "$2\n" + printf "travis_fold:start:%s\n" "${1}" + printf "%s\n" "${2}" } travis_fold_end () { - printf "travis_fold:end:$1\n" + printf "travis_fold:end:%s\n" "${1}" } run_salt () { @@ -42,7 +42,7 @@ run_salt () { if [[ "${SALT_NODE_ID}" == "test" ]]; then # Using .travis.yml to specify Python 3.5 to be preinstalled, just to check - printf "Using $(python3 --version) at $(which python3)\n" + printf "Using %s at %s\n" "$(python3 --version)" "$(which python3)" # Run test suite separately for parallelism ./test.py diff --git a/.travis/install_salt.sh b/.travis/install_salt.sh index 3323c46e..ded05ea0 100755 --- a/.travis/install_salt.sh +++ b/.travis/install_salt.sh @@ -7,7 +7,7 @@ set -o pipefail install_salt () { # Ensure that pinned versions match as closely as possible if [[ "${OS_NAME}" == "linux" ]]; then - printf "$0: installing salt for Linux\n" + printf "%s: installing salt for Linux\n" "${0}" # Use Trusty (Ubuntu 14.04) on Travis # Don't autostart services printf '#!/bin/sh\nexit 101\n' | sudo install -m 755 /dev/stdin /usr/sbin/policy-rc.d @@ -20,7 +20,7 @@ install_salt () { -o Dpkg::Options::="--force-confdef" \ install salt-minion=2016.3.3+ds-1 elif [[ "${OS_NAME}" == "osx" ]]; then - printf "$0: installing salt for Mac OS X\n" + printf "%s: installing salt for Mac OS X\n" "${0}" brew update printf "\nhomebrew --version output:\n" brew --version # For debugging @@ -34,13 +34,13 @@ install_salt () { # In case we had the same version previously, we need to relink brew link saltstack else - printf >&2 "$0: unknown operating system ${OS_NAME}\n" + printf >&2 "%s: unknown operating system %s\n" "${0}" "${OS_NAME}" exit 1 fi } configure_salt () { - printf "$0: copying Salt minion configuration from ${TEMPORARY_CONFIG_DIR}\n" + printf "%s: copying Salt minion configuration from %s\n" "${0}" "${TEMPORARY_CONFIG_DIR}" sudo rm -rf /etc/salt sudo mkdir -p /etc/salt sudo cp "${FORCE_FLAG}" -- "${TEMPORARY_CONFIG_DIR}/minion" /etc/salt/minion @@ -79,7 +79,7 @@ while true; do done if [[ "$#" -lt 1 ]]; then - printf >&2 "usage: $0 [-c [-F]] [--] os_name\n" + printf >&2 "usage: %s [-c [-F]] [--] os_name\n" "${0}" exit 1 fi From 68dd84592cbf6ffba43485967c21a74bb268bd9c Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Tue, 25 Apr 2017 20:04:40 -0400 Subject: [PATCH 2/8] Use consistent style for bash function declaration --- .travis/dispatch.sh | 6 +++--- .travis/install_salt.sh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis/dispatch.sh b/.travis/dispatch.sh index 7564cda4..ecc66925 100755 --- a/.travis/dispatch.sh +++ b/.travis/dispatch.sh @@ -13,16 +13,16 @@ salt_call() { "$@" } -travis_fold_start () { +travis_fold_start() { printf "travis_fold:start:%s\n" "${1}" printf "%s\n" "${2}" } -travis_fold_end () { +travis_fold_end() { printf "travis_fold:end:%s\n" "${1}" } -run_salt () { +run_salt() { travis_fold_start "salt.install.$1" 'Installing and configuring Salt' .travis/install_salt.sh -F -c .travis -- "${TRAVIS_OS_NAME}" travis_fold_end "salt.install.$1" diff --git a/.travis/install_salt.sh b/.travis/install_salt.sh index ded05ea0..12fa9dc9 100755 --- a/.travis/install_salt.sh +++ b/.travis/install_salt.sh @@ -4,7 +4,7 @@ set -o errexit set -o nounset set -o pipefail -install_salt () { +install_salt() { # Ensure that pinned versions match as closely as possible if [[ "${OS_NAME}" == "linux" ]]; then printf "%s: installing salt for Linux\n" "${0}" @@ -39,7 +39,7 @@ install_salt () { fi } -configure_salt () { +configure_salt() { printf "%s: copying Salt minion configuration from %s\n" "${0}" "${TEMPORARY_CONFIG_DIR}" sudo rm -rf /etc/salt sudo mkdir -p /etc/salt From 7ff5c4c50f255f800eb1d675e46b069280186022 Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Tue, 25 Apr 2017 20:03:26 -0400 Subject: [PATCH 3/8] wip: docker-full TODO: reexec dispatch.sh inside the docker container, try out 16.04 as well --- .travis.yml | 9 +++++++++ .travis/dispatch.sh | 22 ++++++++++++++++++++++ .travis/install_salt.sh | 3 +++ 3 files changed, 34 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4cb943c6..cc9a51f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -67,6 +67,15 @@ matrix: dist: trusty language: python python: 3.5 + # Salt inside Docker + - env: + - SALT_NODE_ID=servo-linux1 + - SALT_FROM_SCRATCH=true + # ubuntu/14.04 + - SALT_DOCKER_IMAGE=ubuntu@sha256:edf05697d8ea17028a69726b4b450ad48da8b29884cd640fec950c904bfb50ce + os: linux + sudo: required + dist: trusty # Not a Salt node, runs test suite instead - env: - SALT_NODE_ID=test diff --git a/.travis/dispatch.sh b/.travis/dispatch.sh index ecc66925..9a029c17 100755 --- a/.travis/dispatch.sh +++ b/.travis/dispatch.sh @@ -8,6 +8,7 @@ shopt -s nullglob salt_call() { sudo salt-call \ + --force-color \ --id="${SALT_NODE_ID}" \ --local --file-root='./.' --pillar-root='./.travis/test_pillars' \ "$@" @@ -40,12 +41,33 @@ run_salt() { } +run_inside_docker() { + # Reexec this script inside docker + # (without exporting the `SALT_DOCKER_IMAGE` environment variable + # to prevent recursion) + local -r DOCKER_SALT_ROOT="/tmp/salt" + docker run \ + --env="SALT_NODE_ID=${SALT_NODE_ID}" \ + --env="SALT_FROM_SCRATCH=${SALT_FROM_SCRATCH}" \ + --env="TRAVIS_COMMIT=${TRAVIS_COMMIT}" \ + --env="TRAVIS_OS_NAME=${TRAVIS_OS_NAME}" \ + --volume="$(pwd):${DOCKER_SALT_ROOT}" \ + --workdir="${DOCKER_SALT_ROOT}" \ + "${SALT_DOCKER_IMAGE}" \ + "${DOCKER_SALT_ROOT}/.travis/dispatch.sh" +} + + if [[ "${SALT_NODE_ID}" == "test" ]]; then # Using .travis.yml to specify Python 3.5 to be preinstalled, just to check printf "Using %s at %s\n" "$(python3 --version)" "$(which python3)" # Run test suite separately for parallelism ./test.py +elif [[ -n "${SALT_DOCKER_IMAGE:-}" ]]; then # macOS bash is too old for `-v` + printf "Using %s\n" "$(docker -v)" + + run_inside_docker "$@" else if [ "${SALT_FROM_SCRATCH}" = "true" ]; then run_salt 'scratch' diff --git a/.travis/install_salt.sh b/.travis/install_salt.sh index 12fa9dc9..9b492463 100755 --- a/.travis/install_salt.sh +++ b/.travis/install_salt.sh @@ -11,6 +11,9 @@ install_salt() { # Use Trusty (Ubuntu 14.04) on Travis # Don't autostart services printf '#!/bin/sh\nexit 101\n' | sudo install -m 755 /dev/stdin /usr/sbin/policy-rc.d + # Ensure curl is installed (is not present by default in Docker) + sudo apt-get -y update + sudo apt-get -y install --no-install-recommends ca-certificates curl curl https://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3/SALTSTACK-GPG-KEY.pub | sudo apt-key add - printf 'deb http://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3 trusty main\n' | sudo tee /etc/apt/sources.list.d/saltstack.list >/dev/null sudo apt-get -y update From 2db1495dc19b3e7bb86ef49649f467c951d18ed4 Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Tue, 25 Apr 2017 20:53:20 -0400 Subject: [PATCH 4/8] debug: test on 16.04 --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index cc9a51f8..e57ccfac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -76,6 +76,14 @@ matrix: os: linux sudo: required dist: trusty + - env: + - SALT_NODE_ID=servo-linux1 + - SALT_FROM_SCRATCH=true + # ubuntu/16.04 + - SALT_DOCKER_IMAGE=ubuntu@sha256:f3a61450ae43896c4332bda5e78b453f4a93179045f20c8181043b26b5e79028 + os: linux + sudo: required + dist: trusty # Not a Salt node, runs test suite instead - env: - SALT_NODE_ID=test From fb0b661778ecaac245ec80888ea5d2685395014c Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Tue, 25 Apr 2017 21:07:09 -0400 Subject: [PATCH 5/8] Only use sudo if necessary Ubuntu 16.04 Docker images don't come with sudo. --- .travis/dispatch.sh | 8 +++++++- .travis/install_salt.sh | 25 +++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/.travis/dispatch.sh b/.travis/dispatch.sh index 9a029c17..a2717846 100755 --- a/.travis/dispatch.sh +++ b/.travis/dispatch.sh @@ -7,7 +7,7 @@ set -o pipefail shopt -s nullglob salt_call() { - sudo salt-call \ + ${SUDO} salt-call \ --force-color \ --id="${SALT_NODE_ID}" \ --local --file-root='./.' --pillar-root='./.travis/test_pillars' \ @@ -58,6 +58,12 @@ run_inside_docker() { } +SUDO="" +if (( EUID != 0 )); then + SUDO="sudo" +fi + + if [[ "${SALT_NODE_ID}" == "test" ]]; then # Using .travis.yml to specify Python 3.5 to be preinstalled, just to check printf "Using %s at %s\n" "$(python3 --version)" "$(which python3)" diff --git a/.travis/install_salt.sh b/.travis/install_salt.sh index 9b492463..2dcfba45 100755 --- a/.travis/install_salt.sh +++ b/.travis/install_salt.sh @@ -10,15 +10,15 @@ install_salt() { printf "%s: installing salt for Linux\n" "${0}" # Use Trusty (Ubuntu 14.04) on Travis # Don't autostart services - printf '#!/bin/sh\nexit 101\n' | sudo install -m 755 /dev/stdin /usr/sbin/policy-rc.d + printf '#!/bin/sh\nexit 101\n' | ${SUDO} install -m 755 /dev/stdin /usr/sbin/policy-rc.d # Ensure curl is installed (is not present by default in Docker) - sudo apt-get -y update - sudo apt-get -y install --no-install-recommends ca-certificates curl - curl https://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3/SALTSTACK-GPG-KEY.pub | sudo apt-key add - - printf 'deb http://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3 trusty main\n' | sudo tee /etc/apt/sources.list.d/saltstack.list >/dev/null - sudo apt-get -y update + ${SUDO} apt-get -y update + ${SUDO} apt-get -y install --no-install-recommends ca-certificates curl + curl https://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3/SALTSTACK-GPG-KEY.pub | ${SUDO} apt-key add - + printf 'deb http://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3 trusty main\n' | ${SUDO} tee /etc/apt/sources.list.d/saltstack.list >/dev/null + ${SUDO} apt-get -y update # Use existing config file if it exists (if reinstalling) - sudo apt-get -y \ + ${SUDO} apt-get -y \ -o Dpkg::Options::="--force-confold" \ -o Dpkg::Options::="--force-confdef" \ install salt-minion=2016.3.3+ds-1 @@ -44,11 +44,16 @@ install_salt() { configure_salt() { printf "%s: copying Salt minion configuration from %s\n" "${0}" "${TEMPORARY_CONFIG_DIR}" - sudo rm -rf /etc/salt - sudo mkdir -p /etc/salt - sudo cp "${FORCE_FLAG}" -- "${TEMPORARY_CONFIG_DIR}/minion" /etc/salt/minion + ${SUDO} rm -rf /etc/salt + ${SUDO} mkdir -p /etc/salt + ${SUDO} cp "${FORCE_FLAG}" -- "${TEMPORARY_CONFIG_DIR}/minion" /etc/salt/minion } +SUDO="" +if (( EUID != 0 )); then + SUDO="sudo" +fi + OPTIONS=$(getopt 'c:CF' "$@") eval set -- "${OPTIONS}" From dcd0afa9f591f8ac54a5055d2c15933c64662873 Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Wed, 26 Apr 2017 02:39:24 -0400 Subject: [PATCH 6/8] Skip timezone.system and service.running on Docker `service.running` requires talking to init, which is not running inside Docker. `timezone.system` on systemd distros uses timedatectl which also wants to talk to a running systemd, so skip that on Docker as well. --- admin/init.sls | 2 +- buildbot/master/init.sls | 4 ++++ buildbot/slave/init.sls | 4 ++++ homu/init.sls | 2 ++ intermittent-tracker/init.sls | 2 ++ nginx/init.sls | 5 +++-- salt/master.sls | 6 ++++++ xvfb/init.sls | 2 ++ 8 files changed, 24 insertions(+), 3 deletions(-) diff --git a/admin/init.sls b/admin/init.sls index e9a8f5a4..4f8f4242 100644 --- a/admin/init.sls +++ b/admin/init.sls @@ -11,7 +11,7 @@ admin-packages: - mobile-shell {% endif %} -{% if grains['os'] != 'MacOS' %} +{% if grains['os'] != 'MacOS' and grains.get('virtual_subtype', '') != 'Docker' %} UTC: timezone.system {% endif %} diff --git a/buildbot/master/init.sls b/buildbot/master/init.sls index dd3323c6..e547bb2a 100644 --- a/buildbot/master/init.sls +++ b/buildbot/master/init.sls @@ -14,6 +14,7 @@ buildbot-master: - twisted == 16.6.0 # NOTE: keep in sync with buildbot-slave sls - require: - pkg: pip + {% if grains.get('virtual_subtype', '') != 'Docker' %} service.running: - enable: True # Buildbot must be restarted manually! See 'Buildbot administration' on the @@ -23,6 +24,7 @@ buildbot-master: - pip: buildbot-master - file: ownership-{{ common.servo_home }}/buildbot/master - file: /etc/init/buildbot-master.conf + {% endif %} deploy-{{ common.servo_home }}/buildbot/master: file.recurse: @@ -77,12 +79,14 @@ ownership-{{ common.servo_home }}/buildbot/master: - context: common: {{ common }} +{% if grains.get('virtual_subtype', '') != 'Docker' %} buildbot-github-listener: service.running: - enable: True - watch: - file: /usr/local/bin/github_buildbot.py - file: /etc/init/buildbot-github-listener.conf +{% endif %} remove-old-build-logs: cron.present: diff --git a/buildbot/slave/init.sls b/buildbot/slave/init.sls index 090e1e06..7457453d 100644 --- a/buildbot/slave/init.sls +++ b/buildbot/slave/init.sls @@ -50,11 +50,14 @@ buildbot-slave-dependencies: - template: jinja - context: common: {{ common }} + {% if grains.get('virtual_subtype', '') != 'Docker' %} - watch_in: - service: buildbot-slave + {% endif %} {% endif %} +{% if grains.get('virtual_subtype', '') != 'Docker' %} buildbot-slave: service.running: - enable: True @@ -63,3 +66,4 @@ buildbot-slave: - watch: - pip: buildbot-slave-dependencies - file: {{ common.servo_home }}/buildbot/slave +{% endif %} diff --git a/homu/init.sls b/homu/init.sls index ea28dff2..a01f0e0e 100644 --- a/homu/init.sls +++ b/homu/init.sls @@ -25,6 +25,7 @@ homu: - bin_env: /home/servo/homu/_venv - require: - virtualenv: homu + {% if grains.get('virtual_subtype', '') != 'Docker' %} service.running: - enable: True - require: @@ -32,6 +33,7 @@ homu: - watch: - file: /home/servo/homu/cfg.toml - file: /etc/init/homu.conf + {% endif %} {{ salt['file.dirname'](homu.db) }}: file.directory: diff --git a/intermittent-tracker/init.sls b/intermittent-tracker/init.sls index 77b45dd0..be2aa286 100644 --- a/intermittent-tracker/init.sls +++ b/intermittent-tracker/init.sls @@ -23,6 +23,7 @@ intermittent-tracker: - bin_env: /home/servo/intermittent-tracker/_venv - require: - virtualenv: intermittent-tracker + {% if grains.get('virtual_subtype', '') != 'Docker' %} service.running: - enable: True - name: tracker @@ -31,6 +32,7 @@ intermittent-tracker: - watch: - file: /home/servo/intermittent-tracker/config.json - file: /etc/init/tracker.conf + {% endif %} /home/servo/intermittent-tracker/config.json: file.managed: diff --git a/nginx/init.sls b/nginx/init.sls index 94ede988..86990817 100644 --- a/nginx/init.sls +++ b/nginx/init.sls @@ -1,9 +1,12 @@ nginx: pkg.installed: [] + {% if grains.get('virtual_subtype', '') != 'Docker' %} service.running: - enable: True - watch: - pkg: nginx + - file: /etc/nginx/sites-available/default + {% endif %} /etc/nginx/sites-available/default: file.managed: @@ -11,8 +14,6 @@ nginx: - user: root - group: root - mode: 644 - - watch_in: - - service: nginx /etc/nginx/sites-enabled/default: file.symlink: diff --git a/salt/master.sls b/salt/master.sls index 4173b36b..3152cb61 100644 --- a/salt/master.sls +++ b/salt/master.sls @@ -16,8 +16,10 @@ salt-master-dependencies: - user: root - group: root - mode: 755 + {% if grains.get('virtual_subtype', '') != 'Docker' %} - require_in: - service: salt-master + {% endif %} {{ rootfs_parent_dir }}/ADMIN_README: file.managed: @@ -25,8 +27,10 @@ salt-master-dependencies: - group: root - mode: 644 - source: salt://{{ tpldir }}/files/master/ADMIN_README + {% if grains.get('virtual_subtype', '') != 'Docker' %} - require_in: - service: salt-master + {% endif %} {% endfor %} salt-master: @@ -36,11 +40,13 @@ salt-master: - require: - sls: salt.common - pkg: salt-master-dependencies + {% if grains.get('virtual_subtype', '') != 'Docker' %} service.running: - enable: True - require: # Updates and upgrades must be handled manually - file: /etc/salt/master - pkg: salt-master + {% endif %} /etc/salt/master: file.managed: diff --git a/xvfb/init.sls b/xvfb/init.sls index 30dca514..70f797b9 100644 --- a/xvfb/init.sls +++ b/xvfb/init.sls @@ -7,8 +7,10 @@ xvfb: pkg.installed: [] + {% if grains.get('virtual_subtype', '') != 'Docker' %} service.running: - enable: True - watch: - pkg: xvfb - file: /etc/init/xvfb.conf + {% endif %} From 8fa92a90d3cee321c220140b11d0e9e036d4004e Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Wed, 26 Apr 2017 02:31:03 -0400 Subject: [PATCH 7/8] Support Ubuntu 16.04 for servo-linux1 states More work is needed to support the cross build states. --- .travis/install_salt.sh | 20 ++++++++++++++++---- salt/common.sls | 4 ++-- servo-build-dependencies/init.sls | 4 ++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.travis/install_salt.sh b/.travis/install_salt.sh index 2dcfba45..0f1761bf 100755 --- a/.travis/install_salt.sh +++ b/.travis/install_salt.sh @@ -7,15 +7,27 @@ set -o pipefail install_salt() { # Ensure that pinned versions match as closely as possible if [[ "${OS_NAME}" == "linux" ]]; then - printf "%s: installing salt for Linux\n" "${0}" - # Use Trusty (Ubuntu 14.04) on Travis + local os_codename os_release + os_codename="$(grep 'DISTRIB_CODENAME' /etc/lsb-release | cut -f2 -d'=')" + declare -r os_codename + os_release="$(grep 'DISTRIB_RELEASE' /etc/lsb-release | cut -f2 -d'=')" + declare -r os_release + printf \ + "%s: installing salt for Linux (%s, %s)\n" \ + "${0}" "${os_codename}" "${os_release}" + # Don't autostart services printf '#!/bin/sh\nexit 101\n' | ${SUDO} install -m 755 /dev/stdin /usr/sbin/policy-rc.d # Ensure curl is installed (is not present by default in Docker) ${SUDO} apt-get -y update ${SUDO} apt-get -y install --no-install-recommends ca-certificates curl - curl https://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3/SALTSTACK-GPG-KEY.pub | ${SUDO} apt-key add - - printf 'deb http://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/2016.3.3 trusty main\n' | ${SUDO} tee /etc/apt/sources.list.d/saltstack.list >/dev/null + + curl "https://repo.saltstack.com/apt/ubuntu/${os_release}/amd64/archive/2016.3.3/SALTSTACK-GPG-KEY.pub" | \ + ${SUDO} apt-key add - + printf \ + 'deb http://repo.saltstack.com/apt/ubuntu/%s/amd64/archive/2016.3.3 %s main\n' \ + "${os_release}" "${os_codename}" | \ + ${SUDO} tee /etc/apt/sources.list.d/saltstack.list >/dev/null ${SUDO} apt-get -y update # Use existing config file if it exists (if reinstalling) ${SUDO} apt-get -y \ diff --git a/salt/common.sls b/salt/common.sls index de70a450..c222d5aa 100644 --- a/salt/common.sls +++ b/salt/common.sls @@ -3,9 +3,9 @@ {% if grains['os'] == 'Ubuntu' %} salt: pkgrepo.managed: - - name: 'deb http://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/{{ salt.version }} trusty main' + - name: 'deb http://repo.saltstack.com/apt/ubuntu/{{ grains['osrelease'] }}/amd64/archive/{{ salt.version }} {{ grains['oscodename'] }} main' - file: /etc/apt/sources.list.d/saltstack.list - - key_url: https://repo.saltstack.com/apt/ubuntu/14.04/amd64/archive/{{ salt.version }}/SALTSTACK-GPG-KEY.pub + - key_url: https://repo.saltstack.com/apt/ubuntu/{{ grains['osrelease'] }}/amd64/archive/{{ salt.version }}/SALTSTACK-GPG-KEY.pub /etc/apt/sources.list.d/saltstack.list: file.exists: diff --git a/servo-build-dependencies/init.sls b/servo-build-dependencies/init.sls index 9f3e2acf..ef70633a 100644 --- a/servo-build-dependencies/init.sls +++ b/servo-build-dependencies/init.sls @@ -75,10 +75,10 @@ servo-dependencies: - pip: virtualenv {% endif %} -{% if grains['os'] == 'Ubuntu' and grains['oscodename'] == 'trusty' %} +{% if grains['os'] == 'Ubuntu' %} multiverse: pkgrepo.managed: - - name: 'deb http://archive.ubuntu.com/ubuntu trusty multiverse' + - name: 'deb http://archive.ubuntu.com/ubuntu {{ grains['oscodename'] }} multiverse' - file: /etc/apt/sources.list.d/multiverse.list - require_in: - pkg: ttf-mscorefonts-installer From daedeaac388a467ff0fa1e95df4d41fd2bf7114f Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Wed, 26 Apr 2017 15:01:55 -0400 Subject: [PATCH 8/8] Drop Python requirement for tests to 3.4 from 3.5 Ubuntu Trusty's Python 3 package supplies 3.4, so this makes it possibly to run the tests on Trusty machines without manually installing Python 3.5. To allow running inside Docker, create our own virtualenv for Python test dependencies (e.g. `jinja2`). Don't use the virtualenvs supplied by Travis. Make sure to install some extra Python bits that aren't installed by default for Docker. Rewrite testing code to avoid APIs introduced in Python 3.5. Use block indent and early return in tests. --- .travis.yml | 17 +------------- .travis/dispatch.sh | 20 ++++++++++++++--- python/init.sls | 7 ++++++ test.py | 17 +++++++------- tests/lint/flake8.py | 19 +++++++++------- tests/lint/shebang.py | 6 ++--- tests/lint/trailing_whitespace.py | 6 ++--- tests/sls/buildbot/master/config.py | 25 ++++++++++++--------- tests/sls/buildbot/master/config_lint.py | 28 +++++++++++++++--------- tests/sls/common/timezone.py | 14 ++++++------ tests/sls/homu/valid_builders.py | 13 ++++++----- tests/util.py | 6 ++--- top.sls | 1 + 13 files changed, 103 insertions(+), 76 deletions(-) diff --git a/.travis.yml b/.travis.yml index e57ccfac..2c1b1147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ -# Python is not supported on OS X yet -# But a system python is installed for all workers +# Handle Python installation and dependencies ourselves language: cpp # NOTE: Make sure the matrix covers all node types in top.sls @@ -14,8 +13,6 @@ matrix: os: linux sudo: required dist: trusty - language: python - python: 3.5 - env: - SALT_NODE_ID=servo-mac1 - SALT_FROM_SCRATCH=true @@ -27,16 +24,12 @@ matrix: os: linux sudo: required dist: trusty - language: python - python: 3.5 - env: - SALT_NODE_ID=servo-master1 - SALT_FROM_SCRATCH=true os: linux sudo: required dist: trusty - language: python - python: 3.5 # Salt from previous configuration - env: - SALT_NODE_ID=servo-linux-cross1 @@ -44,8 +37,6 @@ matrix: os: linux sudo: required dist: trusty - language: python - python: 3.5 - env: - SALT_NODE_ID=servo-mac1 - SALT_FROM_SCRATCH=false @@ -57,16 +48,12 @@ matrix: os: linux sudo: required dist: trusty - language: python - python: 3.5 - env: - SALT_NODE_ID=servo-master1 - SALT_FROM_SCRATCH=false os: linux sudo: required dist: trusty - language: python - python: 3.5 # Salt inside Docker - env: - SALT_NODE_ID=servo-linux1 @@ -90,8 +77,6 @@ matrix: os: linux sudo: required dist: trusty - language: python - python: 3.5 script: .travis/dispatch.sh diff --git a/.travis/dispatch.sh b/.travis/dispatch.sh index a2717846..7d5ddb6a 100755 --- a/.travis/dispatch.sh +++ b/.travis/dispatch.sh @@ -58,6 +58,20 @@ run_inside_docker() { } +setup_venv() { + local -r VENV_DIR="/tmp/saltfs-venv3" + # Using .travis.yml to specify Python 3.5 to be preinstalled, just to check + printf "Using %s at %s\n" "$(python3 --version)" "$(which python3)" + + python3 -m venv "${VENV_DIR}" + set +o nounset + source "${VENV_DIR}/bin/activate" + set -o nounset + pip install wheel + pip install -r requirements.txt +} + + SUDO="" if (( EUID != 0 )); then SUDO="sudo" @@ -65,10 +79,8 @@ fi if [[ "${SALT_NODE_ID}" == "test" ]]; then - # Using .travis.yml to specify Python 3.5 to be preinstalled, just to check - printf "Using %s at %s\n" "$(python3 --version)" "$(which python3)" - # Run test suite separately for parallelism + setup_venv ./test.py elif [[ -n "${SALT_DOCKER_IMAGE:-}" ]]; then # macOS bash is too old for `-v` printf "Using %s\n" "$(docker -v)" @@ -97,6 +109,8 @@ else fi # Only run tests against the new configuration + setup_venv + # TODO: don't hard-code this if [[ "${SALT_NODE_ID}" == "servo-master1" ]]; then ./test.py sls.buildbot.master sls.homu sls.nginx diff --git a/python/init.sls b/python/init.sls index 51722649..d0ee3b07 100644 --- a/python/init.sls +++ b/python/init.sls @@ -10,6 +10,13 @@ python3: pkg.installed: - pkgs: - python3 + {% if grains['os'] == 'Ubuntu' %} + {% if grains['osrelease'] == '14.04' %} + - python3.4-venv + {% else %} + - python3-venv + {% endif %} + {% endif %} {% if grains['os'] == 'Ubuntu' %} python2-dev: diff --git a/test.py b/test.py index 0a48f6f7..8f019021 100755 --- a/test.py +++ b/test.py @@ -7,8 +7,8 @@ from tests.util import color, GREEN, RED, Failure, project_path -def is_python_script(dir_entry): - return dir_entry.name.endswith('.py') and dir_entry.is_file() +def is_python_script(path): + return path.endswith('.py') and os.path.isfile(path) def run_tests(tests): @@ -16,10 +16,11 @@ def run_tests(tests): for test_spec in tests: test_dir = os.path.join(project_path(), 'tests', *test_spec.split('.')) - - python_scripts = filter(is_python_script, os.scandir(test_dir)) - tests = sorted([entry.name for entry in python_scripts]) - + # TODO(aneeshusa): switch back to scandirr + tests = sorted( + path for path in os.listdir(test_dir) + if is_python_script(os.path.join(test_dir, path)) + ) for test in tests: test_mod_name = 'tests.{}.{}'.format(test_spec, test[:-3]) test_mod = importlib.import_module(test_mod_name) @@ -44,8 +45,8 @@ def run_tests(tests): def main(): - if sys.version_info < (3, 5): # We use features introduced in Python 3.5 - sys.stderr.write('{}: Python 3.5 or later is needed for this script\n' + if sys.version_info < (3, 4): # Only tested on 3.4 and up + sys.stderr.write('{}: Python 3.4 or later is needed for this script\n' .format(__file__)) return 1 diff --git a/tests/lint/flake8.py b/tests/lint/flake8.py index 5eb523df..481af4da 100644 --- a/tests/lint/flake8.py +++ b/tests/lint/flake8.py @@ -8,12 +8,15 @@ def run(): paths = ['test.py', 'tests'] paths = [os.path.join(project_path(), path) for path in paths] command = ['flake8'] + paths - ret = subprocess.run(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) + proc = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True + ) + stdout, _ = proc.communicate() - if ret.returncode == 0: - return Success("Tests passed flake8 lint") - else: - return Failure("Tests failed flake8 lint:", ret.stdout) + if proc.returncode != 0: + return Failure("Tests failed flake8 lint:", stdout) + + return Success("Tests passed flake8 lint") diff --git a/tests/lint/shebang.py b/tests/lint/shebang.py index de03b937..1d777d99 100644 --- a/tests/lint/shebang.py +++ b/tests/lint/shebang.py @@ -37,8 +37,8 @@ def run(): executables = filter(is_executable, paths()) failures = list(filter(lambda e: not has_correct_header(e), executables)) - if len(failures) == 0: - return Success("All executable shebangs are correct") - else: + if len(failures) != 0: output = '\n'.join([display_path(path) for path in failures]) return Failure("Bad shebangs found in these files:", output) + + return Success("All executable shebangs are correct") diff --git a/tests/lint/trailing_whitespace.py b/tests/lint/trailing_whitespace.py index 0b954146..40551aa9 100644 --- a/tests/lint/trailing_whitespace.py +++ b/tests/lint/trailing_whitespace.py @@ -35,8 +35,8 @@ def check_whitespace(path): def run(): failures = list(itertools.chain(*map(check_whitespace, paths()))) - if len(failures) == 0: - return Success("No trailing whitespace found") - else: + if len(failures) != 0: output = '\n'.join([display_failure(failure) for failure in failures]) return Failure("Trailing whitespace found on files and lines:", output) + + return Success("No trailing whitespace found") diff --git a/tests/sls/buildbot/master/config.py b/tests/sls/buildbot/master/config.py index f0ba05c4..43a81416 100644 --- a/tests/sls/buildbot/master/config.py +++ b/tests/sls/buildbot/master/config.py @@ -4,14 +4,19 @@ def run(): - command = ['sudo', # To get access to buildbot files owned by servo - 'buildbot', 'checkconfig', '/home/servo/buildbot/master'] - ret = subprocess.run(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) + command = [ + 'sudo', # To get access to buildbot files owned by servo + 'buildbot', 'checkconfig', '/home/servo/buildbot/master' + ] + proc = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True + ) + _, stderr = proc.communicate() - if ret.returncode == 0: - return Success("Buildbot master config passed checkconfig") - else: - return Failure("Buildbot master config check failed:", ret.stderr) + if proc.returncode != 0: + return Failure("Buildbot master config check failed:", stderr) + + return Success("Buildbot master config passed checkconfig") diff --git a/tests/sls/buildbot/master/config_lint.py b/tests/sls/buildbot/master/config_lint.py index af044a2c..d4ec5008 100644 --- a/tests/sls/buildbot/master/config_lint.py +++ b/tests/sls/buildbot/master/config_lint.py @@ -5,16 +5,24 @@ def run(): - CONF_DIR = os.path.join(project_path(), - 'buildbot', 'master', 'files', 'config') + CONF_DIR = os.path.join( + project_path(), + 'buildbot', + 'master', + 'files', + 'config' + ) # Have to specify master.cfg separately because it is not a .py file command = ['flake8', CONF_DIR, os.path.join(CONF_DIR, 'master.cfg')] - ret = subprocess.run(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) + proc = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True + ) + stdout, _ = proc.communicate() - if ret.returncode == 0: - return Success("Buildbot master config passed linting") - else: - return Failure("Buildbot master config lint check failed:", ret.stdout) + if proc.returncode != 0: + return Failure("Buildbot master config lint check failed:", stdout) + + return Success("Buildbot master config passed linting") diff --git a/tests/sls/common/timezone.py b/tests/sls/common/timezone.py index add0384a..3bb9bfb5 100644 --- a/tests/sls/common/timezone.py +++ b/tests/sls/common/timezone.py @@ -4,15 +4,15 @@ def run(): - ret = subprocess.run( + proc = subprocess.Popen( ['date'], stdout=subprocess.PIPE, - stderr=subprocess.PIPE + stderr=subprocess.PIPE, + universal_newlines=True ) + stdout, _ = proc.communicate() - stdout = ret.stdout.decode('utf-8') - - if ret.returncode == 0 and 'UTC' in stdout: - return Success('Date is in UTC') - else: + if proc.returncode != 0 or 'UTC' not in stdout: return Failure('Date is not in UTC: ', stdout) + + return Success('Date is in UTC') diff --git a/tests/sls/homu/valid_builders.py b/tests/sls/homu/valid_builders.py index 1aa0f378..0cdcc556 100644 --- a/tests/sls/homu/valid_builders.py +++ b/tests/sls/homu/valid_builders.py @@ -13,17 +13,20 @@ def run(): # We need to invoke a new process to read the Buildbot master config # because Buildbot is written in python2. scriptpath = os.path.join(os.path.dirname(__file__), 'get_buildbot_cfg.py') - ret = subprocess.run( + proc = subprocess.Popen( ['/usr/bin/python2', scriptpath], stdout=subprocess.PIPE, - stderr=subprocess.PIPE + stderr=subprocess.PIPE, + universal_newlines=True ) - if ret.returncode != 0: + stdout, stderr = proc.communicate() + + if proc.returncode != 0: return Failure( - 'Unable to retrieve buildbot builders:', ret.stderr + 'Unable to retrieve buildbot builders:', stderr ) - buildbot_builders = json.loads(ret.stdout.decode('utf-8'))['builders'] + buildbot_builders = json.loads(stdout)['builders'] failure_msg = '' for builder_set in ['builders', 'try_builders']: diff --git a/tests/util.py b/tests/util.py index f726ba59..b16f263c 100644 --- a/tests/util.py +++ b/tests/util.py @@ -22,10 +22,10 @@ def colon(): def project_path(): + abspath = os.path.realpath(os.path.join(os.getcwd(), __file__)) # One dirname for tests dir, another for project dir - project_dir = os.path.dirname(os.path.dirname(__file__)) - common = os.path.commonpath([project_dir, os.getcwd()]) - return project_dir.replace(common, '.', 1) # Only replace once + project_dir = os.path.dirname(os.path.dirname(abspath)) + return os.path.relpath(project_dir) def paths(): diff --git a/top.sls b/top.sls index 7b1306db..1c457fc2 100644 --- a/top.sls +++ b/top.sls @@ -5,6 +5,7 @@ base: - match: compound - admin - common + - python - salt.common 'os:Ubuntu':