From 757b097c816f0ad5ca0033837683c68a22ef91b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Fri, 9 Apr 2021 08:18:59 +0200 Subject: [PATCH] add versioncheck.py script to verify Ansible role versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Ansible or Ansible Galaxy doesn't actually check role versions itself, we have to do it ourselves. This script goes through contents of `ansible/requirements.txt` and verifies each role is installed and has correct version. It also checks the version of Ansible itself. Signed-off-by: Jakub SokoĊ‚owski --- Makefile | 5 ++- ansible/geth.yml | 14 ++++---- ansible/logs.yml | 10 ++++++ ansible/mainnet.yml | 14 ++++---- ansible/prater.yml | 14 ++++---- ansible/pyrmont.yml | 14 ++++---- ansible/requirements.yml | 20 ++++++++--- ansible/versioncheck.py | 71 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 133 insertions(+), 29 deletions(-) create mode 100755 ansible/versioncheck.py diff --git a/Makefile b/Makefile index 20b6aab..8e79699 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,10 @@ all: requirements install-provisioner secrets init-terraform @echo "Success!" requirements: - ansible-galaxy install --ignore-errors --force -r ansible/requirements.yml + ansible-galaxy install --keep-scm-meta --ignore-errors --force -r ansible/requirements.yml + +requirements-check: + ansible/versioncheck.py $(PROVISIONER_PATH): @mkdir -p $(TF_PLUGINS_DIR)/$(ARCH); \ diff --git a/ansible/geth.yml b/ansible/geth.yml index 0a29685..3b060b5 100644 --- a/ansible/geth.yml +++ b/ansible/geth.yml @@ -1,11 +1,13 @@ --- -- name: Pre-playbook checks - hosts: localhost +- name: 'Verify Ansible versions' + hosts: all + run_once: true + connection: local + tags: always + gather_facts: false tasks: - - name: 'Verify Ansible version is 2.8 or newer' - assert: - that: 'ansible_version.full is version_compare("2.8", ">=")' - msg: 'Your Ansible version is lower than 2.8. Upgrade it.' + - local_action: command ./versioncheck.py + changed_when: false - name: Configure geth nodes become: true diff --git a/ansible/logs.yml b/ansible/logs.yml index ae34968..8f84005 100644 --- a/ansible/logs.yml +++ b/ansible/logs.yml @@ -1,4 +1,14 @@ --- +- name: 'Verify Ansible versions' + hosts: all + run_once: true + connection: local + tags: always + gather_facts: false + tasks: + - local_action: command ./versioncheck.py + changed_when: false + - name: Configure ElasticSearch servers become: true hosts: log-store diff --git a/ansible/mainnet.yml b/ansible/mainnet.yml index 693349c..058e3a2 100644 --- a/ansible/mainnet.yml +++ b/ansible/mainnet.yml @@ -1,11 +1,13 @@ --- -- name: Pre-playbook checks - hosts: localhost +- name: 'Verify Ansible versions' + hosts: all + run_once: true + connection: local + tags: always + gather_facts: false tasks: - - name: 'Verify Ansible version is 2.8 or newer' - assert: - that: 'ansible_version.full is version_compare("2.8", ">=")' - msg: 'Your Ansible version is lower than 2.8. Upgrade it.' + - local_action: command ./versioncheck.py + changed_when: false - name: Configure network mainnet bootnodes become: true diff --git a/ansible/prater.yml b/ansible/prater.yml index 74254f7..1e7d7ac 100644 --- a/ansible/prater.yml +++ b/ansible/prater.yml @@ -1,11 +1,13 @@ --- -- name: Pre-playbook checks - hosts: localhost +- name: 'Verify Ansible versions' + hosts: all + run_once: true + connection: local + tags: always + gather_facts: false tasks: - - name: 'Verify Ansible version is 2.8 or newer' - assert: - that: 'ansible_version.full is version_compare("2.8", ">=")' - msg: 'Your Ansible version is lower than 2.8. Upgrade it.' + - local_action: command ./versioncheck.py + changed_when: false - name: Configure build nodes become: true diff --git a/ansible/pyrmont.yml b/ansible/pyrmont.yml index 99750cf..da057fc 100644 --- a/ansible/pyrmont.yml +++ b/ansible/pyrmont.yml @@ -1,11 +1,13 @@ --- -- name: Pre-playbook checks - hosts: localhost +- name: 'Verify Ansible versions' + hosts: all + run_once: true + connection: local + tags: always + gather_facts: false tasks: - - name: 'Verify Ansible version is 2.8 or newer' - assert: - that: 'ansible_version.full is version_compare("2.8", ">=")' - msg: 'Your Ansible version is lower than 2.8. Upgrade it.' + - local_action: command ./versioncheck.py + changed_when: false - name: Configure build nodes become: true diff --git a/ansible/requirements.yml b/ansible/requirements.yml index fa788c0..97bd2cf 100644 --- a/ansible/requirements.yml +++ b/ansible/requirements.yml @@ -1,68 +1,80 @@ --- - name: nginx src: git@github.com:status-im/ansible-role-nginx.git + version: 3043c998cbc92a634a71dc48363b3e2525696d26 scm: git - name: origin-certs src: git@github.com:status-im/infra-role-origin-certs.git + version: 71c3cca0f250f86754d54ec74ddaddbc34f81ebb scm: git - name: open-ports src: git@github.com:status-im/infra-role-open-ports.git + version: 54125c7d291289aaea51ca313fc694d057d803fa scm: git - name: infra-role-tinc src: git@github.com:status-im/infra-role-tinc.git + version: bca648485def8e7a34ed5403bbaf403a2537279a scm: git - name: infra-role-bootstrap src: git@github.com:status-im/infra-role-bootstrap.git + version: e96c7f0f35e5cecbf5e3fa3e7074e0d0b6f77cfa scm: git - name: oauth-proxy src: git@github.com:status-im/infra-role-oauth-proxy.git + version: 64639425de011cd35b715a86d27a65e243031fa7 scm: git - name: consul-service src: git@github.com:status-im/infra-role-consul-service.git + version: b1d5ad5caa7d7a036fd175292fa497175bb7c54c scm: git - name: infra-role-beacon-node src: git@github.com:status-im/infra-role-beacon-node.git - scm: git - -- name: infra-role-eth2-testnet-site - src: git@github.com:status-im/infra-role-eth2-testnet-site.git + version: 0a57ff8b2920bb63d0b54866e3c8ed1822683417 scm: git - name: kibana src: git@github.com:status-im/infra-role-kibana.git + version: 6c170c45c8776fcd1f9cef2274488519245cd35b scm: git - name: elasticsearch src: git@github.com:status-im/infra-role-elasticsearch.git + version: afa5b00c7a7154e65e31579dcb4a8d0aba093fdd scm: git - name: elasticsearch-hq src: git@github.com:status-im/infra-role-elasticsearch-hq.git + version: 051a3bf232904c1845ac58d0ceff3f3cff90a832 scm: git - name: elasticsearch-lb src: git@github.com:status-im/infra-role-elasticsearch-lb.git + version: 2378db00ffcaa5fcbd362ed8479ad275b7506f22 scm: git - name: systemd-timer src: git@github.com:status-im/infra-role-systemd-timer.git + version: b4ef4557682ff5cf1e7da841cbfb195992589f60 scm: git - name: swap-file src: git@github.com:status-im/infra-role-swap-file.git + version: 7b63fb7b5f0c525aa191e1a410fd79f7eab8d11a scm: git - name: infra-role-geth src: git@github.com:status-im/infra-role-geth.git + version: 682b6ffeb3e6b1c713057d8497b32f60505c4f10 scm: git - name: infra-role-geth-exporter src: git+git@github.com:status-im/infra-role-geth-exporter.git + version: b187f16ad9e3dcf1e3024c6189994b71f26f5fde scm: git diff --git a/ansible/versioncheck.py b/ansible/versioncheck.py new file mode 100755 index 0000000..ba7c8ed --- /dev/null +++ b/ansible/versioncheck.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# WARNING: If importing this fails set PYTHONPATH. +import yaml +import ansible +import subprocess +from os import path, environ +from packaging import version + +SCRIPT_DIR = path.dirname(path.realpath(__file__)) +# Where Ansible looks for installed roles. +ANSIBLE_ROLES_PATH = path.join(environ['HOME'], '.ansible/roles') + + +class Role: + def __init__(self, name, version): + self.name = name + self.version = version + + @property + def path(self): + return path.join(ANSIBLE_ROLES_PATH, self.name) + + def exists(self): + return path.isdir(self.path) + + def local_version(self): + cmd = subprocess.run( + ['git', 'rev-parse', 'HEAD'], + capture_output=True, + cwd=self.path + ) + cmd.check_returncode() + return str(cmd.stdout.strip(), 'utf-8') + + +# Verify Ansible version is 2.8 or newer. +if version.parse(ansible.__version__) < version.parse("2.8"): + print('Your Ansible version is lower than 2.8. Upgrade it.') + exit(1) + +# Read Ansible requirements file. +with open(path.join(SCRIPT_DIR, 'requirements.yml'), 'r') as f: + requirements = yaml.load(f, Loader=yaml.FullLoader) + +# Check if each Ansible role is installed and has correct version. +errors = 0 +for req in requirements: + role = Role(req['name'], req.get('version')) + + if not role.exists(): + print('%25s - MISSING!' % role.name) + errors += 1 + continue + + # For now we allow not specifying versions for everyhing. + if role.version is None: + print('%25s - No version!' % role.name) + continue + + local_version = role.local_version() + if role.version != local_version: + print('%25s - MISMATCH: %s != %s' % + (role.name, role.version[:8], local_version[:8])) + errors += 1 + continue + + print('%25s - VALID' % role.name) + +# Any issue with any role should cause failure. +if errors > 0: + exit(1)