|
Lines 126-132
Link Here
|
| 126 |
# Create the logfile |
126 |
# Create the logfile |
| 127 |
if self.logfile: |
127 |
if self.logfile: |
| 128 |
log = open(self.logfile, 'a+') |
128 |
log = open(self.logfile, 'a+') |
| 129 |
log.write('Created instance %s at %s\n' % (section, time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()))) |
129 |
log.write('Creating instance %s at %s\n' % (section, time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()))) |
| 130 |
log.close() |
130 |
log.close() |
| 131 |
self.logfile_fd = None |
131 |
self.logfile_fd = None |
| 132 |
|
132 |
|
|
Lines 144-156
Link Here
|
| 144 |
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
144 |
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
| 145 |
start = now = time.time() |
145 |
start = now = time.time() |
| 146 |
# TODO: make the timeout configurable |
146 |
# TODO: make the timeout configurable |
| 147 |
timeout = 1200 |
147 |
timeout = 600 |
| 148 |
while now - start < timeout: |
148 |
while now - start < timeout: |
| 149 |
try: |
149 |
try: |
| 150 |
self._connect_vm() |
150 |
self._connect_vm() |
| 151 |
break |
151 |
break |
| 152 |
except socket_error: |
152 |
except socket_error: |
| 153 |
self._log('Pending %d...' % (timeout - now + start)) |
153 |
self._log('Connecting %d...' % (timeout - now + start)) |
| 154 |
time.sleep(5) |
154 |
time.sleep(5) |
| 155 |
now = time.time() |
155 |
now = time.time() |
| 156 |
except paramiko.AuthenticationException: |
156 |
except paramiko.AuthenticationException: |
|
Lines 159-165
Link Here
|
| 159 |
now = time.time() |
159 |
now = time.time() |
| 160 |
except Exception, ex: |
160 |
except Exception, ex: |
| 161 |
self._log('Unknown error "%s"...' % (ex,)) |
161 |
self._log('Unknown error "%s"...' % (ex,)) |
| 162 |
self._log('Pending %d...' % (timeout - now + start)) |
162 |
self._log('Connecting %d...' % (timeout - now + start)) |
| 163 |
time.sleep(5) |
163 |
time.sleep(5) |
| 164 |
now = time.time() |
164 |
now = time.time() |
| 165 |
else: |
165 |
else: |
|
Lines 552-561
Link Here
|
| 552 |
'ec2_ami', |
552 |
'ec2_ami', |
| 553 |
'ec2_security_group', |
553 |
'ec2_security_group', |
| 554 |
'ec2_instance_type', |
554 |
'ec2_instance_type', |
|
|
555 |
'ec2_instance_ebsOptimized', |
| 555 |
'ec2_keypair', |
556 |
'ec2_keypair', |
| 556 |
'ec2_region', |
557 |
'ec2_region', |
| 557 |
'ec2_subnet_id', |
558 |
'ec2_subnet_id', |
| 558 |
'ec2_partition_size', |
559 |
'ec2_partition_size', |
|
|
560 |
'ec2_instance_store', |
| 561 |
'ec2_volume_type', |
| 562 |
'ec2_volume_iops', |
| 559 |
] |
563 |
] |
| 560 |
for key in params: |
564 |
for key in params: |
| 561 |
if not config.has_option(section, key): |
565 |
if not config.has_option(section, key): |
|
Lines 575-587
Link Here
|
| 575 |
Create explicit block device with given size. |
579 |
Create explicit block device with given size. |
| 576 |
""" |
580 |
""" |
| 577 |
bdm = None |
581 |
bdm = None |
|
|
582 |
#self._log('Mapping volumes...') |
| 578 |
if self.aws_cfg.get('ec2_partition_size'): |
583 |
if self.aws_cfg.get('ec2_partition_size'): |
|
|
584 |
opt_volume_type = 'standard' |
| 585 |
opt_iops = None |
| 586 |
if self.aws_cfg.get('ec2_volume_type'): |
| 587 |
#self._log('Adding IOPS volumes...') |
| 588 |
#TODO: make sure ebsOptimized is also active |
| 589 |
opt_volume_type = self.aws_cfg.get('ec2_volume_type') |
| 590 |
# IOPS - up to partition_size * 30 (See AWS docs) |
| 591 |
opt_iops = self.aws_cfg.get('ec2_volume_iops') |
| 579 |
dev_sda1 = blockdevicemapping.EBSBlockDeviceType( |
592 |
dev_sda1 = blockdevicemapping.EBSBlockDeviceType( |
| 580 |
size = self.aws_cfg.get('ec2_partition_size'), |
593 |
size = self.aws_cfg.get('ec2_partition_size'), |
| 581 |
delete_on_termination=True, |
594 |
volume_type = opt_volume_type, |
| 582 |
) |
595 |
iops = opt_iops, |
|
|
596 |
delete_on_termination = True) |
| 583 |
bdm = blockdevicemapping.BlockDeviceMapping() |
597 |
bdm = blockdevicemapping.BlockDeviceMapping() |
| 584 |
bdm['/dev/sda1'] = dev_sda1 |
598 |
bdm['/dev/sda1'] = dev_sda1 |
|
|
599 |
#self._log('instance stores %s' % self.aws_cfg.get('ec2_instance_store')) |
| 600 |
#assumming 2 - TODO: cycle for given-number-of-devices |
| 601 |
if self.aws_cfg.get('ec2_instance_store'): |
| 602 |
#self._log('Adding instance store volumes...') |
| 603 |
dev_xvdb = blockdevicemapping.BlockDeviceType() |
| 604 |
dev_xvdc = blockdevicemapping.BlockDeviceType() |
| 605 |
dev_xvdb.ephemeral_name = 'ephemeral0' |
| 606 |
dev_xvdc.ephemeral_name = 'ephemeral1' |
| 607 |
bdm = blockdevicemapping.BlockDeviceMapping() |
| 608 |
bdm['/dev/sdb'] = dev_xvdb |
| 609 |
bdm['/dev/sdc'] = dev_xvdc |
| 610 |
#self._log('...done. MappedDevices: %s' % bdm) |
| 585 |
return bdm |
611 |
return bdm |
| 586 |
|
612 |
|
| 587 |
def _connect_vm(self): |
613 |
def _connect_vm(self): |
|
Lines 605-610
Link Here
|
| 605 |
user_data = '\n'.join(['%s=%s' % (v, os.getenv(v, '')) for v in env_vars]) |
631 |
user_data = '\n'.join(['%s=%s' % (v, os.getenv(v, '')) for v in env_vars]) |
| 606 |
|
632 |
|
| 607 |
self.ec2 = boto.connect_ec2(**aws_cfg) |
633 |
self.ec2 = boto.connect_ec2(**aws_cfg) |
|
|
634 |
|
| 608 |
reuse = self.aws_cfg.get('ec2_reuse') |
635 |
reuse = self.aws_cfg.get('ec2_reuse') |
| 609 |
if reuse: |
636 |
if reuse: |
| 610 |
reservation = self.ec2.get_all_instances(instance_ids=[reuse])[0] |
637 |
reservation = self.ec2.get_all_instances(instance_ids=[reuse])[0] |
|
Lines 617-623
Link Here
|
| 617 |
user_data=user_data, |
644 |
user_data=user_data, |
| 618 |
security_group_ids=[self.aws_cfg['ec2_security_group']], |
645 |
security_group_ids=[self.aws_cfg['ec2_security_group']], |
| 619 |
instance_type=self.aws_cfg['ec2_instance_type'], |
646 |
instance_type=self.aws_cfg['ec2_instance_type'], |
| 620 |
instance_initiated_shutdown_behavior='terminate', # 'save' |
647 |
instance_initiated_shutdown_behavior='terminate', |
| 621 |
block_device_map=self._get_blockdevicemapping() |
648 |
block_device_map=self._get_blockdevicemapping() |
| 622 |
) |
649 |
) |
| 623 |
else: |
650 |
else: |
|
Lines 628-656
Link Here
|
| 628 |
user_data=user_data, |
655 |
user_data=user_data, |
| 629 |
security_groups=[self.aws_cfg['ec2_security_group']], |
656 |
security_groups=[self.aws_cfg['ec2_security_group']], |
| 630 |
instance_type=self.aws_cfg['ec2_instance_type'], |
657 |
instance_type=self.aws_cfg['ec2_instance_type'], |
| 631 |
instance_initiated_shutdown_behavior='terminate', # 'save' |
658 |
instance_initiated_shutdown_behavior='terminate', |
| 632 |
block_device_map=self._get_blockdevicemapping() |
659 |
block_device_map=self._get_blockdevicemapping() |
| 633 |
) |
660 |
) |
|
|
661 |
|
| 662 |
self.instance = reservation.instances[0] |
| 663 |
self._log('Instance %s reserved. ->%s' % (self.instance.id, self.instance.state)) |
| 634 |
|
664 |
|
| 635 |
self.instance = reservation.instances[0] |
|
|
| 636 |
|
| 637 |
self._wait_instance() |
665 |
self._wait_instance() |
| 638 |
|
666 |
|
| 639 |
self.instance.add_tag('Name', 'Test-%s-%s' % (os.getenv('USER'), self.section)) |
667 |
self.instance.add_tag('Name', 'Test-%s-%s' % (os.getenv('USER'), self.section)) |
| 640 |
self.instance.add_tag('class', 'ucs-test') |
668 |
self.instance.add_tag('class', 'ucs-test') |
| 641 |
for var in env_vars: |
669 |
for var in env_vars: |
| 642 |
self.instance.add_tag(var.lower(), os.getenv(var, '')) |
670 |
self.instance.add_tag(var.lower(), os.getenv(var, '')) |
|
|
671 |
#Need ebsOptimized if volume_type is io1 |
| 672 |
#NOTE:launching an instance with image.run does not support ebsOptimized |
| 673 |
#modifying instance attribute: |
| 674 |
#self._log('EBS status: %s' % (self.instance.ebs_optimized)) |
| 675 |
if self.aws_cfg.get('ec2_instance_ebsOptimized') == 'True': |
| 676 |
self._log('Changing EBS status: stopping instance first.') |
| 677 |
# stop VM (make sure it will only be stopped, not terminated) |
| 678 |
self.instance.modify_attribute('instanceInitiatedShutdownBehavior', 'stop') |
| 679 |
self.instance.stop() |
| 680 |
self._wait_instance(desiredState='stopped') |
| 681 |
self.instance.modify_attribute('ebsOptimized', True) |
| 682 |
self.instance.modify_attribute('instanceInitiatedShutdownBehavior', 'terminate') |
| 683 |
self.instance.start() |
| 684 |
self._wait_instance() |
| 643 |
|
685 |
|
| 644 |
def _wait_instance(self, timeout=600): |
686 |
def _wait_instance(self, timeout=600, desiredState='running'): |
| 645 |
""" |
687 |
""" |
| 646 |
Wait until instance is created. |
688 |
Wait until instance is created. |
| 647 |
""" |
689 |
""" |
| 648 |
start = now = time.time() |
690 |
start = now = time.time() |
| 649 |
while now - start < timeout: |
691 |
while now - start < timeout: |
| 650 |
if self.instance.state == 'running': |
692 |
if self.instance.state == desiredState: |
| 651 |
break |
693 |
break |
| 652 |
if self.instance.state == 'pending': |
694 |
if self.instance.state != desiredState: |
| 653 |
self._log('Pending %d...' % (timeout - now + start)) |
695 |
self._log('State: %s, waiting %d...' % (self.instance.state, timeout - now + start)) |
| 654 |
time.sleep(10) |
696 |
time.sleep(10) |
| 655 |
|
697 |
|
| 656 |
try: |
698 |
try: |
|
Lines 661-674
Link Here
|
| 661 |
if error.error_code == 'InvalidInstanceID.NotFound': |
703 |
if error.error_code == 'InvalidInstanceID.NotFound': |
| 662 |
break |
704 |
break |
| 663 |
else: |
705 |
else: |
| 664 |
self._log('Unexcpected error waiting for instance: %s', ex) |
706 |
self._log('Unexpected error waiting for instance: %s', ex) |
| 665 |
raise |
707 |
raise |
| 666 |
now = time.time() |
708 |
now = time.time() |
| 667 |
else: |
709 |
else: |
| 668 |
self._log('Timeout waiting for instance') |
710 |
self._log('Timeout waiting for instance') |
| 669 |
raise |
711 |
raise |
|
|
712 |
self._log('OK ->%s' % (self.instance.state)) |
| 670 |
|
713 |
|
| 671 |
|
|
|
| 672 |
def _print_process(msg): |
714 |
def _print_process(msg): |
| 673 |
''' Print s status line ''' |
715 |
''' Print s status line ''' |
| 674 |
if len(msg) > 64: |
716 |
if len(msg) > 64: |