Add code and examples

This commit is contained in:
Sven Velt 2021-09-20 23:09:50 +02:00
parent ce23f75a57
commit d6f19e05f9
3 changed files with 194 additions and 1 deletions

View file

@ -1,3 +1,13 @@
# module_lxc_container_info
Ansible module to get runtime informations from LXC containers
## Testing Example
% python3 ./lxc_container_info.py <module_test_args.json
## Ansible Example
% ansible localhost -m lxc_container_info
% ansible localhost -m lxc_container_info -a name=container_name

177
lxc_container_info.py Normal file
View file

@ -0,0 +1,177 @@
#!/usr/bin/python
# Copyright: (c) 2020-, Sven Velt <sven-ansiblerole@velt.biz>
# 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()

6
module_test_args.json Normal file
View file

@ -0,0 +1,6 @@
{
"ANSIBLE_MODULE_ARGS": {
"name": "container_name"
}
}