Merge "container_status: "exec" checks status" into stable/train

This commit is contained in:
Zuul 2020-07-15 15:55:48 +00:00 committed by Gerrit Code Review
commit 8c36dc03c3
3 changed files with 63 additions and 61 deletions

View File

@ -137,26 +137,33 @@ class ActionModule(ActionBase):
:param data: Dictionary of container data. :param data: Dictionary of container data.
:returns: List of containers that need to be checked. :returns: List of containers that need to be checked.
""" """
containers = [] containers_exec = []
containers_run = []
# loop through container data to get specific container # loop through container data to get specific container
for container in data: for container in data:
# get container name and data # get container name and data
for name, values in container.items(): for name, values in container.items():
if 'action' in values or 'restart' in values: if 'restart' in values:
continue continue
if 'action' in values:
containers_exec.append(name)
if 'image' in values: if 'image' in values:
# We assume that container configs that don't have a # We assume that container configs that don't have a
# restart policy nor action (used for podman exec) but have # restart policy nor action (used for podman exec) but have
# an image set, will run something and then exit with a # an image set, will run something and then exit with a
# return code. # return code.
containers.append(name) containers_run.append(name)
if self.debug and len(containers) > 0: if self.debug and len(containers_run) > 0:
DISPLAY.display('These containers are supposed to terminate with ' DISPLAY.display('These containers are supposed to terminate with '
'a valid exit code and will be checked: ' 'a valid exit code and will be checked: '
'{}'.format(containers)) '{}'.format(containers_run))
return containers if self.debug and len(containers_exec) > 0:
DISPLAY.display('These containers exec are supposed to terminate '
'with a valid exit code and will be checked: '
'{}'.format(containers_exec))
return containers_run
def _get_create_commands(self, results): def _get_commands(self, results):
"""Return a list of commands that were executed by container tool. """Return a list of commands that were executed by container tool.
:param results: Ansible task results. :param results: Ansible task results.
@ -164,8 +171,16 @@ class ActionModule(ActionBase):
""" """
commands = [] commands = []
for item in results: for item in results:
if item['changed']: try:
commands.extend(item['podman_actions']) if item['changed']:
commands.extend(item['podman_actions'])
except KeyError:
if 'cmd' in item:
commands.append(' '.join(item['cmd']))
else:
raise AnsibleActionFail('Wrong async result data, missing'
' podman_actions or cmd:'
' {}'.format(item))
return commands return commands
def _is_container_running(self, container): def _is_container_running(self, container):
@ -248,22 +263,29 @@ class ActionModule(ActionBase):
:returns: Tuple of containers that changed or failed :returns: Tuple of containers that changed or failed
""" """
changed = [] changed = []
failed = [] create_failed = []
exec_failed = []
for item in results: for item in results:
# if Ansible is run in check mode, the async_results items will # if Ansible is run in check mode, the async_results items will
# not contain failed or finished keys. # not contain failed or finished keys.
if self._play_context.check_mode: if self._play_context.check_mode:
break break
async_result_item = item['create_async_result_item'] if 'create_async_result_item' in item:
if item['changed']: async_item = item['create_async_result_item']
for name, c in async_result_item['container_data'].items(): if item['changed']:
changed.append(name) for name, c in async_item['container_data'].items():
if (item['failed'] or not item['finished'] changed.append(name)
or ('stderr' in async_result_item if (item['failed'] or not item['finished']
and async_result_item['stderr'] != '')): or ('stderr' in async_item
for name, c in async_result_item['container_data'].items(): and async_item['stderr'] != '')):
failed.append(name) for name, c in async_item['container_data'].items():
return (changed, failed) create_failed.append(name)
if 'exec_async_result_item' in item:
async_item = item['exec_async_result_item']
if item['rc'] != 0:
for name, c in async_item['container_exec_data'].items():
exec_failed.append(name)
return (changed, create_failed, exec_failed)
def run(self, tmp=None, task_vars=None): def run(self, tmp=None, task_vars=None):
self._supports_check_mode = True self._supports_check_mode = True
@ -285,13 +307,13 @@ class ActionModule(ActionBase):
valid_exit_codes = args['valid_exit_codes'] valid_exit_codes = args['valid_exit_codes']
self.debug = args['debug'] self.debug = args['debug']
containers_to_check = self._get_containers_to_check(container_data) containers_run_to_check = self._get_containers_to_check(container_data)
# Check that the containers which are supposed to finish have # Check that the containers which are supposed to finish have
# actually finished and also terminated with the right exit code. # actually finished and also terminated with the right exit code.
if len(valid_exit_codes) > 0 and len(containers_to_check) > 0: if len(valid_exit_codes) > 0 and len(containers_run_to_check) > 0:
(running, failed) = self._check_container_state( (running, failed) = self._check_container_state(
containers_to_check, containers_run_to_check,
valid_exit_codes, valid_exit_codes,
task_vars) task_vars)
@ -301,9 +323,12 @@ class ActionModule(ActionBase):
# - reported a failed resource (podman_container failed to create # - reported a failed resource (podman_container failed to create
# the container and return it as self.failed_containers. # the container and return it as self.failed_containers.
# - didn't finish on time and return it as self.failed_containers. # - didn't finish on time and return it as self.failed_containers.
(self.changed_containers, async_failed) = ( (self.changed_containers, async_failed, exec_failed) = (
self._check_errors_in_ansible_async_results(async_results)) self._check_errors_in_ansible_async_results(async_results))
if len(exec_failed) > 0:
DISPLAY.error('Container(s) exec commands which failed to execute'
': {}'.format(failed))
if len(failed) > 0: if len(failed) > 0:
DISPLAY.error('Container(s) which finished with wrong return code' DISPLAY.error('Container(s) which finished with wrong return code'
': {}'.format(failed)) ': {}'.format(failed))
@ -313,13 +338,13 @@ class ActionModule(ActionBase):
if len(running) > 0: if len(running) > 0:
DISPLAY.error('Container(s) which did not finish after {} ' DISPLAY.error('Container(s) which did not finish after {} '
'minutes: {}'.format(TIMEOUT, running)) 'minutes: {}'.format(TIMEOUT, running))
total_errors = list(set(failed + async_failed + running)) total_errors = list(set(failed + exec_failed + async_failed + running))
if len(total_errors) > 0: if len(total_errors) > 0:
raise AnsibleActionFail('Failed container(s): {}, check logs in ' raise AnsibleActionFail('Failed container(s): {}, check logs in '
'/var/log/containers/' '/var/log/containers/'
'stdouts/'.format(total_errors)) 'stdouts/'.format(total_errors))
container_commands = self._get_create_commands(async_results) container_commands = self._get_commands(async_results)
if len(container_commands) > 0 and \ if len(container_commands) > 0 and \
(self._play_context.check_mode or self.debug): (self._play_context.check_mode or self.debug):
for cmd in container_commands: for cmd in container_commands:

View File

@ -45,9 +45,19 @@
register: exec_async_poll_results register: exec_async_poll_results
until: exec_async_poll_results.finished until: exec_async_poll_results.finished
retries: "{{ tripleo_container_manage_exec_retries }}" retries: "{{ tripleo_container_manage_exec_retries }}"
# We fail later if a container failed to execute the command
failed_when: false
when: not ansible_check_mode|bool when: not ansible_check_mode|bool
- name: Block for container commands - name: Check container exec status
include_tasks: podman/get_commands_exec.yml container_status:
container_async_results: "{{ exec_async_poll_results.results }}"
container_data: "{{ batched_container_data | haskey(attribute='action', value='exec') }}"
debug: "{{ tripleo_container_manage_debug | bool }}"
register: container_exec_status_results
- name: "Append the list of all podman commands with the containers execs"
set_fact:
all_containers_commands: "{{ container_status_results.commands | default([]) + (all_containers_commands | default([]) | list) }}"
when: when:
- ansible_check_mode|bool - ansible_check_mode|bool

View File

@ -1,33 +0,0 @@
---
# Copyright 2020 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: "Create a list of podman exec commands that are run"
no_log: "{{ not tripleo_container_manage_debug }}"
set_fact:
containers_commands: >-
{{ (containers_commands | default([])) + ([lookup('dict', container_exec_data).value |
container_exec_cmd(cli=tripleo_container_manage_cli) | join(' ')]) }}
loop: "{{ batched_container_data | haskey(attribute='action', value='exec') }}"
loop_control:
loop_var: container_exec_data
- name: "Print the list of podman exec commands that are run"
debug:
var: containers_commands
- name: "Append the list of all podman commands that are run for containers with changes"
set_fact:
all_containers_commands: "{{ containers_commands|default([], true) + (all_containers_commands | default([]) | list) }}"