示例#1
0
    def _establish_ssh_connection(self):
        """Connect to the running instance with ssh"""
        if self.aborted:
            return
        if self.verbose:
            print('Waiting to obtain instance IP address')
        instance_ip = self.helper_instance.get('PublicIpAddress')
        if self.use_private_ip:
            instance_ip = self.helper_instance.get('PrivateIpAddress')
        timeout_counter = 1
        while not instance_ip:
            instance = self._connect().describe_instances(
                InstanceIds=[self.helper_instance['InstanceId']
                             ])['Reservations'][0]['Instances'][0]
            instance_ip = instance.get('PublicIpAddress')
            if self.use_private_ip:
                instance_ip = instance.get('PrivateIpAddress')
            if self.verbose:
                print('. ', end=' ')
                sys.stdout.flush()
            if timeout_counter * self.default_sleep >= self.ssh_timeout:
                msg = 'Unable to obtain the instance IP address'
                raise EC2UploadImgException(msg)
            timeout_counter += 1
        if self.verbose:
            print()
        client = paramiko.client.SSHClient()
        client.set_missing_host_key_policy(paramiko.WarningPolicy())
        if self.verbose:
            print('Attempt ssh connection')
        ssh_connection = None
        timeout_counter = 1
        while not ssh_connection:
            try:
                ssh_connection = client.connect(
                    key_filename=self.ssh_key_private_key_file,
                    username=self.inst_user_name,
                    hostname=instance_ip)
            except:
                if self.verbose:
                    print('. ', end=' ')
                    sys.stdout.flush()
                time.sleep(self.default_sleep)
                if (timeout_counter * self.default_sleep >= self.ssh_timeout):
                    self._clean_up()
                    msg = 'Time out for ssh connection reached, '
                    msg += 'could not connect'
                    raise EC2UploadImgException(msg)
                timeout_counter += 1
            else:
                ssh_connection = True
                print()

        self.ssh_client = client
示例#2
0
    def _unpack_image(self, image_dir, image_filename):
        """Unpack the uploaded image file"""
        if (image_filename.find('.tar') != -1
                or image_filename.find('.tbz') != -1
                or image_filename.find('.tgz') != -1):
            command = 'tar -C %s -xvf %s/%s' % (image_dir, image_dir,
                                                image_filename)
            files = self._execute_ssh_command(command).split('\r\n')
        elif image_filename[-2:] == 'xz':
            files = [image_filename]

        raw_image_file = None
        if files:
            # Find the disk image
            for fl in files:
                if fl.strip()[-2:] == 'xz':
                    if self.verbose:
                        print('Inflating image: ', fl)
                    command = 'xz -d %s/%s' % (image_dir, fl)
                    result = self._execute_ssh_command(command)
                    raw_image_file = fl.strip()[:-3]
                    break
                if fl.strip()[-4:] == '.raw':
                    raw_image_file = fl.strip()
                    break
        if not raw_image_file:
            self._clean_up()
            msg = 'Unable to find raw image file with .raw extension'
            raise EC2UploadImgException(msg)

        return raw_image_file
示例#3
0
    def _format_storage_volume(self, device_id):
        """Format the storage volume"""

        if self.verbose:
            print('Formating storage volume')
        parted = self._get_command_from_instance('parted')
        sfdifk = None
        if not parted:
            sfdisk = self._get_command_from_instance('sfdisk')

        if not parted and not sfdisk:
            self._clean_up()
            msg = 'Neither parted nor sfdisk found on target image. '
            msg += 'Need to partition storage device but cannot, exiting.'
            raise EC2UploadImgException(msg)

        if parted:
            command = '%s -s %s mklabel gpt' % (parted, device_id)
            result = self._execute_ssh_command(command)
            blockdev = self._get_command_from_instance('blockdev')
            command = '%s --getsize %s' % (blockdev, device_id)
            size = self._execute_ssh_command(command)
            command = ('%s -s %s unit s mkpart primary 2048 %d' %
                       (parted, device_id, int(size) - 100))
            result = self._execute_ssh_command(command)
        else:
            command = 'echo ",,L" > /tmp/partition.txt'
            result = self._execute_ssh_command(command)
            command = '%s %s < /tmp/partition.txt' % (sfdisk, device_id)
            result = self._execute_ssh_command(command)

        return 1
示例#4
0
    def _check_wait_status(self,
                           wait_status,
                           error_msg,
                           repeat_count,
                           skip_cleanup=False):
        """Check the wait status form the waiter and take appropriate action"""
        if wait_status:
            if self.verbose:
                print()
            if repeat_count == self.wait_count:
                self.operation_complete = True
                if self.verbose:
                    self.progress_timer.cancel()
                time.sleep(self.default_sleep)  # Wait for the thread
                if not skip_cleanup:
                    self._clean_up()
                raise EC2UploadImgException(error_msg)
            repeat_count += 1
            print('Entering wait loop number %d of %d' %
                  (repeat_count, self.wait_count))
            self.operation_complete = False
            self._show_progress()
        else:
            repeat_count = self.wait_count + 1
            self.operation_complete = True
            if self.verbose:
                self.progress_timer.cancel()
            time.sleep(self.default_sleep)  # Wait for the thread
            if self.verbose:
                print()

        return repeat_count
示例#5
0
 def _check_image_exists(self):
     """Check if an image with the given name already exists"""
     my_images = self._get_owned_images()
     for image in my_images:
         if image['Name'] == self.image_name:
             msg = 'Image with name "%s" already exists' % self.image_name
             raise EC2UploadImgException(msg)
示例#6
0
 def _check_subnet_exists(self):
     """Verify that the subnet being used for the helper instance
        exists"""
     try:
         self._connect().describe_subnets(SubnetIds=[self.vpc_subnet_id])
     except:
         error_msg = 'Specified subnet %s not found' % self.vpc_subnet_id
         raise EC2UploadImgException(error_msg)
示例#7
0
 def _check_security_groups_exist(self):
     """Check that the specified security groups exist"""
     try:
         self._connect().describe_security_groups(
             GroupIds=self.security_group_ids.split(','))
     except:
         error_msg = 'One or more of the specified security groups '
         error_msg += 'could not be found: %s' % self.security_group_ids
         raise EC2UploadImgException(error_msg)
示例#8
0
    def _get_helper_instance(self):
        """Returns handle to running instance"""
        self._set_zone_to_use()
        helper_instance = self._connect().describe_instances(
            InstanceIds=[self.running_id])['Reservations'][0]['Instances'][0]
        if helper_instance['State']['Name'] != 'running':
            msg = 'Helper instance %s is not running' % self.running_id
            raise EC2UploadImgException(msg)

        return helper_instance
示例#9
0
    def _execute_ssh_command(self, command):
        """Execute a command on the remote machine, on error raise an exception
           return the result of stdout"""
        if self.inst_user_name != 'root':
            command = 'sudo %s' % command

        if not self.ssh_client:
            msg = 'No ssh connection established, cannot execute command'
            raise EC2UploadImgException(msg)
        stdin, stdout, stderr = self.ssh_client.exec_command(command,
                                                             get_pty=True)
        cmd_error = stderr.read()
        if cmd_error:
            self._clean_up()
            msg = 'Execution of "%s" failed with the following error' % command
            msg += '\n%s' % cmd_err
            raise EC2UploadImgException(msg)

        return stdout.read().strip().decode('utf-8')
示例#10
0
 def _check_virt_type_consistent(self):
     """When using root swap the virtualization type of the helper
        image and the target image must be the same"""
     image = self._connect().describe_images(
         ImageIds=[self.launch_ami_id])['Images'][0]
     if not self.image_virt_type == image['VirtualizationType']:
         error_msg = 'Virtualization type of the helper image and the '
         error_msg += 'target image must be the same when using '
         error_msg += 'root-swap method for image creation.'
         raise EC2UploadImgException(error_msg)
示例#11
0
    def _find_equivalent_device(self, device_id):
        """Try and find a device that should be the same device in the
           instance than the one we attached with a given device id."""
        device_letter = device_id[-1]
        expected_name = '/dev/xvd%s' % device_letter
        if self._device_exists(expected_name):
            return expected_name

        self._clean_up()
        msg = 'Could not find disk device in helper instance with path '
        msg += '%s or %s' % (device_id, expected_name)
        raise EC2UploadImgException(msg)