2013-06-23 12:00:17 +02:00
|
|
|
from base import Task
|
2013-06-23 15:26:08 +02:00
|
|
|
from common import phases
|
2013-06-26 23:50:11 +02:00
|
|
|
from common.exceptions import TaskError
|
2013-08-13 14:33:35 +00:00
|
|
|
from common.tasks.filesystem import UnmountVolume
|
2013-06-24 23:12:39 +02:00
|
|
|
import time
|
|
|
|
|
2013-06-23 12:00:17 +02:00
|
|
|
|
2013-07-13 13:55:12 +02:00
|
|
|
class Create(Task):
|
2013-06-24 23:12:39 +02:00
|
|
|
description = 'Creating an EBS volume for bootstrapping'
|
2013-07-09 20:32:50 +02:00
|
|
|
phase = phases.volume_creation
|
2013-06-26 20:14:37 +02:00
|
|
|
|
2013-06-23 12:00:17 +02:00
|
|
|
def run(self, info):
|
2013-07-09 21:27:32 +02:00
|
|
|
info.volume = info.connection.create_volume(info.manifest.ebs_volume_size,
|
|
|
|
info.host['availabilityZone'])
|
2013-06-24 23:12:39 +02:00
|
|
|
while info.volume.volume_state() != 'available':
|
|
|
|
time.sleep(5)
|
|
|
|
info.volume.update()
|
|
|
|
|
2013-06-26 20:14:37 +02:00
|
|
|
|
2013-07-13 13:55:12 +02:00
|
|
|
class Attach(Task):
|
2013-07-09 20:32:50 +02:00
|
|
|
description = 'Attaching the EBS volume'
|
2013-06-24 19:06:12 +02:00
|
|
|
phase = phases.volume_creation
|
2013-07-13 13:55:12 +02:00
|
|
|
after = [Create]
|
2013-06-24 19:06:12 +02:00
|
|
|
|
|
|
|
def run(self, info):
|
|
|
|
def char_range(c1, c2):
|
2013-06-24 23:12:39 +02:00
|
|
|
"""Generates the characters from `c1` to `c2`, inclusive."""
|
2013-08-17 17:28:46 +02:00
|
|
|
for c in xrange(ord(c1), ord(c2) + 1):
|
2013-06-24 19:06:12 +02:00
|
|
|
yield chr(c)
|
|
|
|
|
|
|
|
import os.path
|
2013-06-24 23:12:39 +02:00
|
|
|
info.bootstrap_device = {}
|
|
|
|
for letter in char_range('f', 'z'):
|
2013-06-24 19:06:12 +02:00
|
|
|
dev_path = os.path.join('/dev', 'xvd' + letter)
|
2013-06-24 23:12:39 +02:00
|
|
|
if not os.path.exists(dev_path):
|
|
|
|
info.bootstrap_device['path'] = dev_path
|
|
|
|
info.bootstrap_device['ec2_path'] = os.path.join('/dev', 'sd' + letter)
|
2013-06-24 19:06:12 +02:00
|
|
|
break
|
|
|
|
if 'path' not in info.bootstrap_device:
|
|
|
|
raise VolumeError('Unable to find a free block device path for mounting the bootstrap volume')
|
2013-06-24 23:12:39 +02:00
|
|
|
|
|
|
|
info.volume.attach(info.host['instanceId'], info.bootstrap_device['ec2_path'])
|
|
|
|
while info.volume.attachment_state() != 'attached':
|
|
|
|
time.sleep(2)
|
|
|
|
info.volume.update()
|
|
|
|
|
2013-06-26 20:14:37 +02:00
|
|
|
|
2013-07-13 13:55:12 +02:00
|
|
|
class Detach(Task):
|
2013-07-09 20:32:50 +02:00
|
|
|
description = 'Detaching the EBS volume'
|
2013-06-26 23:40:42 +02:00
|
|
|
phase = phases.volume_unmounting
|
2013-06-27 22:21:43 +02:00
|
|
|
after = [UnmountVolume]
|
2013-06-26 23:40:42 +02:00
|
|
|
|
|
|
|
def run(self, info):
|
2013-06-24 23:12:39 +02:00
|
|
|
info.volume.detach()
|
|
|
|
while info.volume.attachment_state() is not None:
|
|
|
|
time.sleep(2)
|
|
|
|
info.volume.update()
|
2013-06-23 12:00:17 +02:00
|
|
|
|
2013-06-26 20:14:37 +02:00
|
|
|
|
2013-07-13 13:55:12 +02:00
|
|
|
class Snapshot(Task):
|
2013-07-07 19:24:52 +02:00
|
|
|
description = 'Creating a snapshot of the EBS volume'
|
|
|
|
phase = phases.image_registration
|
|
|
|
|
|
|
|
def run(self, info):
|
|
|
|
info.snapshot = info.volume.create_snapshot()
|
|
|
|
while info.snapshot.status != 'completed':
|
|
|
|
time.sleep(2)
|
|
|
|
info.snapshot.update()
|
|
|
|
|
|
|
|
|
2013-07-13 13:55:12 +02:00
|
|
|
class Delete(Task):
|
2013-07-09 20:32:50 +02:00
|
|
|
description = 'Deleting the EBS volume'
|
2013-06-26 23:40:42 +02:00
|
|
|
phase = phases.cleaning
|
|
|
|
|
|
|
|
def run(self, info):
|
|
|
|
info.volume.delete()
|
|
|
|
del info.volume
|
|
|
|
|
|
|
|
|
2013-06-26 23:50:11 +02:00
|
|
|
class VolumeError(TaskError):
|
2013-06-24 19:10:04 +02:00
|
|
|
pass
|