Revert "Revert "Introduce deployment test for Ironic""
fuel-devops 2.9.16 has been released, and updated on jenkins slave. Also python-ironicclient has been installed.
This reverts commit 87a7bca7ee
.
Change-Id: I072370299a16a02f98a79402a1c9c3efa379275e
This commit is contained in:
parent
87a7bca7ee
commit
e918673387
|
@ -122,3 +122,8 @@ SSH Manager
|
|||
-----------
|
||||
.. automodule:: fuelweb_test.helpers.ssh_manager
|
||||
:members:
|
||||
|
||||
Ironic Actions
|
||||
--------------
|
||||
.. automodule:: fuelweb_test.helpers.ironic_actions
|
||||
:members:
|
||||
|
|
|
@ -27,6 +27,7 @@ from keystoneclient.exceptions import ClientException
|
|||
from novaclient.v2 import Client as NovaClient
|
||||
import neutronclient.v2_0.client as neutronclient
|
||||
from proboscis.asserts import assert_equal
|
||||
import ironicclient.client as ironicclient
|
||||
|
||||
|
||||
class Common(object):
|
||||
|
@ -75,6 +76,14 @@ class Common(object):
|
|||
token=token,
|
||||
cacert=path_to_cert)
|
||||
|
||||
ironic_endpoint = self.keystone.service_catalog.url_for(
|
||||
service_type='baremetal',
|
||||
endpoint_type='publicURL')
|
||||
self.ironic = ironicclient.get_client(
|
||||
api_version=1,
|
||||
os_auth_token=token,
|
||||
ironic_url=ironic_endpoint, insecure=True)
|
||||
|
||||
def goodbye_security(self):
|
||||
secgroup_list = self.nova.security_groups.list()
|
||||
LOGGER.debug("Security list is {0}".format(secgroup_list))
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
# 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
|
||||
# a 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 devops.helpers.helpers import tcp_ping
|
||||
from devops.helpers.helpers import wait
|
||||
from fuelweb_test.helpers import os_actions
|
||||
import json
|
||||
|
||||
|
||||
class IronicActions(os_actions.OpenStackActions):
|
||||
"""IronicActions.""" # TODO documentation
|
||||
|
||||
def __init__(self, controller_ip, user='admin',
|
||||
passwd='admin', tenant='admin'):
|
||||
super(IronicActions, self).__init__(controller_ip,
|
||||
user, passwd,
|
||||
tenant)
|
||||
|
||||
def upload_user_image(self, nailgun_node, ssh_manager, img_url):
|
||||
disk_info = [{"name": "vda", "extra": [], "free_space": 11000,
|
||||
"type": "disk", "id": "vda", "size": 11000,
|
||||
"volumes": [{"mount": "/", "type": "partition",
|
||||
"file_system": "ext4", "size": 10000}]}]
|
||||
cmd = ('. /root/openrc; cd /tmp/; '
|
||||
'curl {img_url} | tar -xzp; '
|
||||
'glance image-create --name virtual_trusty_ext4 '
|
||||
'--disk-format raw --container-format bare '
|
||||
'--file trusty-server-cloudimg-amd64.img --visibility public '
|
||||
'--property cpu_arch="x86_64" '
|
||||
'--property hypervisor_type="baremetal" '
|
||||
'--property mos_disk_info=\'{disk_info}\'').format(
|
||||
disk_info=json.dumps(disk_info),
|
||||
img_url=img_url)
|
||||
|
||||
ssh_manager.execute_on_remote(nailgun_node['ip'], cmd=cmd)
|
||||
|
||||
def enroll_ironic_node(self, ironic_slave, hw_ip):
|
||||
deploy_kernel = self.get_image_by_name('ironic-deploy-linux')
|
||||
deploy_ramdisk = self.get_image_by_name('ironic-deploy-initramfs')
|
||||
deploy_squashfs = self.get_image_by_name('ironic-deploy-squashfs')
|
||||
|
||||
libvirt_uri = 'qemu+tcp://{server_ip}/system'.format(
|
||||
server_ip=hw_ip)
|
||||
driver_info = {'libvirt_uri': libvirt_uri,
|
||||
'deploy_kernel': deploy_kernel.id,
|
||||
'deploy_ramdisk': deploy_ramdisk.id,
|
||||
'deploy_squashfs': deploy_squashfs.id}
|
||||
|
||||
mac_address = ironic_slave.interface_by_network_name(
|
||||
'ironic')[0].mac_address
|
||||
|
||||
properties = {'memory_mb': ironic_slave.memory,
|
||||
'cpu_arch': ironic_slave.architecture,
|
||||
'local_gb': '50',
|
||||
'cpus': ironic_slave.vcpu}
|
||||
|
||||
ironic_node = self.create_ironic_node(driver='fuel_libvirt',
|
||||
driver_info=driver_info,
|
||||
properties=properties)
|
||||
self.create_ironic_port(address=mac_address,
|
||||
node_uuid=ironic_node.uuid)
|
||||
|
||||
def wait_for_ironic_hypervisors(self, ironic_conn, ironic_slaves):
|
||||
|
||||
def _wait_for_ironic_hypervisor():
|
||||
hypervisors = ironic_conn.get_hypervisors()
|
||||
ironic_hypervisors = [h for h in hypervisors if
|
||||
h.hypervisor_type == 'ironic']
|
||||
|
||||
if len(ironic_slaves) == len(ironic_hypervisors):
|
||||
for hypervisor in ironic_hypervisors:
|
||||
if hypervisor.memory_mb == 0:
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
wait(_wait_for_ironic_hypervisor,
|
||||
timeout=60 * 3, timeout_msg='Failed to update hypervisor details')
|
||||
|
||||
def wait_for_vms(self, ironic_conn):
|
||||
srv_list = ironic_conn.get_servers()
|
||||
for srv in srv_list:
|
||||
wait(lambda: self.get_instance_detail(srv).status == "ACTIVE",
|
||||
timeout=60 * 15, timeout_msg='Server didn\'t became active')
|
||||
|
||||
def verify_vms_connection(self, ironic_conn):
|
||||
srv_list = ironic_conn.get_servers()
|
||||
for srv in srv_list:
|
||||
wait(lambda: tcp_ping(srv.networks['baremetal'][0], 22),
|
||||
timeout=60 * 5, timeout_msg='Failed to connect to port 22')
|
||||
|
||||
def create_ironic_node(self, **kwargs):
|
||||
return self.ironic.node.create(**kwargs)
|
||||
|
||||
def create_ironic_port(self, **kwargs):
|
||||
return self.ironic.port.create(**kwargs)
|
|
@ -562,3 +562,8 @@ CENTOS_DUMMY_DEPLOY = get_var_as_bool("CENTOS_DUMMY_DEPLOY", False)
|
|||
PERESTROIKA_REPO = os.environ.get(
|
||||
"PERESTROIKA_REPO", "http://perestroika-repo-tst.infra.mirantis.net/"
|
||||
"mos-repos/centos/mos8.0-centos7-fuel/os/x86_64/")
|
||||
|
||||
# Ironic variables
|
||||
IRONIC_USER_IMAGE_URL = os.environ.get(
|
||||
"IRONIC_USER_IMAGE_URL", "https://cloud-images.ubuntu.com/trusty/current/"
|
||||
"trusty-server-cloudimg-amd64.tar.gz")
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
# under the License.
|
||||
|
||||
from fuelweb_test.helpers.decorators import log_snapshot_after_test
|
||||
from fuelweb_test.helpers import ironic_actions
|
||||
from fuelweb_test.settings import DEPLOYMENT_MODE
|
||||
from fuelweb_test.settings import IRONIC_USER_IMAGE_URL
|
||||
from fuelweb_test.settings import NEUTRON_SEGMENT
|
||||
from fuelweb_test.tests.base_test_case import SetupEnvironment
|
||||
from fuelweb_test.tests.base_test_case import TestBasic
|
||||
|
@ -80,3 +82,182 @@ class TestIronicBase(TestBasic):
|
|||
cluster_id=cluster_id)
|
||||
|
||||
self.env.make_snapshot("ironic_base")
|
||||
|
||||
|
||||
@test(groups=["ironic_deploy", "ironic"])
|
||||
class TestIronicDeploy(TestBasic):
|
||||
"""Test ironic provisioning on VM"""
|
||||
|
||||
def _deploy_ironic_cluster(self, **kwargs):
|
||||
default_settings = {
|
||||
'net_provider': 'neutron',
|
||||
'net_segment_type': NEUTRON_SEGMENT['vlan'],
|
||||
'ironic': True}
|
||||
default_nodes = {
|
||||
'slave-01': ['controller'],
|
||||
'slave-02': ['controller', 'ironic'],
|
||||
'slave-03': ['controller', 'ironic'],
|
||||
'slave-04': ['ironic'],
|
||||
'slave-05': ['compute']}
|
||||
settings = kwargs.get('settings') or default_settings
|
||||
nodes = kwargs.get('nodes') or default_nodes
|
||||
|
||||
cluster_id = self.fuel_web.create_cluster(
|
||||
name=self.__class__.__name__,
|
||||
mode=DEPLOYMENT_MODE,
|
||||
settings=settings
|
||||
)
|
||||
|
||||
self.fuel_web.update_nodes(
|
||||
cluster_id,
|
||||
nodes
|
||||
)
|
||||
|
||||
self.fuel_web.deploy_cluster_wait(cluster_id)
|
||||
|
||||
return cluster_id
|
||||
|
||||
def _create_os_resources(self, ironic_conn):
|
||||
devops_node = self.fuel_web.get_nailgun_primary_node(
|
||||
self.env.d_env.nodes().slaves[0])
|
||||
nailgun_node = self.fuel_web.get_nailgun_node_by_devops_node(
|
||||
devops_node)
|
||||
|
||||
ironic_conn.upload_user_image(nailgun_node,
|
||||
ssh_manager=self.ssh_manager,
|
||||
img_url=IRONIC_USER_IMAGE_URL)
|
||||
|
||||
ironic_slaves = self.env.d_env.nodes().ironics
|
||||
server_ip = self.env.d_env.router('public')
|
||||
|
||||
for ironic_slave in ironic_slaves:
|
||||
ironic_conn.enroll_ironic_node(ironic_slave, server_ip)
|
||||
|
||||
ironic_conn.wait_for_ironic_hypervisors(ironic_conn, ironic_slaves)
|
||||
|
||||
def _boot_nova_instances(self, ironic_conn):
|
||||
ironic_slaves = self.env.d_env.nodes().ironics
|
||||
user_image = ironic_conn.get_image_by_name('virtual_trusty_ext4')
|
||||
network = ironic_conn.nova.networks.find(label='baremetal')
|
||||
flavor = ironic_conn.create_flavor('baremetal_flavor', 1024, 1, 50)
|
||||
nics = [{'net-id': network.id}]
|
||||
|
||||
for ironic_slave in ironic_slaves:
|
||||
ironic_conn.nova.servers.create(
|
||||
name=ironic_slave.name,
|
||||
image=user_image.id,
|
||||
flavor=flavor.id,
|
||||
nics=nics)
|
||||
|
||||
@test(depends_on=[SetupEnvironment.prepare_slaves_5],
|
||||
groups=["ironic_deploy_swift"])
|
||||
@log_snapshot_after_test
|
||||
def ironic_deploy_swift(self):
|
||||
"""Deploy ironic with 1 baremetal node
|
||||
|
||||
Scenario:
|
||||
1. Create cluster
|
||||
2. Add 3 node with controller+ironic role
|
||||
3. Add 1 node with compute role
|
||||
4. Add 1 nodes with ironic role
|
||||
5. Deploy the cluster
|
||||
6. Upload image to glance
|
||||
7. Enroll Ironic nodes
|
||||
8. Boot nova instance
|
||||
9. Check Nova instance status
|
||||
|
||||
Duration 90m
|
||||
Snapshot ironic_deploy_swift
|
||||
"""
|
||||
|
||||
self.env.revert_snapshot("ready_with_5_slaves")
|
||||
|
||||
self.show_step(1, initialize=True)
|
||||
self.show_step(2)
|
||||
self.show_step(3)
|
||||
self.show_step(4)
|
||||
self.show_step(5)
|
||||
cluster_id = self._deploy_ironic_cluster()
|
||||
|
||||
ironic_conn = ironic_actions.IronicActions(
|
||||
self.fuel_web.get_public_vip(cluster_id))
|
||||
|
||||
self.show_step(6)
|
||||
self.show_step(7)
|
||||
self._create_os_resources(ironic_conn)
|
||||
|
||||
self.show_step(8)
|
||||
self._boot_nova_instances(ironic_conn)
|
||||
|
||||
self.show_step(9)
|
||||
ironic_conn.wait_for_vms(ironic_conn)
|
||||
ironic_conn.verify_vms_connection(ironic_conn)
|
||||
|
||||
self.env.make_snapshot("ironic_deploy_swift")
|
||||
|
||||
@test(depends_on=[SetupEnvironment.prepare_slaves_5],
|
||||
groups=["ironic_deploy_ceph"])
|
||||
@log_snapshot_after_test
|
||||
def ironic_deploy_ceph(self):
|
||||
"""Deploy ironic with 1 baremetal node
|
||||
|
||||
Scenario:
|
||||
1. Create cluster
|
||||
2. Add 3 node with controller+ironic+ceph-osd role
|
||||
3. Add 1 node with compute role
|
||||
4. Add 1 nodes with ironic role
|
||||
5. Deploy the cluster
|
||||
6. Upload image to glance
|
||||
7. Enroll Ironic nodes
|
||||
8. Boot nova instance
|
||||
9. Check Nova instance status
|
||||
|
||||
Duration 90m
|
||||
Snapshot ironic_deploy_ceph
|
||||
"""
|
||||
|
||||
self.env.revert_snapshot("ready_with_5_slaves")
|
||||
|
||||
data = {
|
||||
'volumes_ceph': True,
|
||||
'images_ceph': True,
|
||||
'objects_ceph': True,
|
||||
'volumes_lvm': False,
|
||||
'tenant': 'ceph1',
|
||||
'user': 'ceph1',
|
||||
'password': 'ceph1',
|
||||
'net_provider': 'neutron',
|
||||
'net_segment_type': NEUTRON_SEGMENT['vlan'],
|
||||
'ironic': True}
|
||||
nodes = {
|
||||
'slave-01': ['controller', 'ceph-osd'],
|
||||
'slave-02': ['controller', 'ironic', 'ceph-osd'],
|
||||
'slave-03': ['controller', 'ironic', 'ceph-osd'],
|
||||
'slave-04': ['ironic'],
|
||||
'slave-05': ['compute']}
|
||||
|
||||
self.show_step(1, initialize=True)
|
||||
self.show_step(2)
|
||||
self.show_step(3)
|
||||
self.show_step(4)
|
||||
self.show_step(5)
|
||||
cluster_id = self._deploy_ironic_cluster(settings=data, nodes=nodes)
|
||||
|
||||
ironic_conn = ironic_actions.IronicActions(
|
||||
self.fuel_web.get_public_vip(cluster_id),
|
||||
user='ceph1',
|
||||
passwd='ceph1',
|
||||
tenant='ceph1')
|
||||
|
||||
self.show_step(6)
|
||||
self.show_step(7)
|
||||
self._create_os_resources(ironic_conn)
|
||||
|
||||
self.show_step(8)
|
||||
self._boot_nova_instances(ironic_conn)
|
||||
|
||||
self.show_step(9)
|
||||
ironic_conn.wait_for_vms(ironic_conn)
|
||||
ironic_conn.verify_vms_connection(ironic_conn)
|
||||
|
||||
self.env.make_snapshot("ironic_deploy_ceph")
|
||||
|
|
Loading…
Reference in New Issue