<repo_name>cyx1231st/pyingx<file_sep>/pyingx/lib/__init__.py
__author__ = 'Yingxin'
<file_sep>/pyingx/api/versions.py
from pyingx.api import wsgi


class Versions(wsgi.Resource):
    def index(self, req, body=None):
        return {'version': '1.0', 'author': 'cyx'}
<file_sep>/pyingx/api/wsgi.py
import routes
import routes.middleware
import webob.dec

from oslo_serialization import jsonutils


class Application(object):
    @classmethod
    def factory(cls, global_config, **local_config):
        return cls(**local_config)

    @webob.dec.wsgify
    def __call__(self, req):
        # Without webob: __call__(self, environ, start_response):
        raise NotImplementedError(_('You must implement __call__'))

class APIMapper(routes.Mapper):
    def routematch(self, url=None, environ=None):
        #if url == "":
            #result = self._match("", environ)
            #return result[0], result[1]
        return routes.Mapper.routematch(self, url, environ)

    def connect(self, *args, **kargs):
        # NOTE(vish): Default the format part of a route to only accept json
        #             and xml so it doesn't eat all characters after a '.'
        #             in the url.
        #kargs.setdefault('requirements', {})
        #if not kargs['requirements'].get('format'):
            #kargs['requirements']['format'] = 'json|xml'
        return routes.Mapper.connect(self, *args, **kargs)

class Router(Application):
    def __init__(self):
        self.map = APIMapper()
        self._router = routes.middleware.RoutesMiddleware(self._dispatch,
                                                          self.map)
    @staticmethod
    @webob.dec.wsgify
    def _dispatch(req):
        match = req.environ['wsgiorg.routing_args'][1]
        if not match:
            return webob.exc.HTTPNotFound()
        app = match['controller']
        return app

    @webob.dec.wsgify
    def __call__(self, req):
        return self._router


class Resource(Application):
    @webob.dec.wsgify
    def __call__(self, req):
        import pdb; pdb.set_trace()
        args = req.environ['wsgiorg.routing_args'][1].copy()
        del args['controller']
        try:
            del args['format']
        except KeyError:
            pass
        action = args.pop('action', None)

        content_type = req.content_type
        body = req.body
        accept = 'application/json'

        resp = self.index(req)

        body = jsonutils.dumps(resp)
        resp = webob.Response(body=body)
        resp.headers['Content-Type'] = 'application/json'
        return resp
<file_sep>/tox.ini
[tox]
envlist =
    py34,py27,pep8
skipsdist =
    True

[testenv]
usedevelop = 
    True
whitelist_externals =
    bash
    find
    rm
install_command =
    pip install -U --force-reinstall {opts} {packages}
setenv = 
    VIRTUAL_ENV={envdir}
    OS_TEST_PATH=./pyingx/tests/unit
    LANGUAGE=en_US
    LC_ALL=en_US.utf-8
deps = 
    -r{toxinidir}/test-requirements.txt
commands =
    find . -type f -name "*.pyc" -delete
    bash tools/pretty_tox.sh '{posargs}'
passenv =
    http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY

[testenv:common-constrains]
install_command =
    pip install -c{toxinidir}/requirements.txt {opts} {packages}

[pep8]
<file_sep>/pyingx/tests/unit/log/test_log.py
__author__ = 'Yingxin'

import fixtures
import testtools

from pyingx import log
from pyingx.experimental import test_obj
from pyingx.experimental import monkey_patch


def test1(*args, **kwargs):
    print args
    print kwargs
    print "in test1"

def dec(func):
    def func_wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return func_wrapper


class TestLog(testtools.TestCase):
    def test_global_level(self):
        g_level = log.get_global_level()
        self.assertEqual(g_level,
                         log.Level.INFO,
                         "Default log level should be INFO, not %r." % g_level)

        g_level = log.Level.ERROR
        log.set_global_level(g_level)
        self.assertEqual(log.get_global_level(),
                         g_level,
                         "Global level cannot be set.")

    def test_default_object(self):
        self.assertIsInstance(log.LOG, log.Logger, "LOG should be a instance of Logger.")

    def test_test(self):
        fixture = fixtures.MonkeyPatch('pyingx.experimental.test_obj.A.action', test1)
        fixture.setUp()
        ttt = test_obj.A()
        fixture.cleanUp()

        test_obj.A.action = dec(test_obj.A.action)

        a = monkey_patch.test1()

        ttt = test_obj.A()
        ttt.action()
<file_sep>/setup.sh
#!/bin/bash
set -x
TOP_DIR=$(cd $(dirname "$0") && pwd)
pushd $TOP_DIR > /dev/null

virtualenv venv_dev
source ./venv_dev/bin/activate
python setup.py develop
sudo mkdir /etc/pyingx
sudo cp ./etc/* /etc/pyingx/
# ln -sf $TOP_DIR/../pyingx ~/pyingx

popd > /dev/null
<file_sep>/pyingx/api/v1/test.py
from pyingx.api.v1 import Extension
from pyingx.api import wsgi


class Test(Extension, wsgi.Resource):
    name = "test"
    alias = "test"
    def index(self, req):
        return {'version': '1.0', 'author': 'cyx'}
<file_sep>/README.rst
install: 
$python setup.py install -e
$python setup.py develop

test:
$python setup.py testr
<file_sep>/pyingx/cmd/main.py
import eventlet
eventlet.monkey_patch(os=False)

from pyingx import server
from pyingx import config


def main():
    config.setup()
    server.launch()
<file_sep>/pyingx/config.py
from oslo_config import cfg
from oslo_log import log as logging


CONF = cfg.CONF
LOG = logging.getLogger(__name__)


def setup():
    logging.register_options(CONF)
    logging.set_defaults(default_log_levels=logging.get_default_log_levels())
    CONF(['--config-file', '/etc/pyingx/pyingx.conf'],
         project='test_server_conf')
    logging.setup(CONF, 'test_server_log')
<file_sep>/pyingx/experimental/monkey_patch.py
import fixtures
from pyingx.experimental import test_obj

def test(*args, **kwargs):
    print args
    print kwargs
    print "hello world"

def test1():
    ttt = test_obj.A()
    ttt.action()
    ttt.a = 6
    return ttt
<file_sep>/testbed/install_rabbit.sh
#!/bin/bash
set -o xtrace
unset GREP_OPTIONS
set -o nounset
umask 022

RABBIT_USERID=rabbituser
RABBIT_PASSWORD=<PASSWORD>

function apt-get {
    local result
    sudo apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@" < /dev/null
    result=$?
    echo $result
    return $result
}

# clean up
apt-get purge rabbitmq-server
apt-get purge erlang*

# install
apt-get install rabbitmq-server

# config
sudo /usr/sbin/service rabbitmq-server restart

sudo rabbitmqctl add_user "$RABBIT_USERID" "$RABBIT_PASSWORD" ||
    { echo "failed to add user" 1>&2; return 1; }
sudo rabbitmqctl set_permissions "$RABBIT_USERID" ".*" ".*" ".*" ||
    { echo "failed to set permissions" 1>&2; return 1; }
sudo rabbitmqctl change_password $RABBIT_USERID $RABBIT_PASSWORD ||
    { echo "failed to change password" 1>&2; return 1; }

echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/"
<file_sep>/testbed/test_wsgi/test_server.py
import eventlet
eventlet.monkey_patch(os=False)
from paste import deploy

from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import service


CONF = cfg.CONF
LOG = logging.getLogger(__name__)

logging.register_options(CONF)
logging.set_defaults(default_log_levels=logging.get_default_log_levels())
CONF(['--config-file', '/home/vagrant/test_wsgi/test_server.conf'],
     project='test_server_conf')
logging.setup(CONF, 'test_server_log')

# config
wsgi_group = cfg.OptGroup(
      'wsgi',
      title='WSGI Options')

api_paste_config = cfg.StrOpt(
      'api_paste_config',
      default="api-paste.ini",
      help='File name for the paste.deploy config')
app = cfg.StrOpt(
      'app',
      default="test",
      help='Paste app to load')

CONF.register_group(wsgi_group)
CONF.register_opts([app, api_paste_config], group=wsgi_group)


class Service(service.Service):
    def __init__(self):
        super(Service, self).__init__()
        import pdb; pdb.set_trace()

        # paste
        paste_config = CONF.wsgi.api_paste_config
        app = CONF.wsgi.app
        self.app = deploy.loadapp("config:%s" % paste_config, name=app)

    def start(self):
        LOG.info("Service started")

    def stop(self):
        LOG.info("Service stopped")

    def reset(self):
        LOG.info("Service reset")


if __name__ == "__main__":
    test_server = Service()
    launcher = service.launch(CONF, test_server, workers=1)
    launcher.wait()
<file_sep>/testbed/install_hypervisor.sh
#!/bin/bash
set -o xtrace
unset GREP_OPTIONS
set -o nounset
umask 022

RABBIT_USERID=rabbituser
RABBIT_PASSWORD=<PASSWORD>

function apt-get {
    local result
    sudo apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@" < /dev/null
    result=$?
    echo $result
    return $result
}

# install
apt-get install pkg-config qemu-kvm libguestfs0 libvirt-bin libvirt-dev
sudo pip install libvirt-python

# config
log_filters="1:libvirt 1:qemu 1:conf 1:security 3:object 3:event 3:json 3:file 1:util 1:cpu"
log_outputs="1:file:/var/log/libvirt/libvirtd.log"
if ! sudo grep -q "^log_filters=\"$log_filters\"" /etc/libvirt/libvirtd.conf; then
    echo "log_filters=\"$log_filters\"" | sudo tee -a /etc/libvirt/libvirtd.conf
fi
if ! sudo grep -q "^log_outputs=\"$log_outputs\"" /etc/libvirt/libvirtd.conf; then
    echo "log_outputs=\"$log_outputs\"" | sudo tee -a /etc/libvirt/libvirtd.conf
fi

sudo /usr/sbin/service libvirt-bin restart
<file_sep>/testbed/test_wsgi/paste.ini
[composite:paste_test]
use = egg:Paste#urlmap
/ = home
/test = test

[app:home]
paste.app_factory =

[app:test]
paste.app_factory =
<file_sep>/pyingx/experimental/test_obj.py
class A(object):
    def __init__(self):
        self.a = 5
    def action(self):
        print self.a
        print "hi"

def test(a, b):
    print a
    print b
    print "in test"
<file_sep>/pyingx/api/v1/__init__.py
import stevedore

from pyingx.api import wsgi


class Extension(object):
    name = None
    alias = None
    collection_actions = {}
    member_actions = {}
    def __init__(self, extension_info):
        self._extension_info = extension_info
        self._set_alias()

    def is_valid(self):
        return True

    @classmethod
    def _set_alias(cls):
        pass

class RouterV1(wsgi.Router):
    def __init__(self):
        super(RouterV1, self).__init__()
        self._extension_info = {}

        def _register_extension(ext):
            ext = ext.obj
            if not ext.is_valid():
                return False
            if ext.name in self._extension_info:
                raise RuntimeError("Duplicated extension name: %s!" % ext.name)
            self._extension_info[ext.name] = ext
            return True

        self._api_extension_manager = stevedore.enabled.EnabledExtensionManager(
                namespace='pyingx.api.v1',
                check_func=_register_extension,
                invoke_on_load=True,
                invoke_kwds={'extension_info': self._extension_info})

        def _map_extension(ext):
            ext = ext.obj
            self.map.resource(ext.alias, ext.alias,
                              controller=ext,
                              collection=ext.collection_actions,
                              member=ext.member_actions)

        self._api_extension_manager.map(_map_extension)
<file_sep>/pyingx/server.py
import eventlet
import eventlet.wsgi
from paste import deploy
import socket

from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import service


CONF = cfg.CONF
LOG = logging.getLogger(__name__)


# config
wsgi_group = cfg.OptGroup(
    'wsgi',
    title='WSGI Options')

api_paste_config = cfg.StrOpt(
    'api_paste_config',
    default="/etc/pyingx/api-paste.ini",
    help='File name for the paste.deploy config')

client_socket_timeout = cfg.IntOpt(
    'client_socket_timeout',
    default=900,
    help="Timeout for client connections' socket operations. "
         "If an incoming connection is idle for this number of "
         "seconds it will be closed. A value of '0' means "
         "wait forever.")

app = cfg.StrOpt(
    'app',
    default="pyingx",
    help='Paste app to load')

wsgi_log_format = cfg.StrOpt(
    'wsgi_log_format',
    default='%(client_ip)s "%(request_line)s" status: %(status_code)s'
            ' len: %(body_length)s time: %(wall_seconds).7f',
    help='A python format string that is used as the template to '
         'generate log lines. The following values can be formatted '
         'into it: client_ip, date_time, request_line, status_code, '
         'body_length, wall_seconds.')

tcp_keepidle = cfg.IntOpt(
    'tcp_keepidle',
    default=600,
    help='Sets the value of TCP_KEEPIDLE in seconds for each '
         'server socket. Not supported on OS X.')

default_pool_size = cfg.IntOpt(
    'default_pool_size',
    default=1000,
    help='Size of the pool of greenthreads used by wsgi')

keep_alive = cfg.BoolOpt(
    'keep_alive',
    default=True,
    help='If False, closes the client socket connection explicitly.')

client_socket_timeout = cfg.IntOpt(
    'client_socket_timeout',
    default=900,
    help="Timeout for client connections' socket operations. "
         "If an incoming connection is idle for this number of "
         "seconds it will be closed. A value of '0' means "
         "wait forever.")


CONF.register_group(wsgi_group)
CONF.register_opts([api_paste_config,
                    app,
                    client_socket_timeout,
                    default_pool_size,
                    keep_alive,
                    tcp_keepidle,
                    wsgi_log_format,
                   ],
                   group=wsgi_group)


class Service(service.Service):
    def __init__(self):
        """ Init ONCE in the parent process """
        super(Service, self).__init__()

        self.is_child = False
        # paste
        paste_config = CONF.wsgi.api_paste_config
        app = CONF.wsgi.app
        self._app = deploy.loadapp("config:%s" % paste_config, name=app)
        # pool
        self._pool = eventlet.GreenPool(CONF.wsgi.default_pool_size)
        # logger
        self._logger = logging.getLogger("pyingx.wsgi.server")
        # socket
        info = socket.getaddrinfo('0.0.0.0',
                                  '1314',
                                  socket.AF_UNSPEC,
                                  socket.SOCK_STREAM)
        family = info[0][0]
        bind_addr = info[0][-1]
        self._socket = eventlet.listen(bind_addr,
                                       family=family,
                                       backlog=128)
        (self.host, self.port) = self._socket.getsockname()[0:2]
        LOG.info("pyingx listening on %(host)s:%(port)s",
                 {'host': self.host, 'port': self.port})

    def start(self):
        """ Init in child processes """
        self.is_child = True
        # dupsocket
        dup_socket = self._socket.dup()
        dup_socket.setsockopt(socket.SOL_SOCKET,
                              socket.SO_REUSEADDR, 1)
        # sockets can hang around forever without keepalive
        dup_socket.setsockopt(socket.SOL_SOCKET,
                              socket.SO_KEEPALIVE, 1)

        # This option isn't available in the OS X version of eventlet
        if hasattr(socket, 'TCP_KEEPIDLE'):
            dup_socket.setsockopt(socket.IPPROTO_TCP,
                                  socket.TCP_KEEPIDLE,
                                  CONF.wsgi.tcp_keepidle)
        wsgi_kwargs = {
            'func': eventlet.wsgi.server,
            'sock': dup_socket,
            'site': self._app,
            'protocol': eventlet.wsgi.HttpProtocol,
            'custom_pool': self._pool,
            'log': self._logger,
            'log_format': CONF.wsgi.wsgi_log_format,
            'debug': False,
            'keepalive': CONF.wsgi.keep_alive,
            'socket_timeout': CONF.wsgi.client_socket_timeout
        }
        self._server = eventlet.spawn(**wsgi_kwargs)
        LOG.info("Service started")

    def stop(self):
        if self.is_child:
            self._pool.resize(0)
            self._server.kill()
        LOG.info("Service stopped")

    def reset(self):
        LOG.info("Service reset")

    def wait(self):
        if self.is_child:
            self._pool.waitall()
            self._server.wait()
        LOG.info("Service wait")


def launch():
    test_server = Service()
    launcher = service.launch(CONF, test_server, workers=4)
    launcher.wait()
<file_sep>/requirements.txt
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.

pbr>=1.6
iso8601>=0.1.9
enum34
Routes!=2.0,!=2.1,!=2.3.0,>=1.12.3;python_version=='2.7' # MIT
Routes!=2.0,!=2.3.0,>=1.12.3;python_version!='2.7' # MIT

oslo.config>=3.10.0
oslo.log>=1.14.0
oslo.service>=1.10.0
oslo.utils>=3.11.0

# test
testrepository
testtools
coverage
<file_sep>/pyingx/log/__init__.py
from logger import Logger
from logger import set_global_level
from logger import get_global_level
from logger import Level
from logger import LOG
<file_sep>/testbed/install_mysql.sh
#!/bin/bash
set -o xtrace
unset GREP_OPTIONS
set -o nounset
umask 022

MYSQL_USER=root
MYSQL_HOST=127.0.0.1
MYSQL_PASSWORD=<PASSWORD>

BASE_SQL_CONN=mysql+pymysql://$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST

source ./ini-config

function apt-get {
    local result
    sudo apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@" < /dev/null
    result=$?
    echo $result
    return $result
}

function stop_service {
    sudo /usr/sbin/service $1 stop
}

function start_service {
    sudo /usr/sbin/service $1 start
}

function restart_service {
    sudo /usr/sbin/service $1 restart
}

# clean up
apt-get purge mysql* mariadb*
sudo rm -rf /var/lib/mysql
sudo rm -rf /etc/mysql

# install
sudo debconf-set-selections <<EOF
mysql-server mysql-server/root_password password $<PASSWORD>
mysql-server mysql-server/root_password_again password $<PASSWORD>
mysql-server mysql-server/start_on_boot boolean true
EOF

if [[ ! -e $HOME/.my.cnf ]]; then
    cat <<EOF >$HOME/.my.cnf
[client]
user=$MYSQL_USER
password=$<PASSWORD>
host=$MYSQL_HOST
EOF
fi
chmod 0600 $HOME/.my.cnf

apt-get install mysql-server
start_service mysql

# config
sudo mysql -uroot -p$MYSQL_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%' identified by '$MYSQL_PASSWORD';"

my_conf=/etc/mysql/my.cnf
iniset -sudo $my_conf mysqld bind-address 0.0.0.0
iniset -sudo $my_conf mysqld sql_mode STRICT_ALL_TABLES
iniset -sudo $my_conf mysqld default-storage-engine InnoDB
iniset -sudo $my_conf mysqld max_connections 1024
iniset -sudo $my_conf mysqld query_cache_type OFF
iniset -sudo $my_conf mysqld query_cache_size 0

restart_service mysql

sudo pip install PyMySQL
sudo pip install SQLAlchemy

# echo configuration
echo "$BASE_SQL_CONN/mysql?charset=utf8"
<file_sep>/pyingx/log/logger.py
from enum import IntEnum

from pyingx import lib


class Level(IntEnum):
    INFO = 0
    WARN = 1
    ERROR = 2

_global_level = Level.INFO


def set_global_level(level):
    assert isinstance(level, Level)
    global _global_level
    _global_level = level


def get_global_level():
    return _global_level


class Logger(object):
    def __init__(self, level=None):
        if not level:
            self._level = None
        else:
            self._level = level

    def warn(self, msg):
        if (self._level or _global_level) <= Level.WARN:
            print "WARN: " + msg

    def error(self, msg):
        if (self._level or _global_level) <= Level.ERROR:
            print "ERROR: " + msg

    def info(self, msg):
        if (self._level or _global_level) <= Level.INFO:
            print "INFO: " + msg

    def set_level(self, level):
        assert isinstance(level, Level) or None
        self._level = level

    def get_level(self):
        return self._level or _global_level

LOG = Logger()
<file_sep>/testbed/libvirt_connect.py
import eventlet
eventlet.monkey_patch(os=False)

from eventlet import patcher
from eventlet import tpool
import libvirt
import six
import threading

from oslo_log import log as logging
from oslo_config import cfg


native_threading = patcher.original("threading")
native_queue = patcher.original("Queue" if six.PY2 else "queue")

CONF = cfg.CONF
LOG = logging.getLogger(__name__)


def init_logs(product="default_project"):
    logging.register_options(CONF)

    CONF.logging_exception_prefix = \
        "%(color)s%(asctime)s.%(msecs)03d " \
        "TRACE %(name)s [01;35m%(instance)s[00m"
    CONF.logging_debug_format_suffix = \
        "[00;33mfrom " \
        "(pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d[00m"
    CONF.logging_default_format_string = \
        "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s " \
        "[[00;36m-%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
    CONF.logging_context_format_string = \
        "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s " \
        "[[01;36m%(request_id)s " \
        "[00;36m%(user_name)s %(project_name)s%(color)s] " \
        "[01;35m%(instance)s%(color)s%(message)s[00m"

    logging.set_defaults(default_log_levels=logging.get_default_log_levels())
    logging.setup(CONF, product)


# libvirt utils start >>>
def libvirt_test_conn(conn):
    try:
        conn.getLibVersion()
        return True
    except libvirt.libvirtError as ex:
        if (ex.get_error_code() in (libvirt.VIR_ERR_SYSTEM_ERROR,
                                    libvirt.VIR_ERR_INTERNAL_ERROR) and
            ex.get_error_domain() in (libvirt.VIR_FROM_REMOTE,
                                      libvirt.VIR_FROM_RPC)):
            LOG.warn("libvirt connection broken")
            return False
        raise


def _connect_auth_cb(creds, opaque):
        if len(creds) == 0:
            return 0
        raise RuntimeError(
            "Can not handle authentication request for %d credentials"
            % len(creds))


def libvirt_connect(uri, read_only):
    auth = [[libvirt.VIR_CRED_AUTHNAME,
             libvirt.VIR_CRED_ECHOPROMPT,
             libvirt.VIR_CRED_REALM,
             libvirt.VIR_CRED_PASSPHRASE,
             libvirt.VIR_CRED_NOECHOPROMPT,
             libvirt.VIR_CRED_EXTERNAL],
            _connect_auth_cb,
            None]

    flags = 0
    if read_only:
        flags = libvirt.VIR_CONNECT_RO
    # tpool.proxy_call creates a native thread. Due to limitations
    # with eventlet locking we cannot use the logging API inside
    # the called function.
    return tpool.proxy_call(
        (libvirt.virDomain, libvirt.virConnect),
        libvirt.openAuth, uri, auth, flags)

# libvirt utils end <<<


class LibvirtHost(object):
    def __init__(self, uri, read_only=False):
        self._native_event_queue = None

        self._event_thread = None

        self._uri = None
        self._read_only = read_only
        self._conn = None
        self._conn_lock = threading.Lock()

    def _native_event_lifecycle(self, conn, dom, event, detail, opaque):
        print("Event lifecycle, uuid: %s, event: %s" % (dom.uuid, event))

    def _native_close_callback(self, conn, reason, opaque):
        print("Close, reason: %s" % reason)

    def _native_thread(self):
        """Do not use LOG here!"""
        print("In native thread %s" % native_threading._get_ident())
        while True:
            libvirt.virEventRunDefaultImpl()

    def _dispatch_event(self):
        LOG.info("In green thread %s" % native_threading._get_ident())
        while True:
            eventlet.sleep(5)

    @staticmethod
    def _native_libvirt_error_handler(context, err):
        print("Error: %s" % err)

    def initialize(self):
        # prepare libvirt
        libvirt.registerErrorHandler(self._native_libvirt_error_handler, None)
        libvirt.virEventRegisterDefaultImpl()

        # start native listening thread
        self._native_event_queue = native_queue.Queue()
        self._event_thread = native_threading.Thread(
            target=self._native_thread)
        self._event_thread.setDaemon(True)
        self._event_thread.start()

        # prepare dispatching greenthread
        eventlet.spawn_n(self._dispatch_event)

    def get_connection(self):
        """:returns: a libvirt.virConnect object """
        with self._conn_lock:
            if not self._conn or not libvirt_test_conn(self._conn):
                LOG.info("Get new libvirt connection...")
                try:
                    self._conn = libvirt_connect(self._uri, self._read_only)
                finally:
                    if not self._conn:
                        LOG.warn("Failed to connect to libvirt!")

                try:
                    # NOTE: What is opaque?
                    self._conn.domainEventRegisterAny(
                        None,
                        libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                        self._native_event_lifecycle,
                        self)
                except Exception as e:
                    LOG.warn("URI %(uri)s does not support events: %(error)s" %
                             {'uri': self._uri, 'error': e})

                try:
                    self._conn.registerCloseCallback(
                        self._native_close_callback,
                        None)
                except (TypeError, AttributeError) as e:
                    # NOTE: The registerCloseCallback of python-libvirt 1.0.1+
                    # is defined with 3 arguments, and the above registerClose-
                    # Callback succeeds. However, the one of python-libvirt
                    # 1.0.0 is defined with 4 arguments and TypeError happens
                    # here.  Then python-libvirt 0.9 does not define a method
                    # register- CloseCallback.
                    LOG.warn("The version of python-libvirt does not support "
                             "registerCloseCallback or is too old: %s", e)
                except libvirt.libvirtError as e:
                    LOG.warn("URI %(uri)s does not support connection"
                             " events: %(error)s" %
                             {'uri': self._uri, 'error': e})

        return self._conn

    def get_info(self):
        return self.get_connection().getInfo()


if __name__ == "__main__":
    init_logs(product="libvirt")

    host = LibvirtHost("qemu:///system")
    host.initialize()

    print(host.get_info())

    LOG.info("Start finished..")
    eventlet.hubs.get_hub().switch()
