Merge "Smoke and bvt tests"
This commit is contained in:
commit
c3447a069a
|
@ -0,0 +1,4 @@
|
||||||
|
[submodule "plugin_test/fuel-qa"]
|
||||||
|
path = plugin_test/fuel-qa
|
||||||
|
url = https://github.com/openstack/fuel-qa
|
||||||
|
branch = stable/mitaka
|
|
@ -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.
|
||||||
|
"""
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 15681971a6ff4adc9a8fd0b567f7443a3db6ffab
|
|
@ -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.
|
||||||
|
"""
|
|
@ -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')
|
||||||
|
}
|
|
@ -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
|
|
@ -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()
|
|
@ -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
|
|
@ -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.
|
||||||
|
"""
|
|
@ -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)
|
|
@ -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'])
|
|
@ -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 -*-
|
"""Copyright 2016 Mirantis, Inc.
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import sys
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
import os
|
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,
|
# 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
|
# 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.
|
# 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 ------------------------------------------------
|
# -- General configuration ------------------------------------------------
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
# 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
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
|
@ -37,7 +35,7 @@ templates_path = ['_templates']
|
||||||
source_suffix = '.rst'
|
source_suffix = '.rst'
|
||||||
|
|
||||||
# The encoding of source files.
|
# The encoding of source files.
|
||||||
#source_encoding = 'utf-8-sig'
|
# source_encoding = 'utf-8-sig'
|
||||||
|
|
||||||
# The master toctree document.
|
# The master toctree document.
|
||||||
master_doc = 'index'
|
master_doc = 'index'
|
||||||
|
@ -57,13 +55,13 @@ release = '1.0.0'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
#language = None
|
# language = None
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some
|
# There are two options for replacing |today|: either, you set today to some
|
||||||
# non-false value, then it is used:
|
# non-false value, then it is used:
|
||||||
#today = ''
|
# today = ''
|
||||||
# Else, today_fmt is used as the format for a strftime call.
|
# 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
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# 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
|
# The reST default role (used for this markup: `text`) to use for all
|
||||||
# documents.
|
# documents.
|
||||||
#default_role = None
|
# default_role = None
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
# 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
|
# If true, the current module name will be prepended to all description
|
||||||
# unit titles (such as .. function::).
|
# unit titles (such as .. function::).
|
||||||
#add_module_names = True
|
# add_module_names = True
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||||
# output. They are ignored by default.
|
# output. They are ignored by default.
|
||||||
#show_authors = False
|
# show_authors = False
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
pygments_style = 'sphinx'
|
pygments_style = 'sphinx'
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
# 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.
|
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||||
#keep_warnings = False
|
# keep_warnings = False
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output ----------------------------------------------
|
# -- 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
|
# 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
|
# further. For a list of options available for each theme, see the
|
||||||
# documentation.
|
# documentation.
|
||||||
#html_theme_options = {}
|
# html_theme_options = {}
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
# 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
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||||||
# "<project> v<release> documentation".
|
# "<project> v<release> documentation".
|
||||||
#html_title = None
|
# html_title = None
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
# 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
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
# of the sidebar.
|
# 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
|
# 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
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
# pixels large.
|
# pixels large.
|
||||||
#html_favicon = None
|
# html_favicon = None
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# 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,
|
# 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
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
# directly to the root of the documentation.
|
# 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,
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||||
# using the given strftime format.
|
# 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
|
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||||
# typographically correct entities.
|
# typographically correct entities.
|
||||||
#html_use_smartypants = True
|
# html_use_smartypants = True
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
# 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
|
# Additional templates that should be rendered to pages, maps page names to
|
||||||
# template names.
|
# template names.
|
||||||
#html_additional_pages = {}
|
# html_additional_pages = {}
|
||||||
|
|
||||||
# If false, no module index is generated.
|
# If false, no module index is generated.
|
||||||
#html_domain_indices = True
|
# html_domain_indices = True
|
||||||
|
|
||||||
# If false, no index is generated.
|
# 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.
|
# 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.
|
# 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.
|
# 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.
|
# 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
|
# 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
|
# contain a <link> tag referring to it. The value of this option must be the
|
||||||
# base URL from which the finished HTML is served.
|
# 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").
|
# 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.
|
# Output file base name for HTML help builder.
|
||||||
htmlhelp_basename = 'FuelNSXTplugindoc'
|
htmlhelp_basename = 'FuelNSXTplugindoc'
|
||||||
|
@ -183,13 +181,13 @@ htmlhelp_basename = 'FuelNSXTplugindoc'
|
||||||
|
|
||||||
latex_elements = {
|
latex_elements = {
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
# The paper size ('letterpaper' or 'a4paper').
|
||||||
#'papersize': 'letterpaper',
|
# 'papersize': 'letterpaper',
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
#'pointsize': '10pt',
|
# 'pointsize': '10pt',
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
# Additional stuff for the LaTeX preamble.
|
||||||
#'preamble': '',
|
# 'preamble': '',
|
||||||
}
|
}
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
# 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 name of an image file (relative to this directory) to place at the top of
|
||||||
# the title page.
|
# the title page.
|
||||||
#latex_logo = None
|
# latex_logo = None
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||||
# not chapters.
|
# not chapters.
|
||||||
#latex_use_parts = False
|
# latex_use_parts = False
|
||||||
|
|
||||||
# If true, show page references after internal links.
|
# If true, show page references after internal links.
|
||||||
#latex_show_pagerefs = False
|
# latex_show_pagerefs = False
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
# 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.
|
# Documents to append as an appendix to all manuals.
|
||||||
#latex_appendices = []
|
# latex_appendices = []
|
||||||
|
|
||||||
# If false, no module index is generated.
|
# If false, no module index is generated.
|
||||||
#latex_domain_indices = True
|
# latex_domain_indices = True
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output ---------------------------------------
|
# -- Options for manual page output ---------------------------------------
|
||||||
|
@ -231,7 +229,7 @@ man_pages = [
|
||||||
]
|
]
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
# If true, show URL addresses after external links.
|
||||||
#man_show_urls = False
|
# man_show_urls = False
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Texinfo output -------------------------------------------
|
# -- Options for Texinfo output -------------------------------------------
|
||||||
|
@ -246,13 +244,13 @@ texinfo_documents = [
|
||||||
]
|
]
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
# Documents to append as an appendix to all manuals.
|
||||||
#texinfo_appendices = []
|
# texinfo_appendices = []
|
||||||
|
|
||||||
# If false, no module index is generated.
|
# If false, no module index is generated.
|
||||||
#texinfo_domain_indices = True
|
# texinfo_domain_indices = True
|
||||||
|
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
# 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.
|
# 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