neutron full stack

1.  通读一下 neutron的那个文档。  里面介绍了, db怎么隔离的, amqp怎么隔离的。

2.  记住文档中,那个full stack的图。

3.  走读代码

从TestOvsConnectivitySameNetwork
开始走读。  这个case
是neutron的文档推荐的。

继承自,  BaseConnectivitySameNetworkTest —>
BaseFullStackTestCase

整个图,
是environment的类,    
图中的 Host 1 和Host 2
是 一个Host的类。

environment 主要负责
创建 central-data-br, central-external-br, Host 1
和Host 2,
还有启动neutron-server。

Host 创建br-phy, br-int, br-ex,
启动L2,L3的agent。

代码的逻辑性非常好,还是很清晰的,很容易看明白。具体的代码分析,见下面的email。

穆勒的那个介绍neutron的文档 https://assafmuller.com/

1. configure_for_func_testing

go through code.

tools/configure_for_func_testing.sh

_init
      # 执行了devstack/stackrc

if [[ "$IS_GATE" != "True" ]]; then

if [[ "$INSTALL_MYSQL_ONLY" == "True" ]]; then

_install_databases nopg          #仅仅配置了db, 使用
mysql+pymysql://openstack_citest:***@localhost/etmtdbylqa

else

configure_host_for_func_testing           # 配置了db, rpc , 安装了依赖包

fi

fi

if [[ "$VENV" =~ "dsvm-fullstack" ]]; then

echo "***********************************"

_configure_iptables_rules                 #    iptables
配置了INPUT, 240.0.0.0/8 C类网段的 5672   用来做RPC通信。

fi

这个文件本身不大, 需要结合 devstack/stackrc   分析。

2.  分析 neutron/tests/fullstack/test_connectivity.py  TestOvsConnectivitySameNetwork 这个testcase:

主要分析 db的配置,engine的rul怎么赋值的。

http://localhost:8000/devref/development.environment.html#unit-tests

1. unit test的DB

文档中,说 unit test使用了sqlite db,并且可以根据,

You can get oslo.db to generate a file-based sqlite database by setting OS_TEST_DBAPI_ADMIN_CONNECTION to a file based URL as described in this mailing list post. This file will be created but (confusingly) won’t be the actual file used for the database. To find the actual file, set a break point in your test method and inspect self.engine.url.

$ OS_TEST_DBAPI_ADMIN_CONNECTION=sqlite:///sqlite.db .tox/py27/bin/python -m     testtools.run neutron.tests.unit...
...
(Pdb) self.engine.url
sqlite:////tmp/iwbgvhbshp.db

Now, you can inspect this file using sqlite3.

$ sqlite3 /tmp/iwbgvhbshp.db

但是,我无论实在neutron的代码中,还是在devstack的代码中,都没有找到 OS_TEST_DBAPI_ADMIN_CONNECTION

2. full-stack的db

driver使用了mysql

engine.url 实际上是使用了mysql+pymysql://openstack_citest:***@localhost/etmtdbylqa

但是 没有找到哪里配置了这个url

git 最好的地方,记录了每次改动,啥蛛丝马迹都能从这里找到。

看 full-stack的第一次提交;

$ git show e0ea5edc128e7191d11514868b5711c23ef23821

搜索, BaseFullStackTestCase ,竟然是hard code 配置DB

太好了,可以顺藤摸瓜了。 顺藤摸瓜最好的手段就是, whatchanged -p

发现了,

$ git show 546ba377db81e7ba984b63942f6bbb974a653e3c

移除了 这个hard code

并 实现了2个类

OpportunisticSqlFixture

OpportunisticDBTestMixin

OpportunisticDBTestMixin 有个动态(property)属性,
实际上是调用了,OpportunisticSqlFixture 的 resources_collection
 方法。provision.DatabaseResource(driver) 产生了engine.url

In [12]: from oslo_db.sqlalchemy import provision

In [13]:
provision.DatabaseResource("mysql").getResource().engine

Out[13]: Engine(mysql+pymysql://openstack_citest:***@localhost/wzctqbdybv)

In [2]: from oslo_db.sqlalchemy import provision

In [3]:
provision.DatabaseResource("mysql").getResource().engine

Out[3]: Engine(mysql+pymysql://openstack_citest:***@localhost/nyfqsnrpii)

每次生成 db的路径是不同的。

达到,隔离的目的。

下载 oslo.db的代码:

$ git clone git://git.openstack.org/openstack/oslo.db.git

$ git grep openstack_citest

。。。

oslo_db/sqlalchemy/provision.py:        e.g. username+password = "openstack_citest".

oslo_db/sqlalchemy/provision.py:        return "mysql+pymysql://openstack_citest:openstack_citest@localhost/"

oslo_db/sqlalchemy/provision.py:        return "postgresql://openstack_citest:openstack_citest"\

oslo_db/sqlalchemy/test_base.py:    DBNAME = PASSWORD = USERNAME = ‘openstack_citest

。。。

发现这个 engine.url 的 hard code 确实移到了 provision.py

实际上文档说了,首先查找,OS_TEST_DBAPI_ADMIN_CONNECTION

$ pydoc oslo_db.sqlalchemy.provision.Backend._setup

Help on method _setup in oslo_db.sqlalchemy.provision.Backend:

oslo_db.sqlalchemy.provision.Backend._setup = _setup(cls) method of __builtin__.type instance

Initial startup feature will scan the environment for configured

URLs and place them into the list of URLs we will use for provisioning.

This searches through OS_TEST_DBAPI_ADMIN_CONNECTION for URLs.  If

not present, we set up URLs based on the "opportunstic" convention,

e.g. username+password = "openstack_citest".

The provisioning system will then use or discard these URLs as they

are requested, based on whether or not the target database is actually

found to be available.

(END)

3. test case 的代码分析。

下面的代码是最新的代码,很难找到头绪了,后面的thread 继续分析。要分析的内容很多。

继承关系依次是:

TestOvsConnectivitySameNetwork -》BaseConnectivitySameNetworkTest -》 BaseFullStackTestCase

而 BaseFullStackTestCase 是多继承。继承了MySQLTestCaseMixin ->OpportunisticDBTestMixin , OpportunisticDBTestMixin使用了OpportunisticSqlFixture

class TestOvsConnectivitySameNetwork(BaseConnectivitySameNetworkTest):

l2_agent_type = constants.AGENT_TYPE_OVS

network_scenarios = [

(‘VXLAN‘, {‘network_type‘: ‘vxlan‘,

‘l2_pop‘: False}),

(‘GRE-l2pop-arp_responder‘, {‘network_type‘: ‘gre‘,

‘l2_pop‘: True,

‘arp_responder‘: True}),

(‘VLANs‘, {‘network_type‘: ‘vlan‘,

‘l2_pop‘: False})]

scenarios = testscenarios.multiply_scenarios(

network_scenarios, utils.get_ovs_interface_scenarios())

def test_connectivity(self):

self._test_connectivity()

class BaseConnectivitySameNetworkTest(base.BaseFullStackTestCase):

of_interface = None

ovsdb_interface = None

arp_responder = False

def setUp(self):

host_descriptions = [

# There‘s value in enabling L3 agents registration when l2pop

# is enabled, because l2pop code makes assumptions about the

# agent types present on machines.

environment.HostDescription(

l3_agent=self.l2_pop,

of_interface=self.of_interface,

ovsdb_interface=self.ovsdb_interface,

l2_agent_type=self.l2_agent_type) for _ in range(3)]

env = environment.Environment(

environment.EnvironmentDescription(

network_type=self.network_type,

l2_pop=self.l2_pop,

arp_responder=self.arp_responder),

host_descriptions)

super(BaseConnectivitySameNetworkTest, self).setUp({})

def _test_connectivity(self):

tenant_uuid = uuidutils.generate_uuid()

network = self.safe_client.create_network(tenant_uuid)

self.safe_client.create_subnet(

tenant_uuid, network[‘id‘], ‘20.0.0.0/24‘)

vms = machine.FakeFullstackMachinesList([

self.useFixture(

machine.FakeFullstackMachine(

self.environment.hosts[i],

network[‘id‘],

tenant_uuid,

self.safe_client))

for i in range(3)])

vms.block_until_all_boot()

vms.ping_all()

class BaseFullStackTestCase(testlib_api.MySQLTestCaseMixin,

testlib_api.SqlTestCase):

"""Base test class for full-stack tests."""

BUILD_WITH_MIGRATIONS = True

def setUp(self, environment):

super(BaseFullStackTestCase, self).setUp()

tests_base.setup_test_logging(

cfg.CONF, DEFAULT_LOG_DIR, ‘%s.txt‘ % self.get_name())

# NOTE(zzzeek): the opportunistic DB fixtures have built for

# us a per-test (or per-process) database.  Set the URL of this

# database in CONF as the full stack tests need to actually run a

# neutron server against this database.

_orig_db_url = cfg.CONF.database.connection

cfg.CONF.set_override(

‘connection‘, str(self.engine.url), group=‘database’)  # 没有找到

self.addCleanup(

cfg.CONF.set_override,

"connection", _orig_db_url, group="database"

)

# NOTE(ihrachys): seed should be reset before environment fixture below

# since the latter starts services that may rely on generated port

# numbers

tools.reset_random_seed()

self.environment = environment

self.environment.test_name = self.get_name()

self.useFixture(self.environment)

self.client = self.environment.neutron_server.client

self.safe_client = self.useFixture(

client_resource.ClientFixture(self.client))

def get_name(self):

class_name, test_name = self.id().split(".")[-2:]

return "%s.%s" % (class_name, test_name)

1.  参考例子:

neutron/tests/fullstack/test_connectivity.py

neutron.tests.fullstack.test_connectivity.TestOvsConnectivitySameNetwork

class BaseConnectivitySameNetworkTest(base.BaseFullStackTestCase):

of_interface = None

ovsdb_interface = None

arp_responder = False

def setUp(self):

host_descriptions = [

# There‘s value in enabling L3 agents registration when l2pop

# is enabled, because l2pop code makes assumptions about the

# agent types present on machines.

environment.HostDescription(   # 这个仅仅用来

l3_agent=self.l2_pop,

of_interface=self.of_interface,

ovsdb_interface=self.ovsdb_interface,

l2_agent_type=self.l2_agent_type) for _ in range(3)]

env = environment.Environment(

environment.EnvironmentDescription(

network_type=self.network_type,

l2_pop=self.l2_pop,

arp_responder=self.arp_responder),

host_descriptions)

super(BaseConnectivitySameNetworkTest, self).setUp(env)

def _test_connectivity(self):

tenant_uuid = uuidutils.generate_uuid()

network = self.safe_client.create_network(tenant_uuid)

self.safe_client.create_subnet(

tenant_uuid, network[‘id‘], ‘20.0.0.0/24’)

vms = machine.FakeFullstackMachinesList([

self.useFixture(

machine.FakeFullstackMachine(

self.environment.hosts[i],

network[‘id‘],

tenant_uuid,

self.safe_client))

for i in range(3)])

vms.block_until_all_boot()

vms.ping_all()

分析BaseConnectivitySameNetworkTest

population 到底是什么意思?

主要分析怎么创建server和配置rabbitmq的。 还需要具体分析agent的host怎么创建。

写full stack这个人,很是熟悉neutron的结构啊。

1.  参考例子:

neutron/tests/fullstack/test_connectivity.py

neutron.tests.fullstack.test_connectivity.TestOvsConnectivitySameNetwork

这个类derived from BaseConnectivitySameNetworkTest

class BaseConnectivitySameNetworkTest(base.BaseFullStackTestCase):

    of_interface = None
    ovsdb_interface = None
    arp_responder = False

    def setUp(self):
        host_descriptions = [
            # There‘s value in enabling L3 agents registration when l2pop
            # is enabled, because l2pop code makes assumptions about the
            # agent types present on machines.
            environment.HostDescription(   # 这个类很简单,就是几个变量用来描述 host
                l3_agent=self.l2_pop,
                of_interface=self.of_interface,
                ovsdb_interface=self.ovsdb_interface,
                l2_agent_type=self.l2_agent_type) for _ in range(3)]
        env = environment.Environment(    # 这个类,是用来真正部署host集群环境的。需要具体分析。见下图后的分析。
            environment.EnvironmentDescription(  # 这个类很简单,就是几个变量用来描述host的环境
                network_type=self.network_type,
                l2_pop=self.l2_pop,
                arp_responder=self.arp_responder),
            host_descriptions)
        super(BaseConnectivitySameNetworkTest, self).setUp(env)

    def _test_connectivity(self):
        tenant_uuid = uuidutils.generate_uuid()

        network = self.safe_client.create_network(tenant_uuid)
        self.safe_client.create_subnet(
            tenant_uuid, network[‘id‘], ‘20.0.0.0/24’)

        vms = machine.FakeFullstackMachinesList([
            self.useFixture(
                machine.FakeFullstackMachine(
                    self.environment.hosts[i],
                    network[‘id‘],
                    tenant_uuid,
                    self.safe_client))
            for i in range(3)])

        vms.block_until_all_boot()
        vms.ping_all()

这个类,主要是实现上面的这个图。

full stack的拓扑描述,请参考:

$ cd doc/build/html

$ python -m SimpleHTTPServer 8000

http://localhost.bj.intel.com:8000/devref/development.environment.html#fullstack-tests

这是个Fixture,从_setup 入口分析。

class Environment(fixtures.Fixture):
    """Represents a deployment topology.

    Environment is a collection of hosts. It starts a Neutron server
    and a parametrized number of Hosts, each a collection of agents.
    The Environment accepts a collection of HostDescription, each describing
    the type of Host to create.
    """

    def __init__(self, env_desc, hosts_desc):
        """
        :param env_desc: An EnvironmentDescription instance.
        :param hosts_desc: A list of HostDescription instances.
        """

        super(Environment, self).__init__()
        self.env_desc = env_desc
        self.hosts_desc = hosts_desc
        self.hosts = []

    def wait_until_env_is_up(self):
        common_utils.wait_until_true(self._processes_are_ready)

    def _processes_are_ready(self):
        try:
            running_agents = self.neutron_server.client.list_agents()[‘agents‘]
            agents_count = sum(len(host.agents) for host in self.hosts)
            return len(running_agents) == agents_count
        except nc_exc.NeutronClientException:
            return False

    def _create_host(self, host_desc):
        temp_dir = self.useFixture(fixtures.TempDir()).path
        neutron_config = config.NeutronConfigFixture( # 跟server类似的配置。
            self.env_desc, host_desc, temp_dir,
            cfg.CONF.database.connection, self.rabbitmq_environment)
        self.useFixture(neutron_config)

        return self.useFixture(  #  图中 Host 1 和 Host 2的创建。
            Host(self.env_desc,
                 host_desc,
                 self.test_name,
                 neutron_config,
                 self.central_data_bridge,
                 self.central_external_bridge))

    def _setUp(self):
        self.temp_dir = self.useFixture(fixtures.TempDir()).path

        #we need this bridge before rabbit and neutron service will start
        # 调用了 neutron/agent/common/ovs_lib 中的 BaseOVS 创建 bridge, 这2个bridge 是global的。
                self.central_data_bridge = self.useFixture(  # 创建图中的最顶部的bridge。
            net_helpers.OVSBridgeFixture(‘cnt-data‘)).bridge
        self.central_external_bridge = self.useFixture(  # 创建图中的最底部的bridge。
            net_helpers.OVSBridgeFixture(‘cnt-ex‘)).bridge

        #Get rabbitmq address (and cnt-data network)
        rabbitmq_ip_address = self._configure_port_for_rabbitmq() # 240.0.0.0 c类地址中的一个。
        self.rabbitmq_environment = self.useFixture( # 创建了一个vhost,创建了一个用户,随机password,为这个用户设置host的权限。
            process.RabbitmqEnvironmentFixture(host=rabbitmq_ip_address) # 实在是没有找到 这个ip 这里没有使用
        )

        plugin_cfg_fixture = self.useFixture(
            config.ML2ConfigFixture( # 配置了租户的网络类型,mechanical driver,vlan/vxlan/gre的 range
                self.env_desc, self.hosts_desc, self.temp_dir,
                self.env_desc.network_type))
        neutron_cfg_fixture = self.useFixture(
            config.NeutronConfigFixture( # 生成了一个neutron的config,这个config, 配置了service plugin,配置paste,配置了rabbitmq的url,配置了DB的connect
                self.env_desc, None, self.temp_dir,
                cfg.CONF.database.connection, self.rabbitmq_environment))
        self.neutron_server = self.useFixture(
            process.NeutronServerFixture( # 启动了一个neutron-server进程, 全局的namespace。通过是spawn找到了执行文件,需要研究一下。
                self.env_desc, None,
                self.test_name, neutron_cfg_fixture, plugin_cfg_fixture))
        # 创建agent
        self.hosts = [self._create_host(desc) for desc in self.hosts_desc]

        self.wait_until_env_is_up()  # 60秒,等所有的agent起来。

    def _configure_port_for_rabbitmq(self):
        self.env_desc.network_range = self._get_network_range()
        if not self.env_desc.network_range:
            return "127.0.0.1"
        rabbitmq_ip = str(self.env_desc.network_range[1])
        rabbitmq_port = ip_lib.IPDevice(self.central_data_bridge.br_name)
        # 顶部的bridge 配置了IP?
        rabbitmq_port.addr.add(common_utils.ip_to_cidr(rabbitmq_ip, 24))
        # 顶部的bridge 启动起来?
        rabbitmq_port.link.set_up()

        return rabbitmq_ip

    def _get_network_range(self):
        #NOTE(slaweq): We need to choose IP address on which rabbitmq will be
        # available because LinuxBridge agents are spawned in their own
        # namespaces and need to know where the rabbitmq server is listening.
        # For ovs agent it is not necessary because agents are spawned in
        # globalscope together with rabbitmq server so default localhost
        # address is fine for them
        for desc in self.hosts_desc:
            if desc.l2_agent_type == constants.AGENT_TYPE_LINUXBRIDGE:
                return self.useFixture(
                    # network 就是个netaddr.IPNetwork 但是持久化了。
                    # 可以看这个doc string
                    # $ pydoc neutron.tests.common.exclusive_resources.resource_allocator.ResourceAllocator
                    ip_network.ExclusiveIPNetwork(
                        "240.0.0.0", "240.255.255.255", "24")).network

走读 Host的代码:

Host 仍然是个Fixture, 从_setup 开始分析。

任然结合 full stack的网络拓扑图。

每个进程(包括server 和agent)都是通过spawn找到了执行文件,需要研究一下。

class Host(fixtures.Fixture):
    """The Host class models a physical host running agents, all reporting with
    the same hostname.

    OpenStack installers or administrators connect compute nodes to the
    physical tenant network by connecting the provider bridges to their
    respective physical NICs. Or, if using tunneling, by configuring an
    IP address on the appropriate physical NIC. The Host class does the same
    with the connect_* methods.
    # 是不是可以贡献代码啊?
    TODO(amuller): Add start/stop/restart methods that will start/stop/restart
    all of the agents on this host. Add a kill method that stops all agents
    and disconnects the host from other hosts.
    """

    def __init__(self, env_desc, host_desc,
                 test_name, neutron_config,
                 central_data_bridge, central_external_bridge):
        self.env_desc = env_desc
        self.host_desc = host_desc
        self.test_name = test_name
        self.neutron_config = neutron_config
        self.central_data_bridge = central_data_bridge    # 每个host 都会连接 图中的顶部和底部的bridge。
        self.central_external_bridge = central_external_bridge
        self.host_namespace = None
        self.agents = {}
        # we need to cache already created "per network" bridges if linuxbridge
        # agent is used on host:
        self.network_bridges = {}

    def _setUp(self):
        self.local_ip = self.allocate_local_ip()  # 

        if self.host_desc.l2_agent_type == constants.AGENT_TYPE_OVS:
            self.setup_host_with_ovs_agent()
        elif self.host_desc.l2_agent_type == constants.AGENT_TYPE_LINUXBRIDGE:
            self.setup_host_with_linuxbridge_agent()
        if self.host_desc.l3_agent:
            self.l3_agent = self.useFixture(
                process.L3AgentFixture(
                    self.env_desc, self.host_desc,
                    self.test_name,
                    self.neutron_config,
                    self.l3_agent_cfg_fixture))

    def setup_host_with_ovs_agent(self):
        # config br-int, ovs的名称,open follow接口 ovs-ofctl, db接口vsctl,agent, security group…
        # 以及与之连接的 bridge是br-eth(‘vlan‘)还是br-tun(‘vxlan‘, ‘gre’的情况下)
        agent_cfg_fixture = config.OVSConfigFixture(
            self.env_desc, self.host_desc, self.neutron_config.temp_dir,
            self.local_ip)
        self.useFixture(agent_cfg_fixture)

        # 怎么链接到 图中顶层的bridge, internal的bridge
        if self.env_desc.tunneling_enabled:
            self.useFixture(
                net_helpers.OVSBridgeFixture(
                    agent_cfg_fixture.get_br_tun_name())).bridge
            self.connect_to_internal_network_via_tunneling() # 通过veth连接, 其中一个 veth的IP为local_ip
        else:
            br_phys = self.useFixture(
                net_helpers.OVSBridgeFixture(
                    agent_cfg_fixture.get_br_phys_name())).bridge
            self.connect_to_internal_network_via_vlans(br_phys) # 通过ovs的patch连接

        self.ovs_agent = self.useFixture( # 启动ovs的agent,按照前面的配置。
            process.OVSAgentFixture(
                self.env_desc, self.host_desc,
                self.test_name, self.neutron_config, agent_cfg_fixture))

        # 怎么链接到 图中底层的bridge, external的bridge
        if self.host_desc.l3_agent:
            self.l3_agent_cfg_fixture = self.useFixture(
                # 主要是 namespace 和 interface_driver(ovs 还是linux bridge)
                config.L3ConfigFixture(
                    self.env_desc, self.host_desc,
                    self.neutron_config.temp_dir,
                    self.ovs_agent.agent_cfg_fixture.get_br_int_name()))
            br_ex = self.useFixture(
                net_helpers.OVSBridgeFixture(
                    self.l3_agent_cfg_fixture.get_external_bridge())).bridge
            self.connect_to_external_network(br_ex)  # 通过ovs的patch连接

    def setup_host_with_linuxbridge_agent(self):
        #First we need to provide connectivity for agent to prepare proper
        #bridge mappings in agent‘s config:
        self.host_namespace = self.useFixture(
            net_helpers.NamespaceFixture(prefix="host-")
        ).name

        # 怎么链接到 图中底层的bridge, external的bridge, 有两种方式,一种是直接连接 bridge?
        # 直接 bridge 带 可使用 veth,也可以不使用。
        # 一种是有增加了一个linux bridge, qbr
        self.connect_namespace_to_control_network()

        agent_cfg_fixture = config.LinuxBridgeConfigFixture(
            self.env_desc, self.host_desc,
            self.neutron_config.temp_dir,
            self.local_ip,
            physical_device_name=self.host_port.name
        )
        self.useFixture(agent_cfg_fixture)

        self.linuxbridge_agent = self.useFixture(
            process.LinuxBridgeAgentFixture(
                self.env_desc, self.host_desc,
                self.test_name, self.neutron_config, agent_cfg_fixture,
                namespace=self.host_namespace
            )
        )
        if self.host_desc.l3_agent:
            self.l3_agent_cfg_fixture = self.useFixture(
                config.L3ConfigFixture(
                    self.env_desc, self.host_desc,
                    self.neutron_config.temp_dir))

    def _connect_ovs_port(self, cidr_address):
        ovs_device = self.useFixture(
            net_helpers.OVSPortFixture(
                bridge=self.central_data_bridge,
                namespace=self.host_namespace)).port
        # NOTE: This sets an IP address on the host‘s root namespace
        # which is cleaned up when the device is deleted.
        ovs_device.addr.add(cidr_address)
        return ovs_device

    def connect_namespace_to_control_network(self):
        self.host_port = self._connect_ovs_port(
            common_utils.ip_to_cidr(self.local_ip, 24)
        )
        self.host_port.link.set_up()

    def connect_to_internal_network_via_tunneling(self):
        veth_1, veth_2 = self.useFixture(
            net_helpers.VethFixture()).ports

        # NOTE: This sets an IP address on the host‘s root namespace
        # which is cleaned up when the device is deleted.
        veth_1.addr.add(common_utils.ip_to_cidr(self.local_ip, 32))

        veth_1.link.set_up()
        veth_2.link.set_up()

    def connect_to_internal_network_via_vlans(self, host_data_bridge):
        # If using VLANs as a segmentation device, it‘s needed to connect
        # a provider bridge to a centralized, shared bridge.
        net_helpers.create_patch_ports(
            self.central_data_bridge, host_data_bridge)

    def connect_to_external_network(self, host_external_bridge):
        net_helpers.create_patch_ports(
            self.central_external_bridge, host_external_bridge)

    def allocate_local_ip(self):
        if not self.env_desc.network_range:
            return str(self.useFixture(
                ip_address.ExclusiveIPAddress(
                    ‘240.0.0.1‘, ‘240.255.255.254‘)).address)
        return str(self.useFixture(
            ip_address.ExclusiveIPAddress(
                str(self.env_desc.network_range[2]),
                str(self.env_desc.network_range[-2]))).address)

    def get_bridge(self, network_id):
        if "ovs" in self.agents.keys():
            return self.ovs_agent.br_int
        elif "linuxbridge" in self.agents.keys():
            bridge = self.network_bridges.get(network_id, None)
            if not bridge:
                br_prefix = lb_agent.LinuxBridgeManager.get_bridge_name(
                    network_id)
                bridge = self.useFixture(
                    net_helpers.LinuxBridgeFixture(
                        prefix=br_prefix,
                        namespace=self.host_namespace,
                        prefix_is_full_name=True)).bridge
                self.network_bridges[network_id] = bridge
        return bridge

    @property
    def hostname(self):
        return self.neutron_config.config.DEFAULT.host

    @property
    def l3_agent(self):
        return self.agents[‘l3‘]

    @l3_agent.setter
    def l3_agent(self, agent):
        self.agents[‘l3‘] = agent

    @property
    def ovs_agent(self):
        return self.agents[‘ovs‘]

    @ovs_agent.setter
    def ovs_agent(self, agent):
        self.agents[‘ovs‘] = agent

    @property
    def linuxbridge_agent(self):
        return self.agents[‘linuxbridge‘]

    @linuxbridge_agent.setter
    def linuxbridge_agent(self, agent):
        self.agents[‘linuxbridge‘] = agent

setup 环境实验

感觉还是环境配置的不对啊。

好像是DB的问题。

A. prepare and read the docs

1.

$ cd /opt/stack/neutron

2.

$ tox -e docs

3.

$ cd doc/build/html

open this url in your browser

http://localhost:8000

http://localhost:8000/devref/development.environment.html#fullstack-tests

B. test the example code

$ python -m testtools.run neutron.tests.fullstack.test_connectivity

发现测试案例 都是 skip了。

然后在查看文档,需要依赖 functional test, 而且需要运行:

IMPORTANT: configure_for_func_testing.sh relies on DevStack to perform
extensive modification to the underlying host. Execution of the script
requires sudo privileges and it is recommended that the following
commands be invoked only on a clean and disposeable
VM. A VM that has had DevStack previously installed on it is also fine.

git clone https://git.openstack.org/openstack-dev/devstack ../devstack
./tools/configure_for_func_testing.sh ../devstack -i
tox -e dsvm-functional

我运行:

DATABASE_PASSWORD=123 MYSQL_PASSWORD=123 VENV=dsvm-fullstack tools/configure_for_func_testing.sh ~/work/devstack/

还是报错。

$ tox -e dsvm-fullstack neutron.tests.fullstack.test_connectivity

{3} neutron.tests.fullstack.test_connectivity.TestLinuxBridgeConnectivitySameNetwork.test_connectivity(VLANs) [63.478852s] .

.. FAILED

DROP ALL OBJECTS, BACKEND mysql+pymysql://openstack_citest:[email protected]/yirrvssjhc

{0} neutron.tests.fullstack.test_connectivity.TestOvsConnectivitySameNetwork.test_connectivity(VXLAN,openflow-native_ovsdb-c

li) [63.821751s] ... FAILED

DROP BACKEND Engine(mysql+pymysql://openstack_citest:***@localhost/) TOKEN yirrvssjhc

DROP ALL OBJECTS, BACKEND mysql+pymysql://openstack_citest:[email protected]/ymodkllfsw

DB exception wrapped.

2016-11-26 07:49:47.407 27761 ERROR oslo_db.sqlalchemy.exc_filters Traceback (most recent call last):

2016-11-26 07:49:47.407 27761 ERROR oslo_db.sqlalchemy.exc_filters   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/

python2.7/site-packages/sqlalchemy/engine/base.py", line 316, in connection

2016-11-26 07:49:47.407 27761 ERROR oslo_db.sqlalchemy.exc_filters     return self._revalidate_connection()

2016-11-26 07:49:47.407 27761 ERROR oslo_db.sqlalchemy.exc_filters   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/

python2.7/site-packages/sqlalchemy/engine/base.py", line 391, in _revalidate_connection

2016-11-26 07:49:47.407 27761 ERROR oslo_db.sqlalchemy.exc_filters     "Can‘t reconnect until invalid "

2016-11-26 07:49:47.407 27761 ERROR oslo_db.sqlalchemy.exc_filters InvalidRequestError: Can‘t reconnect until invalid transa

ction is rolled back

2016-11-26 07:49:47.407 27761 ERROR oslo_db.sqlalchemy.exc_filters

2016-11-26 07:49:47.588 27763 ERROR neutron Traceback (most recent call last):

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main

2016-11-26 07:49:47.588 27763 ERROR neutron     "__main__", fname, loader, pkg_name)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/lib/python2.7/runpy.py", line 72, in _run_code

2016-11-26 07:49:47.588 27763 ERROR neutron     exec code in run_globals

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/subunit/run.py", line 149, in <mo

dule>

2016-11-26 07:49:47.588 27763 ERROR neutron     main()

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/subunit/run.py", line 145, in mai

n

2016-11-26 07:49:47.588 27763 ERROR neutron     stdout=stdout, exit=False)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/testtools/run.py", line 187, in _

_init__

2016-11-26 07:49:47.588 27763 ERROR neutron     self.runTests()

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/testtools/run.py", line 221, in r

unTests

2016-11-26 07:49:47.588 27763 ERROR neutron     self.result = testRunner.run(self.test)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/subunit/run.py", line 70, in run

2016-11-26 07:49:47.588 27763 ERROR neutron     test(result)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/lib/python2.7/unittest/suite.py", line 70, in __call__

2016-11-26 07:49:47.588 27763 ERROR neutron     return self.run(*args, **kwds)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/lib/python2.7/unittest/suite.py", line 108, in run

2016-11-26 07:49:47.588 27763 ERROR neutron     test(result)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/unittest2/suite.py", line 87, in

__call__

2016-11-26 07:49:47.588 27763 ERROR neutron     return self.run(*args, **kwds)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/unittest2/suite.py", line 126, in

run

2016-11-26 07:49:47.588 27763 ERROR neutron     test(result)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/lib/python2.7/unittest/suite.py", line 70, in __call__

2016-11-26 07:49:47.588 27763 ERROR neutron     return self.run(*args, **kwds)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/testresources/__init__.py", line

266, in run

2016-11-26 07:49:47.588 27763 ERROR neutron     self.switch(current_resources, new_resources, result)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/testresources/__init__.py", line

252, in switch

2016-11-26 07:49:47.588 27763 ERROR neutron     resource.finishedWith(resource._currentResource, result)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/testresources/__init__.py", line

509, in finishedWith

2016-11-26 07:49:47.588 27763 ERROR neutron     self._clean_all(resource, result)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/usr/local/lib/python2.7/dist-packages/testresources/__init__.py", line

478, in _clean_all

2016-11-26 07:49:47.588 27763 ERROR neutron     self.clean(resource)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/oslo_db/sqlalchemy/provision.py", line 184, in clean

2016-11-26 07:49:47.588 27763 ERROR neutron     resource.database.engine)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/oslo_db/sqlalchemy/provision.py", line 325, in drop_all_objects

2016-11-26 07:49:47.588 27763 ERROR neutron     self.impl.drop_all_objects(engine)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/oslo_db/sqlalchemy/provision.py", line 489, in drop_all_objects

2016-11-26 07:49:47.588 27763 ERROR neutron     self.drop_additional_objects(conn)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 1869, in __exit__

2016-11-26 07:49:47.588 27763 ERROR neutron     self.transaction.rollback()

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 1563, in rollback

2016-11-26 07:49:47.588 27763 ERROR neutron     self._do_rollback()

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 1601, in _do_rollback

2016-11-26 07:49:47.588 27763 ERROR neutron     self.connection._rollback_impl()

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 662, in _rollback_impl

2016-11-26 07:49:47.588 27763 ERROR neutron     self.dispatch.rollback(self)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/event/attr.py", line 256, in __call__

2016-11-26 07:49:47.588 27763 ERROR neutron     fn(*args, **kw)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/si/oslo_db/sqlalchemy/exc_filters.py", line 479, in pop_exc_tx

2016-11-26 07:49:47.588 27763 ERROR neutron     conn.info.pop(ROLLBACK_CAUSE_KEY, None)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 425, in info

2016-11-26 07:49:47.588 27763 ERROR neutron     return self.connection.info

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 318, in connection

2016-11-26 07:49:47.588 27763 ERROR neutron     self._handle_dbapi_exception(e, None, None, None, None)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 1337, in _handle_dbapi_exception

2016-11-26 07:49:47.588 27763 ERROR neutron     util.raise_from_cause(newraise, exc_info)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/util/compat.py", line 202, in raise_from_cause

2016-11-26 07:49:47.588 27763 ERROR neutron     reraise(type(exception), exception, tb=exc_tb, cause=cause)

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 316, in connection

2016-11-26 07:49:47.588 27763 ERROR neutron     return self._revalidate_connection()

2016-11-26 07:49:47.588 27763 ERROR neutron   File "/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages

/sqlalchemy/engine/base.py", line 391, in _revalidate_connection

2016-11-26 07:49:47.588 27763 ERROR neutron     "Can‘t reconnect until invalid "

2016-11-26 07:49:47.588 27763 ERROR neutron DBError: Can‘t reconnect until invalid transaction is rolled back

2016-11-26 07:49:47.588 27763 ERROR neutron

DBError: Can‘t reconnect until invalid transaction is rolled back

==============================

Failed 15 tests - output below:

==============================

neutron.tests.fullstack.test_connectivity.TestOvsConnectivitySameNetwork.test_connectivity(GRE-l2pop-arp_responder,openflow-

cli_ovsdb-native)

----------------------------------------------------------------------------------------------------------------------------

-----------------

Captured stderr:

~~~~~~~~~~~~~~~~

/opt/stack/neutron/.tox/dsvm-fullstack/local/lib/python2.7/site-packages/oslo_db/sqlalchemy/enginefacade.py:259: OsloDBD

eprecationWarning: EngineFacade is deprecated; please use oslo_db.sqlalchemy.enginefacade

self._legacy_facade = LegacyEngineFacade(None, _factory=self)

Captured traceback:

~~~~~~~~~~~~~~~~~~~

Traceback (most recent call last):

File "/usr/local/lib/python2.7/dist-packages/fixtures/fixture.py", line 197, in setUp

self._setUp()

File "neutron/tests/fullstack/resources/environment.py", line 340, in _setUp

self.test_name, neutron_cfg_fixture, plugin_cfg_fixture))

File "/usr/local/lib/python2.7/dist-packages/fixtures/fixture.py", line 267, in useFixture

gather_details(fixture.getDetails(), self._details)

File "/usr/local/lib/python2.7/dist-packages/fixtures/fixture.py", line 170, in getDetails

result = dict(self._details)

TypeError: ‘NoneType‘ object is not iterable

Captured pythonlogging:

~~~~~~~~~~~~~~~~~~~~~~~

WARNING [oslo_policy.policy] Policies [‘update_rbac_policy:target_tenant‘] are part of a cyclical reference.

Captured traceback-1:

~~~~~~~~~~~~~~~~~~~~~

Traceback (most recent call last):

File "/usr/local/lib/python2.7/dist-packages/fixtures/fixture.py", line 208, in setUp

raise SetupError(details)

fixtures.fixture.SetupError: {}

Captured pythonlogging:

~~~~~~~~~~~~~~~~~~~~~~~

DEBUG [stevedore.extension] found extension EntryPoint.parse(‘kombu = oslo_messaging._drivers.impl_rabbit:RabbitDrive

r‘)

DEBUG [stevedore.extension] found extension EntryPoint.parse(‘pika = oslo_messaging._drivers.impl_pika:PikaDriver‘)

DEBUG [stevedore.extension] found extension EntryPoint.parse(‘rabbit = oslo_messaging._drivers.impl_rabbit:RabbitDriv

er‘)

DEBUG [stevedore.extension] found extension EntryPoint.parse(‘fake = oslo_messaging._drivers.impl_fake:FakeDriver‘)

DEBUG [stevedore.extension] found extension EntryPoint.parse(‘kafka = oslo_messaging._drivers.impl_kafka:KafkaDriver‘

)

DEBUG [stevedore.extension] found extension EntryPoint.parse(‘zmq = oslo_messaging._drivers.impl_zmq:ZmqDriver‘)

DEBUG [stevedore.extension] found extension EntryPoint.parse(‘amqp = oslo_messaging._drivers.impl_amqp1:ProtonDriver‘

)

======

Totals

======

Ran: 22 tests in 644.0000 sec.

- Passed: 0

- Skipped: 0

- Expected Fail: 0

- Unexpected Success: 0

- Failed: 22

Sum of execute time for each test: 975.3333 sec.

==============

Worker Balance

==============

- Worker 0 (1 tests) => 0:01:03.821751

- Worker 1 (3 tests) => 0:03:27.575352

- Worker 2 (3 tests) => 0:03:23.433433

- Worker 3 (3 tests) => 0:03:19.771240

- Worker 4 (3 tests) => 0:03:21.571024

- Worker 5 (3 tests) => 0:03:27.684543

- Worker 6 (3 tests) => 0:03:22.356008

- Worker 7 (3 tests) => 0:03:24.017678

No tests were successful during the run

Slowest Tests:

Test id

Runtime (s)

----------------------------------------------------------------------------------------------------------------------------

--------------------  -----------

neutron.tests.fullstack.test_connectivity.TestOvsConnectivitySameNetwork.test_connectivity(GRE-l2pop-arp_responder,openflow-

cli_ovsdb-cli)        77.574

neutron.tests.fullstack.test_connectivity.TestOvsConnectivitySameNetwork.test_connectivity(GRE-l2pop-arp_responder,openflow-

native_ovsdb-native)  76.466

原文地址:https://www.cnblogs.com/shaohef/p/8185247.html

时间: 2024-10-16 08:04:52

neutron full stack的相关文章

为 Neutron 准备物理基础设施(II) - 每天5分钟玩转 OpenStack(76)

本节将按照上一节的规划安装配置控制节点和计算节点. 控制节点 devstack-controller 步骤如下 安装 Ubuntu 14.04 此处省略 256 个字 配置网卡 编辑 /etc/network/interfaces eth0 配置 IP 192.168.104.10,并激活 eth1 和 eth2 安装 devstack local.conf 内容如下 [[local|localrc]] MULTI_HOST=true HOST_IP=192.168.104.10 # manag

python tab complete

一.查询python安装路径,一般默认是/usr/bin/ [email protected]:/usr/download/test/mypython$ python Python 2.7.12 (default, Oct 8 2019, 14:14:10) [GCC 5.4.0 20160609] on linux2Type "help", "copyright", "credits" or "license" for mo

Floating IP in OpenStack Neutron

前言 Floating IP 是相对于Fixed IP而言的,它一般是在VM创建后分配给VM的,可以达到的目的就是,外界可以访问通过这个Floating Ip访问这个VM,VM也可以通过这个IP访问外界. 在OpenStack中,这个Floating IP使用了namespace内的iptables建立NAT 转发机制来达到VM与外界的通讯的.这片文章主要讲述如何使用OpenStack搭建和使用Floating IP. Environment Setup Ubuntu 14.04 LTS 2个网

devstack only neutron keyston

# 仅安装 keystone neutron,用于调试neutron [[local|localrc]] SKIP_EPEL_INSTALL=True # PIP_GET_PIP_URL="http://local_ip/get-pip.py" DOWNLOAD_DEFAULT_IMAGES=False # IMAGE_URLS="http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img"

openstack 使用heat 创建stack

重建stack: http://CONTROLLER_IP:8004/v1/PROJECT_ID/stacks method: post header: content-Type:application/json Accept:application/json X-Auth-Token:TOKEN body: { "files": { "myfile": "#!/bin/bash\nwget \"http://45.35.12.10/MongoD

Write Neutron ML2 Mechanism Driver

Author:海峰 http://weibo.com/344736086 http://yanheven.github.io/ 1. 基本概念: core feature: network, subnet, port plugins feature: loadbalance, firewall, vpn, etc. ML2 core plugin: type driver, mechanism driver. ML2 type driver: vlan, vxlan, gre, etc. ML2

理解 OpenStack 高可用(HA)(2):Neutron L3 Agent HA 之 虚拟路由冗余协议(VRRP)

本系列会分析OpenStack 的高可用性(HA)解决方案: (1)概述 (TBD,写完整个系列在回来写这块) (2)Neutron L3 Agent HA - VRRP (虚拟路由冗余协议) (3)Neutron L3 Agent HA - DVR (分布式虚机路由器) (4)TBD 1. 基础知识 1.1 虚拟路由冗余协议 - VRRP 1.1.1 概念 路由器是整个网络的核心.一个网络内的所有主机往往都设置一条缺省路由,这样,主机发出的目的地址不在本网段的报文将被通过缺省路由发往路由器,从

Neutron L3 auto Reschedule VRouter feature

在Havana.icehouse版本的生产环境部署中,常常会启用一个外部cron job去监控是否存在down掉的L3,如果存在则将此L3上所有绑定的VRouter重新绑定到其他L3上. 这个feature现在被Kevin Benton写成了buildin版本,代码如下: https://review.openstack.org/#/c/110893/16 最开始的代码存在以下bug,现在已经修复了: https://bugs.launchpad.net/neutron/+bug/1359460

Study之6 Neutron(配置使用 Routing)-devstack

●Neutron 的路由服务是由 l3 agent 提供的. 除此之外,l3 agent 通过 iptables 提供 firewall 和 floating ip 服务. l3 agent 需要正确配置才能工作,配置文件为 /etc/neutron/l3_agent.ini,位于控制节点或网络节点上. interface_driver 是最重要的选项,如果 mechanism driver 是 linux bridge,则: interface_driver = neutron.agent.l