Skip to content

Commit 772a0c2

Browse files
committed
Add storage pool support
1 parent 74c34bb commit 772a0c2

6 files changed

Lines changed: 749 additions & 0 deletions

File tree

cloudify_libvirt/pool_tasks.py

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
########
2+
# Copyright (c) 2016-2018 GigaSpaces Technologies Ltd. All rights reserved
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import libvirt
17+
import time
18+
19+
from cloudify import ctx
20+
from cloudify.decorators import operation
21+
from cloudify import exceptions as cfy_exc
22+
import cloudify_libvirt.common as common
23+
24+
25+
def _update_template_params(template_params):
26+
# set all params to default values
27+
if not template_params.get("path"):
28+
template_params["path"] = (
29+
"/var/lib/libvirt/images/{}".format(template_params["name"]))
30+
31+
32+
@operation
33+
def create(**kwargs):
34+
ctx.logger.info("Creating new pool.")
35+
36+
libvirt_auth, template_params = common.get_libvirt_params(**kwargs)
37+
conn = libvirt.open(libvirt_auth)
38+
if conn is None:
39+
raise cfy_exc.NonRecoverableError(
40+
'Failed to open connection to the hypervisor'
41+
)
42+
43+
_update_template_params(template_params)
44+
try:
45+
if ctx.instance.runtime_properties.get("use_external_resource"):
46+
# lookup the default pool by name
47+
resource_id = ctx.instance.runtime_properties["resource_id"]
48+
try:
49+
pool = conn.storagePoolLookupByName(resource_id)
50+
except libvirt.libvirtError as e:
51+
raise cfy_exc.NonRecoverableError(
52+
'Failed to find the pool: {}'.format(repr(e))
53+
)
54+
55+
# save settings
56+
ctx.instance.runtime_properties['params'] = template_params
57+
ctx.instance.runtime_properties['resource_id'] = pool.name()
58+
ctx.instance.runtime_properties['use_external_resource'] = True
59+
return
60+
61+
xmlconfig = common.gen_xml_template(kwargs, template_params, 'pool')
62+
63+
# create a persistent virtual pool
64+
pool = conn.storagePoolDefineXML(xmlconfig)
65+
if pool is None:
66+
raise cfy_exc.NonRecoverableError(
67+
'Failed to create a virtual pool')
68+
69+
ctx.logger.info('pool ' + pool.name() + ' has created.')
70+
ctx.logger.info('Params: ' + repr(template_params))
71+
ctx.instance.runtime_properties['params'] = template_params
72+
ctx.instance.runtime_properties['resource_id'] = pool.name()
73+
ctx.instance.runtime_properties['use_external_resource'] = False
74+
finally:
75+
conn.close()
76+
77+
78+
@operation
79+
def configure(**kwargs):
80+
ctx.logger.info("configure")
81+
82+
resource_id = ctx.instance.runtime_properties.get('resource_id')
83+
84+
if not resource_id:
85+
# not uninstall workflow, raise exception
86+
raise cfy_exc.NonRecoverableError("No pool for configure")
87+
88+
if ctx.instance.runtime_properties.get('use_external_resource'):
89+
ctx.logger.info("External resource, skip")
90+
return
91+
92+
libvirt_auth, _ = common.get_libvirt_params(**kwargs)
93+
conn = libvirt.open(libvirt_auth)
94+
if conn is None:
95+
raise cfy_exc.NonRecoverableError(
96+
'Failed to open connection to the hypervisor'
97+
)
98+
99+
try:
100+
try:
101+
pool = conn.storagePoolLookupByName(resource_id)
102+
except libvirt.libvirtError as e:
103+
raise cfy_exc.NonRecoverableError(
104+
'Failed to find the pool: {}'.format(repr(e))
105+
)
106+
107+
state, capacity, allocation, available = pool.info()
108+
ctx.logger.info(
109+
"State: {}, Capacity: {}, Allocation: {}, Available: {}"
110+
.format(repr(state), repr(capacity),
111+
repr(allocation), repr(available)))
112+
if state == libvirt.VIR_STORAGE_POOL_INACTIVE:
113+
if pool.build(0) < 0:
114+
raise cfy_exc.RecoverableError(
115+
'Can not build guest pool.'
116+
)
117+
finally:
118+
conn.close()
119+
120+
121+
@operation
122+
def start(**kwargs):
123+
ctx.logger.info("start")
124+
125+
resource_id = ctx.instance.runtime_properties.get('resource_id')
126+
127+
if not resource_id:
128+
# not uninstall workflow, raise exception
129+
raise cfy_exc.NonRecoverableError("No pool for start")
130+
131+
if ctx.instance.runtime_properties.get('use_external_resource'):
132+
ctx.logger.info("External resource, skip")
133+
return
134+
135+
libvirt_auth, _ = common.get_libvirt_params(**kwargs)
136+
conn = libvirt.open(libvirt_auth)
137+
if conn is None:
138+
raise cfy_exc.NonRecoverableError(
139+
'Failed to open connection to the hypervisor'
140+
)
141+
142+
try:
143+
try:
144+
pool = conn.storagePoolLookupByName(resource_id)
145+
except libvirt.libvirtError as e:
146+
raise cfy_exc.NonRecoverableError(
147+
'Failed to find the pool: {}'.format(repr(e))
148+
)
149+
150+
# pool create
151+
for i in xrange(10):
152+
if pool.isActive():
153+
ctx.logger.info("Looks as active.")
154+
break
155+
156+
ctx.logger.info("Tring to start pool {}/10".format(i))
157+
if pool.create() < 0:
158+
raise cfy_exc.RecoverableError(
159+
'Can not start pool.'
160+
)
161+
time.sleep(30)
162+
else:
163+
raise cfy_exc.RecoverableError(
164+
'Can not start pool.'
165+
)
166+
finally:
167+
conn.close()
168+
169+
170+
@operation
171+
def stop(**kwargs):
172+
ctx.logger.info("stop")
173+
174+
resource_id = ctx.instance.runtime_properties.get('resource_id')
175+
176+
if not resource_id:
177+
# not raise exception on 'uninstall' workflow
178+
ctx.logger.info("No pools for stop")
179+
return
180+
181+
if ctx.instance.runtime_properties.get('use_external_resource'):
182+
ctx.logger.info("External resource, skip")
183+
return
184+
185+
libvirt_auth, _ = common.get_libvirt_params(**kwargs)
186+
conn = libvirt.open(libvirt_auth)
187+
if conn is None:
188+
raise cfy_exc.NonRecoverableError(
189+
'Failed to open connection to the hypervisor'
190+
)
191+
192+
try:
193+
try:
194+
pool = conn.storagePoolLookupByName(resource_id)
195+
except libvirt.libvirtError as e:
196+
raise cfy_exc.NonRecoverableError(
197+
'Failed to find the pool: {}'.format(repr(e))
198+
)
199+
200+
for i in xrange(10):
201+
if not pool.isActive():
202+
ctx.logger.info("Looks as not active.")
203+
break
204+
205+
ctx.logger.info("Tring to stop vm {}/10".format(i))
206+
if pool.destroy() < 0:
207+
raise cfy_exc.NonRecoverableError(
208+
'Can not destroy pool.'
209+
)
210+
time.sleep(30)
211+
212+
state, capacity, allocation, available = pool.info()
213+
ctx.logger.info(
214+
"State: {}, Capacity: {}, Allocation: {}, Available: {}"
215+
.format(repr(state), repr(capacity),
216+
repr(allocation), repr(available)))
217+
if state != libvirt.VIR_STORAGE_POOL_INACTIVE:
218+
if pool.delete() < 0:
219+
raise cfy_exc.RecoverableError(
220+
'Can not delete guest pool.'
221+
)
222+
finally:
223+
conn.close()
224+
225+
226+
@operation
227+
def delete(**kwargs):
228+
resource_id = ctx.instance.runtime_properties.get('resource_id')
229+
ctx.logger.info("Delete: {}".format(repr(resource_id)))
230+
231+
if not resource_id:
232+
# not raise exception on 'uninstall' workflow
233+
ctx.logger.info("No pool for delete")
234+
return
235+
236+
if ctx.instance.runtime_properties.get('use_external_resource'):
237+
ctx.logger.info("External resource, skip")
238+
return
239+
240+
libvirt_auth, _ = common.get_libvirt_params(**kwargs)
241+
conn = libvirt.open(libvirt_auth)
242+
if conn is None:
243+
raise cfy_exc.NonRecoverableError(
244+
'Failed to open connection to the hypervisor'
245+
)
246+
247+
try:
248+
# lookup the default pool by name
249+
try:
250+
pool = conn.storagePoolLookupByName(resource_id)
251+
except libvirt.libvirtError as e:
252+
raise cfy_exc.NonRecoverableError(
253+
'Failed to find the pool: {}'.format(repr(e))
254+
)
255+
256+
if pool.undefine() < 0:
257+
raise cfy_exc.NonRecoverableError(
258+
'Can not undefine pool.'
259+
)
260+
261+
ctx.instance.runtime_properties['resource_id'] = None
262+
ctx.instance.runtime_properties['backups'] = {}
263+
finally:
264+
conn.close()
265+
266+
267+
@operation
268+
def snapshot_create(**kwargs):
269+
resource_id = ctx.instance.runtime_properties.get('resource_id')
270+
ctx.logger.info("Snapshot create: {}".format(repr(resource_id)))
271+
272+
if not resource_id:
273+
# not uninstall workflow, raise exception
274+
raise cfy_exc.NonRecoverableError("No pool for backup")
275+
276+
libvirt_auth, _ = common.get_libvirt_params(**kwargs)
277+
conn = libvirt.open(libvirt_auth)
278+
if conn is None:
279+
raise cfy_exc.NonRecoverableError(
280+
'Failed to open connection to the hypervisor'
281+
)
282+
283+
try:
284+
# lookup the default pool by name
285+
try:
286+
pool = conn.storagePoolLookupByName(resource_id)
287+
except libvirt.libvirtError as e:
288+
raise cfy_exc.NonRecoverableError(
289+
'Failed to find the pool: {}'.format(repr(e))
290+
)
291+
292+
common.xml_snapshot_create(kwargs, resource_id, pool.XMLDesc())
293+
finally:
294+
conn.close()
295+
296+
297+
@operation
298+
def snapshot_apply(**kwargs):
299+
resource_id = ctx.instance.runtime_properties.get('resource_id')
300+
ctx.logger.info("Snapshot restore for: {}".format(repr(resource_id)))
301+
302+
if not resource_id:
303+
# not uninstall workflow, raise exception
304+
raise cfy_exc.NonRecoverableError("No pool for restore")
305+
306+
libvirt_auth, _ = common.get_libvirt_params(**kwargs)
307+
conn = libvirt.open(libvirt_auth)
308+
if conn is None:
309+
raise cfy_exc.NonRecoverableError(
310+
'Failed to open connection to the hypervisor'
311+
)
312+
313+
try:
314+
# lookup the default pool by name
315+
try:
316+
pool = conn.storagePoolLookupByName(resource_id)
317+
except libvirt.libvirtError as e:
318+
raise cfy_exc.NonRecoverableError(
319+
'Failed to find the pool: {}'.format(repr(e))
320+
)
321+
322+
common.xml_snapshot_apply(kwargs, resource_id, pool.XMLDesc())
323+
finally:
324+
conn.close()
325+
326+
327+
@operation
328+
def snapshot_delete(**kwargs):
329+
resource_id = ctx.instance.runtime_properties.get('resource_id')
330+
ctx.logger.info("Snapshot delete for: {}".format(repr(resource_id)))
331+
332+
if not resource_id:
333+
# not uninstall workflow, raise exception
334+
raise cfy_exc.NonRecoverableError("No pool for backup delete")
335+
336+
common.xml_snapshot_delete(kwargs, resource_id)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<pool type='dir'>
2+
<name>{{ name }}</name>
3+
<uuid>{{ instance_uuid }}</uuid>
4+
<capacity unit='GiB'>{{ capacity }}</capacity>
5+
<source>
6+
</source>
7+
<target>
8+
<path>{{ path }}</path>
9+
<permissions>
10+
<mode>0755</mode>
11+
<owner>-1</owner>
12+
<group>-1</group>
13+
</permissions>
14+
</target>
15+
</pool>
16+
17+

0 commit comments

Comments
 (0)