ansible: add versioncheck.py script to verify role versions

This was originally introduced to `infra-nimbus` and proved robust.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2021-05-11 09:22:02 +02:00
parent f8c5b713be
commit b79993c331
No known key found for this signature in database
GPG Key ID: 4EF064D0E6D63020
5 changed files with 106 additions and 2 deletions

View File

@ -19,8 +19,13 @@ PROVISIONER_PATH = $(TF_PLUGINS_DIR)/$(ARCH)/$(PROVISIONER_NAME)_$(PROVISIONER_V
all: requirements install-provisioner secrets init-terraform
@echo "Success!"
requirements:
ansible-galaxy install --ignore-errors --force -r ansible/requirements.yml
requirements-install:
ansible-galaxy install --keep-scm-meta --ignore-errors --force -r ansible/requirements.yml
requirements-check:
ansible/versioncheck.py
requirements: requirements-install requirements-check
$(PROVISIONER_PATH):
@mkdir -p $(TF_PLUGINS_DIR)/$(ARCH); \

View File

@ -9,6 +9,16 @@
#
# This is run on every newly provisioned host.
#
- name: Verify Ansible versions
hosts: all
tags: always
become: false
run_once: true
gather_facts: false
tasks:
- local_action: command ./versioncheck.py
changed_when: false
- name: Bootstrap Python support for Ansible
gather_facts: False
hosts: all

View File

@ -1,4 +1,14 @@
---
- name: Verify Ansible versions
hosts: all
tags: always
become: false
run_once: true
gather_facts: false
tasks:
- local_action: command ./versioncheck.py
changed_when: false
- name: Install certs, open ports, add SWAP
hosts: faucet-master
roles:

View File

@ -1,31 +1,39 @@
- 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: 244ed6a740d6c20250024de9ae1a0232d71b1f57
scm: git
- name: consul-service
src: git@github.com:status-im/infra-role-consul-service.git
version: b1d5ad5caa7d7a036fd175292fa497175bb7c54c
scm: git
- name: infra-role-geth
src: git@github.com:status-im/infra-role-geth.git
version: f76e6f37792dc39302d175017f79a4711ecf33df
scm: git
- name: infra-role-geth-exporter
src: git+git@github.com:status-im/infra-role-geth-exporter.git
version: b187f16ad9e3dcf1e3024c6189994b71f26f5fde
scm: git

71
ansible/versioncheck.py Executable file
View File

@ -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)