forked from andsens/bootstrap-vz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathebsvolume.py
81 lines (65 loc) · 3.03 KB
/
ebsvolume.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
from bootstrapvz.base.fs.volume import Volume
from bootstrapvz.base.fs.exceptions import VolumeError
class EBSVolume(Volume):
def create(self, conn, zone, tags=[], encrypted=False, kms_key_id=None):
self.fsm.create(connection=conn, zone=zone, tags=tags, encrypted=encrypted, kms_key_id=kms_key_id)
def _before_create(self, e):
self.conn = e.connection
zone = e.zone
tags = e.tags
size = self.size.bytes.get_qty_in('GiB')
params = {
'Size': size,
'AvailabilityZone': zone,
'VolumeType': 'gp2',
}
if tags:
params['TagSpecifications'] = [{'ResourceType': 'volume', 'Tags': tags}]
if e.encrypted:
params['Encrypted'] = e.encrypted
if e.kms_key_id:
params['KmsKeyId'] = e.kms_key_id
self.volume = self.conn.create_volume(**params)
self.vol_id = self.volume['VolumeId']
waiter = self.conn.get_waiter('volume_available')
waiter.wait(VolumeIds=[self.vol_id],
Filters=[{'Name': 'status', 'Values': ['available']}])
def attach(self, instance_id):
self.fsm.attach(instance_id=instance_id)
def _before_attach(self, e):
import os.path
import string
self.instance_id = e.instance_id
for letter in string.ascii_lowercase[5:]:
dev_path = os.path.join('/dev', 'xvd' + letter)
if not os.path.exists(dev_path):
self.device_path = dev_path
self.ec2_device_path = os.path.join('/dev', 'sd' + letter)
break
if self.device_path is None:
raise VolumeError('Unable to find a free block device path for mounting the bootstrap volume')
self.conn.attach_volume(VolumeId=self.vol_id,
InstanceId=self.instance_id,
Device=self.ec2_device_path)
waiter = self.conn.get_waiter('volume_in_use')
waiter.wait(VolumeIds=[self.vol_id],
Filters=[{'Name': 'attachment.status', 'Values': ['attached']}])
def _before_detach(self, e):
self.conn.detach_volume(VolumeId=self.vol_id,
InstanceId=self.instance_id,
Device=self.ec2_device_path)
waiter = self.conn.get_waiter('volume_available')
waiter.wait(VolumeIds=[self.vol_id],
Filters=[{'Name': 'status', 'Values': ['available']}])
del self.ec2_device_path
self.device_path = None
def _before_delete(self, e):
self.conn.delete_volume(VolumeId=self.vol_id)
def snapshot(self):
snapshot = self.conn.create_snapshot(VolumeId=self.vol_id)
self.snap_id = snapshot['SnapshotId']
waiter = self.conn.get_waiter('snapshot_completed')
waiter.wait(SnapshotIds=[self.snap_id],
Filters=[{'Name': 'status', 'Values': ['completed']}],
WaiterConfig={'Delay': 15, 'MaxAttempts': 120})
return self.snap_id