Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions ansible/library/kolla_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@
- compare_image
- create_volume
- ensure_image
- get_container_env
- get_container_state
- pull_image
- remove_container
- remove_image
Expand Down Expand Up @@ -276,8 +274,6 @@ def generate_module():
'compare_image',
'create_volume',
'ensure_image',
'get_container_env',
'get_container_state',
'pull_image',
'recreate_or_restart_container',
'remove_container',
Expand Down Expand Up @@ -344,8 +340,6 @@ def generate_module():
['action', 'compare_image', ['name']],
['action', 'create_volume', ['name']],
['action', 'ensure_image', ['image']],
['action', 'get_container_env', ['name']],
['action', 'get_container_state', ['name']],
['action', 'recreate_or_restart_container', ['name']],
['action', 'remove_container', ['name']],
['action', 'remove_image', ['image']],
Expand Down
152 changes: 100 additions & 52 deletions ansible/library/kolla_container_facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from abc import ABC
from abc import abstractmethod
from ansible.module_utils.basic import AnsibleModule
from traceback import format_exc

Expand Down Expand Up @@ -63,47 +61,106 @@
container_engine: docker
name:
- glance_api
- glance_registry
container_engine: podman
action: get_containers

- name: Get Horizon container state
kolla_container_facts:
container_engine: podman
name: horizon
action: get_containers_state

- name: Get Glance container environment
kolla_container_facts:
container_engine: docker
name:
- glance_api
action: get_containers_env
'''


class ContainerFactsWorker(ABC):
class ContainerFactsWorker():
def __init__(self, module):
self.module = module
self.results = dict(changed=False, _containers=[])
self.params = module.params
self.result = dict(changed=False)

def _get_container_info(self, name: str) -> dict:
"""Return info about container if it exists."""
try:
cont = self.client.containers.get(name)
return cont.attrs
except self.containerError.NotFound:
self.module.fail_json(msg="No such container: {}".format(name))
return None

def _remap_envs(self, envs_raw: list) -> dict:
"""Split list of environment variables separated by '=' to dict.

Example item in list could be KOLLA_BASE_DISTRO=ubuntu, which
would breakdown to {'KOLLA_BASE_DISTRO':'ubuntu'}
"""
envs = dict()
for env in envs_raw:
if '=' in env:
key, value = env.split('=', 1)
else:
key, value = env, ''
envs[key] = value
return envs

@abstractmethod
def get_containers(self):
pass
"""Handle when module is called with action get_containers"""
names = self.params.get('name')
self.result['containers'] = dict()

containers = self.client.containers.list()
for container in containers:
container.reload()
container_name = container.name
if names and container_name not in names:
continue
self.result['containers'][container_name] = container.attrs

def get_containers_state(self):
"""Handle when module is called with action get_containers_state"""
# NOTE(r-krcek): This function can be removed when bifrost and swift
# roles switch to modern format
names = self.params.get('name')
self.result['states'] = dict()

for name in names:
cont = self._get_container_info(name)
if cont:
self.result['states'][name] = cont["State"]["Status"]

def get_containers_env(self):
"""Handle when module is called with action get_containers_state"""
# NOTE(r-krcek): This function can be removed when bifrost and swift
# roles switch to modern format
names = self.params.get('name')
self.result['envs'] = dict()

for name in names:
cont = self._get_container_info(name)
if cont:
envs = self._remap_envs(cont['Config']['Env'])
self.result['envs'][name] = envs


class DockerFactsWorker(ContainerFactsWorker):
def __init__(self, module):
super().__init__(module)
try:
import docker
import docker.errors as dockerError
except ImportError:
self.module.fail_json(
msg="The docker library could not be imported")
self.client = docker.APIClient(version=module.params.get(
'api_version'))

def get_containers(self):
containers = self.client.containers()
names = self.params.get('name')
if names and not isinstance(names, list):
names = [names]
for container in containers:
for container_name in container['Names']:
# remove '/' prefix character
container_name = container_name[1:]
if names and container_name not in names:
continue
self.results['_containers'].append(container)
self.results[container_name] = container
super().__init__(module)
self.client = docker.DockerClient(
base_url='http+unix:/var/run/docker.sock',
version=module.params.get('api_version'))
self.containerError = dockerError


class PodmanFactsWorker(ContainerFactsWorker):
Expand All @@ -114,29 +171,10 @@ def __init__(self, module):
except ImportError:
self.module.fail_json(
msg="The podman library could not be imported")
self.podmanError = podmanError
super().__init__(module)
self.client = PodmanClient(
base_url="http+unix:/run/podman/podman.sock")

def get_containers(self):
try:
containers = self.client.containers.list(
all=True, ignore_removed=True)
except self.podmanError.APIError as e:
self.module.fail_json(failed=True,
msg=f"Internal error: {e.explanation}")
names = self.params.get('name')
if names and not isinstance(names, list):
names = [names]

for container in containers:
container.reload()
container_name = container.attrs['Name']
if container_name not in names:
continue
self.results['_containers'].append(container.attrs)
self.results[container_name] = container.attrs
self.containerError = podmanError


def main():
Expand All @@ -145,23 +183,33 @@ def main():
api_version=dict(required=False, type='str', default='auto'),
container_engine=dict(required=True, type='str'),
action=dict(required=True, type='str',
choices=['get_containers']),
choices=['get_containers',
'get_containers_env',
'get_containers_state']),
)

module = AnsibleModule(argument_spec=argument_spec)
required_if = [
['action', 'get_containers_env', ['name']],
['action', 'get_containers_state', ['name']],
]
module = AnsibleModule(
argument_spec=argument_spec,
required_if=required_if,
bypass_checks=False
)

cw: ContainerFactsWorker = None
cfw: ContainerFactsWorker = None
try:
if module.params.get('container_engine') == 'docker':
cw = DockerFactsWorker(module)
cfw = DockerFactsWorker(module)
else:
cw = PodmanFactsWorker(module)
cfw = PodmanFactsWorker(module)

result = bool(getattr(cw, module.params.get('action'))())
module.exit_json(result=result, **cw.results)
result = bool(getattr(cfw, module.params.get('action'))())
module.exit_json(result=result, **cfw.result)
except Exception:
module.fail_json(changed=True, msg=repr(format_exc()),
**getattr(cw, 'result', {}))
**getattr(cfw, 'result', {}))


if __name__ == "__main__":
Expand Down
24 changes: 0 additions & 24 deletions ansible/module_utils/kolla_container_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,30 +449,6 @@ def recreate_or_restart_container(self):
def start_container(self):
pass

def get_container_env(self):
name = self.params.get('name')
info = self.get_container_info()
if not info:
self.module.fail_json(msg="No such container: {}".format(name))
else:
envs = dict()
for env in info['Config']['Env']:
if '=' in env:
key, value = env.split('=', 1)
else:
key, value = env, ''
envs[key] = value

self.module.exit_json(**envs)

def get_container_state(self):
name = self.params.get('name')
info = self.get_container_info()
if not info:
self.module.fail_json(msg="No such container: {}".format(name))
else:
self.module.exit_json(**info['State'])

def parse_healthcheck(self, healthcheck):
if not healthcheck:
return None
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/aodh/tasks/precheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
timeout: 1
state: stopped
when:
- container_facts['aodh_api'] is not defined
- container_facts.containers['aodh_api'] is not defined
- inventory_hostname in groups['aodh-api']
2 changes: 0 additions & 2 deletions ansible/roles/aodh/templates/aodh.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,5 @@ amqp_durable_queues = true
rabbit_quorum_queue = true
{% endif %}

{% if om_enable_queue_manager | bool %}
[oslo_concurrency]
lock_path = /var/lib/aodh/tmp
{% endif %}
2 changes: 1 addition & 1 deletion ansible/roles/barbican/tasks/precheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
timeout: 1
state: stopped
when:
- container_facts['barbican_api'] is not defined
- container_facts.containers['barbican_api'] is not defined
- inventory_hostname in groups['barbican-api']
2 changes: 0 additions & 2 deletions ansible/roles/barbican/templates/barbican.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,5 @@ enable_proxy_headers_parsing = True
policy_file = {{ barbican_policy_file }}
{% endif %}

{% if om_enable_queue_manager | bool %}
[oslo_concurrency]
lock_path = /var/lib/barbican/tmp
{% endif %}
28 changes: 17 additions & 11 deletions ansible/roles/bifrost/tasks/reconfigure.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
- name: Ensuring the containers up
become: true
kolla_container:
common_options: "{{ docker_common_options }}"
kolla_container_facts:
name: "{{ item.name }}"
action: "get_container_state"
action: "get_containers_state"
container_engine: "{{ kolla_container_engine }}"
register: container_state
failed_when: not container_state.Running
failed_when: container_state.states[item.name] != "running"
when: inventory_hostname in groups[item.group]
with_items:
- { name: bifrost-deploy, group: bifrost-deploy }
Expand All @@ -28,25 +28,28 @@
# just remove the container and start again
- name: Containers config strategy
become: true
kolla_container:
common_options: "{{ docker_common_options }}"
kolla_container_facts:
name: "{{ item.name }}"
action: "get_container_env"
action: "get_containers_env"
container_engine: "{{ kolla_container_engine }}"
register: container_envs
when: inventory_hostname in groups[item.group]
with_items:
- { name: bifrost-deploy, group: bifrost-deploy }

- name: Remove the containers
become: true
vars:
container_name: "{{ item[0]['name'] }}"
container_config_strategy: "{{ item[1].envs[container_name] }}"
kolla_container:
common_options: "{{ docker_common_options }}"
name: "{{ item[0]['name'] }}"
name: "{{ container_name }}"
action: "remove_container"
register: remove_containers
when:
- inventory_hostname in groups[item[0]['group']]
- config_strategy == "COPY_ONCE" or item[1]['KOLLA_CONFIG_STRATEGY'] == 'COPY_ONCE'
- config_strategy == "COPY_ONCE" or container_config_strategy == 'COPY_ONCE'
- item[2]['rc'] == 1
with_together:
- [{ name: bifrost-deploy, group: bifrost-deploy }]
Expand All @@ -58,14 +61,17 @@

- name: Restart containers
become: true
vars:
container_name: "{{ item[0]['name'] }}"
container_config_strategy: "{{ item[1].envs[container_name] }}"
kolla_container:
common_options: "{{ docker_common_options }}"
name: "{{ item[0]['name'] }}"
name: "{{ container_name }}"
action: "restart_container"
when:
- inventory_hostname in groups[item[0]['group']]
- config_strategy == 'COPY_ALWAYS'
- item[1]['KOLLA_CONFIG_STRATEGY'] != 'COPY_ONCE'
- container_config_strategy != 'COPY_ONCE'
- item[2]['rc'] == 1
with_together:
- [{ name: bifrost-deploy, group: bifrost-deploy }]
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/bifrost/tasks/stop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
common_options: "{{ docker_common_options }}"
name: "bifrost_deploy"

when: "'bifrost_deploy' in container_facts"
when: "container_facts.containers['bifrost_deploy'] is defined"

when:
- inventory_hostname in groups['bifrost']
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/blazar/tasks/precheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
timeout: 1
state: stopped
when:
- container_facts['blazar_api'] is not defined
- container_facts.containers['blazar_api'] is not defined
- inventory_hostname in groups['blazar-api']
2 changes: 0 additions & 2 deletions ansible/roles/blazar/templates/blazar.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,5 @@ rabbit_quorum_queue = true
policy_file = {{ blazar_policy_file }}
{% endif %}

{% if om_enable_queue_manager | bool %}
[oslo_concurrency]
lock_path = /var/lib/blazar/tmp
{% endif %}
Loading