Merge "Smoke and bvt tests"
This commit is contained in:
commit
c3447a069a
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "plugin_test/fuel-qa"]
|
||||
path = plugin_test/fuel-qa
|
||||
url = https://github.com/openstack/fuel-qa
|
||||
branch = stable/mitaka
|
14
plugin_test/__init__.py
Normal file
14
plugin_test/__init__.py
Normal file
@ -0,0 +1,14 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
1
plugin_test/fuel-qa
Submodule
1
plugin_test/fuel-qa
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 15681971a6ff4adc9a8fd0b567f7443a3db6ffab
|
14
plugin_test/helpers/__init__.py
Normal file
14
plugin_test/helpers/__init__.py
Normal file
@ -0,0 +1,14 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
81
plugin_test/helpers/settings.py
Normal file
81
plugin_test/helpers/settings.py
Normal file
@ -0,0 +1,81 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from fuelweb_test.settings import get_var_as_bool
|
||||
from fuelweb_test.settings import iface_alias
|
||||
from fuelweb_test.settings import NEUTRON_SEGMENT_TYPE
|
||||
|
||||
|
||||
HALF_MIN_WAIT = 30 # 30 seconds
|
||||
WAIT_FOR_COMMAND = 60 * 3 # 3 minutes
|
||||
WAIT_FOR_LONG_DEPLOY = 60 * 180 # 180 minutes
|
||||
|
||||
EXT_IP = '8.8.8.8' # Google DNS ^_^
|
||||
PRIVATE_NET = os.environ.get('PRIVATE_NET', 'admin_internal_net')
|
||||
ADMIN_NET = os.environ.get('ADMIN_NET', 'admin_floating_net')
|
||||
DEFAULT_ROUTER_NAME = os.environ.get('DEFAULT_ROUTER_NAME', 'router04')
|
||||
METADATA_IP = os.environ.get('METADATA_IP', '169.254.169.254')
|
||||
VM_USER = 'cirros'
|
||||
VM_PASS = 'cubswin:)'
|
||||
AZ_VCENTER1 = 'vcenter'
|
||||
AZ_VCENTER2 = 'vcenter2'
|
||||
FLAVOR_NAME = 'm1.micro128'
|
||||
|
||||
PLUGIN_NAME = os.environ.get('PLUGIN_NAME', 'nsx-t')
|
||||
NSXT_PLUGIN_PATH = os.environ.get('NSXT_PLUGIN_PATH')
|
||||
NSXT_PLUGIN_VERSION = os.environ.get('NSXT_PLUGIN_VERSION', '1.0.0')
|
||||
NSXT_MANAGERS_IP = os.environ.get('NSXT_MANAGERS_IP')
|
||||
NSXT_USER = os.environ.get('NSXT_USER')
|
||||
|
||||
|
||||
assigned_networks = {
|
||||
iface_alias('eth0'): ['fuelweb_admin', 'private'],
|
||||
iface_alias('eth1'): ['public'],
|
||||
iface_alias('eth2'): ['storage'],
|
||||
iface_alias('eth4'): ['management']
|
||||
}
|
||||
|
||||
cluster_settings = {
|
||||
'net_provider': 'neutron',
|
||||
'assign_to_all_nodes': True,
|
||||
'net_segment_type': NEUTRON_SEGMENT_TYPE
|
||||
}
|
||||
|
||||
plugin_configuration = {
|
||||
'insecure/value': get_var_as_bool(os.environ.get('NSXT_INSECURE'), True),
|
||||
'nsx_api_managers/value': NSXT_MANAGERS_IP,
|
||||
'nsx_api_user/value': NSXT_USER,
|
||||
'nsx_api_password/value': os.environ.get('NSXT_PASSWORD'),
|
||||
'default_overlay_tz_uuid/value': os.environ.get('NSXT_OVERLAY_TZ_UUID'),
|
||||
'default_vlan_tz_uuid/value': os.environ.get('NSXT_VLAN_TZ_UUID'),
|
||||
'default_tier0_router_uuid/value': os.environ.get(
|
||||
'NSXT_TIER0_ROUTER_UUID'),
|
||||
'default_edge_cluster_uuid/value': os.environ.get(
|
||||
'NSXT_EDGE_CLUSTER_UUID'),
|
||||
'uplink_profile_uuid/value': os.environ.get('NSXT_UPLINK_PROFILE_UUID'),
|
||||
'controller_ip_pool_uuid/value': os.environ.get(
|
||||
'NSXT_CONTROLLER_IP_POOL_UUID'),
|
||||
'controller_pnics_pairs/value': os.environ.get(
|
||||
'NSXT_CONTROLLER_PNICS_PAIRS'),
|
||||
'compute_ip_pool_uuid/value': os.environ.get('NSXT_COMPUTE_IP_POOL_UUID'),
|
||||
'compute_pnics_pairs/value': os.environ.get('NSXT_COMPUTE_PNICS_PAIRS'),
|
||||
'floating_ip_range/value': os.environ.get('NSXT_FLOATING_IP_RANGE'),
|
||||
'floating_net_cidr/value': os.environ.get('NSXT_FLOATING_NET_CIDR'),
|
||||
'internal_net_cidr/value': os.environ.get('NSXT_INTERNAL_NET_CIDR'),
|
||||
'floating_net_gw/value': os.environ.get('NSXT_FLOATING_NET_GW'),
|
||||
'internal_net_dns/value': os.environ.get('NSXT_INTERNAL_NET_DNS')
|
||||
}
|
54
plugin_test/helpers/tools.py
Normal file
54
plugin_test/helpers/tools.py
Normal file
@ -0,0 +1,54 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
|
||||
from fuelweb_test import logger
|
||||
|
||||
|
||||
def find_first(seq, predicate):
|
||||
"""Find the first item of sequence for which predicate is performed."""
|
||||
return next((x for x in seq if predicate(x)), None)
|
||||
|
||||
|
||||
class ShowPos(object):
|
||||
"""Print func name and its parameters for each call."""
|
||||
|
||||
@staticmethod
|
||||
def deco(f):
|
||||
"""Logger decorator."""
|
||||
def wrapper(*args, **kwargs):
|
||||
logger.debug("Call {0}({1}, {2})".format(f.__name__, args, kwargs))
|
||||
return f(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
def __getattribute__(self, name):
|
||||
"""Log by attributes."""
|
||||
attr = object.__getattribute__(self, name)
|
||||
if callable(attr):
|
||||
return ShowPos.deco(attr)
|
||||
else:
|
||||
return attr
|
||||
|
||||
|
||||
def show_pos(f):
|
||||
"""Wrapper shows current POSition in debug output."""
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
logger.debug('Call {func}({args}, {kwargs})'.format(func=f.__name__,
|
||||
args=args,
|
||||
kwargs=kwargs))
|
||||
return f(*args, **kwargs)
|
||||
return wrapper
|
65
plugin_test/run_tests.py
Normal file
65
plugin_test/run_tests.py
Normal file
@ -0,0 +1,65 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from nose.plugins import Plugin
|
||||
from paramiko.transport import _join_lingering_threads
|
||||
|
||||
|
||||
class CloseSSHConnectionsPlugin(Plugin):
|
||||
"""Closes all paramiko's ssh connections after each test case.
|
||||
|
||||
Plugin fixes proboscis disability to run cleanup of any kind.
|
||||
'afterTest' calls _join_lingering_threads function from paramiko,
|
||||
which stops all threads (set the state to inactive and join for 10s)
|
||||
"""
|
||||
|
||||
name = 'closesshconnections'
|
||||
|
||||
def options(self, parser, env=os.environ):
|
||||
super(CloseSSHConnectionsPlugin, self).options(parser, env=env)
|
||||
|
||||
def configure(self, options, conf):
|
||||
super(CloseSSHConnectionsPlugin, self).configure(options, conf)
|
||||
self.enabled = True
|
||||
|
||||
def afterTest(self, *args, **kwargs):
|
||||
_join_lingering_threads()
|
||||
|
||||
|
||||
def import_tests():
|
||||
from tests import test_plugin_nsxt # noqa
|
||||
|
||||
|
||||
def run_tests():
|
||||
from proboscis import TestProgram # noqa
|
||||
import_tests()
|
||||
|
||||
# Run Proboscis and exit.
|
||||
TestProgram(addplugins=[CloseSSHConnectionsPlugin()]).run_and_exit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.path.append(sys.path[0] + "/fuel-qa")
|
||||
import_tests()
|
||||
from fuelweb_test.helpers.patching import map_test
|
||||
if any(re.search(r'--group=patching_master_tests', arg)
|
||||
for arg in sys.argv):
|
||||
map_test('master')
|
||||
elif any(re.search(r'--group=patching.*', arg) for arg in sys.argv):
|
||||
map_test('environment')
|
||||
run_tests()
|
209
plugin_test/test_templates/default.yaml
Normal file
209
plugin_test/test_templates/default.yaml
Normal file
@ -0,0 +1,209 @@
|
||||
---
|
||||
template:
|
||||
devops_settings:
|
||||
aliases:
|
||||
|
||||
dynamic_address_pool:
|
||||
- &pool_default !os_env POOL_DEFAULT, 10.109.0.0/16:24
|
||||
|
||||
default_interface_model:
|
||||
- &interface_model !os_env INTERFACE_MODEL, e1000
|
||||
|
||||
rack-01-slave-interfaces: &rack-01-slave-interfaces
|
||||
- label: eth0
|
||||
l2_network_device: admin # Libvirt bridge name. It is *NOT* Nailgun networks
|
||||
interface_model: *interface_model
|
||||
- label: eth1
|
||||
l2_network_device: public
|
||||
interface_model: *interface_model
|
||||
- label: eth2
|
||||
l2_network_device: management
|
||||
interface_model: *interface_model
|
||||
- label: eth3
|
||||
l2_network_device: private
|
||||
interface_model: *interface_model
|
||||
- label: eth4
|
||||
l2_network_device: storage
|
||||
interface_model: *interface_model
|
||||
|
||||
rack-01-slave-network_config: &rack-01-slave-network_config
|
||||
eth0:
|
||||
networks:
|
||||
- fuelweb_admin
|
||||
eth1:
|
||||
networks:
|
||||
- public
|
||||
eth2:
|
||||
networks:
|
||||
- management
|
||||
eth3:
|
||||
networks:
|
||||
- private
|
||||
eth4:
|
||||
networks:
|
||||
- storage
|
||||
|
||||
rack-01-slave-node-params: &rack-01-slave-node-params
|
||||
vcpu: !os_env SLAVE_NODE_CPU, 4
|
||||
memory: !os_env SLAVE_NODE_MEMORY, 8192
|
||||
boot:
|
||||
- network
|
||||
- hd
|
||||
volumes:
|
||||
- name: system
|
||||
capacity: !os_env NODE_VOLUME_SIZE, 55
|
||||
format: qcow2
|
||||
- name: cinder
|
||||
capacity: !os_env NODE_VOLUME_SIZE, 55
|
||||
format: qcow2
|
||||
- name: swift
|
||||
capacity: !os_env NODE_VOLUME_SIZE, 55
|
||||
format: qcow2
|
||||
interfaces: *rack-01-slave-interfaces
|
||||
network_config: *rack-01-slave-network_config
|
||||
|
||||
rack-02-slave-node-params: &rack-02-slave-node-params
|
||||
vcpu: !os_env SLAVE_NODE_CPU, 2
|
||||
memory: !os_env SLAVE_NODE_MEMORY, 3072
|
||||
boot:
|
||||
- network
|
||||
- hd
|
||||
volumes:
|
||||
- name: system
|
||||
capacity: !os_env NODE_VOLUME_SIZE, 55
|
||||
format: qcow2
|
||||
- name: cinder
|
||||
capacity: !os_env NODE_VOLUME_SIZE, 55
|
||||
format: qcow2
|
||||
- name: swift
|
||||
capacity: !os_env NODE_VOLUME_SIZE, 55
|
||||
format: qcow2
|
||||
interfaces: *rack-01-slave-interfaces
|
||||
network_config: *rack-01-slave-network_config
|
||||
|
||||
|
||||
env_name: !os_env ENV_NAME
|
||||
|
||||
address_pools:
|
||||
# Network pools used by the environment
|
||||
fuelweb_admin-pool01:
|
||||
net: *pool_default
|
||||
params:
|
||||
tag: 0
|
||||
public-pool01:
|
||||
net: *pool_default
|
||||
params:
|
||||
tag: 0
|
||||
storage-pool01:
|
||||
net: *pool_default
|
||||
params:
|
||||
tag: 101
|
||||
management-pool01:
|
||||
net: *pool_default
|
||||
params:
|
||||
tag: 102
|
||||
private-pool01:
|
||||
net: *pool_default
|
||||
params:
|
||||
tag: 103
|
||||
|
||||
groups:
|
||||
- name: cat
|
||||
driver:
|
||||
name: devops.driver.libvirt.libvirt_driver
|
||||
params:
|
||||
connection_string: !os_env CONNECTION_STRING, qemu:///system
|
||||
storage_pool_name: !os_env STORAGE_POOL_NAME, default
|
||||
stp: True
|
||||
hpet: False
|
||||
use_host_cpu: !os_env DRIVER_USE_HOST_CPU, true
|
||||
|
||||
network_pools: # Address pools for OpenStack networks.
|
||||
# Actual names should be used for keys
|
||||
# (the same as in Nailgun, for example)
|
||||
|
||||
fuelweb_admin: fuelweb_admin-pool01
|
||||
public: public-pool01
|
||||
storage: storage-pool01
|
||||
management: management-pool01
|
||||
private: private-pool01
|
||||
|
||||
l2_network_devices: # Libvirt bridges. It is *NOT* Nailgun networks
|
||||
admin:
|
||||
address_pool: fuelweb_admin-pool01
|
||||
dhcp: false
|
||||
forward:
|
||||
mode: nat
|
||||
|
||||
public:
|
||||
address_pool: public-pool01
|
||||
dhcp: false
|
||||
forward:
|
||||
mode: nat
|
||||
|
||||
storage:
|
||||
address_pool: storage-pool01
|
||||
dhcp: false
|
||||
|
||||
management:
|
||||
address_pool: management-pool01
|
||||
dhcp: false
|
||||
|
||||
private:
|
||||
address_pool: private-pool01
|
||||
dhcp: false
|
||||
|
||||
nodes:
|
||||
- name: admin # Custom name of VM for Fuel admin node
|
||||
role: fuel_master # Fixed role for Fuel master node properties
|
||||
params:
|
||||
vcpu: !os_env ADMIN_NODE_CPU, 2
|
||||
memory: !os_env ADMIN_NODE_MEMORY, 8192
|
||||
boot:
|
||||
- hd
|
||||
- cdrom # for boot from usb - without 'cdrom'
|
||||
volumes:
|
||||
- name: system
|
||||
capacity: !os_env ADMIN_NODE_VOLUME_SIZE, 80
|
||||
format: qcow2
|
||||
- name: iso
|
||||
source_image: !os_env ISO_PATH # if 'source_image' set, then volume capacity is calculated from it's size
|
||||
format: raw
|
||||
device: cdrom # for boot from usb - 'disk'
|
||||
bus: ide # for boot from usb - 'usb'
|
||||
interfaces:
|
||||
- label: eth0
|
||||
l2_network_device: admin # Libvirt bridge name. It is *NOT* a Nailgun network
|
||||
interface_model: *interface_model
|
||||
network_config:
|
||||
eth0:
|
||||
networks:
|
||||
- fuelweb_admin
|
||||
|
||||
- name: slave-01
|
||||
role: fuel_slave
|
||||
params: *rack-01-slave-node-params
|
||||
- name: slave-02
|
||||
role: fuel_slave
|
||||
params: *rack-01-slave-node-params
|
||||
- name: slave-03
|
||||
role: fuel_slave
|
||||
params: *rack-01-slave-node-params
|
||||
- name: slave-04
|
||||
role: fuel_slave
|
||||
params: *rack-02-slave-node-params
|
||||
- name: slave-05
|
||||
role: fuel_slave
|
||||
params: *rack-02-slave-node-params
|
||||
- name: slave-06
|
||||
role: fuel_slave
|
||||
params: *rack-02-slave-node-params
|
||||
- name: slave-07
|
||||
role: fuel_slave
|
||||
params: *rack-02-slave-node-params
|
||||
- name: slave-08
|
||||
role: fuel_slave
|
||||
params: *rack-02-slave-node-params
|
||||
- name: slave-09
|
||||
role: fuel_slave
|
||||
params: *rack-02-slave-node-params
|
14
plugin_test/tests/__init__.py
Normal file
14
plugin_test/tests/__init__.py
Normal file
@ -0,0 +1,14 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
98
plugin_test/tests/base_plugin_test.py
Normal file
98
plugin_test/tests/base_plugin_test.py
Normal file
@ -0,0 +1,98 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from proboscis.asserts import assert_true
|
||||
|
||||
from fuelweb_test import logger
|
||||
from fuelweb_test.helpers import utils
|
||||
from fuelweb_test.helpers.utils import pretty_log
|
||||
from fuelweb_test.tests.base_test_case import TestBasic
|
||||
from helpers import settings
|
||||
|
||||
|
||||
class TestNSXtBase(TestBasic):
|
||||
"""Base class for NSX-T plugin tests"""
|
||||
|
||||
def __init__(self):
|
||||
super(TestNSXtBase, self).__init__()
|
||||
self.default = settings
|
||||
|
||||
def install_nsxt_plugin(self):
|
||||
"""Download and install NSX-T plugin on master node.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
master_ip = self.ssh_manager.admin_ip
|
||||
utils.upload_tarball(ip=master_ip,
|
||||
tar_path=self.default.NSXT_PLUGIN_PATH,
|
||||
tar_target='/var')
|
||||
|
||||
utils.install_plugin_check_code(
|
||||
ip=master_ip,
|
||||
plugin=os.path.basename(self.default.NSXT_PLUGIN_PATH))
|
||||
|
||||
def enable_plugin(self, cluster_id, settings=None):
|
||||
"""Enable NSX-T plugin on cluster.
|
||||
|
||||
:param cluster_id: cluster id
|
||||
:param settings: settings in dict format
|
||||
:return: None
|
||||
"""
|
||||
msg = "Plugin couldn't be enabled. Check plugin version. Test aborted"
|
||||
settings = settings if settings else {}
|
||||
checker = self.fuel_web.check_plugin_exists(cluster_id,
|
||||
self.default.PLUGIN_NAME)
|
||||
assert_true(checker, msg)
|
||||
logger.info('Configure cluster with '
|
||||
'following parameters: \n{}'.format(pretty_log(settings)))
|
||||
self.fuel_web.update_plugin_settings(
|
||||
cluster_id,
|
||||
self.default.PLUGIN_NAME,
|
||||
self.default.NSXT_PLUGIN_VERSION,
|
||||
dict(self.default.plugin_configuration, **settings))
|
||||
|
||||
def reconfigure_cluster_interfaces(self, cluster_id):
|
||||
# clear network mapping enp0s6 for all deployed nodes
|
||||
nodes = self.fuel_web.client.list_cluster_nodes(cluster_id)
|
||||
for node in nodes:
|
||||
self.fuel_web.update_node_networks(node['id'],
|
||||
settings.assigned_networks)
|
||||
|
||||
def delete_nsxt_plugin(self, failover=False):
|
||||
"""Delete NSX-T plugin
|
||||
|
||||
:param failover: True if we expect that plugin won't be deleted
|
||||
:return:
|
||||
"""
|
||||
plugin_name = self.default.PLUGIN_NAME
|
||||
plugin_vers = self.default.NSXT_PLUGIN_VERSION
|
||||
tmp = "Plugin '{0}' {1} removed"
|
||||
msg = tmp.format(plugin_name, 'was' if failover else "wasn't")
|
||||
cmd = 'fuel plugins --remove {0}=={1}'.format(plugin_name, plugin_vers)
|
||||
|
||||
self.ssh_manager.check_call(
|
||||
ip=self.ssh_manager.admin_ip,
|
||||
command=cmd,
|
||||
expected=[1 if failover else 0],
|
||||
raise_on_err=not failover
|
||||
)
|
||||
|
||||
output = self.ssh_manager.check_call(
|
||||
ip=self.ssh_manager.admin_ip,
|
||||
command='fuel2 plugins list -f value -c name'
|
||||
).stdout[-1].split(' ')
|
||||
assert_true(plugin_name in output != failover, msg)
|
204
plugin_test/tests/test_plugin_nsxt.py
Normal file
204
plugin_test/tests/test_plugin_nsxt.py
Normal file
@ -0,0 +1,204 @@
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
||||
|
||||
from proboscis import test
|
||||
from proboscis.asserts import assert_true
|
||||
|
||||
from fuelweb_test.helpers.decorators import log_snapshot_after_test
|
||||
from fuelweb_test.settings import DEPLOYMENT_MODE
|
||||
from fuelweb_test.tests.base_test_case import SetupEnvironment
|
||||
from tests.base_plugin_test import TestNSXtBase
|
||||
|
||||
|
||||
@test(groups=["plugins", "nsxt_plugin", 'nsxt_smoke_scenarios'])
|
||||
class TestNSXtSmoke(TestNSXtBase):
|
||||
"""Tests from test plan that have been marked as 'Automated'."""
|
||||
|
||||
@test(depends_on=[SetupEnvironment.prepare_slaves_1],
|
||||
groups=["nsxt_install", 'nsxt_smoke'])
|
||||
@log_snapshot_after_test
|
||||
def nsxt_install(self):
|
||||
"""Check that plugin can be installed.
|
||||
|
||||
Scenario:
|
||||
1. Connect to the Fuel master node via ssh.
|
||||
2. Upload NSX-T plugin.
|
||||
3. Install NSX-T plugin.
|
||||
4. Run command 'fuel plugins'.
|
||||
5. Check name, version and package version of plugin.
|
||||
|
||||
Duration 30 min
|
||||
|
||||
"""
|
||||
self.env.revert_snapshot('ready_with_1_slaves')
|
||||
|
||||
self.show_step(1)
|
||||
self.show_step(2)
|
||||
self.show_step(3)
|
||||
self.install_nsxt_plugin()
|
||||
|
||||
self.show_step(4)
|
||||
output = self.ssh_manager.execute_on_remote(
|
||||
ip=self.ssh_manager.admin_ip, cmd='fuel plugins list'
|
||||
)['stdout'].pop().split(' ')
|
||||
|
||||
self.show_step(5)
|
||||
msg = "Plugin '{0}' is not installed.".format(self.default.PLUGIN_NAME)
|
||||
# check name
|
||||
assert_true(self.default.PLUGIN_NAME in output, msg)
|
||||
# check version
|
||||
assert_true(self.default.NSXT_PLUGIN_VERSION in output, msg)
|
||||
|
||||
self.env.make_snapshot("nsxt_install", is_make=True)
|
||||
|
||||
@test(depends_on=[nsxt_install],
|
||||
groups=["nsxt_uninstall", 'nsxt_smoke'])
|
||||
@log_snapshot_after_test
|
||||
def nsxt_uninstall(self):
|
||||
"""Check that NSX-T plugin can be removed.
|
||||
|
||||
Scenario:
|
||||
1. Revert to snapshot nsxt_install
|
||||
2. Remove NSX-T plugin.
|
||||
3. Run command 'fuel plugins' to ensure the NSX-T plugin has
|
||||
been removed.
|
||||
|
||||
Duration: 5 min
|
||||
"""
|
||||
self.show_step(1)
|
||||
self.env.revert_snapshot("nsxt_install")
|
||||
|
||||
self.show_step(2)
|
||||
cmd = 'fuel plugins --remove {0}=={1}'.format(
|
||||
self.default.PLUGIN_NAME, self.default.NSXT_PLUGIN_VERSION)
|
||||
|
||||
self.ssh_manager.execute_on_remote(
|
||||
ip=self.ssh_manager.admin_ip,
|
||||
cmd=cmd,
|
||||
err_msg='Can not remove plugin.')
|
||||
|
||||
self.show_step(3)
|
||||
self.delete_nsxt_plugin()
|
||||
|
||||
@test(depends_on=[nsxt_install],
|
||||
groups=['nsxt_kvm_smoke', 'nsxt_smoke'])
|
||||
@log_snapshot_after_test
|
||||
def nsxt_kvm_smoke(self):
|
||||
"""Deploy a cluster with NSXt Plugin.
|
||||
|
||||
Scenario:
|
||||
1. Upload the plugin to master node.
|
||||
2. Create cluster.
|
||||
3. Provision one controller node.
|
||||
4. Configure NSXt for that cluster.
|
||||
5. Deploy cluster with plugin.
|
||||
6. Run 'smoke' OSTF.
|
||||
|
||||
Duration 90 min
|
||||
|
||||
"""
|
||||
self.show_step(1)
|
||||
self.env.revert_snapshot('nsxt_install')
|
||||
|
||||
self.show_step(2)
|
||||
cluster_id = self.fuel_web.create_cluster(
|
||||
name=self.__class__.__name__,
|
||||
mode=DEPLOYMENT_MODE,
|
||||
settings=self.default.cluster_settings,
|
||||
configure_ssl=False)
|
||||
|
||||
self.show_step(3)
|
||||
self.fuel_web.update_nodes(cluster_id, {'slave-01': ['controller']})
|
||||
|
||||
self.reconfigure_cluster_interfaces(cluster_id)
|
||||
|
||||
self.show_step(4)
|
||||
self.enable_plugin(cluster_id)
|
||||
|
||||
self.show_step(5)
|
||||
self.fuel_web.deploy_cluster_wait(cluster_id)
|
||||
|
||||
self.show_step(6)
|
||||
self.fuel_web.run_ostf(cluster_id=cluster_id, test_sets=['smoke'])
|
||||
|
||||
|
||||
@test(groups=["plugins", "nsxt_plugin", 'nsxt_bvt_scenarios'])
|
||||
class TestNSXtBVT(TestNSXtBase):
|
||||
"""NSX-t BVT scenarios"""
|
||||
|
||||
@test(depends_on=[SetupEnvironment.prepare_slaves_9],
|
||||
groups=["nsxt_bvt"])
|
||||
@log_snapshot_after_test
|
||||
def nsxt_bvt(self):
|
||||
"""Deploy cluster with plugin and vmware datastore backend.
|
||||
|
||||
Scenario:
|
||||
1. Upload plugins to the master node.
|
||||
2. Create cluster with vcenter.
|
||||
3. Add 3 node with controller role, 3 ceph,
|
||||
compute-vmware + cinder-vmware, compute.
|
||||
4. Configure vcenter.
|
||||
5. Configure NSXt for that cluster.
|
||||
6. Deploy cluster.
|
||||
7. Run OSTF.
|
||||
|
||||
Duration 3 hours
|
||||
|
||||
"""
|
||||
self.env.revert_snapshot("ready_with_9_slaves")
|
||||
|
||||
self.show_step(1)
|
||||
self.install_nsxt_plugin()
|
||||
|
||||
self.show_step(2)
|
||||
settings = self.default.cluster_settings
|
||||
settings["images_ceph"] = True
|
||||
|
||||
cluster_id = self.fuel_web.create_cluster(
|
||||
name=self.__class__.__name__,
|
||||
mode=DEPLOYMENT_MODE,
|
||||
settings=settings,
|
||||
configure_ssl=False)
|
||||
|
||||
self.show_step(3)
|
||||
self.fuel_web.update_nodes(
|
||||
cluster_id,
|
||||
{'slave-01': ['controller'],
|
||||
'slave-02': ['controller'],
|
||||
'slave-03': ['controller'],
|
||||
'slave-04': ['ceph-osd'],
|
||||
'slave-05': ['ceph-osd'],
|
||||
'slave-06': ['ceph-osd'],
|
||||
'slave-07': ['compute-vmware', 'cinder-vmware'],
|
||||
'slave-08': ['compute']}
|
||||
)
|
||||
|
||||
self.reconfigure_cluster_interfaces(cluster_id)
|
||||
|
||||
self.show_step(4)
|
||||
target_node_2 = \
|
||||
self.fuel_web.get_nailgun_node_by_name('slave-07')['hostname']
|
||||
self.fuel_web.vcenter_configure(cluster_id,
|
||||
multiclusters=True,
|
||||
target_node_2=target_node_2)
|
||||
self.show_step(5)
|
||||
self.enable_plugin(cluster_id)
|
||||
|
||||
self.show_step(6)
|
||||
self.fuel_web.deploy_cluster_wait(cluster_id)
|
||||
|
||||
self.show_step(7)
|
||||
self.fuel_web.run_ostf(
|
||||
cluster_id=cluster_id, test_sets=['smoke', 'sanity', 'ha'])
|
660
plugin_test/utils/jenkins/system_tests.sh
Executable file
660
plugin_test/utils/jenkins/system_tests.sh
Executable file
@ -0,0 +1,660 @@
|
||||
#!/bin/sh
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
INVALIDOPTS_ERR=100
|
||||
NOJOBNAME_ERR=101
|
||||
NOISOPATH_ERR=102
|
||||
NOTASKNAME_ERR=103
|
||||
NOWORKSPACE_ERR=104
|
||||
NOISOFOUND_ERR=107
|
||||
CDWORKSPACE_ERR=110
|
||||
ISODOWNLOAD_ERR=111
|
||||
INVALIDTASK_ERR=112
|
||||
|
||||
# Defaults
|
||||
|
||||
export REBOOT_TIMEOUT=${REBOOT_TIMEOUT:-5000}
|
||||
export ALWAYS_CREATE_DIAGNOSTIC_SNAPSHOT=${ALWAYS_CREATE_DIAGNOSTIC_SNAPSHOT:-true}
|
||||
|
||||
ShowHelp() {
|
||||
cat << EOF
|
||||
System Tests Script
|
||||
|
||||
It can perform several actions depending on Jenkins JOB_NAME it's ran from
|
||||
or it can take names from exported environment variables or command line options
|
||||
if you do need to override them.
|
||||
|
||||
-w (dir) - Path to workspace where fuelweb git repository was checked out.
|
||||
Uses Jenkins' WORKSPACE if not set
|
||||
-e (name) - Directly specify environment name used in tests
|
||||
Uses ENV_NAME variable is set.
|
||||
-j (name) - Name of this job. Determines ISO name, Task name and used by tests.
|
||||
Uses Jenkins' JOB_NAME if not set
|
||||
-v - Do not use virtual environment
|
||||
-V (dir) - Path to python virtual environment
|
||||
-i (file) - Full path to ISO file to build or use for tests.
|
||||
Made from iso dir and name if not set.
|
||||
-t (name) - Name of task this script should perform. Should be one of defined ones.
|
||||
Taken from Jenkins' job's suffix if not set.
|
||||
-o (str) - Allows you any extra command line option to run test job if you
|
||||
want to use some parameters.
|
||||
-a (str) - Allows you to path NOSE_ATTR to the test job if you want
|
||||
to use some parameters.
|
||||
-A (str) - Allows you to path NOSE_EVAL_ATTR if you want to enter attributes
|
||||
as python expressions.
|
||||
-m (name) - Use this mirror to build ISO from.
|
||||
Uses 'srt' if not set.
|
||||
-U - ISO URL for tests.
|
||||
Null by default.
|
||||
-r (yes/no) - Should built ISO file be placed with build number tag and
|
||||
symlinked to the last build or just copied over the last file.
|
||||
-b (num) - Allows you to override Jenkins' build number if you need to.
|
||||
-l (dir) - Path to logs directory. Can be set by LOGS_DIR evironment variable.
|
||||
Uses WORKSPACE/logs if not set.
|
||||
-d - Dry run mode. Only show what would be done and do nothing.
|
||||
Useful for debugging.
|
||||
-k - Keep previously created test environment before tests run
|
||||
-K - Keep test environment after tests are finished
|
||||
-h - Show this help page
|
||||
|
||||
Most variables uses guesses from Jenkins' job name but can be overriden
|
||||
by exported variable before script is run or by one of command line options.
|
||||
|
||||
You can override following variables using export VARNAME="value" before running this script
|
||||
WORKSPACE - path to directory where Fuelweb repository was checked out by Jenkins or manually
|
||||
JOB_NAME - name of Jenkins job that determines which task should be done and ISO file name.
|
||||
|
||||
If task name is "iso" it will make iso file
|
||||
Other defined names will run Nose tests using previously built ISO file.
|
||||
|
||||
ISO file name is taken from job name prefix
|
||||
Task name is taken from job name suffix
|
||||
Separator is one dot '.'
|
||||
|
||||
For example if JOB_NAME is:
|
||||
mytest.somestring.iso
|
||||
ISO name: mytest.iso
|
||||
Task name: iso
|
||||
If ran with such JOB_NAME iso file with name mytest.iso will be created
|
||||
|
||||
If JOB_NAME is:
|
||||
mytest.somestring.node
|
||||
ISO name: mytest.iso
|
||||
Task name: node
|
||||
If script was run with this JOB_NAME node tests will be using ISO file mytest.iso.
|
||||
|
||||
First you should run mytest.somestring.iso job to create mytest.iso.
|
||||
Then you can ran mytest.somestring.node job to start tests using mytest.iso and other tests too.
|
||||
EOF
|
||||
}
|
||||
|
||||
GlobalVariables() {
|
||||
# where built iso's should be placed
|
||||
# use hardcoded default if not set before by export
|
||||
ISO_DIR="${ISO_DIR:=/var/www/fuelweb-iso}"
|
||||
|
||||
# name of iso file
|
||||
# taken from jenkins job prefix
|
||||
# if not set before by variable export
|
||||
if [ -z "${ISO_NAME}" ]; then
|
||||
ISO_NAME="${JOB_NAME%.*}.iso"
|
||||
fi
|
||||
|
||||
# full path where iso file should be placed
|
||||
# make from iso name and path to iso shared directory
|
||||
# if was not overriden by options or export
|
||||
if [ -z "${ISO_PATH}" ]; then
|
||||
ISO_PATH="${ISO_DIR}/${ISO_NAME}"
|
||||
fi
|
||||
|
||||
# what task should be ran
|
||||
# it's taken from jenkins job name suffix if not set by options
|
||||
if [ -z "${TASK_NAME}" ]; then
|
||||
TASK_NAME="${JOB_NAME##*.}"
|
||||
fi
|
||||
|
||||
# do we want to keep iso's for each build or just copy over single file
|
||||
ROTATE_ISO="${ROTATE_ISO:=yes}"
|
||||
|
||||
# choose mirror to build iso from. Default is 'srt' for Saratov's mirror
|
||||
# you can change mirror by exporting USE_MIRROR variable before running this script
|
||||
USE_MIRROR="${USE_MIRROR:=srt}"
|
||||
|
||||
# only show what commands would be executed but do nothing
|
||||
# this feature is useful if you want to debug this script's behaviour
|
||||
DRY_RUN="${DRY_RUN:=no}"
|
||||
|
||||
VENV="${VENV:=yes}"
|
||||
}
|
||||
|
||||
GetoptsVariables() {
|
||||
while getopts ":w:j:i:t:o:a:A:m:U:r:b:V:l:dkKe:v:h" opt; do
|
||||
case $opt in
|
||||
w)
|
||||
WORKSPACE="${OPTARG}"
|
||||
;;
|
||||
j)
|
||||
JOB_NAME="${OPTARG}"
|
||||
;;
|
||||
i)
|
||||
ISO_PATH="${OPTARG}"
|
||||
;;
|
||||
t)
|
||||
TASK_NAME="${OPTARG}"
|
||||
;;
|
||||
o)
|
||||
TEST_OPTIONS="${TEST_OPTIONS} ${OPTARG}"
|
||||
;;
|
||||
a)
|
||||
NOSE_ATTR="${OPTARG}"
|
||||
;;
|
||||
A)
|
||||
NOSE_EVAL_ATTR="${OPTARG}"
|
||||
;;
|
||||
m)
|
||||
USE_MIRROR="${OPTARG}"
|
||||
;;
|
||||
U)
|
||||
ISO_URL="${OPTARG}"
|
||||
;;
|
||||
r)
|
||||
ROTATE_ISO="${OPTARG}"
|
||||
;;
|
||||
V)
|
||||
VENV_PATH="${OPTARG}"
|
||||
;;
|
||||
l)
|
||||
LOGS_DIR="${OPTARG}"
|
||||
;;
|
||||
k)
|
||||
KEEP_BEFORE="yes"
|
||||
;;
|
||||
K)
|
||||
KEEP_AFTER="yes"
|
||||
;;
|
||||
e)
|
||||
ENV_NAME="${OPTARG}"
|
||||
;;
|
||||
d)
|
||||
DRY_RUN="yes"
|
||||
;;
|
||||
v)
|
||||
VENV="no"
|
||||
;;
|
||||
h)
|
||||
ShowHelp
|
||||
exit 0
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG"
|
||||
ShowHelp
|
||||
exit $INVALIDOPTS_ERR
|
||||
;;
|
||||
:)
|
||||
echo "Option -$OPTARG requires an argument."
|
||||
ShowHelp
|
||||
exit $INVALIDOPTS_ERR
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
CheckVariables() {
|
||||
|
||||
if [ -z "${JOB_NAME}" ]; then
|
||||
echo "Error! JOB_NAME is not set!"
|
||||
exit $NOJOBNAME_ERR
|
||||
fi
|
||||
if [ -z "${ISO_PATH}" ]; then
|
||||
echo "Error! ISO_PATH is not set!"
|
||||
exit $NOISOPATH_ERR
|
||||
fi
|
||||
if [ -z "${TASK_NAME}" ]; then
|
||||
echo "Error! TASK_NAME is not set!"
|
||||
exit $NOTASKNAME_ERR
|
||||
fi
|
||||
if [ -z "${WORKSPACE}" ]; then
|
||||
echo "Error! WORKSPACE is not set!"
|
||||
exit $NOWORKSPACE_ERR
|
||||
fi
|
||||
|
||||
if [ -z "${POOL_PUBLIC}" ]; then
|
||||
export POOL_PUBLIC='172.16.0.0/24:24'
|
||||
fi
|
||||
if [ -z "${POOL_MANAGEMENT}" ]; then
|
||||
export POOL_MANAGEMENT='172.16.1.0/24:24'
|
||||
fi
|
||||
if [ -z "${POOL_PRIVATE}" ]; then
|
||||
export POOL_PRIVATE='192.168.0.0/24:24'
|
||||
fi
|
||||
|
||||
# vCenter variables
|
||||
if [ -z "${DISABLE_SSL}" ]; then
|
||||
export DISABLE_SSL="true"
|
||||
fi
|
||||
if [ -z "${VCENTER_USE}" ]; then
|
||||
export VCENTER_USE="true"
|
||||
fi
|
||||
if [ -z "${VCENTER_IP}" ]; then
|
||||
export VCENTER_IP="172.16.0.254"
|
||||
fi
|
||||
if [ -z "${VCENTER_USERNAME}" ]; then
|
||||
export VCENTER_USERNAME="administrator@vsphere.local"
|
||||
fi
|
||||
if [ -z "${VCENTER_PASSWORD}" ]; then
|
||||
echo "Error! VCENTER_PASSWORD is not set!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${VC_DATACENTER}" ]; then
|
||||
export VC_DATACENTER="Datacenter"
|
||||
fi
|
||||
if [ -z "${VC_DATASTORE}" ]; then
|
||||
export VC_DATASTORE="nfs"
|
||||
fi
|
||||
if [ -z "${VCENTER_IMAGE_DIR}" ]; then
|
||||
export VCENTER_IMAGE_DIR="/openstack_glance"
|
||||
fi
|
||||
if [ -z "${WORKSTATION_NODES}" ]; then
|
||||
export WORKSTATION_NODES="esxi1 esxi2 esxi3 vcenter trusty nsx-edge"
|
||||
fi
|
||||
if [ -z "${WORKSTATION_IFS}" ]; then
|
||||
export WORKSTATION_IFS="vmnet1 vmnet2 vmnet5"
|
||||
fi
|
||||
if [ -z "${VCENTER_CLUSTERS}" ]; then
|
||||
export VCENTER_CLUSTERS="Cluster1,Cluster2"
|
||||
fi
|
||||
if [ -z "${WORKSTATION_SNAPSHOT}" ]; then
|
||||
echo "Error! WORKSTATION_SNAPSHOT is not set!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${WORKSTATION_USERNAME}" ]; then
|
||||
echo "Error! WORKSTATION_USERNAME is not set!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${WORKSTATION_PASSWORD}" ]; then
|
||||
echo "Error! WORKSTATION_PASSWORD is not set!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# NSXt variables
|
||||
if [ -z "${NSXT_PLUGIN_PATH}" ]; then
|
||||
echo "Error! NSXT_PLUGIN_PATH is not set!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${NEUTRON_SEGMENT_TYPE}" ]; then
|
||||
export NEUTRON_SEGMENT_TYPE="tun"
|
||||
fi
|
||||
if [ -z "${NSXT_INSECURE}" ]; then
|
||||
export NSXT_INSECURE='true'
|
||||
fi
|
||||
if [ -z "${NSXT_MANAGERS_IP}" ]; then
|
||||
export NSXT_MANAGERS_IP="172.16.0.249"
|
||||
fi
|
||||
if [ -z "${NSXT_USER}" ]; then
|
||||
export NSXT_USER='admin'
|
||||
fi
|
||||
if [ -z "${NSXT_PASSWORD}" ]; then
|
||||
echo "Error! NSXT_PASSWORD is not set!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${NSXT_OVERLAY_TZ_UUID}" ]; then
|
||||
export NSXT_OVERLAY_TZ_UUID='0eeb1b85-c826-403d-8762-6a9c23a4f132'
|
||||
fi
|
||||
if [ -z "${NSXT_VLAN_TZ_UUID}" ]; then
|
||||
export NSXT_VLAN_TZ_UUID='8efe20d2-e71a-4d6e-acdd-f78a2ec2e90c'
|
||||
fi
|
||||
if [ -z "${NSXT_TIER0_ROUTER_UUID}" ]; then
|
||||
export NSXT_TIER0_ROUTER_UUID='606acd01-c5f8-40ea-ae20-9a91eb7ebcb4'
|
||||
fi
|
||||
if [ -z "${NSXT_EDGE_CLUSTER_UUID}" ]; then
|
||||
export NSXT_EDGE_CLUSTER_UUID='c53d602a-4010-47cc-a8b1-4ef11d0a3edd'
|
||||
fi
|
||||
if [ -z "${NSXT_UPLINK_PROFILE_UUID}" ]; then
|
||||
export NSXT_UPLINK_PROFILE_UUID='99864272-b34f-46a5-89c8-5657fa7042ea'
|
||||
fi
|
||||
if [ -z "${NSXT_CONTROLLER_IP_POOL_UUID}" ]; then
|
||||
export NSXT_CONTROLLER_IP_POOL_UUID='2e06fcb2-7c5b-4515-a7a9-98809c7b863a'
|
||||
fi
|
||||
if [ -z "${NSXT_CONTROLLER_PNICS_PAIRS}" ]; then
|
||||
export NSXT_CONTROLLER_PNICS_PAIRS='enp0s6:uplink'
|
||||
fi
|
||||
if [ -z "${NSXT_COMPUTE_IP_POOL_UUID}" ]; then
|
||||
export NSXT_COMPUTE_IP_POOL_UUID='2e06fcb2-7c5b-4515-a7a9-98809c7b863a'
|
||||
fi
|
||||
if [ -z "${NSXT_COMPUTE_PNICS_PAIRS}" ]; then
|
||||
export NSXT_COMPUTE_PNICS_PAIRS='enp0s6:uplink'
|
||||
fi
|
||||
|
||||
if [ -z "${NSXT_FLOATING_IP_RANGE}" ]; then
|
||||
export NSXT_FLOATING_IP_RANGE='172.16.212.2-172.16.212.40'
|
||||
fi
|
||||
if [ -z "${NSXT_FLOATING_NET_CIDR}" ]; then
|
||||
export NSXT_FLOATING_NET_CIDR='172.16.212.0/24'
|
||||
fi
|
||||
if [ -z "${NSXT_ROUTING_NET_CIDR}" ]; then
|
||||
export NSXT_ROUTING_NET_CIDR='172.16.214.0/30'
|
||||
fi
|
||||
if [ -z "${NSXT_FLOATING_NET_GW}" ]; then
|
||||
export NSXT_FLOATING_NET_GW='172.16.212.1'
|
||||
fi
|
||||
if [ -z "${NSXT_INTERNAL_NET_CIDR}" ]; then
|
||||
export NSXT_INTERNAL_NET_CIDR='192.168.251.0/24'
|
||||
fi
|
||||
if [ -z "${NSXT_INTERNAL_NET_DNS}" ]; then
|
||||
export NSXT_INTERNAL_NET_DNS='8.8.8.8'
|
||||
fi
|
||||
|
||||
if [ ! -f "${DEVOPS_SETTINGS_TEMPLATE}" ]; then
|
||||
if [ -z "${NODE_VOLUME_SIZE}" ]; then
|
||||
export NODE_VOLUME_SIZE=350
|
||||
fi
|
||||
if [ -z "${ADMIN_NODE_MEMORY}" ]; then
|
||||
export ADMIN_NODE_MEMORY=4096
|
||||
fi
|
||||
if [ -z "${ADMIN_NODE_CPU}" ]; then
|
||||
export ADMIN_NODE_CPU=4
|
||||
fi
|
||||
if [ -z "${SLAVE_NODE_MEMORY}" ]; then
|
||||
export SLAVE_NODE_MEMORY=4096
|
||||
fi
|
||||
if [ -z "${SLAVE_NODE_CPU}" ]; then
|
||||
export SLAVE_NODE_CPU=4
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
CdWorkSpace() {
|
||||
# chdir into workspace or fail if could not
|
||||
if [ "${DRY_RUN}" != "yes" ]; then
|
||||
cd "${WORKSPACE}"
|
||||
ec=$?
|
||||
|
||||
if [ "${ec}" -gt "0" ]; then
|
||||
echo "Error! Cannot cd to WORKSPACE!"
|
||||
exit $CDWORKSPACE_ERR
|
||||
fi
|
||||
else
|
||||
echo cd "${WORKSPACE}"
|
||||
fi
|
||||
}
|
||||
|
||||
RunTest() {
|
||||
# Run test selected by task name
|
||||
|
||||
# check if iso file exists
|
||||
if [ ! -f "${ISO_PATH}" ]; then
|
||||
if [ -z "${ISO_URL}" -a "${DRY_RUN}" != "yes" ]; then
|
||||
echo "Error! File ${ISO_PATH} not found and no ISO_URL (-U key) for downloading!"
|
||||
exit $NOISOFOUND_ERR
|
||||
else
|
||||
if [ "${DRY_RUN}" = "yes" ]; then
|
||||
echo wget -c ${ISO_URL} -O ${ISO_PATH}
|
||||
else
|
||||
echo "No ${ISO_PATH} found. Trying to download file."
|
||||
wget -c ${ISO_URL} -O ${ISO_PATH}
|
||||
rc=$?
|
||||
if [ $rc -ne 0 ]; then
|
||||
echo "Failed to fetch ISO from ${ISO_URL}"
|
||||
exit $ISODOWNLOAD_ERR
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${VENV_PATH}" ]; then
|
||||
VENV_PATH="/home/jenkins/venv-nailgun-tests"
|
||||
fi
|
||||
|
||||
# run python virtualenv
|
||||
if [ "${VENV}" = "yes" ]; then
|
||||
if [ "${DRY_RUN}" = "yes" ]; then
|
||||
echo . $VENV_PATH/bin/activate
|
||||
else
|
||||
. $VENV_PATH/bin/activate
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${ENV_NAME}" = "" ]; then
|
||||
ENV_NAME="${JOB_NAME}_system_test"
|
||||
fi
|
||||
|
||||
if [ "${LOGS_DIR}" = "" ]; then
|
||||
LOGS_DIR="${WORKSPACE}/logs"
|
||||
fi
|
||||
|
||||
if [ ! -f "$LOGS_DIR" ]; then
|
||||
mkdir -p $LOGS_DIR
|
||||
fi
|
||||
|
||||
export ENV_NAME
|
||||
export LOGS_DIR
|
||||
export ISO_PATH
|
||||
|
||||
if [ "${KEEP_BEFORE}" != "yes" ]; then
|
||||
# remove previous environment
|
||||
if [ "${DRY_RUN}" = "yes" ]; then
|
||||
echo dos.py erase "${ENV_NAME}"
|
||||
else
|
||||
if dos.py list | grep -q "^${ENV_NAME}\$" ; then
|
||||
dos.py erase "${ENV_NAME}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# gather additional option for this nose test run
|
||||
OPTS=""
|
||||
if [ -n "${NOSE_ATTR}" ]; then
|
||||
OPTS="${OPTS} -a ${NOSE_ATTR}"
|
||||
fi
|
||||
if [ -n "${NOSE_EVAL_ATTR}" ]; then
|
||||
OPTS="${OPTS} -A ${NOSE_EVAL_ATTR}"
|
||||
fi
|
||||
if [ -n "${TEST_OPTIONS}" ]; then
|
||||
OPTS="${OPTS} ${TEST_OPTIONS}"
|
||||
fi
|
||||
|
||||
clean_old_bridges
|
||||
|
||||
# run python test set to create environments, deploy and test product
|
||||
if [ "${DRY_RUN}" = "yes" ]; then
|
||||
echo export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${WORKSPACE}"
|
||||
echo python plugin_test/run_tests.py -q --nologcapture --with-xunit ${OPTS}
|
||||
else
|
||||
export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}${WORKSPACE}"
|
||||
echo ${PYTHONPATH}
|
||||
python plugin_test/run_tests.py -q --nologcapture --with-xunit ${OPTS} &
|
||||
|
||||
fi
|
||||
|
||||
SYSTEST_PID=$!
|
||||
|
||||
if ! ps -p $SYSTEST_PID > /dev/null
|
||||
then
|
||||
echo System tests exited prematurely, aborting
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while [ "$(virsh net-list | grep -c $ENV_NAME)" -ne 5 ];do sleep 10
|
||||
if ! ps -p $SYSTEST_PID > /dev/null
|
||||
then
|
||||
echo System tests exited prematurely, aborting
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
sleep 10
|
||||
|
||||
|
||||
# Configre vcenter nodes and interfaces
|
||||
setup_net $ENV_NAME
|
||||
clean_iptables
|
||||
setup_stt $ENV_NAME
|
||||
setup_external_net
|
||||
|
||||
revert_ws "$WORKSTATION_NODES" || { echo "killing $SYSTEST_PID and its childs" && pkill --parent $SYSTEST_PID && kill $SYSTEST_PID && exit 1; }
|
||||
|
||||
echo waiting for system tests to finish
|
||||
wait $SYSTEST_PID
|
||||
|
||||
export RES=$?
|
||||
echo ENVIRONMENT NAME is $ENV_NAME
|
||||
virsh net-dumpxml ${ENV_NAME}_admin | grep -P "(\d+\.){3}" -o | awk '{print "Fuel master node IP: "$0"2"}'
|
||||
|
||||
if [ "${KEEP_AFTER}" != "yes" ]; then
|
||||
# remove environment after tests
|
||||
if [ "${DRY_RUN}" = "yes" ]; then
|
||||
echo dos.py destroy "${ENV_NAME}"
|
||||
else
|
||||
dos.py destroy "${ENV_NAME}"
|
||||
fi
|
||||
fi
|
||||
|
||||
exit "${RES}"
|
||||
}
|
||||
|
||||
RouteTasks() {
|
||||
# this selector defines task names that are recognised by this script
|
||||
# and runs corresponding jobs for them
|
||||
# running any jobs should exit this script
|
||||
|
||||
case "${TASK_NAME}" in
|
||||
test)
|
||||
RunTest
|
||||
;;
|
||||
*)
|
||||
echo "Unknown task: ${TASK_NAME}!"
|
||||
exit $INVALIDTASK_ERR
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
}
|
||||
|
||||
add_interface_to_bridge() {
|
||||
env=$1
|
||||
net_name=$2
|
||||
nic=$3
|
||||
ip=$4
|
||||
|
||||
for net in $(virsh net-list |grep ${env}_${net_name} |awk '{print $1}');do
|
||||
bridge=$(virsh net-info $net |grep -i bridge |awk '{print $2}')
|
||||
setup_bridge $bridge $nic $ip && echo $net_name bridge $bridge ready
|
||||
done
|
||||
}
|
||||
|
||||
setup_bridge() {
|
||||
bridge=$1
|
||||
nic=$2
|
||||
ip=$3
|
||||
|
||||
sudo /sbin/brctl stp $bridge off
|
||||
sudo /sbin/brctl addif $bridge $nic
|
||||
# set if with existing ip down
|
||||
for itf in $(sudo ip -o addr show to $ip | cut -d' ' -f2); do
|
||||
echo deleting $ip from $itf
|
||||
sudo ip addr del dev $itf $ip
|
||||
done
|
||||
echo adding $ip to $bridge
|
||||
sudo /sbin/ip addr add $ip dev $bridge
|
||||
echo $nic added to $bridge
|
||||
sudo /sbin/ip link set dev $bridge up
|
||||
if sudo /sbin/iptables-save |grep $bridge | grep -i reject| grep -q FORWARD; then
|
||||
sudo /sbin/iptables -D FORWARD -o $bridge -j REJECT --reject-with icmp-port-unreachable
|
||||
sudo /sbin/iptables -D FORWARD -i $bridge -j REJECT --reject-with icmp-port-unreachable
|
||||
fi
|
||||
}
|
||||
|
||||
clean_old_bridges() {
|
||||
for intf in $WORKSTATION_IFS; do
|
||||
for br in $(/sbin/brctl show | grep -v "bridge name" | cut -f1 -d' '); do
|
||||
/sbin/brctl show $br| grep -q $intf && sudo /sbin/brctl delif $br $intf \
|
||||
&& sudo /sbin/ip link set dev $br down && echo $intf deleted from $br
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
clean_iptables() {
|
||||
sudo /sbin/iptables -F
|
||||
sudo /sbin/iptables -t nat -F
|
||||
sudo /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
}
|
||||
|
||||
revert_ws() {
|
||||
for i in $1
|
||||
do
|
||||
vmrun -T ws-shared -h https://localhost:443/sdk -u $WORKSTATION_USERNAME -p $WORKSTATION_PASSWORD listRegisteredVM | grep -q $i || { echo "VM $i does not exist"; continue; }
|
||||
echo vmrun: reverting $i to $WORKSTATION_SNAPSHOT
|
||||
vmrun -T ws-shared -h https://localhost:443/sdk -u $WORKSTATION_USERNAME -p $WORKSTATION_PASSWORD revertToSnapshot "[standard] $i/$i.vmx" $WORKSTATION_SNAPSHOT || { echo "Error: revert of $i failed"; return 1; }
|
||||
done
|
||||
|
||||
for i in $1
|
||||
do
|
||||
echo vmrun: starting $i
|
||||
vmrun -T ws-shared -h https://localhost:443/sdk -u $WORKSTATION_USERNAME -p $WORKSTATION_PASSWORD start "[standard] $i/$i.vmx" || { echo "Error: $i failed to start"; return 1; }
|
||||
done
|
||||
}
|
||||
|
||||
setup_net() {
|
||||
env=$1
|
||||
add_interface_to_bridge $env public vmnet1 172.16.0.1/24
|
||||
}
|
||||
|
||||
setup_stt() {
|
||||
set -e
|
||||
env=$1
|
||||
net_name='private'
|
||||
nic='vmnet2'
|
||||
|
||||
for net in $(virsh net-list |grep ${env}_${net_name} | awk '{print $1}');do
|
||||
bridge=$(virsh net-info $net | grep -i bridge | awk '{print $2}')
|
||||
done
|
||||
sudo /sbin/brctl stp $bridge off
|
||||
sudo /sbin/brctl addif $bridge $nic
|
||||
echo $nic added to $bridge
|
||||
sudo /sbin/ip link set dev $bridge up
|
||||
if sudo /sbin/iptables-save | grep $bridge | grep -i reject| grep -q FORWARD; then
|
||||
sudo /sbin/iptables -D FORWARD -o $bridge -j REJECT --reject-with icmp-port-unreachable
|
||||
sudo /sbin/iptables -D FORWARD -i $bridge -j REJECT --reject-with icmp-port-unreachable
|
||||
fi
|
||||
|
||||
echo "Stt added to $net_name bridge $bridge"
|
||||
}
|
||||
|
||||
setup_external_net() {
|
||||
nic='vmnet5'
|
||||
|
||||
ip=${NSXT_ROUTING_NET_CIDR%\.*}.1
|
||||
gw_ip=${NSXT_ROUTING_NET_CIDR%\.*}.2
|
||||
mask=${NSXT_ROUTING_NET_CIDR##*\/}
|
||||
|
||||
#set if with existing ip down
|
||||
for itf in $(sudo ip -o addr show to $ip | cut -d' ' -f2); do
|
||||
echo deleting $ip from $itf
|
||||
sudo ip addr del $ip/$mask dev $itf
|
||||
done
|
||||
|
||||
for itf in $(sudo ip -o ro show to ${NSXT_FLOATING_NET_CIDR} | cut -d' ' -f5); do
|
||||
echo deleting route to ${NSXT_FLOATING_NET_CIDR} dev $itf
|
||||
sudo ip ro del ${NSXT_FLOATING_NET_CIDR} dev $itf
|
||||
done
|
||||
|
||||
set -e
|
||||
sudo /sbin/ip addr add ${ip}/${mask} dev $nic
|
||||
sudo /sbin/ip ro add ${NSXT_FLOATING_NET_CIDR} via ${gw_ip}
|
||||
echo "Routing net added to $nic"
|
||||
}
|
||||
|
||||
# MAIN
|
||||
|
||||
# first we want to get variable from command line options
|
||||
GetoptsVariables "${@}"
|
||||
|
||||
# then we define global variables and there defaults when needed
|
||||
GlobalVariables
|
||||
|
||||
# check do we have all critical variables set
|
||||
CheckVariables
|
||||
|
||||
# first we chdir into our working directory unless we dry run
|
||||
CdWorkSpace
|
||||
|
||||
# finally we can choose what to do according to TASK_NAME
|
||||
RouteTasks
|
118
spec/conf.py
118
spec/conf.py
@ -1,29 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Fuel NSXv plugin documentation build configuration file, created by
|
||||
# sphinx-quickstart on Fri Aug 14 12:14:29 2015.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
"""Copyright 2016 Mirantis, Inc.
|
||||
|
||||
import sys
|
||||
import os
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
"""
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@ -37,7 +35,7 @@ templates_path = ['_templates']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
@ -57,13 +55,13 @@ release = '1.0.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
@ -71,27 +69,27 @@ exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
# modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
# keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
@ -103,26 +101,26 @@ html_theme = 'default'
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
@ -132,48 +130,48 @@ html_static_path = ['_static']
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
# html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'FuelNSXTplugindoc'
|
||||
@ -183,13 +181,13 @@ htmlhelp_basename = 'FuelNSXTplugindoc'
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
# 'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
@ -202,23 +200,23 @@ latex_documents = [
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
@ -231,7 +229,7 @@ man_pages = [
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
@ -246,13 +244,13 @@ texinfo_documents = [
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
# texinfo_no_detailmenu = False
|
||||
|
Loading…
Reference in New Issue
Block a user