TripleO Ansible project repository. Contains playbooks for use with TripleO OpenStack deployments.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
7.2KB

  1. # Copyright 2019 Red Hat, Inc.
  2. # All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. from __future__ import absolute_import
  16. from __future__ import division
  17. from __future__ import print_function
  18. __metaclass__ = type
  19. from ansible.module_utils.basic import AnsibleModule
  20. import json
  21. import os
  22. import paunch as p
  23. import re
  24. import yaml
  25. from paunch import runner as prunner
  26. from paunch.builder import compose1 as pcompose1
  27. from paunch.builder import podman as ppodman
  28. from paunch.utils import common as putils_common
  29. ANSIBLE_METADATA = {
  30. 'metadata_version': '1.0',
  31. 'status': ['preview'],
  32. 'supported_by': 'community'
  33. }
  34. DOCUMENTATION = """
  35. ---
  36. module: paunch
  37. author:
  38. - OpenStack TripleO Contributors
  39. version_added: '1.0'
  40. short_description: Manage containers with Paunch
  41. notes: []
  42. requirements:
  43. - "paunch module"
  44. - "podman or docker"
  45. description:
  46. - Start or stop containers with Paunch
  47. options:
  48. config:
  49. description:
  50. - JSON file or directory of JSON files containing configuration data
  51. config_id:
  52. description:
  53. - ID to assign to containers
  54. required: True
  55. type: list
  56. action:
  57. description:
  58. - The desired action to apply for the container.
  59. default: apply
  60. choices:
  61. - apply
  62. - cleanup
  63. config_overrides:
  64. description:
  65. - Dictionary to override containers configs
  66. default: {}
  67. type: dict
  68. container_cli:
  69. description:
  70. - The container CLI.
  71. default: podman
  72. choices:
  73. - podman
  74. - docker
  75. container_log_stdout_path:
  76. description:
  77. - Absolute path to a directory where container stdout will be stored.
  78. default: /var/log/containers/stdouts
  79. healthcheck_disabled:
  80. description:
  81. - Whether or not we disable the Containers Healthchecks
  82. type: bool
  83. default: False
  84. managed_by:
  85. description:
  86. - Name of the tool managing the containers. Only containers labelled with
  87. this will be modified
  88. default: paunch
  89. debug:
  90. description:
  91. - Whether or not we enable Debug
  92. type: bool
  93. default: True
  94. log_file:
  95. description:
  96. - Absolute path for the paunch log file.
  97. default: /var/log/paunch.log
  98. cleanup:
  99. description:
  100. - Whether or not we cleanup containers not in config. Useful only for apply action.
  101. type: bool
  102. default: True
  103. """
  104. EXAMPLES = """
  105. # Paunch apply example
  106. - name: Start containers for step 1
  107. paunch:
  108. config: /var/lib/tripleo-config/hashed-container-startup-config-step_1.json
  109. config_overrides:
  110. haproxy:
  111. image: docker.io/tripleomaster/centos-binary-haproxy:current-tripleo-hotfix
  112. config_id: tripleo_step1
  113. cleanup: false
  114. action: apply
  115. # Paunch cleanup example
  116. - name: Cleanup containers for step 1 and step 2
  117. paunch:
  118. config_id:
  119. - tripleo_step1
  120. - tripleo_step2
  121. action: cleanup
  122. """
  123. class PaunchManager:
  124. def __init__(self, module, results):
  125. super(PaunchManager, self).__init__()
  126. self.module = module
  127. self.results = results
  128. self.config = self.module.params['config']
  129. if (isinstance(self.module.params['config_id'], list)
  130. and len(self.module.params['config_id']) == 1):
  131. self.config_id = self.module.params['config_id'][0]
  132. else:
  133. self.config_id = self.module.params['config_id']
  134. self.action = self.module.params['action']
  135. self.healthcheck_disabled = \
  136. self.module.params['healthcheck_disabled']
  137. self.container_cli = self.module.params['container_cli']
  138. self.cleanup = self.module.params['cleanup']
  139. self.config_overrides = self.module.params['config_overrides']
  140. self.container_log_stdout_path = \
  141. self.module.params['container_log_stdout_path']
  142. self.managed_by = self.module.params['managed_by']
  143. self.debug = self.module.params['debug']
  144. self.log_file = self.module.params['log_file']
  145. if self.debug:
  146. self.log_level = 3
  147. else:
  148. # if debug is disabled, only show WARNING level
  149. self.log_level = 1
  150. self.log = putils_common.configure_logging('paunch-ansible',
  151. level=self.log_level,
  152. log_file=self.log_file)
  153. if self.config:
  154. if self.config.endswith('.json'):
  155. self.module.warn('Only one config was given, cleanup disabled')
  156. self.cleanup = False
  157. self.config_yaml = putils_common.load_config(
  158. self.config,
  159. overrides=self.config_overrides)
  160. if self.action == 'apply':
  161. self.paunch_apply()
  162. elif self.action == 'cleanup':
  163. self.paunch_cleanup()
  164. def paunch_apply(self):
  165. self.results['action'].append('Applying config_id %s' % self.config_id)
  166. if not self.config:
  167. self.module.fail_json(
  168. msg="Paunch apply requires 'config' parameter",
  169. stdout='',
  170. stderr='',
  171. rc=1)
  172. stdout_list, stderr_list, rc = p.apply(
  173. self.config_id,
  174. self.config_yaml,
  175. managed_by=self.managed_by,
  176. labels=[],
  177. cont_cmd=self.container_cli,
  178. log_level=self.log_level,
  179. log_file=self.log_file,
  180. cont_log_path=self.container_log_stdout_path,
  181. healthcheck_disabled=self.healthcheck_disabled,
  182. cleanup=self.cleanup
  183. )
  184. stdout, stderr = ["\n".join(i) for i in (stdout_list, stderr_list)]
  185. # Test paunch idempotency how we can.
  186. changed_strings = ['rm -f', 'Completed', 'Created']
  187. if any(s in stdout for s in changed_strings):
  188. self.results['changed'] = True
  189. self.results.update({"stdout": stdout, "stderr": stderr, "rc": rc})
  190. if rc != 0:
  191. self.module.fail_json(
  192. msg="Paunch failed with config_id %s" % self.config_id,
  193. stdout=stdout,
  194. stderr=stderr,
  195. rc=rc)
  196. self.module.exit_json(**self.results)
  197. def paunch_cleanup(self):
  198. self.results['action'].append('Cleaning-up config_id(s) '
  199. '%s' % self.config_id)
  200. p.cleanup(
  201. self.config_id,
  202. managed_by=self.managed_by,
  203. cont_cmd=self.container_cli,
  204. log_level=self.log_level,
  205. log_file=self.log_file
  206. )
  207. self.module.exit_json(**self.results)
  208. def main():
  209. module = AnsibleModule(
  210. argument_spec=yaml.safe_load(DOCUMENTATION)['options'],
  211. supports_check_mode=False,
  212. )
  213. results = dict(
  214. changed=False,
  215. action=[]
  216. )
  217. PaunchManager(module, results)
  218. if __name__ == '__main__':
  219. main()