-
Notifications
You must be signed in to change notification settings - Fork 0
/
lilik_container.py
251 lines (228 loc) · 7.44 KB
/
lilik_container.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/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()