Merge "Add ability to get stopped container's facts"

This commit is contained in:
Zuul
2025-10-07 18:03:00 +00:00
committed by Gerrit Code Review
2 changed files with 74 additions and 16 deletions

View File

@@ -20,10 +20,10 @@ from traceback import format_exc
DOCUMENTATION = ''' DOCUMENTATION = '''
--- ---
module: kolla_container_facts module: kolla_container_facts
short_description: Module for collecting Docker container facts short_description: Module for collecting container facts
description: description:
- A module targeting at collecting Docker container facts. It is used for - A module targeted at collecting container facts. It is used for
detecting whether the container is running on host in Kolla. retrieving data about containers like their environment or state.
options: options:
container_engine: container_engine:
description: description:
@@ -32,7 +32,7 @@ options:
type: str type: str
api_version: api_version:
description: description:
- The version of the api for docker-py to use when contacting docker - The version of the API for container SDK to use
required: False required: False
type: str type: str
default: auto default: auto
@@ -44,18 +44,45 @@ options:
action: action:
description: description:
- The action to perform - The action to perform
- The action "get_containers" only returns running containers, unless
argument get_all_containers is True
required: True required: True
type: str type: str
author: Jeffrey Zhang, Michal Nasiadka, Ivan Halomi choices:
- get_containers
- get_container_env
- get_container_state
args:
description:
- Additional arguments for actions
required: False
type: dict
elements: dict
suboptions:
get_all_containers:
description:
- Get all containers, even stopped containers when
performing action "get_containers"
type: bool
required: False
default: False
author: Jeffrey Zhang, Michal Nasiadka, Roman Krček, Ivan Halomi
''' '''
EXAMPLES = ''' EXAMPLES = '''
- hosts: all - hosts: all
tasks: tasks:
- name: Gather docker facts - name: Gather docker facts for running containers
kolla_container_facts: kolla_container_facts:
container_engine: docker container_engine: docker
action: get_containers action: get_containers
- name: Gather docker facts for all containers
kolla_container_facts:
container_engine: docker
action: get_containers
args:
get_all_containers: true
- name: Gather glance container facts - name: Gather glance container facts
kolla_container_facts: kolla_container_facts:
@@ -136,9 +163,11 @@ class ContainerFactsWorker():
def get_containers(self): def get_containers(self):
"""Handle when module is called with action get_containers""" """Handle when module is called with action get_containers"""
names = self.params.get('name') names = self.params.get('name')
args = self.params.get('args', {})
get_all_containers = args.get('get_all_containers', False)
self.result['containers'] = dict() self.result['containers'] = dict()
containers = self.client.containers.list() containers = self.client.containers.list(all=get_all_containers)
for container in containers: for container in containers:
container.reload() container.reload()
container_name = container.name container_name = container.name
@@ -226,9 +255,19 @@ def main():
action=dict(required=True, type='str', action=dict(required=True, type='str',
choices=['get_containers', choices=['get_containers',
'get_containers_env', 'get_containers_env',
'get_containers_state', 'get_volumes',
'get_containers_names', 'get_containers_names',
'get_volumes']), 'get_containers_state']),
args=dict(
type='dict',
required=False,
default={},
options=dict(
get_all_containers=dict(required=False,
type='bool',
default=False)
)
)
) )
required_if = [ required_if = [

View File

@@ -109,7 +109,7 @@ def contruct_volume(vol_dict: dict) -> mock.Mock:
return volume return volume
def get_containers(override=None): def get_containers(override=None, all: bool = False):
if override: if override:
cont_dicts = override cont_dicts = override
else: else:
@@ -117,9 +117,11 @@ def get_containers(override=None):
containers = [] containers = []
for c in cont_dicts: for c in cont_dicts:
# Only running containers should be returned by the container APIs # With the option "all", only running containers are returned
if c['State']['Status'] == 'running': # by the container API
containers.append(construct_container(c)) if not all and c['State']['Status'] != 'running':
continue
containers.append(construct_container(c))
return containers return containers
@@ -152,8 +154,9 @@ class TestContainerFacts(base.BaseTestCase):
self.assertDictEqual( self.assertDictEqual(
self.fake_data['containers'][0], self.fake_data['containers'][0],
self.dfw.result['containers']['my_container']) self.dfw.result['containers']['my_container'])
self.dfw.client.containers.list.assert_called_once_with(all=False)
def test_get_container_multi(self): def test_get_containers_multi(self):
self.dfw = get_DockerFactsWorker( self.dfw = get_DockerFactsWorker(
{'name': ['my_container', 'exited_container'], {'name': ['my_container', 'exited_container'],
'action': 'get_containers'}) 'action': 'get_containers'})
@@ -165,8 +168,9 @@ class TestContainerFacts(base.BaseTestCase):
self.assertIn('my_container', self.dfw.result['containers']) self.assertIn('my_container', self.dfw.result['containers'])
self.assertNotIn('my_container', self.dfw.result) self.assertNotIn('my_container', self.dfw.result)
self.assertNotIn('exited_container', self.dfw.result['containers']) self.assertNotIn('exited_container', self.dfw.result['containers'])
self.dfw.client.containers.list.assert_called_once_with(all=False)
def test_get_container_all(self): def test_get_containers_all_running(self):
self.dfw = get_DockerFactsWorker({'name': [], self.dfw = get_DockerFactsWorker({'name': [],
'action': 'get_containers'}) 'action': 'get_containers'})
running_containers = get_containers(self.fake_data['containers']) running_containers = get_containers(self.fake_data['containers'])
@@ -177,6 +181,21 @@ class TestContainerFacts(base.BaseTestCase):
self.assertIn('my_container', self.dfw.result['containers']) self.assertIn('my_container', self.dfw.result['containers'])
self.assertNotIn('my_container', self.dfw.result) self.assertNotIn('my_container', self.dfw.result)
self.assertNotIn('exited_container', self.dfw.result['containers']) self.assertNotIn('exited_container', self.dfw.result['containers'])
self.dfw.client.containers.list.assert_called_once_with(all=False)
def test_get_containers_all_including_stopped(self):
self.dfw = get_DockerFactsWorker({'name': [],
'action': 'get_containers',
'args': {
'get_all_containers': True}})
all_containers = get_containers(self.fake_data['containers'], all=True)
self.dfw.client.containers.list.return_value = all_containers
self.dfw.get_containers()
self.assertFalse(self.dfw.result['changed'])
self.assertIn('my_container', self.dfw.result['containers'])
self.assertIn('exited_container', self.dfw.result['containers'])
self.dfw.client.containers.list.assert_called_once_with(all=True)
def test_get_containers_env(self): def test_get_containers_env(self):
fake_env = dict(KOLLA_BASE_DISTRO='ubuntu', fake_env = dict(KOLLA_BASE_DISTRO='ubuntu',