def make_snapshot(request, fuel, env):
    """Make fuel diagnostic snapshot after failed tests"""
    yield

    try:
        skip_snapshot = not request.config.getoption("--make-snapshots")
        if skip_snapshot and os.environ.get('JOB_NAME') is None:
            return

        steps_rep = [getattr(request.node, 'rep_{}'.format(name), None)
                     for name in ("setup", "call", "teardown")]
        if not any(x for x in steps_rep if x is not None and x.failed):
            return

        test_name = request.node.nodeid
        logger.info('Making snapshot to test {}'.format(test_name))
        filename = unicode(re.sub('[^\w\s-]', '_', test_name).strip().lower())
        filename += '.tar.xz'
        path = os.path.join('snapshots', filename)

        config = SnapshotTask.get_default_config()
        task = SnapshotTask.start_snapshot_task(config)
        task.wait()
        if task.status != 'ready':
            raise Exception(
                "Snapshot generating task ended with error. Task message: {0}"
                .format(task.data["message"]))

        url = 'http://{fuel.admin_ip}:8000{task.data[message]}'.format(
            fuel=fuel,
            task=task)
        response = requests.get(url,
                                stream=True,
                                headers={'x-auth-token': APIClient.auth_token})
        with open(path, 'wb') as f:
            for chunk in response.iter_content(65536):
                f.write(chunk)
    except Exception as e:
        logger.warning(e)
def pytest_runtest_makereport(item, call):
    config = item.session.config
    fuel_ip = getattr(item, 'fuel_ip', None)
    if fuel_ip is None:
        return

    make_snapshot = config.getoption("--make-snapshots")
    is_ci = os.environ.get('JOB_NAME') is not None
    test_failed = call.excinfo is not None
    if test_failed and (make_snapshot or is_ci):
        logger.info('Start generate fuel snapshot')
        try:
            task = SnapshotTask.start_snapshot_task({})
            waiting.wait(lambda: task.is_finished,
                         timeout_seconds=10 * 60,
                         sleep_seconds=5,
                         waiting_for='dump to be finished')
            if task.status != 'ready':
                raise Exception("Snapshot generating task ended with error. "
                                "Task message: {message}".format(**task.data))

            url = 'http://{fuel_ip}:8000{task.data[message]}'.format(
                fuel_ip=fuel_ip, task=task)
            response = requests.get(
                url,
                stream=True,
                headers={'x-auth-token': APIClient.auth_token})

            test_name = item.nodeid
            logger.info('Making snapshot to test {}'.format(test_name))
            filename = re.sub('[^\w\s-]', '_', test_name).strip().lower()
            _, ext = os.path.splitext(task.data['message'])
            ext = ext or '.tar'
            path = os.path.join('snapshots', filename + ext)

            with open(path, 'wb') as f:
                for chunk in response.iter_content(65536):
                    f.write(chunk)
        except Exception as e:
            logger.warning(e)
def _attach_diagnostic_snapshot():
    _configure_log()

    # FIXME(schipiga): include already installed packages for import visibility
    sys.path.extend(['/usr/lib/python2.7',
                     '/usr/lib/python2.7/dist-packages',
                     '/usr/local/lib/python2.7/dist-packages'])

    try:
        from devops.models import Environment
        from fuelclient import client, fuelclient_settings
        from fuelclient.objects import SnapshotTask
    except ImportError as e:
        LOGGER.error(e)
        return

    job_name = os.environ.get('JOB_NAME')
    if not job_name:
        LOGGER.info("Diagnostic snapshot is attached only on CI server")
        return

    env_name = os.environ.get('ENV_NAME')
    if not env_name:
        LOGGER.error("Environment name isn't specified at build")
        return

    try:
        env = Environment.get(name=env_name)
        master = env.get_nodes(role__in=('fuel_master', 'admin'))[0]
        admin_ip = master.get_ip_address_by_network_name('admin')

        os.environ.update({
            'SERVER_ADDRESS': admin_ip,
            'OS_USERNAME': '******',
            'OS_PASSWORD': '******',
        })
        fuelclient_settings._SETTINGS = None
        client.APIClient.__init__()

        config = SnapshotTask.get_default_config()
        task = SnapshotTask.start_snapshot_task(config)

        LOGGER.info('Starting snapshot creating...')
        task.wait()
        if task.status != 'ready':
            LOGGER.error("Snapshot creating is finished with error: {}".format(
                task.data["message"]))
            return
        LOGGER.info("Snapshot creating is finished")

        response = requests.get(
            'http://{}:8000{}'.format(admin_ip, task.data["message"]),
            stream=True,
            headers={'x-auth-token': client.APIClient.auth_token})

        file_path = os.path.join(_reports_dir(), 'diagnostic_snapshot.tar.xz')
        with open(file_path, 'wb') as f:
            for chunk in response.iter_content(65536):
                if chunk:
                    f.write(chunk)
    except Exception as e:
        LOGGER.error(e)