diff --git a/releasenotes/notes/isolate-ansible-3e8fcfdff9962a9b.yaml b/releasenotes/notes/isolate-ansible-3e8fcfdff9962a9b.yaml new file mode 100644 index 0000000000..2df1f84aa5 --- /dev/null +++ b/releasenotes/notes/isolate-ansible-3e8fcfdff9962a9b.yaml @@ -0,0 +1,9 @@ +--- +features: + - To ensure the deployment system remains clean the Ansible execution environment is + contained within a virtual environment. The virtual environment is created at + "/opt/ansible-runtime" and the "ansible.*" CLI commands are linked within /usr/local/bin + to ensure there is no interruption in the deployer workflow. +deprecations: + - Installation of Ansible on the root system, outside of a virtual environment, will + no longer be supported. diff --git a/requirements.txt b/requirements.txt index cfc7c5f623..f9f7c8a721 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,8 @@ netaddr>=0.7.12 # playbooks/inventory/dynamic_inventory.py PrettyTable>=0.7,<0.8 # scripts/inventory-manage.py +pycrypto>=2.6 # scripts/pw-token-gen.py +PyYAML>=3.1.0 # scripts/pw-token-gen.py +virtualenv>=14.0.0 # Used for Ansible isolation ### ### These are pinned to ensure exactly the same behaviour forever! ### ### These pins are updated through the sources-branch-updater script ### diff --git a/scripts/bootstrap-ansible.sh b/scripts/bootstrap-ansible.sh index da653db083..790670f6f9 100755 --- a/scripts/bootstrap-ansible.sh +++ b/scripts/bootstrap-ansible.sh @@ -83,17 +83,25 @@ if [ ! $(which "$PIP_COMMAND") ]; then PIP_COMMAND=pip fi -# Install requirements if there are any -if [ -f "requirements.txt" ];then - # When upgrading there will already be a pip.conf file locking pip down to the repo server, in such cases it may be - # necessary to use --isolated because the repo server does not meet the specified requirements. - $PIP_COMMAND install $PIP_OPTS -r requirements.txt || $PIP_COMMAND install --isolated $PIP_OPTS -r requirements.txt -fi - -# Install ansible # When upgrading there will already be a pip.conf file locking pip down to the repo server, in such cases it may be # necessary to use --isolated because the repo server does not meet the specified requirements. -$PIP_COMMAND install $PIP_OPTS "${ANSIBLE_WORKING_DIR}" || $PIP_COMMAND install --isolated $PIP_OPTS "${ANSIBLE_WORKING_DIR}" +$PIP_COMMAND install $PIP_OPTS -r requirements.txt || $PIP_COMMAND install --isolated $PIP_OPTS -r requirements.txt + +# Create a Virtualenv for the Ansible runtime +PYTHON_EXEC_PATH="$(which python2 || which python)" +virtualenv --always-copy --system-site-packages --python="${PYTHON_EXEC_PATH}" /opt/ansible-runtime + +# Install ansible +PIP_OPTS+=" --upgrade" +PIP_COMMAND="/opt/ansible-runtime/bin/pip" +# When upgrading there will already be a pip.conf file locking pip down to the repo server, in such cases it may be +# necessary to use --isolated because the repo server does not meet the specified requirements. +$PIP_COMMAND install $PIP_OPTS -r requirements.txt "${ANSIBLE_WORKING_DIR}" || $PIP_COMMAND install --isolated $PIP_OPTS "${ANSIBLE_WORKING_DIR}" + +# Link the venv installation of Ansible to the local path +pushd /usr/local/bin + find /opt/ansible-runtime/bin/ -name 'ansible*' -exec ln -sf {} \; +popd # Update dependent roles if [ -f "${ANSIBLE_ROLE_FILE}" ]; then diff --git a/test-requirements.txt b/test-requirements.txt index 2a1aff3c6c..44c1456fe3 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -7,6 +7,7 @@ hacking>=0.10.0,<0.11 mccabe==0.2.1 # capped for flake8 pep8==1.5.7 pyflakes==0.8.1 +virtualenv>=14.0.0 # this is required for the docs build jobs sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2