#!/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: virt_lxc_info short_description: Gather info about Libvirt-LXC Containers version_added: "0.0.1" description: Gather some information about (all) Libvirt-LXC Containers options: name: description: Name of Container to gather informations required: false type: str requirements: - 'libvirt-python3' author: - Sven Velt ''' EXAMPLES = r''' # Gather information of all containers: - name: Gather Libvirt-LXC informations virt_lxc_info: # Gather information of one container: - name: Gather Libvirt-LXC informations virt_lxc_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 fnmatch import ipaddress try: import libvirt except ImportError: HAS_LIBVIRT = False else: HAS_LIBVIRT = True from ansible.module_utils.basic import AnsibleModule libvirt_state = { libvirt.VIR_DOMAIN_NOSTATE: "nostate", libvirt.VIR_DOMAIN_RUNNING: "running", libvirt.VIR_DOMAIN_BLOCKED: "blocked", libvirt.VIR_DOMAIN_PAUSED: "paused", libvirt.VIR_DOMAIN_SHUTDOWN: "shutdown", libvirt.VIR_DOMAIN_SHUTOFF: "shutoff", libvirt.VIR_DOMAIN_CRASHED: "crashed", libvirt.VIR_DOMAIN_PMSUSPENDED: "pmsuspended", } def run_module(): module_args = dict( name=dict(type='str', default=''), uuid=dict(type='str', default=''), ) result = dict( changed=False, containers={}, ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True ) if not HAS_LIBVIRT: module.fail_json( msg='The `libvirt` module is not importable. Check the requirements.' ) try: virt_conn = libvirt.open('lxc:/') # FIXME: Remote? except: module.fail_json( msg='Could not connect to LXC hypervisor.' ) name_filter = module.params['name'] or '*' uuid_filter = module.params['uuid'] or '*' for ct in virt_conn.listAllDomains(): res_ct = { 'name': ct.name(), 'id': ct.ID(), 'uuid': ct.UUIDString(), 'exists': True, } if not fnmatch.fnmatch(res_ct['name'], name_filter): continue if not fnmatch.fnmatch(res_ct['uuid'], uuid_filter): continue info_list = ct.info() # state, maxmem, mem, cpu-nr, cpu-time state_list = ct.state() res_ct.update( { 'active': ct.isActive() == 1, 'persistent': ct.isPersistent() == 1, 'state_list': state_list, 'state': libvirt_state.get( state_list[0] ) or 'unknown', 'state_reason': state_list[1], 'info_list': info_list, 'info': { 'state': info_list[0], 'memory': { 'max': info_list[1], 'actuel': info_list[2], }, 'cpus': info_list[3], 'cpu_time': info_list[4], }, 'running': ct.isActive() != 0, # FIXME: ? 'autostart': ct.autostart() == 1, } ) try: res_ct['memory_stats'] = ct.memoryStats() except libvirt.libvirtError: pass try: res_ct['memory_parameters'] = ct.memoryParameters() except libvirt.libvirtError: pass result['containers'][ct.name()] = res_ct module.exit_json(**result) def main(): run_module() if __name__ == '__main__': main()