|
|
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
-
- DOCUMENTATION = """
- ---
- module: lilik_container
- short_description: Manage LXC Containers - Lilik style
- version_added: 2.1.0
- description:
- - Management of LXC containers
- options:
- name:
- description:
- - Name of a container
- required: true
- backing_store:
- choices:
- - dir
- - lvm
- - loop
- - btrfs
- - overlayfs
- - zfs
- description
- - Backend storage type for the container.
- required: false
- default: lvm
- config:
- description:
- - Path to the LXC configuration file
- required: false
- default: /etc/lxc/default.conf
- template:
- description:
- - Name of the template to use within an LXC create.
- required: false
- default: debian
- template_options:
- description:
- - Template options when building the container.
- required: false
- default: --release jessie --packages=ssh,python
- lv_name:
- description:
- - Name of the logical volume, defaults to the container name.
- default: "vm_{{$CONTAINER_NAME}}"
- required: false
- vg_name:
- description:
- - If Backend store is lvm, specify the name of the volume group.
- default: newsysvg
- required: false
- fs_type:
- description:
- - Create fstype TYPE.
- default: ext4
- required: false
- fs_size:
- description:
- - File system Size.
- default: 5G
- required: false
- container_command:
- description:
- - Run a command within a container.
- required: false
- state:
- choices:
- - started
- - stopped
- - restarted
- - absent
- - frozen
- description:
- - Define the state of a container.
- required: false
- default: started
- requirements:
- - 'liblxc1 >= 1.1.5 # OS package'
- - 'python >= 2.6 # OS package'
- - 'lxc-python2 >= 0.1 #PIP package from https://github.com/lxc/python2-lxc'
- """
-
-
- from ansible.module_utils.basic import *
-
- class LilikContainer(object):
- """
- A generic lxc container manipulation object based on python-lxc
- """
- def __init__(self, module):
- self.module = module
- self.state = module.params['state']
- self.name = module.params['name']
- self.template = module.params['template']
- self.template_options = module.params['template_options']
- self.config = module.params['config']
- self.backing_store = module.params['backing_store']
- # handle default name
- self.lvname = module.params.get('lv_name', 'vm_%s' % module.params['name'])
- self.vgname = module.params['vg_name']
- self.fstype = module.params['fs_type']
- self.fssize = module.params['fs_size']
-
- def create_container(self):
- """
- Create a lxc.Container object as specified in the playbook, use it
- to create a lxc container and returns the reference
- """
- container_options = {
- 'bdev': self.backing_store,
- 'config': self.config,
- 'lvname': self.lvname,
- 'vgname': self.vgname,
- 'fstype': self.fstype,
- 'fssize': self.fssize,
- 'bdev' : self.backing_store,
- }
- try:
- import lxc
- except ImportError:
- self.module.fail_json(changed=False, msg='Error importing lxc')
-
- container = lxc.Container(name = self.name)
-
- # TODO: python2-lxc does not like bdevtype but python-lxc does
- return container.create(
- template = self.template,
- args = container_options,
- # bdevtype = self.backing_store
- )
-
- def main():
-
- module = AnsibleModule(
- argument_spec = dict(
- backing_store = dict(
- default='lvm',
- choices=['dir', 'lvm', 'loop', 'btrsf', 'overlayfs', 'zfs',],
- type='str',
- ),
- config = dict(
- required=False,
- default='/etc/lxc/default.conf',
- ),
- container_command = dict(
- required=False,
- type='str',
- default='',
- ),
- fs_size = dict(
- required=False,
- default='5G',
- type='str',
- ),
- fs_type = dict(
- required=False,
- default='ext4',
- type='str',
- ),
- lv_name = dict(
- type='str',
- ),
- name = dict(
- required=True,
- type='str',
- ),
- state = dict(
- default='started',
- choices=['started', 'stopped', 'restarted', 'absent', 'frozen'],
- type='str',
- ),
- template = dict(
- required=False,
- default='debian',
- type='str',
- ),
- template_options = dict(
- required=False,
- default='--release jessie --packages=ssh,python',
- type='str',
- ),
- vg_name = dict(
- required=False,
- default='newsysvg',
- type='str',
- ),
- )
- )
-
- try:
- import lxc
- except ImportError:
- module.fail_json(changed=False, msg='liblxc is required for this module to work')
-
- lilik_container = LilikContainer(module)
-
- result = {}
- result['name'] = lilik_container.name
- result['state'] = lilik_container.state
-
- if lilik_container.state == 'absent':
-
- # destroy the container
- if lilik_container.destoy():
- module.exit_json(changed=True)
-
- # TODO: remove redundant test
- # test wether the container is absent or not
- if lilik_container.name in lxc.list_containers():
- module.fail_json(changed=False)
-
- # the container has been removed
- else:
- module.exit_json(changed=True)
- # end TODO: remove redundant test
-
- elif lilik_container.state in ['started', 'stopped', 'restarted', 'frozen']:
-
- # the container exists, just set the state as required
- if lilik_container.name in lxc.list_containers():
-
- container_actions_from_state = {
- 'started': lilik_container.start,
- 'stopped': lilik_container.stop,
- 'restarted': lilik_container.restart,
- 'frozen': lilik_container.freeze,
- }
-
- # selected action
- action = container_actions.get(container.state)
-
- if action():
- module.exit_json(changed=True)
- else:
- module.exit_json(changed=False)
-
- # the container does not exists, create it
- else:
- try:
- new_container = lilik_container.create_container()
- module.exit_json(changed=True)
- except Exception as e:
- module.fail_json(
- changed=False,
- msg='An excption was raised while creating the container',
- exception_message=str(e),
- )
-
- if __name__ == '__main__':
- main()
|