Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/boto/pyami/installers/ubuntu/ebs.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author | guerler |
---|---|
date | Fri, 31 Jul 2020 00:18:57 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d30785e31577 |
---|---|
1 # Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/ | |
2 # | |
3 # Permission is hereby granted, free of charge, to any person obtaining a | |
4 # copy of this software and associated documentation files (the | |
5 # "Software"), to deal in the Software without restriction, including | |
6 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
7 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
8 # persons to whom the Software is furnished to do so, subject to the fol- | |
9 # lowing conditions: | |
10 # | |
11 # The above copyright notice and this permission notice shall be included | |
12 # in all copies or substantial portions of the Software. | |
13 # | |
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
20 # IN THE SOFTWARE. | |
21 # | |
22 """ | |
23 Automated installer to attach, format and mount an EBS volume. | |
24 This installer assumes that you want the volume formatted as | |
25 an XFS file system. To drive this installer, you need the | |
26 following section in the boto config passed to the new instance. | |
27 You also need to install dateutil by listing python-dateutil | |
28 in the list of packages to be installed in the Pyami seciont | |
29 of your boto config file. | |
30 | |
31 If there is already a device mounted at the specified mount point, | |
32 the installer assumes that it is the ephemeral drive and unmounts | |
33 it, remounts it as /tmp and chmods it to 777. | |
34 | |
35 Config file section:: | |
36 | |
37 [EBS] | |
38 volume_id = <the id of the EBS volume, should look like vol-xxxxxxxx> | |
39 logical_volume_name = <the name of the logical volume that contaings | |
40 a reference to the physical volume to be mounted. If this parameter | |
41 is supplied, it overrides the volume_id setting.> | |
42 device = <the linux device the EBS volume should be mounted on> | |
43 mount_point = <directory to mount device, defaults to /ebs> | |
44 | |
45 """ | |
46 import boto | |
47 from boto.manage.volume import Volume | |
48 from boto.exception import EC2ResponseError | |
49 import os, time | |
50 from boto.pyami.installers.ubuntu.installer import Installer | |
51 from string import Template | |
52 | |
53 BackupScriptTemplate = """#!/usr/bin/env python | |
54 # Backup EBS volume | |
55 import boto | |
56 from boto.pyami.scriptbase import ScriptBase | |
57 import traceback | |
58 | |
59 class Backup(ScriptBase): | |
60 | |
61 def main(self): | |
62 try: | |
63 ec2 = boto.connect_ec2() | |
64 self.run("/usr/sbin/xfs_freeze -f ${mount_point}", exit_on_error = True) | |
65 snapshot = ec2.create_snapshot('${volume_id}') | |
66 boto.log.info("Snapshot created: %s " % snapshot) | |
67 except Exception as e: | |
68 self.notify(subject="${instance_id} Backup Failed", body=traceback.format_exc()) | |
69 boto.log.info("Snapshot created: ${volume_id}") | |
70 except Exception as e: | |
71 self.notify(subject="${instance_id} Backup Failed", body=traceback.format_exc()) | |
72 finally: | |
73 self.run("/usr/sbin/xfs_freeze -u ${mount_point}") | |
74 | |
75 if __name__ == "__main__": | |
76 b = Backup() | |
77 b.main() | |
78 """ | |
79 | |
80 BackupCleanupScript= """#!/usr/bin/env python | |
81 import boto | |
82 from boto.manage.volume import Volume | |
83 | |
84 # Cleans Backups of EBS volumes | |
85 | |
86 for v in Volume.all(): | |
87 v.trim_snapshots(True) | |
88 """ | |
89 | |
90 TagBasedBackupCleanupScript= """#!/usr/bin/env python | |
91 import boto | |
92 | |
93 # Cleans Backups of EBS volumes | |
94 | |
95 ec2 = boto.connect_ec2() | |
96 ec2.trim_snapshots() | |
97 """ | |
98 | |
99 class EBSInstaller(Installer): | |
100 """ | |
101 Set up the EBS stuff | |
102 """ | |
103 | |
104 def __init__(self, config_file=None): | |
105 super(EBSInstaller, self).__init__(config_file) | |
106 self.instance_id = boto.config.get('Instance', 'instance-id') | |
107 self.device = boto.config.get('EBS', 'device', '/dev/sdp') | |
108 self.volume_id = boto.config.get('EBS', 'volume_id') | |
109 self.logical_volume_name = boto.config.get('EBS', 'logical_volume_name') | |
110 self.mount_point = boto.config.get('EBS', 'mount_point', '/ebs') | |
111 | |
112 def attach(self): | |
113 ec2 = boto.connect_ec2() | |
114 if self.logical_volume_name: | |
115 # if a logical volume was specified, override the specified volume_id | |
116 # (if there was one) with the current AWS volume for the logical volume: | |
117 logical_volume = next(Volume.find(name=self.logical_volume_name)) | |
118 self.volume_id = logical_volume._volume_id | |
119 volume = ec2.get_all_volumes([self.volume_id])[0] | |
120 # wait for the volume to be available. The volume may still be being created | |
121 # from a snapshot. | |
122 while volume.update() != 'available': | |
123 boto.log.info('Volume %s not yet available. Current status = %s.' % (volume.id, volume.status)) | |
124 time.sleep(5) | |
125 instance = ec2.get_only_instances([self.instance_id])[0] | |
126 attempt_attach = True | |
127 while attempt_attach: | |
128 try: | |
129 ec2.attach_volume(self.volume_id, self.instance_id, self.device) | |
130 attempt_attach = False | |
131 except EC2ResponseError as e: | |
132 if e.error_code != 'IncorrectState': | |
133 # if there's an EC2ResonseError with the code set to IncorrectState, delay a bit for ec2 | |
134 # to realize the instance is running, then try again. Otherwise, raise the error: | |
135 boto.log.info('Attempt to attach the EBS volume %s to this instance (%s) returned %s. Trying again in a bit.' % (self.volume_id, self.instance_id, e.errors)) | |
136 time.sleep(2) | |
137 else: | |
138 raise e | |
139 boto.log.info('Attached volume %s to instance %s as device %s' % (self.volume_id, self.instance_id, self.device)) | |
140 # now wait for the volume device to appear | |
141 while not os.path.exists(self.device): | |
142 boto.log.info('%s still does not exist, waiting 2 seconds' % self.device) | |
143 time.sleep(2) | |
144 | |
145 def make_fs(self): | |
146 boto.log.info('make_fs...') | |
147 has_fs = self.run('fsck %s' % self.device) | |
148 if has_fs != 0: | |
149 self.run('mkfs -t xfs %s' % self.device) | |
150 | |
151 def create_backup_script(self): | |
152 t = Template(BackupScriptTemplate) | |
153 s = t.substitute(volume_id=self.volume_id, instance_id=self.instance_id, | |
154 mount_point=self.mount_point) | |
155 fp = open('/usr/local/bin/ebs_backup', 'w') | |
156 fp.write(s) | |
157 fp.close() | |
158 self.run('chmod +x /usr/local/bin/ebs_backup') | |
159 | |
160 def create_backup_cleanup_script(self, use_tag_based_cleanup=False): | |
161 fp = open('/usr/local/bin/ebs_backup_cleanup', 'w') | |
162 if use_tag_based_cleanup: | |
163 fp.write(TagBasedBackupCleanupScript) | |
164 else: | |
165 fp.write(BackupCleanupScript) | |
166 fp.close() | |
167 self.run('chmod +x /usr/local/bin/ebs_backup_cleanup') | |
168 | |
169 def handle_mount_point(self): | |
170 boto.log.info('handle_mount_point') | |
171 if not os.path.isdir(self.mount_point): | |
172 boto.log.info('making directory') | |
173 # mount directory doesn't exist so create it | |
174 self.run("mkdir %s" % self.mount_point) | |
175 else: | |
176 boto.log.info('directory exists already') | |
177 self.run('mount -l') | |
178 lines = self.last_command.output.split('\n') | |
179 for line in lines: | |
180 t = line.split() | |
181 if t and t[2] == self.mount_point: | |
182 # something is already mounted at the mount point | |
183 # unmount that and mount it as /tmp | |
184 if t[0] != self.device: | |
185 self.run('umount %s' % self.mount_point) | |
186 self.run('mount %s /tmp' % t[0]) | |
187 break | |
188 self.run('chmod 777 /tmp') | |
189 # Mount up our new EBS volume onto mount_point | |
190 self.run("mount %s %s" % (self.device, self.mount_point)) | |
191 self.run('xfs_growfs %s' % self.mount_point) | |
192 | |
193 def update_fstab(self): | |
194 f = open("/etc/fstab", "a") | |
195 f.write('%s\t%s\txfs\tdefaults 0 0\n' % (self.device, self.mount_point)) | |
196 f.close() | |
197 | |
198 def install(self): | |
199 # First, find and attach the volume | |
200 self.attach() | |
201 | |
202 # Install the xfs tools | |
203 self.run('apt-get -y install xfsprogs xfsdump') | |
204 | |
205 # Check to see if the filesystem was created or not | |
206 self.make_fs() | |
207 | |
208 # create the /ebs directory for mounting | |
209 self.handle_mount_point() | |
210 | |
211 # create the backup script | |
212 self.create_backup_script() | |
213 | |
214 # Set up the backup script | |
215 minute = boto.config.get('EBS', 'backup_cron_minute', '0') | |
216 hour = boto.config.get('EBS', 'backup_cron_hour', '4,16') | |
217 self.add_cron("ebs_backup", "/usr/local/bin/ebs_backup", minute=minute, hour=hour) | |
218 | |
219 # Set up the backup cleanup script | |
220 minute = boto.config.get('EBS', 'backup_cleanup_cron_minute') | |
221 hour = boto.config.get('EBS', 'backup_cleanup_cron_hour') | |
222 if (minute is not None) and (hour is not None): | |
223 # Snapshot clean up can either be done via the manage module, or via the new tag based | |
224 # snapshot code, if the snapshots have been tagged with the name of the associated | |
225 # volume. Check for the presence of the new configuration flag, and use the appropriate | |
226 # cleanup method / script: | |
227 use_tag_based_cleanup = boto.config.has_option('EBS', 'use_tag_based_snapshot_cleanup') | |
228 self.create_backup_cleanup_script(use_tag_based_cleanup) | |
229 self.add_cron("ebs_backup_cleanup", "/usr/local/bin/ebs_backup_cleanup", minute=minute, hour=hour) | |
230 | |
231 # Set up the fstab | |
232 self.update_fstab() | |
233 | |
234 def main(self): | |
235 if not os.path.exists(self.device): | |
236 self.install() | |
237 else: | |
238 boto.log.info("Device %s is already attached, skipping EBS Installer" % self.device) |