#!/usr/bin/python # Copyright: (c) 2020-, Sven Velt # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = r''' --- module: lxc_container_info short_description: Gather info about LXC Containers version_added: "0.1.0" description: Gather some information about (all) LXC Containers options: name: description: Name of Container to gather informations required: false type: str requirements: - 'lxc-python3' author: - Sven Velt ''' EXAMPLES = r''' # Gather information of all containers: - name: Gather LXC informations lxc_container_info: # Gather information of one container: - name: Gather LXC informations lxc_container_info: name: containername ''' RETURN = r''' # These are examples of possible return values, and in general should use other names for return values. containers: description: dict of container information returned: always type: complex contains: containername: description: name of container type: complex contains: all_interfaces: description: List of all interfaces type: str returned: always sample: '["lo", "eth0"]' defined: description: if container is defined type: bool returned: always sample: true exists: description: if container is defined type: bool returned: always sample: true init_pid: description: PID of init of container (if running) type: init sample: 1234 original_message: description: The original name param that was passed in. type: str returned: always sample: 'hello world' message: description: The output message that the test module generates. type: str returned: always sample: 'goodbye' my_useful_info: description: The dictionary containing information about your system. type: dict returned: always sample: { 'foo': 'bar', 'answer': 42, } ''' import ipaddress try: import lxc except ImportError: HAS_LXC = False else: HAS_LXC = True from ansible.module_utils.basic import AnsibleModule def run_module(): module_args = dict( name=dict(type='str', default=''), ) result = dict( changed=False, containers={}, ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True ) if not HAS_LXC: module.fail_json( msg='The `lxc` module is not importable. Check the requirements.' ) if module.params['name']: ctnames = [ module.params['name'], ] else: ctnames = lxc.list_containers() for ctname in ctnames: ct = lxc.Container(ctname) res_ct = {} res_ct['defined'] = ct.defined res_ct['exists'] = ct.defined res_ct['state'] = ct.state res_ct['running'] = ct.running res_ct['init_pid'] = ct.init_pid res_ct['all_interfaces'] = ct.get_interfaces() res_ifaces = {} for iface in ct.get_interfaces(): res_if = {} res_if['ipv4_addresses'] = [] res_if['ipv6_addresses'] = [] for addr in ct.get_ips(iface): try: res_if['ipv4_addresses'].append(str(ipaddress.IPv4Address(addr))) except ipaddress.AddressValueError: try: res_if['ipv6_addresses'].append(str(ipaddress.IPv6Address(addr))) except: pass res_ifaces[iface] = res_if res_ct['interfaces'] = res_ifaces res_stat = {} if ct.running: res_stat['mem'] = { 'usage': int(ct.get_cgroup_item("memory.usage_in_bytes")), 'max_usage': int(ct.get_cgroup_item("memory.max_usage_in_bytes")), 'usage_mb': int(ct.get_cgroup_item("memory.usage_in_bytes")) // 1048576, 'max_usage_mb': int(ct.get_cgroup_item("memory.max_usage_in_bytes")) // 1048576, } res_stat['kmem'] = { 'usage': int(ct.get_cgroup_item("memory.kmem.usage_in_bytes")), 'max_usage': int(ct.get_cgroup_item("memory.kmem.max_usage_in_bytes")), 'usage_mb': int(ct.get_cgroup_item("memory.kmem.usage_in_bytes")) // 1048576, 'max_usage_mb': int(ct.get_cgroup_item("memory.kmem.max_usage_in_bytes")) // 1048576, } res_ct['stats'] = res_stat result['containers'][ctname] = res_ct module.exit_json(**result) def main(): run_module() if __name__ == '__main__': main()