Always run growvols playbook after provision

Just like cli-overcloud-node-network-config.yaml,
cli-overcloud-node-growvols.yaml will be run by the "openstack
overcloud node provision" directly after provisioning so that whole
disk images will have their /var volume grown to 100%.

This default growvols behaviour can be overridden by adding an
ansible_playbooks entry which sets different arguments:

- count: 3
  name: Controller
  ansible_playbooks:
  - playbook: /usr/share/ansible/tripleo-playbooks/cli-overcloud-node-growvols.yaml
    extra_vars:
      growvols_args: /var=50% /srv=50%

Other changes in this commit include:
- Always call run_role_playbooks and pass network_config as an
  argument
- Full unit test coverage on run_role_playbooks
- Fix run_role_playbook using os.path.basename instead of os.path.dirname

Change-Id: I085ab9da30e1e1a7d2b9a9f230dd0275bd40480d
Blueprint: whole-disk-default
Depends-On: I0a847ad4077a02a02ad817dd189a6a31c3637a93
This commit is contained in:
Steve Baker 2021-06-21 16:27:59 +12:00
parent e8dae35edd
commit 3f303b907b
6 changed files with 272 additions and 13 deletions

View File

@ -255,6 +255,221 @@ class TestRunAnsiblePlaybook(TestCase):
)
class TestRunRolePlaybooks(TestCase):
def setUp(self):
tmp_dir = utils.TempDirs().dir
self.work_dir = os.path.join(tmp_dir, 'working_dir')
utils.makedirs(self.work_dir)
self.inventory_path = os.path.join(
self.work_dir, 'tripleo-ansible-inventory.yaml')
with open(self.inventory_path, 'w') as f:
f.write('{}')
self.cmd = mock.Mock()
self.cmd.app.options.debug = False
self.cmd.app_args.verbose_level = 0
@mock.patch('tripleoclient.utils.run_ansible_playbook')
def test_network_config(self, mock_run):
roles = [
{'count': 10, 'name': 'Compute'},
{'count': 3, 'name': 'Controller'}
]
utils.run_role_playbooks(self.cmd, self.work_dir, self.work_dir,
roles, True)
self.assertEqual(3, mock_run.call_count)
mock_run.assert_has_calls([
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Compute',
extra_vars={}
),
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Controller',
extra_vars={}
),
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-network-config.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts=None,
extra_vars={}
)
])
@mock.patch('tripleoclient.utils.run_ansible_playbook')
def test_no_network_config(self, mock_run):
roles = [
{'count': 10, 'name': 'Compute'},
{'count': 3, 'name': 'Controller'}
]
utils.run_role_playbooks(self.cmd, self.work_dir, self.work_dir,
roles, False)
self.assertEqual(2, mock_run.call_count)
mock_run.assert_has_calls([
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Compute',
extra_vars={}
),
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Controller',
extra_vars={}
)
])
@mock.patch('tripleoclient.utils.run_ansible_playbook')
def test_override_growvols(self, mock_run):
roles = [
{'count': 10, 'name': 'Compute'},
{
'count': 3,
'name': 'Controller',
'ansible_playbooks': [
{
'playbook': '/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
'extra_vars': {
'growvols_args': '/var=50% /srv=50%'
}
}
]
}
]
utils.run_role_playbooks(self.cmd, self.work_dir, self.work_dir,
roles, False)
self.assertEqual(2, mock_run.call_count)
mock_run.assert_has_calls([
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Compute',
extra_vars={}
),
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Controller',
extra_vars={'growvols_args': '/var=50% /srv=50%'}
)
])
@mock.patch('tripleoclient.utils.run_ansible_playbook')
def test_role_playbooks(self, mock_run):
roles = [
{'count': 10, 'name': 'Compute'},
{
'count': 3,
'name': 'Controller',
'ansible_playbooks': [
{
'playbook': 'the_thing.yaml'
},
{
'playbook': '/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
'extra_vars': {
'growvols_args': '/var=50% /srv=50%'
}
},
{
'playbook': 'the_other_thing.yaml'
},
]
}
]
utils.run_role_playbooks(self.cmd, self.work_dir, self.work_dir,
roles, True)
self.assertEqual(5, mock_run.call_count)
mock_run.assert_has_calls([
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Compute',
extra_vars={}
),
mock.call(
playbook=os.path.join(self.work_dir, 'the_thing.yaml'),
inventory={},
workdir=mock.ANY,
playbook_dir=self.work_dir,
verbosity=0,
limit_hosts='Controller',
extra_vars={}
),
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-growvols.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts='Controller',
extra_vars={'growvols_args': '/var=50% /srv=50%'}
),
mock.call(
playbook=os.path.join(self.work_dir, 'the_other_thing.yaml'),
inventory={},
workdir=mock.ANY,
playbook_dir=self.work_dir,
verbosity=0,
limit_hosts='Controller',
extra_vars={}
),
mock.call(
playbook='/usr/share/ansible/tripleo-playbooks/'
'cli-overcloud-node-network-config.yaml',
inventory={},
workdir=mock.ANY,
playbook_dir='/usr/share/ansible/tripleo-playbooks',
verbosity=0,
limit_hosts=None,
extra_vars={}
)
])
class TestRunCommandAndLog(TestCase):
def setUp(self):
self.mock_logger = mock.Mock(spec=logging.Logger)

View File

@ -103,6 +103,14 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.mock_playbook = playbook_runner.start()
self.addCleanup(playbook_runner.stop)
# Mock role playbooks runner
role_playbooks = mock.patch(
'tripleoclient.utils.run_role_playbooks',
autospec=True
)
self.mock_role_playbooks = role_playbooks.start()
self.addCleanup(role_playbooks.stop)
# Mock horizon url return
horizon_url = mock.patch(
'tripleoclient.workflows.deployment.get_horizon_url',
@ -1537,6 +1545,16 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
workdir=mock.ANY
)
])
self.mock_role_playbooks.assert_called_once_with(
self.cmd,
self.tmp_dir.join('working_dir'),
self.tmp_dir.path,
[
{'count': 10, 'name': 'Compute'},
{'count': 3, 'name': 'Controller'}
],
False
)
def test__provision_networks(self):
networks_file_path = self.tmp_dir.join('networks.yaml')

View File

@ -315,7 +315,9 @@ class TestProvisionNode(fakes.TestOvercloudNode):
@mock.patch('tripleoclient.utils.run_ansible_playbook',
autospec=True)
def test_ok(self, mock_playbook):
@mock.patch('tripleoclient.utils.run_role_playbooks',
autospec=True)
def test_ok(self, mock_role_playbooks, mock_playbook):
with tempfile.NamedTemporaryFile() as inp:
with tempfile.NamedTemporaryFile() as outp:
with tempfile.NamedTemporaryFile() as keyf:
@ -361,6 +363,16 @@ class TestProvisionNode(fakes.TestOvercloudNode):
verbosity=mock.ANY,
workdir=mock.ANY
)
mock_role_playbooks.assert_called_once_with(
self.cmd,
mock.ANY,
'/tmp',
[
{'name': 'Compute'},
{'name': 'Controller'}
],
False
)
class TestUnprovisionNode(fakes.TestOvercloudNode):

View File

@ -2851,7 +2851,7 @@ def validate_roles_playbooks(roles_file_dir, roles):
def run_role_playbook(self, inventory, relative_dir, playbook,
limit_hosts=None, extra_vars=dict()):
playbook_path = rel_or_abs_path_role_playbook(relative_dir, playbook)
playbook_dir = os.path.basename(playbook_path)
playbook_dir = os.path.dirname(playbook_path)
with TempDirs() as tmp:
run_ansible_playbook(
@ -2865,19 +2865,36 @@ def run_role_playbook(self, inventory, relative_dir, playbook,
)
def run_role_playbooks(self, working_dir, roles_file_dir, roles):
def run_role_playbooks(self, working_dir, roles_file_dir, roles,
network_config=True):
inventory_file = os.path.join(working_dir,
'tripleo-ansible-inventory.yaml')
with open(inventory_file, 'r') as f:
inventory = yaml.safe_load(f.read())
growvols_play = 'cli-overcloud-node-growvols.yaml'
growvols_path = rel_or_abs_path_role_playbook(
constants.ANSIBLE_TRIPLEO_PLAYBOOKS, growvols_play)
# Pre-Network Config
for role in roles:
role_playbooks = []
for x in role.get('ansible_playbooks', []):
role_playbooks.append(x['playbook'])
run_role_playbook(self, inventory, roles_file_dir, x['playbook'],
limit_hosts=role['name'],
extra_vars=x.get('extra_vars', {}))
if growvols_path not in role_playbooks:
# growvols was not run with custom extra_vars, run it with defaults
run_role_playbook(self, inventory,
constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
growvols_play,
limit_hosts=role['name'])
if network_config:
# Network Config
run_role_playbook(self, inventory, constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
'cli-overcloud-node-network-config.yaml')

View File

@ -465,9 +465,8 @@ class DeployOvercloud(command.Command):
verbosity=utils.playbook_verbosity(self=self),
extra_vars=extra_vars,
)
if parsed_args.network_config:
utils.run_role_playbooks(self, self.working_dir, roles_file_dir,
roles)
roles, parsed_args.network_config)
return [output_path]

View File

@ -326,10 +326,8 @@ class ProvisionNode(command.Command):
verbosity=oooutils.playbook_verbosity(self=self),
extra_vars=extra_vars,
)
if parsed_args.network_config:
oooutils.run_role_playbooks(self, working_dir, roles_file_dir,
roles)
roles, parsed_args.network_config)
print('Nodes deployed successfully, add %s to your deployment '
'environment' % parsed_args.output)