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
)
This commit is contained in:
parent
2d1a48b505
commit
68784620ef
|
@ -38,6 +38,7 @@ class FilterModule(object):
|
||||||
'haskey': self.haskey,
|
'haskey': self.haskey,
|
||||||
'list_of_keys': self.list_of_keys,
|
'list_of_keys': self.list_of_keys,
|
||||||
'container_exec_cmd': self.container_exec_cmd,
|
'container_exec_cmd': self.container_exec_cmd,
|
||||||
|
'containers_not_running': self.containers_not_running,
|
||||||
'get_key_from_dict': self.get_key_from_dict,
|
'get_key_from_dict': self.get_key_from_dict,
|
||||||
'get_role_assignments': self.get_role_assignments,
|
'get_role_assignments': self.get_role_assignments,
|
||||||
'get_domain_id': self.get_domain_id,
|
'get_domain_id': self.get_domain_id,
|
||||||
|
@ -330,6 +331,44 @@ class FilterModule(object):
|
||||||
cmd.extend(data['command'])
|
cmd.extend(data['command'])
|
||||||
return cmd
|
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',
|
def get_role_assignments(self, data, default_role='admin',
|
||||||
default_project='service'):
|
default_project='service'):
|
||||||
"""Return a dict of all roles and their users.
|
"""Return a dict of all roles and their users.
|
||||||
|
|
|
@ -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"
|
|
|
@ -15,10 +15,12 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
- name: "Check if containers are running before doing exec"
|
- name: "Check if containers are running before doing exec"
|
||||||
include_tasks: container_running.yml
|
assert:
|
||||||
loop: "{{ batched_container_data | haskey(attribute='action', value='exec') }}"
|
that:
|
||||||
loop_control:
|
- (podman_containers.containers | containers_not_running(execs=batched_container_data) | length) == 0
|
||||||
loop_var: container_exists_data
|
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
|
when: not ansible_check_mode|bool
|
||||||
|
|
||||||
- name: "Async container exec"
|
- name: "Async container exec"
|
||||||
|
|
|
@ -816,6 +816,74 @@ class TestHelperFilters(tests_base.TestCase):
|
||||||
result = self.filters.container_exec_cmd(data=data)
|
result = self.filters.container_exec_cmd(data=data)
|
||||||
self.assertEqual(result, expected_cmd)
|
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):
|
def test_get_role_assignments(self):
|
||||||
data = [{
|
data = [{
|
||||||
'nova': {
|
'nova': {
|
||||||
|
|
Loading…
Reference in New Issue