OLD | NEW |
1 # Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/ | 1 # Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/ |
2 # | 2 # |
3 # Permission is hereby granted, free of charge, to any person obtaining a | 3 # Permission is hereby granted, free of charge, to any person obtaining a |
4 # copy of this software and associated documentation files (the | 4 # copy of this software and associated documentation files (the |
5 # "Software"), to deal in the Software without restriction, including | 5 # "Software"), to deal in the Software without restriction, including |
6 # without limitation the rights to use, copy, modify, merge, publish, dis- | 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 | 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- | 8 # persons to whom the Software is furnished to do so, subject to the fol- |
9 # lowing conditions: | 9 # lowing conditions: |
10 # | 10 # |
(...skipping 27 matching lines...) Expand all Loading... |
38 volume_id = <the id of the EBS volume, should look like vol-xxxxxxxx> | 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 | 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 | 40 a reference to the physical volume to be mounted. If this parameter |
41 is supplied, it overrides the volume_id setting.> | 41 is supplied, it overrides the volume_id setting.> |
42 device = <the linux device the EBS volume should be mounted on> | 42 device = <the linux device the EBS volume should be mounted on> |
43 mount_point = <directory to mount device, defaults to /ebs> | 43 mount_point = <directory to mount device, defaults to /ebs> |
44 | 44 |
45 """ | 45 """ |
46 import boto | 46 import boto |
47 from boto.manage.volume import Volume | 47 from boto.manage.volume import Volume |
| 48 from boto.exception import EC2ResponseError |
48 import os, time | 49 import os, time |
49 from boto.pyami.installers.ubuntu.installer import Installer | 50 from boto.pyami.installers.ubuntu.installer import Installer |
50 from string import Template | 51 from string import Template |
51 | 52 |
52 BackupScriptTemplate = """#!/usr/bin/env python | 53 BackupScriptTemplate = """#!/usr/bin/env python |
53 # Backup EBS volume | 54 # Backup EBS volume |
54 import boto | 55 import boto |
55 from boto.pyami.scriptbase import ScriptBase | 56 from boto.pyami.scriptbase import ScriptBase |
56 import traceback | 57 import traceback |
57 | 58 |
58 class Backup(ScriptBase): | 59 class Backup(ScriptBase): |
59 | 60 |
60 def main(self): | 61 def main(self): |
61 try: | 62 try: |
62 ec2 = boto.connect_ec2() | 63 ec2 = boto.connect_ec2() |
63 self.run("/usr/sbin/xfs_freeze -f ${mount_point}") | 64 self.run("/usr/sbin/xfs_freeze -f ${mount_point}", exit_on_error = T
rue) |
64 snapshot = ec2.create_snapshot('${volume_id}') | 65 snapshot = ec2.create_snapshot('${volume_id}') |
65 boto.log.info("Snapshot created: %s " % snapshot) | 66 boto.log.info("Snapshot created: %s " % snapshot) |
66 except Exception, e: | 67 except Exception, e: |
67 self.notify(subject="${instance_id} Backup Failed", body=traceback.f
ormat_exc()) | 68 self.notify(subject="${instance_id} Backup Failed", body=traceback.f
ormat_exc()) |
68 boto.log.info("Snapshot created: ${volume_id}") | 69 boto.log.info("Snapshot created: ${volume_id}") |
69 except Exception, e: | 70 except Exception, e: |
70 self.notify(subject="${instance_id} Backup Failed", body=traceback.f
ormat_exc()) | 71 self.notify(subject="${instance_id} Backup Failed", body=traceback.f
ormat_exc()) |
71 finally: | 72 finally: |
72 self.run("/usr/sbin/xfs_freeze -u ${mount_point}") | 73 self.run("/usr/sbin/xfs_freeze -u ${mount_point}") |
73 | 74 |
74 if __name__ == "__main__": | 75 if __name__ == "__main__": |
75 b = Backup() | 76 b = Backup() |
76 b.main() | 77 b.main() |
77 """ | 78 """ |
78 | 79 |
79 BackupCleanupScript= """#!/usr/bin/env python | 80 BackupCleanupScript= """#!/usr/bin/env python |
80 import boto | 81 import boto |
81 from boto.manage.volume import Volume | 82 from boto.manage.volume import Volume |
82 | 83 |
83 # Cleans Backups of EBS volumes | 84 # Cleans Backups of EBS volumes |
84 | 85 |
85 for v in Volume.all(): | 86 for v in Volume.all(): |
86 v.trim_snapshots(True) | 87 v.trim_snapshots(True) |
87 """ | 88 """ |
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 |
89 class EBSInstaller(Installer): | 99 class EBSInstaller(Installer): |
90 """ | 100 """ |
91 Set up the EBS stuff | 101 Set up the EBS stuff |
92 """ | 102 """ |
93 | 103 |
94 def __init__(self, config_file=None): | 104 def __init__(self, config_file=None): |
95 Installer.__init__(self, config_file) | 105 Installer.__init__(self, config_file) |
96 self.instance_id = boto.config.get('Instance', 'instance-id') | 106 self.instance_id = boto.config.get('Instance', 'instance-id') |
97 self.device = boto.config.get('EBS', 'device', '/dev/sdp') | 107 self.device = boto.config.get('EBS', 'device', '/dev/sdp') |
98 self.volume_id = boto.config.get('EBS', 'volume_id') | 108 self.volume_id = boto.config.get('EBS', 'volume_id') |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 | 150 |
141 def create_backup_script(self): | 151 def create_backup_script(self): |
142 t = Template(BackupScriptTemplate) | 152 t = Template(BackupScriptTemplate) |
143 s = t.substitute(volume_id=self.volume_id, instance_id=self.instance_id, | 153 s = t.substitute(volume_id=self.volume_id, instance_id=self.instance_id, |
144 mount_point=self.mount_point) | 154 mount_point=self.mount_point) |
145 fp = open('/usr/local/bin/ebs_backup', 'w') | 155 fp = open('/usr/local/bin/ebs_backup', 'w') |
146 fp.write(s) | 156 fp.write(s) |
147 fp.close() | 157 fp.close() |
148 self.run('chmod +x /usr/local/bin/ebs_backup') | 158 self.run('chmod +x /usr/local/bin/ebs_backup') |
149 | 159 |
150 def create_backup_cleanup_script(self): | 160 def create_backup_cleanup_script(self, use_tag_based_cleanup = False): |
151 fp = open('/usr/local/bin/ebs_backup_cleanup', 'w') | 161 fp = open('/usr/local/bin/ebs_backup_cleanup', 'w') |
152 fp.write(BackupCleanupScript) | 162 if use_tag_based_cleanup: |
| 163 fp.write(TagBasedBackupCleanupScript) |
| 164 else: |
| 165 fp.write(BackupCleanupScript) |
153 fp.close() | 166 fp.close() |
154 self.run('chmod +x /usr/local/bin/ebs_backup_cleanup') | 167 self.run('chmod +x /usr/local/bin/ebs_backup_cleanup') |
155 | 168 |
156 def handle_mount_point(self): | 169 def handle_mount_point(self): |
157 boto.log.info('handle_mount_point') | 170 boto.log.info('handle_mount_point') |
158 if not os.path.isdir(self.mount_point): | 171 if not os.path.isdir(self.mount_point): |
159 boto.log.info('making directory') | 172 boto.log.info('making directory') |
160 # mount directory doesn't exist so create it | 173 # mount directory doesn't exist so create it |
161 self.run("mkdir %s" % self.mount_point) | 174 self.run("mkdir %s" % self.mount_point) |
162 else: | 175 else: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 213 |
201 # Set up the backup script | 214 # Set up the backup script |
202 minute = boto.config.get('EBS', 'backup_cron_minute', '0') | 215 minute = boto.config.get('EBS', 'backup_cron_minute', '0') |
203 hour = boto.config.get('EBS', 'backup_cron_hour', '4,16') | 216 hour = boto.config.get('EBS', 'backup_cron_hour', '4,16') |
204 self.add_cron("ebs_backup", "/usr/local/bin/ebs_backup", minute=minute,
hour=hour) | 217 self.add_cron("ebs_backup", "/usr/local/bin/ebs_backup", minute=minute,
hour=hour) |
205 | 218 |
206 # Set up the backup cleanup script | 219 # Set up the backup cleanup script |
207 minute = boto.config.get('EBS', 'backup_cleanup_cron_minute') | 220 minute = boto.config.get('EBS', 'backup_cleanup_cron_minute') |
208 hour = boto.config.get('EBS', 'backup_cleanup_cron_hour') | 221 hour = boto.config.get('EBS', 'backup_cleanup_cron_hour') |
209 if (minute != None) and (hour != None): | 222 if (minute != None) and (hour != None): |
210 self.create_backup_cleanup_script(); | 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); |
211 self.add_cron("ebs_backup_cleanup", "/usr/local/bin/ebs_backup_clean
up", minute=minute, hour=hour) | 229 self.add_cron("ebs_backup_cleanup", "/usr/local/bin/ebs_backup_clean
up", minute=minute, hour=hour) |
212 | 230 |
213 # Set up the fstab | 231 # Set up the fstab |
214 self.update_fstab() | 232 self.update_fstab() |
215 | 233 |
216 def main(self): | 234 def main(self): |
217 if not os.path.exists(self.device): | 235 if not os.path.exists(self.device): |
218 self.install() | 236 self.install() |
219 else: | 237 else: |
220 boto.log.info("Device %s is already attached, skipping EBS Installer
" % self.device) | 238 boto.log.info("Device %s is already attached, skipping EBS Installer
" % self.device) |
OLD | NEW |