From c8ece0c625a9ddc10c4a8bb95fa2edd68011129f Mon Sep 17 00:00:00 2001 From: Riccardo Pittau Date: Wed, 6 Mar 2019 15:12:44 +0100 Subject: [PATCH] Add option to set python interpreter for ansible This patch adds the option to configure the python interpreter that is used when deploying machines using the ansible deploy interface. Also set the default interpreter for tinyipa image with ansible deploy interface to /usr/bin/python3 on devstack and marks ironic-standalone job as voting again. Change-Id: I8eb58fb00980c9e8946e3b3ef77611a9f5212668 Story: #2005159 Task: #29877 --- devstack/lib/ironic | 3 ++ ironic/conf/ansible.py | 4 +++ ironic/drivers/modules/ansible/deploy.py | 3 ++ .../drivers/modules/ansible/test_deploy.py | 29 +++++++++++++++++++ ...e-python-interpreter-2035e0f23d407aaf.yaml | 13 +++++++++ zuul.d/project.yaml | 9 ++---- 6 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/add-ansible-python-interpreter-2035e0f23d407aaf.yaml diff --git a/devstack/lib/ironic b/devstack/lib/ironic index 06dfd75d25..707f3b5845 100644 --- a/devstack/lib/ironic +++ b/devstack/lib/ironic @@ -1279,6 +1279,9 @@ function configure_ironic_conductor { # we definitely know the default username to use for TinyIPA image IRONIC_ANSIBLE_SSH_USER='tc' fi + # (rpittau) most recent tinyipa uses python3 natively so we need to change + # the default ansible python interpreter. + iniset $IRONIC_CONF_FILE ansible default_python_interpreter /usr/bin/python3 fi iniset $IRONIC_CONF_FILE ansible default_key_file $IRONIC_ANSIBLE_SSH_KEY if [[ -n $IRONIC_ANSIBLE_SSH_USER ]]; then diff --git a/ironic/conf/ansible.py b/ironic/conf/ansible.py index 97869460c4..bcabb1b963 100644 --- a/ironic/conf/ansible.py +++ b/ironic/conf/ansible.py @@ -134,6 +134,10 @@ opts = [ "It may be overridden by per-node " "'ansible_clean_steps_config' option in node's " "'driver_info' field.")), + cfg.StrOpt('default_python_interpreter', + help=_("Absolute path to the python interpreter on the " + "managed machines. By default, ansible uses " + "/usr/bin/python")), ] diff --git a/ironic/drivers/modules/ansible/deploy.py b/ironic/drivers/modules/ansible/deploy.py index a5b28cd776..17d7174520 100644 --- a/ironic/drivers/modules/ansible/deploy.py +++ b/ironic/drivers/modules/ansible/deploy.py @@ -126,6 +126,9 @@ def _run_playbook(node, name, extra_vars, key, tags=None, notags=None): playbook = os.path.join(root, name) inventory = os.path.join(root, 'inventory') ironic_vars = {'ironic': extra_vars} + if CONF.ansible.default_python_interpreter: + ironic_vars['ansible_python_interpreter'] = ( + CONF.ansible.default_python_interpreter) args = [CONF.ansible.ansible_playbook_script, playbook, '-i', inventory, '-e', json.dumps(ironic_vars), diff --git a/ironic/tests/unit/drivers/modules/ansible/test_deploy.py b/ironic/tests/unit/drivers/modules/ansible/test_deploy.py index 69237b312a..1391bcc5ec 100644 --- a/ironic/tests/unit/drivers/modules/ansible/test_deploy.py +++ b/ironic/tests/unit/drivers/modules/ansible/test_deploy.py @@ -10,6 +10,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json + from ironic_lib import utils as irlib_utils import mock from oslo_concurrency import processutils @@ -162,6 +164,33 @@ class TestAnsibleMethods(AnsibleDeployTestCaseBase): '/path/to/playbooks/inventory', '-e', '{"ironic": {"foo": "bar"}}', '--private-key=/path/to/key', '-vvvv') + @mock.patch.object(com_utils, 'execute', return_value=('out', 'err'), + autospec=True) + def test__run_playbook_ansible_interpreter_python3(self, execute_mock): + self.config(group='ansible', playbooks_path='/path/to/playbooks') + self.config(group='ansible', config_file_path='/path/to/config') + self.config(group='ansible', verbosity=3) + self.config(group='ansible', + default_python_interpreter='/usr/bin/python3') + self.config(group='ansible', ansible_extra_args='--timeout=100') + extra_vars = {'foo': 'bar'} + + ansible_deploy._run_playbook(self.node, 'deploy', + extra_vars, '/path/to/key', + tags=['spam'], notags=['ham']) + + execute_mock.assert_called_once_with( + 'env', 'ANSIBLE_CONFIG=/path/to/config', + 'ansible-playbook', '/path/to/playbooks/deploy', '-i', + '/path/to/playbooks/inventory', '-e', + mock.ANY, '--tags=spam', '--skip-tags=ham', + '--private-key=/path/to/key', '-vvv', '--timeout=100') + + all_vars = execute_mock.call_args[0][7] + self.assertEqual({"ansible_python_interpreter": "/usr/bin/python3", + "ironic": {"foo": "bar"}}, + json.loads(all_vars)) + @mock.patch.object(com_utils, 'execute', side_effect=processutils.ProcessExecutionError( description='VIKINGS!'), diff --git a/releasenotes/notes/add-ansible-python-interpreter-2035e0f23d407aaf.yaml b/releasenotes/notes/add-ansible-python-interpreter-2035e0f23d407aaf.yaml new file mode 100644 index 0000000000..9981967598 --- /dev/null +++ b/releasenotes/notes/add-ansible-python-interpreter-2035e0f23d407aaf.yaml @@ -0,0 +1,13 @@ +--- +features: + - Adds option ``[ansible]default_python_interpreter`` to choose + the python interpreter that ansible uses on managed machines. + By default, ansible uses ``/usr/bin/python`` as interpreter, making the + assumption that that path is always present on remote managed systems. + This might not be always the case, for example in custom build + images or Python 3 native distributions. + With this option the operator has the ability to set the absolute + path of the python interpreter on the remote machines, for example + ``/usr/bin/python3``. + The same interpreter will be used in all operations that use the + ansible deploy interface. diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 2932855fee..0c89d48d17 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -11,10 +11,7 @@ check: jobs: - ironic-tox-unit-with-driver-libs - # making ironic-standalone non voting until we can run ansible - # with python3 interpreter on remote machines - - ironic-standalone: - voting: false + - ironic-standalone - ironic-tempest-functional-python2 - ironic-tempest-functional-python3 - ironic-grenade-dsvm @@ -40,9 +37,7 @@ queue: ironic jobs: - ironic-tox-unit-with-driver-libs - # removing ironic-standalone from gate until we can run ansible - # with python3 interpreter on remote machines - # - ironic-standalone + - ironic-standalone - ironic-tempest-functional-python2 - ironic-tempest-functional-python3 - ironic-grenade-dsvm