Browse Source

Use filter for containers not running check

Rather than using ansible task loops which increase the time to execute,
this change creates a filter that is used to assert that the containers
used in execs are running before we run the execs

Change-Id: I5e15cc71c45160109f5c303c13dd25a052ede3c3
(cherry picked from commit 2232a27ffb)
changes/39/738439/1
Alex Schultz 2 weeks ago
committed by Emilien Macchi
parent
commit
68784620ef
4 changed files with 113 additions and 29 deletions
  1. +39
    -0
      tripleo_ansible/ansible_plugins/filter/helpers.py
  2. +0
    -25
      tripleo_ansible/roles/tripleo-container-manage/tasks/container_running.yml
  3. +6
    -4
      tripleo_ansible/roles/tripleo-container-manage/tasks/podman/exec.yml
  4. +68
    -0
      tripleo_ansible/tests/plugins/filter/test_helpers.py

+ 39
- 0
tripleo_ansible/ansible_plugins/filter/helpers.py View File

@@ -38,6 +38,7 @@ class FilterModule(object):
'haskey': self.haskey,
'list_of_keys': self.list_of_keys,
'container_exec_cmd': self.container_exec_cmd,
'containers_not_running': self.containers_not_running,
'get_key_from_dict': self.get_key_from_dict,
'get_role_assignments': self.get_role_assignments,
'get_domain_id': self.get_domain_id,
@@ -330,6 +331,44 @@ class FilterModule(object):
cmd.extend(data['command'])
return cmd

def containers_not_running(self, container_info, execs=[]):
"""Check if specified services aren't running

:params: container_info: containers list from podman_container_info
result
:params: execs: list of dicts for container actions
"""
not_running = []
expected_containers = set()

# Get the container out of any execs by extracting the container
# out of the command to be executed
#
# NOTE this could be written as:
# [v.get('command')[0]
# for i in self.haskey(execs, attribute='action', value='exec')
# for k, v in i.items()]
# But this won't handle missing command. I'm uncertain if we ever would
# pass in an exec without an action but the code below won't blow up
# if command is missing
for action in self.haskey(execs, attribute='action', value='exec'):
for k, v in action.items():
command = v.get('command')
if command and len(command) > 0:
expected_containers.add(command[0])

# we don't have any containers we're checking so just stop
if len(expected_containers) == 0:
return []

# check running containers against exec containers
for container in container_info:
container_name = container.get('Name')
if (container_name in expected_containers
and not container.get('State', {}).get('Running')):
not_running.append(container_name)
return not_running

def get_role_assignments(self, data, default_role='admin',
default_project='service'):
"""Return a dict of all roles and their users.


+ 0
- 25
tripleo_ansible/roles/tripleo-container-manage/tasks/container_running.yml View File

@@ -1,25 +0,0 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
- name: "Assert that {{ lookup('dict', container_exists_data).value.command.0 }} is running before exec"
assert:
that:
- podman_containers.containers | selectattr('Name', 'equalto', lookup('dict', container_exists_data).value.command.0) |
map(attribute='State.Running') | first | default(false)
fail_msg: >-
Can't run container exec for {{ lookup('dict', container_exists_data).key }},
{{ lookup('dict', container_exists_data).value.command.0 }} is not running
success_msg: "{{ lookup('dict', container_exists_data).value.command.0 }} is running"

+ 6
- 4
tripleo_ansible/roles/tripleo-container-manage/tasks/podman/exec.yml View File

@@ -15,10 +15,12 @@
# under the License.

- name: "Check if containers are running before doing exec"
include_tasks: container_running.yml
loop: "{{ batched_container_data | haskey(attribute='action', value='exec') }}"
loop_control:
loop_var: container_exists_data
assert:
that:
- (podman_containers.containers | containers_not_running(execs=batched_container_data) | length) == 0
fail_msg: >-
Can't run container exec as the following containers are not running:
{{ podman_containers.containers | containers_not_running(execs=batched_container_data) | join(', ') }}
when: not ansible_check_mode|bool

- name: "Async container exec"


+ 68
- 0
tripleo_ansible/tests/plugins/filter/test_helpers.py View File

@@ -816,6 +816,74 @@ class TestHelperFilters(tests_base.TestCase):
result = self.filters.container_exec_cmd(data=data)
self.assertEqual(result, expected_cmd)

def test_containers_not_running(self):
results = [
{
"Name": "keystone",
"State": {"Running": False}
},
{
"Name": "neutron",
"State": {"Running": True}
}
]
commands = [{
"keystone_bootstrap": {
"action": "exec",
"command": [
"keystone",
"/usr/bin/bootstrap_host_exec",
"keystone",
"keystone-manage",
"bootstrap"
]
},
"neutron_bootstrap": {
"action": "exec",
"command": [
"neutron",
"/usr/bin/bootstrap_host_exec",
"neutron",
"neutron-manage",
"bootstrap"
]
}
}]

expected = ['keystone']
actual = self.filters.containers_not_running(results, commands)
self.assertEqual(actual, expected)

def test_containers_not_running_missing_command(self):
results = [
{
"Name": "keystone",
"State": {"Running": True}
},
{
"Name": "neutron",
"State": {"Running": True}
}
]
commands = [{
"keystone_bootstrap": {
"action": "exec",
"command": [
"keystone",
"/usr/bin/bootstrap_host_exec",
"keystone",
"keystone-manage",
"bootstrap"
]
},
"neutron_bootstrap": {
"action": "exec",
}
}]
expected = []
actual = self.filters.containers_not_running(results, commands)
self.assertEqual(actual, expected)

def test_get_role_assignments(self):
data = [{
'nova': {


Loading…
Cancel
Save