Package starcluster :: Module image
[hide private]
[frames] | no frames]

Source Code for Module starcluster.image

  1  #!/usr/bin/env python 
  2  import os 
  3  import pickle 
  4  from optparse import OptionParser 
  5  from starcluster import awsutils 
  6  from starcluster import exception 
  7  from starcluster import utils 
  8  from starcluster import node 
  9  from starcluster.logger import log 
 10  from starcluster.utils import print_timing 
11 12 -def create_image(instanceid, image_name, bucket, cfg, **kwargs):
13 instance = node.get_node(instanceid, cfg) 14 if instance.state != 'running': 15 raise exception.InstanceNotRunning(instance.id) 16 kwargs.update(cfg.aws) 17 kwargs.update({ 18 'instance': instance, 19 'prefix': image_name, 20 'bucket': bucket, 21 }) 22 icreator = EC2ImageCreator(**kwargs) 23 return icreator.create_image()
24
25 -class EC2ImageCreator(object):
26 """ 27 Class for creating a new AMI from a running instance 28 29 instance must be a starcluster.node.Node instance 30 """
31 - def __init__(self, instance=None, aws_access_key_id=None, 32 aws_secret_access_key=None, aws_user_id=None, 33 ec2_cert=None, ec2_private_key=None, prefix='image', 34 bucket=None, description=None, 35 kernel_id=None, ramdisk_id=None, 36 remove_image_files=False, **kwargs):
37 self.host = instance # starcluster.node.Node instance 38 self.access_key = aws_access_key_id 39 self.secret_key = aws_secret_access_key 40 self.userid = aws_user_id 41 self.private_key = ec2_private_key 42 self.bucket = bucket 43 self.prefix = prefix 44 self.description = description 45 self.kernel_id = kernel_id 46 self.ramdisk_id = ramdisk_id 47 self.cert = ec2_cert 48 self.remove_image_files = remove_image_files 49 if not utils.is_valid_bucket_name(self.bucket): 50 raise exception.InvalidBucketName(self.bucket) 51 if not utils.is_valid_image_name(self.prefix): 52 raise exception.InvalidImageName(self.prefix) 53 self.ec2 = awsutils.EasyEC2( 54 aws_access_key_id = self.access_key, 55 aws_secret_access_key = self.secret_key, 56 ) 57 if not self.cert: 58 try: 59 self.cert = os.environ['EC2_CERT'] 60 except KeyError,e: 61 raise exception.EC2CertRequired() 62 if not self.private_key: 63 try: 64 self.private_key = os.environ['EC2_PRIVATE_KEY'] 65 except KeyError,e: 66 raise exception.EC2PrivateKeyRequired() 67 if not os.path.exists(self.cert): 68 raise exception.EC2CertDoesNotExist(self.cert) 69 if not os.path.exists(self.private_key): 70 raise exception.EC2PrivateKeyDoesNotExist(self.private_key) 71 self.config_dict = { 72 'access_key': self.access_key, 73 'secret_key': self.secret_key, 74 'private_key': os.path.split(self.private_key)[-1], 75 'userid': self.userid, 76 'cert': os.path.split(self.cert)[-1], 77 'bucket': self.bucket, 78 'prefix': self.prefix, 79 'arch': self.host.arch, 80 }
81 82 @print_timing
83 - def create_image(self):
84 # first remove any image files from a previous run 85 self._remove_image_files() 86 self._bundle_image() 87 self._upload_image() 88 ami_id = self._register_image() 89 if self.remove_image_files: 90 # remove image files from this run if user says to 91 self._remove_image_files() 92 return ami_id
93
94 - def _remove_image_files(self):
95 conn = self.host.ssh 96 conn.execute('umount /mnt/img-mnt', ignore_exit_status=True) 97 conn.execute('rm -rf /mnt/img-mnt') 98 conn.execute('rm -rf /mnt/%(prefix)s*' % self.config_dict)
99
100 - def _transfer_pem_files(self):
101 """copy pem files to /mnt on image host""" 102 conn = self.host.ssh 103 conn.put(self.private_key, "/mnt/" + os.path.basename(self.private_key)) 104 conn.put(self.cert, "/mnt/" + os.path.basename(self.cert))
105 106 @print_timing
107 - def _bundle_image(self):
108 # run script to prepare the host 109 conn = self.host.ssh 110 config_dict = self.config_dict 111 self._transfer_pem_files() 112 self.__clean_private_data() 113 log.info('Creating the bundled image:') 114 conn.execute('ec2-bundle-vol -d /mnt -k /mnt/%(private_key)s \ 115 -c /mnt/%(cert)s -p %(prefix)s -u %(userid)s -r %(arch)s -e /root/.ssh' % \ 116 config_dict, 117 silent=False) 118 self._cleanup_pem_files()
119 120 @print_timing
121 - def _upload_image(self):
122 log.info('Uploading bundled image:') 123 conn = self.host.ssh 124 config_dict = self.config_dict 125 conn.execute('ec2-upload-bundle -b %(bucket)s \ 126 -m /mnt/%(prefix)s.manifest.xml -a %(access_key)s -s %(secret_key)s' % \ 127 config_dict, silent=False)
128
129 - def _cleanup(self):
130 #just in case... 131 self._cleanup_pem_files() 132 conn.execute('rm -f ~/.bash_history', silent=False)
133
134 - def _cleanup_pem_files(self):
135 log.info('Cleaning up...') 136 # delete keys and remove bash history 137 conn = self.host.ssh 138 conn.execute('rm -f /mnt/*.pem /mnt/*.pem', silent=False)
139
140 - def _register_image(self):
141 # register image in s3 with ec2 142 conn = self.ec2 143 config_dict = self.config_dict 144 return conn.register_image( 145 self.prefix, 146 description=self.description, 147 image_location= "%(bucket)s/%(prefix)s.manifest.xml" % config_dict, 148 kernel_id=self.kernel_id, 149 ramdisk_id=self.ramdisk_id, 150 architecture=config_dict.get('arch'), 151 )
152
153 - def __clean_private_data(self):
154 log.info('Removing private data...') 155 conn = self.host.ssh 156 conn.execute('find /home -maxdepth 1 -type d -exec rm -rf {}/.ssh \;', 157 silent=False) 158 conn.execute('rm -f /var/log/secure', silent=False) 159 conn.execute('rm -f /var/log/lastlog', silent=False) 160 conn.execute('rm -rf /root/*', silent=False) 161 conn.execute('rm -f ~/.bash_history', silent=False) 162 conn.execute('rm -rf /tmp/*', silent=False) 163 conn.execute('rm -rf /root/*.hist*', silent=False) 164 conn.execute('rm -rf /var/log/*.gz', silent=False)
165