Beispiel #1
0
    def shutdown(self, wait=True):
        """Shutdown instance."""

        if self.pid:
            # This relies on _execute which uses sudo over ssh.  The ssh
            # connection would get killed before sudo exited, so ignore errors.
            cmd = ['shutdown', 'now']
            try:
                self._execute(cmd)
            except util.InTargetExecuteError:
                pass
            self._ssh_close()

            if wait:
                LOG.debug("Executed shutdown. waiting on pid %s to end",
                          self.pid)
                time_for_shutdown = 120
                give_up_at = time.time() + time_for_shutdown
                pid_file_path = '/proc/%s' % self.pid
                msg = ("pid %s did not exit in %s seconds after shutdown." %
                       (self.pid, time_for_shutdown))
                while True:
                    if not os.path.exists(pid_file_path):
                        break
                    if time.time() > give_up_at:
                        raise util.PlatformError("shutdown", msg)
                self.pid = None
Beispiel #2
0
    def start(self, wait=True, wait_for_cloud_init=False):
        """Start instance on EC2 with the platfrom's VPC."""
        if self.instance:
            if self.instance.state['Name'] == 'running':
                return

            LOG.debug('starting instance %s', self.instance.id)
            self.instance.start()
        else:
            LOG.debug('launching instance')

            args = {
                'ImageId':
                self.image_ami,
                'InstanceType':
                self.platform.instance_type,
                'KeyName':
                self.platform.key_name,
                'MaxCount':
                1,
                'MinCount':
                1,
                'SecurityGroupIds': [self.platform.security_group.id],
                'SubnetId':
                self.platform.subnet.id,
                'TagSpecifications': [{
                    'ResourceType':
                    'instance',
                    'Tags': [{
                        'Key': 'Name',
                        'Value': self.platform.tag
                    }]
                }],
            }

            if self.user_data:
                args['UserData'] = self.user_data

            try:
                instances = self.platform.ec2_resource.create_instances(**args)
            except botocore.exceptions.ClientError as error:
                error_msg = error.response['Error']['Message']
                raise util.PlatformError('start', error_msg)

            self.instance = instances[0]

        LOG.debug('instance id: %s', self.instance.id)
        if wait:
            self.instance.wait_until_running()
            self.instance.reload()
            self.ssh_ip = self.instance.public_ip_address
            self._wait_for_system(wait_for_cloud_init)
Beispiel #3
0
    def console_log(self):
        """Collect console log from instance.

        The console log is buffered and not always present, therefore
        may return empty string.
        """
        try:
            # OutputBytes comes from platform._decode_console_output_as_bytes
            response = self.instance.console_output()
            return response['OutputBytes']
        except KeyError:
            if 'Output' in response:
                msg = ("'OutputBytes' did not exist in console_output() but "
                       "'Output' did: %s..." % response['Output'][0:128])
                raise util.PlatformError('console_log', msg)
            return ('No Console Output [%s]' % self.instance).encode()
Beispiel #4
0
def collect_script(instance, base_dir, script, script_name):
    """Collect script data.

    @param instance: instance to run script on
    @param base_dir: base directory for output data
    @param script: script contents
    @param script_name: name of script to run
    @return_value: None, may raise errors
    """
    LOG.debug('running collect script: %s', script_name)
    (out, err, exit) = instance.run_script(
        script.encode(), rcs=False,
        description='collect: {}'.format(script_name))
    if err:
        LOG.debug("collect script %s had stderr: %s", script_name, err)
    if not isinstance(out, bytes):
        raise util.PlatformError(
            "Collection of '%s' returned type %s, expected bytes: %s" %
            (script_name, type(out), out))

    c_util.write_file(os.path.join(base_dir, script_name), out)
Beispiel #5
0
    def _wait_for_system(self, wait_for_cloud_init):
        """Wait until system has fully booted and cloud-init has finished.

        @param wait_time: maximum time to wait
        @return_value: None, may raise OSError if wait_time exceeded
        """
        def clean_test(test):
            """Clean formatting for system ready test testcase."""
            return ' '.join(line for line in test.strip().splitlines()
                            if not line.lstrip().startswith('#'))

        boot_timeout = self.config['boot_timeout']
        tests = [self.config['system_ready_script']]
        if wait_for_cloud_init:
            tests.append(self.config['cloud_init_ready_script'])

        formatted_tests = ' && '.join(clean_test(t) for t in tests)
        cmd = ('i=0; while [ $i -lt {time} ] && i=$(($i+1)); do {test} && '
               'exit 0; sleep 1; done; exit 1').format(time=boot_timeout,
                                                       test=formatted_tests)

        end_time = time.time() + boot_timeout
        while True:
            try:
                return_code = self.execute(
                    cmd, rcs=(0, 1), description='wait for instance start')[-1]
                if return_code == 0:
                    break
            except util.InTargetExecuteError:
                LOG.warning("failed to connect via SSH")

            if time.time() < end_time:
                time.sleep(3)
            else:
                raise util.PlatformError(
                    'ssh', 'after %ss instance is not '
                    'reachable' % boot_timeout)