Merge "Adding Ethernet flow"
This commit is contained in:
commit
a28999c034
|
@ -0,0 +1,5 @@
|
||||||
|
.build
|
||||||
|
bootstrap/*
|
||||||
|
repositories/*
|
||||||
|
*.rpm
|
||||||
|
*.deb
|
|
@ -1,4 +1,4 @@
|
||||||
mellanox_plugin
|
mellanox-plugin
|
||||||
================
|
================
|
||||||
|
|
||||||
Plugin description
|
Plugin description
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
readonly SCRIPT_NAME=`basename $0`
|
||||||
|
|
||||||
|
function logger_print () {
|
||||||
|
priority=$1
|
||||||
|
msg=$2
|
||||||
|
logger -t $SCRIPT_NAME "${priority}: ${msg}"
|
||||||
|
echo $(date +"%Y-%m-%d %H:%M:%S") $SCRIPT_NAME ${priority}: ${msg} >> /var/log/mellanox-plugin.log
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_mlnx_param () {
|
||||||
|
param="$1"
|
||||||
|
val=$(ruby -r hiera -r yaml -e "hiera = Hiera.new(:config => '/etc/puppet/hiera.yaml'); mlnx = hiera.lookup 'mellanox-plugin', [], {}; puts mlnx['"$param"']")
|
||||||
|
echo $val
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_distro () {
|
||||||
|
if [[ -f /etc/redhat-release ]]; then
|
||||||
|
dist='redhat';
|
||||||
|
elif [[ -f /etc/debian_version ]]; then
|
||||||
|
dist='ubuntu';
|
||||||
|
else
|
||||||
|
logger_print error "Could not detect linux distribution"
|
||||||
|
fi
|
||||||
|
echo $dist
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly DISTRO=`get_distro`
|
||||||
|
readonly DRIVER=`get_mlnx_param driver`
|
||||||
|
readonly SRIOV=`get_mlnx_param sriov`
|
||||||
|
readonly USER_NUM_OF_VFS=`get_mlnx_param num_of_vfs`
|
||||||
|
readonly ISER=`get_mlnx_param iser`
|
||||||
|
readonly MAX_VFS=64
|
||||||
|
readonly MIN_VFS=1
|
|
@ -0,0 +1,100 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
## Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
##
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
require 'hiera'
|
||||||
|
ENV['LANG'] = 'C'
|
||||||
|
LOG_FILE="/var/log/mellanox-plugin.log"
|
||||||
|
|
||||||
|
def log(level, msg)
|
||||||
|
current_time = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
File.open(LOG_FILE, 'a') { |f|
|
||||||
|
f.puts "#{current_time} delete_images.rb #{level}: #{msg}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def image_list
|
||||||
|
stdout = `. /root/openrc && glance image-list`
|
||||||
|
return_code = $?.exitstatus
|
||||||
|
[ stdout, return_code ]
|
||||||
|
end
|
||||||
|
|
||||||
|
def images_ids
|
||||||
|
stdout, return_code = image_list
|
||||||
|
if return_code != 0
|
||||||
|
raise 'Failed retrieving image-list'
|
||||||
|
end
|
||||||
|
ids = []
|
||||||
|
stdout.split("\n").each do |line|
|
||||||
|
fields = line.split('|').map { |f| f.chomp.strip }
|
||||||
|
next if fields[1] == 'ID'
|
||||||
|
next unless fields[1]
|
||||||
|
ids << fields[1]
|
||||||
|
end
|
||||||
|
{:ids => ids, :exit_code => return_code}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def delete_image(id)
|
||||||
|
command = ". /root/openrc && /usr/bin/glance image-delete #{id}"
|
||||||
|
stdout = `#{command}`
|
||||||
|
return_code = $?.exitstatus
|
||||||
|
[ stdout, return_code ]
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait_for_glance
|
||||||
|
5.times.each do |retries|
|
||||||
|
sleep 10 if retries > 0
|
||||||
|
_, return_code = image_list
|
||||||
|
return if return_code == 0
|
||||||
|
end
|
||||||
|
raise 'Could not get a list of glance images!'
|
||||||
|
end
|
||||||
|
|
||||||
|
def main
|
||||||
|
log("info", "Waiting for glance response")
|
||||||
|
wait_for_glance
|
||||||
|
|
||||||
|
log("info", "Fetching list of current images")
|
||||||
|
ids = images_ids
|
||||||
|
if ids[:exit_code] != 0
|
||||||
|
raise 'Failed retrieving existing images ids'
|
||||||
|
end
|
||||||
|
|
||||||
|
succeed = true
|
||||||
|
ids[:ids].each do |id|
|
||||||
|
stdout, return_code = delete_image(id)
|
||||||
|
if return_code != 0
|
||||||
|
log("error", "Failed deleting image with ID = '#{id}'" + stdout)
|
||||||
|
succeed = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ! succeed
|
||||||
|
log("error", "Some images weren't deleted, this may cause errors when "+
|
||||||
|
"uploading images to glance or when creating an instance")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
########################
|
||||||
|
|
||||||
|
begin
|
||||||
|
main
|
||||||
|
rescue
|
||||||
|
log("error", "Some images weren't deleted, this may cause errors when "+
|
||||||
|
"uploading images to glance or when creating an instance")
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log("info", "Successfully deleted all existing images from glance")
|
||||||
|
end
|
|
@ -0,0 +1,133 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
readonly SCRIPT_DIR=$(dirname "$0")
|
||||||
|
source $SCRIPT_DIR/common
|
||||||
|
|
||||||
|
readonly KERNEL_VERSION="$(uname -r)"
|
||||||
|
readonly OFED_PACKAGE_NAME="mlnx-ofed-fuel"
|
||||||
|
readonly OFED_BASE_DIR="/opt/ofed"
|
||||||
|
readonly OFED_SRC_DIR="${OFED_BASE_DIR}/MLNX_OFED"
|
||||||
|
readonly OFED_SUCCESS_FILE="${OFED_BASE_DIR}/.success"
|
||||||
|
readonly OFED_INFO="/usr/bin/ofed_info"
|
||||||
|
OFED_DIR=$OFED_SRC_DIR
|
||||||
|
OFED_INSTALL_SCRIPT_CMD="${OFED_DIR}/mlnxofedinstall"
|
||||||
|
|
||||||
|
function is_ofed_installed () {
|
||||||
|
if [ -f ${OFED_SUCCESS_FILE} ] && [ -f ${OFED_INFO} ] && ( ${OFED_INFO} 2>&1 >/dev/null ); then
|
||||||
|
installed_ofed_version=`${OFED_INFO} -s`
|
||||||
|
logger_print info "OFED is already installed: ${installed_ofed_version}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_mlnx_ofed_src () {
|
||||||
|
logger_print info "Installing ${OFED_PACKAGE_NAME} source code"
|
||||||
|
if [ "$DISTRO" == "redhat" ]; then
|
||||||
|
yum install ${OFED_PACKAGE_NAME} -y
|
||||||
|
elif [ "$DISTRO" == "ubuntu" ]; then
|
||||||
|
apt-get install ${OFED_PACKAGE_NAME} -y
|
||||||
|
fi
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger_print error "Failed installing ${OFED_PACKAGE_NAME} package"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_kernel_support () {
|
||||||
|
# ubuntu doesn't require recompilation in case of kernel change, it supports dkms
|
||||||
|
if [ "$DISTRO" == "ubuntu" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
OFED_ADD_KERNEL_SUPPORT_SCRIPT="${OFED_DIR}/mlnx_add_kernel_support.sh"
|
||||||
|
if [ ! -x $OFED_ADD_KERNEL_SUPPORT_SCRIPT ] ; then
|
||||||
|
logger_print error "Failed to find $OFED_ADD_KERNEL_SUPPORT_SCRIPT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
OFED_VERSION=$(cat ${OFED_DIR}/.mlnx)
|
||||||
|
OFED_ARCH=$(cat ${OFED_DIR}/.arch)
|
||||||
|
OFED_DISTRO=$(cat ${OFED_DIR}/distro)
|
||||||
|
RECOMPILED_OFED_NAME="MLNX_OFED_LINUX-${OFED_VERSION}-${OFED_DISTRO}-${OFED_ARCH}-ext"
|
||||||
|
RECOMPILED_OFED_DIR="${OFED_BASE_DIR}/${RECOMPILED_OFED_NAME}"
|
||||||
|
|
||||||
|
# Recompile OFED in case original OFED at $OFED_DIR doesn't support the existing kernel
|
||||||
|
if ( ! grep -Fxq ${KERNEL_VERSION} ${OFED_DIR}/.supported_kernels ); then
|
||||||
|
if [ ! -d ${RECOMPILED_OFED_DIR} ] || ( ! grep -Fxq ${KERNEL_VERSION} ${RECOMPILED_OFED_DIR}/.supported_kernels); then
|
||||||
|
logger_print info "Recompiling OFED for kernel ${KERNEL_VERSION}"
|
||||||
|
${OFED_DIR}/mlnx_add_kernel_support.sh --force --yes --make-tgz --mlnx_ofed ${OFED_DIR}
|
||||||
|
recompiled_ofed_archive=/tmp/${RECOMPILED_OFED_NAME}.tgz
|
||||||
|
tar zxf $recompiled_ofed_archive -C ${OFED_BASE_DIR}
|
||||||
|
rm -f $recompiled_ofed_archive
|
||||||
|
fi
|
||||||
|
OFED_DIR=$RECOMPILED_OFED_DIR
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_ofed_without_fw_update () {
|
||||||
|
OFED_INSTALL_SCRIPT="${OFED_DIR}/mlnxofedinstall"
|
||||||
|
if [ ! -x $OFED_INSTALL_SCRIPT ] ; then
|
||||||
|
logger_print error "Failed to find $OFED_INSTALL_SCRIPT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
logger_print info "Installing OFED drivers"
|
||||||
|
OFED_INSTALL_SCRIPT_CMD="/usr/bin/perl ${OFED_INSTALL_SCRIPT}"
|
||||||
|
${OFED_INSTALL_SCRIPT_CMD} --force --enable-sriov --without-fw-update
|
||||||
|
rc=$?
|
||||||
|
if [ $rc -ne 0 ] ;then
|
||||||
|
logger_print error "Failed execute ${OFED_INSTALL_SCRIPT_CMD} error code ${rc}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
touch ${OFED_SUCCESS_FILE}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_fw_if_not_oem () {
|
||||||
|
BUS_ID=`lspci | grep -m 1 Mellanox | cut -d' ' -f1`
|
||||||
|
if [ -z $BUS_ID ]; then
|
||||||
|
logger_print info "Didn't find bus, skipping firmware upgrade"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mstflint -d ${BUS_ID} q | grep -i PSID | grep MT_
|
||||||
|
if [ $? -ne 0 ] ;then
|
||||||
|
logger_print info "Not Mellanox Card, skipping firmware upgrade"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
logger_print info "Updating FW on Mellanox HCA with BUS ID = ${BUS_ID}"
|
||||||
|
${OFED_INSTALL_SCRIPT_CMD} --fw-update-only
|
||||||
|
if [ $? -ne 0 ] ;then
|
||||||
|
logger_print error "Failed execute ${OFED_INSTALL_SCRIPT_CMD} error code $?"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! is_ofed_installed; then
|
||||||
|
# Install mlnx-ofed-fuel rpm/deb package which extracts OFED installation dir
|
||||||
|
install_mlnx_ofed_src
|
||||||
|
|
||||||
|
# Add support for the current kernel in case the OFED included in Fuel
|
||||||
|
# wasn't compiled for the current kernel
|
||||||
|
add_kernel_support
|
||||||
|
|
||||||
|
# First install OFED without SR-IOV and FW upgrade
|
||||||
|
install_ofed_without_fw_update
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OEM cards require a different dedicated OFED build, this build doesn't
|
||||||
|
# support them.
|
||||||
|
update_fw_if_not_oem
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
source ./common
|
||||||
|
ROLES="primary-controller controller compute cinder"
|
||||||
|
ASTUTE_FILE=/etc/astute.yaml
|
||||||
|
|
||||||
|
function check_symlink () {
|
||||||
|
symlink_source=$(readlink ${ASTUTE_FILE})
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if a symlink already exists
|
||||||
|
check_symlink
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
logger_print info "Symbolic link already exists: ${ASTUTE_FILE} --> ${symlink_source}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create astute.yaml symlink to any of the <role>.yaml files
|
||||||
|
for role in $ROLES; do
|
||||||
|
role_file=/etc/"$role".yaml
|
||||||
|
if [ -f $role_file ]; then
|
||||||
|
ln -s -f $role_file ${ASTUTE_FILE}
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
check_symlink
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger_print error "Failed creating a symbolic link for ${ASTUTE_FILE}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
logger_print info "Symbolic link ${ASTUTE_FILE} --> ${symlink_source} was created"
|
||||||
|
exit 0
|
||||||
|
fi
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
source ./common
|
||||||
|
logger_print info "===== Running plugin $1 stage ====="
|
|
@ -0,0 +1,308 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import yaml
|
||||||
|
import glob
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
MLNX_SECTION = 'mellanox-plugin'
|
||||||
|
SETTINGS_FILE = '/etc/astute.yaml'
|
||||||
|
PLUGIN_OVERRIDE_FILE = '/etc/hiera/override/plugins.yaml'
|
||||||
|
MLNX_DRIVERS_LIST = ('mlx4_en', 'eth_ipoib')
|
||||||
|
ISER_IFC_NAME = 'eth_iser0'
|
||||||
|
|
||||||
|
|
||||||
|
class MellanoxSettingsException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MellanoxSettings(object):
|
||||||
|
|
||||||
|
data = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_mlnx_section(cls):
|
||||||
|
if cls.data is None:
|
||||||
|
raise MellanoxSettingsException("No YAML file loaded")
|
||||||
|
if MLNX_SECTION not in cls.data:
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Couldn't find section '{0}'".format(MLNX_SECTION)
|
||||||
|
)
|
||||||
|
return cls.data[MLNX_SECTION]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_bridge_for_network(cls, network):
|
||||||
|
network_to_bridge = {
|
||||||
|
'private': 'prv',
|
||||||
|
'management': 'mgmt',
|
||||||
|
'storage': 'storage',
|
||||||
|
}
|
||||||
|
return 'br-{0}'.format(network_to_bridge[network])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_interface_by_network(cls, network):
|
||||||
|
if network not in ('management', 'storage', 'private'):
|
||||||
|
raise MellanoxSettingsException("Unknown network: {0}".format(network))
|
||||||
|
br_name = cls.get_bridge_for_network(network)
|
||||||
|
endpoints = cls.get_endpoints_section()
|
||||||
|
ifc = endpoints[br_name]['vendor_specific']['phy_interfaces'][0]
|
||||||
|
return ifc
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_driver(cls):
|
||||||
|
interfaces = cls.get_interfaces_section()
|
||||||
|
mlnx = cls.get_mlnx_section()
|
||||||
|
|
||||||
|
# validation that no more than 1 mellanox driver is used
|
||||||
|
interfaces_drivers = {}
|
||||||
|
for ifc in cls.get_physical_interfaces():
|
||||||
|
if ('driver' not in interfaces[ifc]['vendor_specific']) :
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Couldn't find 'driver' for interface '{0}'".format(ifc)
|
||||||
|
)
|
||||||
|
interfaces_drivers[ifc] = interfaces[ifc]['vendor_specific']['driver']
|
||||||
|
mlnx_drivers = dict(
|
||||||
|
(ifc, drv) for (ifc, drv) in interfaces_drivers.iteritems()
|
||||||
|
if drv in MLNX_DRIVERS_LIST
|
||||||
|
)
|
||||||
|
if len(set(mlnx_drivers.values())) > 1:
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Found mismatching Mellanox drivers on different interfaces: "
|
||||||
|
"{0}".format(mlnx_drivers)
|
||||||
|
)
|
||||||
|
|
||||||
|
# add the driver to the yaml
|
||||||
|
mlnx['driver'] = mlnx_drivers.values().pop()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_physical_port(cls):
|
||||||
|
interfaces = cls.get_interfaces_section()
|
||||||
|
mlnx = cls.get_mlnx_section()
|
||||||
|
|
||||||
|
private_ifc = cls.get_interface_by_network('private')
|
||||||
|
if mlnx['driver'] == 'eth_ipoib':
|
||||||
|
if 'bus_info' not in interfaces[private_ifc]['vendor_specific']:
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Couldn't find 'bus_info' for interface "
|
||||||
|
"{0}".format(private_ifc)
|
||||||
|
)
|
||||||
|
mlnx['physical_port'] = interfaces[private_ifc]['vendor_specific']['bus_info']
|
||||||
|
elif mlnx['driver'] == 'mlx4_en':
|
||||||
|
mlnx['physical_port'] = private_ifc
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_storage_vlan(cls):
|
||||||
|
mlnx = cls.get_mlnx_section()
|
||||||
|
endpoints = cls.get_endpoints_section()
|
||||||
|
try:
|
||||||
|
vlan = int(endpoints['br-storage']['vendor_specific']['vlans'])
|
||||||
|
except ValueError:
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Failed reading vlan for br-storage"
|
||||||
|
)
|
||||||
|
mlnx['storage_vlan'] = vlan
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_storage_parent(cls):
|
||||||
|
mlnx = cls.get_mlnx_section()
|
||||||
|
storage_ifc = cls.get_interface_by_network('storage')
|
||||||
|
mlnx['storage_parent'] = storage_ifc
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_iser_interface_name(cls):
|
||||||
|
mlnx = cls.get_mlnx_section()
|
||||||
|
storage_ifc = cls.get_interface_by_network('storage')
|
||||||
|
if mlnx['driver'] == 'mlx4_en':
|
||||||
|
mlnx['iser_ifc_name'] = ISER_IFC_NAME
|
||||||
|
elif mlnx['driver'] == 'eth_ipoib':
|
||||||
|
interfaces = cls.get_interfaces_section()
|
||||||
|
mlnx['iser_ifc_name'] = interfaces[storage_ifc]['vendor_specific']['bus_info']
|
||||||
|
else:
|
||||||
|
raise MellanoxSettingsException("Could not find 'driver' in "
|
||||||
|
"{0} section".format(MLNX_SECTION))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_storage_networking_scheme(cls):
|
||||||
|
endpoints = cls.get_endpoints_section()
|
||||||
|
interfaces = cls.get_interfaces_section()
|
||||||
|
transformations = cls.data['network_scheme']['transformations']
|
||||||
|
mlnx = cls.get_mlnx_section()
|
||||||
|
|
||||||
|
# Handle iSER interface with and w/o vlan tagging
|
||||||
|
storage_vlan = mlnx['storage_vlan']
|
||||||
|
if storage_vlan:
|
||||||
|
vlan_name = "{0}.{1}".format(ISER_IFC_NAME, storage_vlan)
|
||||||
|
# Set storage rule to iSER interface vlan interface
|
||||||
|
cls.data['network_scheme']['roles']['storage'] = vlan_name
|
||||||
|
# Set iSER interface vlan interface
|
||||||
|
transf_add = {
|
||||||
|
'action': 'add-port',
|
||||||
|
'name': vlan_name,
|
||||||
|
'vlan_id': int(storage_vlan),
|
||||||
|
'vlan_dev': ISER_IFC_NAME
|
||||||
|
}
|
||||||
|
if transf_add not in transformations:
|
||||||
|
transformations.append(transf_add)
|
||||||
|
transformations_to_delete = [
|
||||||
|
{ 'action': 'add-port',
|
||||||
|
'name': "{0}.{1}".format(
|
||||||
|
cls.get_interface_by_network('storage'),
|
||||||
|
storage_vlan
|
||||||
|
),
|
||||||
|
'bridge': 'br-storage' } ,
|
||||||
|
{ 'action': 'add-br',
|
||||||
|
'name': 'br-storage' }
|
||||||
|
]
|
||||||
|
endpoints['br-storage']['vendor_specific']['phy_interfaces'] = [ ISER_IFC_NAME ]
|
||||||
|
endpoints[vlan_name] = (
|
||||||
|
endpoints.pop('br-storage', {})
|
||||||
|
)
|
||||||
|
for transf_del in transformations_to_delete:
|
||||||
|
transformations.remove(transf_del)
|
||||||
|
else:
|
||||||
|
# Set storage rule to iSER port
|
||||||
|
cls.data['network_scheme']['roles']['storage'] = ISER_IFC_NAME
|
||||||
|
# Set iSER endpoint with br-storage parameters
|
||||||
|
endpoints[ISER_IFC_NAME] = (
|
||||||
|
endpoints.pop('br-storage', {})
|
||||||
|
)
|
||||||
|
interfaces[ISER_IFC_NAME] = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_endpoints_section(cls):
|
||||||
|
return cls.data['network_scheme']['endpoints']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_physical_interfaces(cls):
|
||||||
|
endpoints = cls.get_endpoints_section()
|
||||||
|
interfaces = cls.get_interfaces_section()
|
||||||
|
mlnx_phys_ifcs = []
|
||||||
|
for ep in endpoints:
|
||||||
|
# skip non physical interfaces
|
||||||
|
if ('vendor_specific' not in endpoints[ep] or
|
||||||
|
'phy_interfaces' not in endpoints[ep]['vendor_specific']):
|
||||||
|
continue
|
||||||
|
phys_ifc = endpoints[ep]['vendor_specific']['phy_interfaces'][0]
|
||||||
|
if ('vendor_specific' not in interfaces[phys_ifc] or
|
||||||
|
'driver' not in interfaces[phys_ifc]['vendor_specific']):
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Missing 'vendor_specific' or 'driver' "
|
||||||
|
"in {0}".format(phys_ifc)
|
||||||
|
)
|
||||||
|
if (interfaces[phys_ifc]['vendor_specific']['driver'] in
|
||||||
|
MLNX_DRIVERS_LIST):
|
||||||
|
mlnx_phys_ifcs.append(phys_ifc)
|
||||||
|
return list(set(mlnx_phys_ifcs))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_interfaces_section(cls):
|
||||||
|
return cls.data['network_scheme']['interfaces']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_iser_enabled(cls):
|
||||||
|
return cls.get_mlnx_section()['iser']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_role_settings(cls):
|
||||||
|
# realize the driver in use (eth/ib)
|
||||||
|
cls.add_driver()
|
||||||
|
# decide the physical function for SR-IOV
|
||||||
|
cls.add_physical_port()
|
||||||
|
# set iSER parameters
|
||||||
|
if cls.is_iser_enabled():
|
||||||
|
cls.add_storage_parent()
|
||||||
|
cls.add_storage_vlan()
|
||||||
|
cls.add_iser_interface_name()
|
||||||
|
cls.set_storage_networking_scheme()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def read_from_yaml(cls, settings_file):
|
||||||
|
try:
|
||||||
|
fd = open(settings_file, 'r')
|
||||||
|
except IOError:
|
||||||
|
raise MellanoxSettingsException("Given YAML file {0} doesn't "
|
||||||
|
"exist".format(settings_file))
|
||||||
|
try:
|
||||||
|
data = yaml.load(fd)
|
||||||
|
except yaml.YAMLError, exc:
|
||||||
|
if hasattr(exc, 'problem_mark'):
|
||||||
|
mark = exc.problem_mark
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Faild parsing YAML file {0}: error position "
|
||||||
|
"({2},{3})".format(mark.line+1, mark.column+1)
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
fd.close()
|
||||||
|
cls.data = data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def write_to_yaml(cls, settings_file):
|
||||||
|
# choose only the edited sections
|
||||||
|
data = {}
|
||||||
|
data['network_scheme'] = cls.data['network_scheme']
|
||||||
|
data[MLNX_SECTION] = cls.data[MLNX_SECTION]
|
||||||
|
# create containing adir
|
||||||
|
try:
|
||||||
|
settings_dir = os.path.dirname(settings_file)
|
||||||
|
if not os.path.isdir(settings_dir):
|
||||||
|
os.makedirs(settings_dir)
|
||||||
|
except OSError:
|
||||||
|
raise MellanoxSettingsException(
|
||||||
|
"Failed creating directory: {0}".format(settings_dir)
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
fd = open(settings_file, 'w')
|
||||||
|
yaml.dump(data, fd, default_flow_style=False)
|
||||||
|
except IOError:
|
||||||
|
raise MellanoxSettingsException("Failed writing changes to "
|
||||||
|
"{0}".format(settings_file))
|
||||||
|
finally:
|
||||||
|
if fd:
|
||||||
|
fd.close()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_settings(cls):
|
||||||
|
# define input yaml file
|
||||||
|
try:
|
||||||
|
cls.read_from_yaml(SETTINGS_FILE)
|
||||||
|
cls.update_role_settings()
|
||||||
|
cls.write_to_yaml(PLUGIN_OVERRIDE_FILE)
|
||||||
|
except MellanoxSettingsException, exc:
|
||||||
|
sys.stderr.write("Couldn't add Mellanox settings to "
|
||||||
|
"{0}: {1}\n".format(settings_file, exc))
|
||||||
|
raise MellanoxSettingsException("Failed updating one or more "
|
||||||
|
"setting files")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
settings = MellanoxSettings()
|
||||||
|
settings.update_settings()
|
||||||
|
except MellanoxSettingsException, exc:
|
||||||
|
sys.stderr.write("Failed adding Mellanox settings: {0}\n".format(exc))
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception, exc:
|
||||||
|
sys.stderr.write("An unknown error has occured while adding "
|
||||||
|
"Mellanox settings: {0}\n".format(
|
||||||
|
traceback.format_exc()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
sys.stdout.write("Done adding Mellanox settings\n")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,7 @@
|
||||||
|
$mlnx = hiera('mellanox-plugin')
|
||||||
|
$storage_address = hiera('storage_address')
|
||||||
|
|
||||||
|
class { 'mellanox_openstack::cinder' :
|
||||||
|
iser => $mlnx['iser'],
|
||||||
|
iser_ip_address => $storage_address,
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
$network_scheme = hiera('network_scheme')
|
||||||
|
$quantum_settings = hiera('quantum_settings')
|
||||||
|
$mlnx = hiera('mellanox-plugin')
|
||||||
|
|
||||||
|
class { 'mellanox_openstack::compute' :
|
||||||
|
physnet => $quantum_settings['predefined_networks']['net04']['L2']['physnet'],
|
||||||
|
physifc => $mlnx['physical_port'],
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
$eswitch_vnic_type = 'hostdev'
|
||||||
|
$eswitch_apply_profile_patch = 'True'
|
||||||
|
$mechanism_drivers = 'openvswitch'
|
||||||
|
|
||||||
|
class { 'mellanox_openstack::controller' :
|
||||||
|
eswitch_vnic_type => $eswitch_vnic_type,
|
||||||
|
eswitch_apply_profile_patch => $eswitch_apply_profile_patch,
|
||||||
|
mechanism_drivers => $mechanism_drivers,
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
$mlnx = hiera('mellanox-plugin')
|
||||||
|
|
||||||
|
if ($mlnx['iser']) {
|
||||||
|
class { 'mellanox_openstack::iser_rename' :
|
||||||
|
storage_parent => $mlnx['storage_parent'],
|
||||||
|
iser_interface_name => $mlnx['iser_ifc_name'],
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package { 'cirros-testvm-mellanox' :
|
||||||
|
ensure => installed,
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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.
|
|
@ -0,0 +1,6 @@
|
||||||
|
name 'mellanox-mellanox_openstack'
|
||||||
|
version '1.1.0'
|
||||||
|
author 'mellanox'
|
||||||
|
license 'Apache License, Version 2.0'
|
||||||
|
summary 'Mellanox module for Mirantis Fuel Openstack deployment'
|
||||||
|
description 'This is a Puppet module to install Mellanox Openstack components over Mirantis Fuel'
|
|
@ -0,0 +1,31 @@
|
||||||
|
# mellanox_openstack
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The mellanox_openstack module is designated for configuring the Mellanox plugin
|
||||||
|
for openstack installed using Fuel.
|
||||||
|
|
||||||
|
|
||||||
|
## Module Description
|
||||||
|
|
||||||
|
This module was written for integrating Mellanox into Fuel (https://launchpad.net/fuel).
|
||||||
|
The plugin supports SR-IOV for networking and iSER protocol for storage features over Mellanox hardware.
|
||||||
|
* SR-IOV - ml2 is configured to work with Mellanox plugin, including Eswitchd service
|
||||||
|
for managing virtual functions, and Mellanox Neutron Agent for networking properties.
|
||||||
|
* iSER - Cinder is set to work with iSER protocol.
|
||||||
|
|
||||||
|
|
||||||
|
### Setup Requirements
|
||||||
|
|
||||||
|
The module is designed to be used by Fuel (an openstack installer by Mirantis).
|
||||||
|
It assumes an Openstack environment using Neutron with VLAN segmentation & KVM.
|
||||||
|
|
||||||
|
|
||||||
|
## Release Notes/Contributors/Etc
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Gil Meir, gilmeir@mellanox.com
|
||||||
|
Aviram Bar-Haim, aviramb@mellanox.com
|
||||||
|
|
||||||
|
Support:
|
||||||
|
Mellanox support - support@mellanox.com
|
|
@ -0,0 +1,18 @@
|
||||||
|
require 'rubygems'
|
||||||
|
require 'puppetlabs_spec_helper/rake_tasks'
|
||||||
|
require 'puppet-lint/tasks/puppet-lint'
|
||||||
|
PuppetLint.configuration.send('disable_80chars')
|
||||||
|
PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"]
|
||||||
|
|
||||||
|
desc "Validate manifests, templates, and ruby files"
|
||||||
|
task :validate do
|
||||||
|
Dir['manifests/**/*.pp'].each do |manifest|
|
||||||
|
sh "puppet parser validate --noop #{manifest}"
|
||||||
|
end
|
||||||
|
Dir['spec/**/*.rb','lib/**/*.rb'].each do |ruby_file|
|
||||||
|
sh "ruby -c #{ruby_file}" unless ruby_file =~ /spec\/fixtures/
|
||||||
|
end
|
||||||
|
Dir['templates/**/*.erb'].each do |template|
|
||||||
|
sh "erb -P -x -T '-' #{template} | ruby -c"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,94 @@
|
||||||
|
# nova-rootwrap command filters for network nodes
|
||||||
|
# This file should be owned by (and only-writeable by) the root user
|
||||||
|
|
||||||
|
[Filters]
|
||||||
|
# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap'
|
||||||
|
# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up'
|
||||||
|
# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev)
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1]
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge
|
||||||
|
# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', ..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ...
|
||||||
|
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up'
|
||||||
|
# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up'
|
||||||
|
# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, ..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
|
||||||
|
# nova/network/linux_net.py: 'ip', 'route', 'add', ..
|
||||||
|
# nova/network/linux_net.py: 'ip', 'route', 'del', .
|
||||||
|
# nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev
|
||||||
|
ip: CommandFilter, ip, root
|
||||||
|
|
||||||
|
# nova/virt/libvirt/vif.py: 'ovs-vsctl', ...
|
||||||
|
# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ...
|
||||||
|
# nova/network/linux_net.py: 'ovs-vsctl', ....
|
||||||
|
ovs-vsctl: CommandFilter, ovs-vsctl, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'ovs-ofctl', ....
|
||||||
|
ovs-ofctl: CommandFilter, ovs-ofctl, root
|
||||||
|
|
||||||
|
# nova/virt/libvirt/vif.py: 'ivs-ctl', ...
|
||||||
|
# nova/virt/libvirt/vif.py: 'ivs-ctl', 'del-port', ...
|
||||||
|
# nova/network/linux_net.py: 'ivs-ctl', ....
|
||||||
|
ivs-ctl: CommandFilter, ivs-ctl, root
|
||||||
|
|
||||||
|
# nova/virt/libvirt/vif.py: 'ifc_ctl', ...
|
||||||
|
ifc_ctl: CommandFilter, /opt/pg/bin/ifc_ctl, root
|
||||||
|
|
||||||
|
# nova/virt/libvirt/vif.py: 'ebrctl', ...
|
||||||
|
ebrctl: CommandFilter, ebrctl, root
|
||||||
|
|
||||||
|
# nova/virt/libvirt/vif.py: 'mm-ctl', ...
|
||||||
|
mm-ctl: CommandFilter, mm-ctl, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'ebtables', '-D' ...
|
||||||
|
# nova/network/linux_net.py: 'ebtables', '-I' ...
|
||||||
|
ebtables: CommandFilter, ebtables, root
|
||||||
|
ebtables_usr: CommandFilter, ebtables, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ...
|
||||||
|
iptables-save: CommandFilter, iptables-save, root
|
||||||
|
ip6tables-save: CommandFilter, ip6tables-save, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
|
||||||
|
iptables-restore: CommandFilter, iptables-restore, root
|
||||||
|
ip6tables-restore: CommandFilter, ip6tables-restore, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ...
|
||||||
|
# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],..
|
||||||
|
arping: CommandFilter, arping, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
|
||||||
|
dhcp_release: CommandFilter, dhcp_release, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'kill', '-9', pid
|
||||||
|
# nova/network/linux_net.py: 'kill', '-HUP', pid
|
||||||
|
kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'kill', pid
|
||||||
|
kill_radvd: KillFilter, root, /usr/sbin/radvd
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: dnsmasq call
|
||||||
|
dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'..
|
||||||
|
radvd: CommandFilter, radvd, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'brctl', 'addbr', bridge
|
||||||
|
# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0
|
||||||
|
# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off'
|
||||||
|
# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface
|
||||||
|
brctl: CommandFilter, brctl, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'sysctl', ....
|
||||||
|
sysctl: CommandFilter, sysctl, root
|
||||||
|
|
||||||
|
# nova/network/linux_net.py: 'conntrack'
|
||||||
|
conntrack: CommandFilter, conntrack, root
|
|
@ -0,0 +1,22 @@
|
||||||
|
Puppet::Type.type(:mellanox_agent_config).provide(
|
||||||
|
:ini_setting,
|
||||||
|
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
|
||||||
|
) do
|
||||||
|
|
||||||
|
def section
|
||||||
|
resource[:name].split('/', 2).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def setting
|
||||||
|
resource[:name].split('/', 2).last
|
||||||
|
end
|
||||||
|
|
||||||
|
def separator
|
||||||
|
'='
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
'/etc/neutron/plugins/mlnx/mlnx_conf.ini'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,22 @@
|
||||||
|
Puppet::Type.type(:mellanox_eswitchd_config).provide(
|
||||||
|
:ini_setting,
|
||||||
|
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
|
||||||
|
) do
|
||||||
|
|
||||||
|
def section
|
||||||
|
resource[:name].split('/', 2).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def setting
|
||||||
|
resource[:name].split('/', 2).last
|
||||||
|
end
|
||||||
|
|
||||||
|
def separator
|
||||||
|
'='
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
'/etc/eswitchd/eswitchd.conf'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
Puppet::Type.newtype(:mellanox_agent_config) do
|
||||||
|
|
||||||
|
ensurable
|
||||||
|
|
||||||
|
newparam(:name, :namevar => true) do
|
||||||
|
desc 'Section/setting name to manage from /etc/neutron/plugins/mlnx/mlnx_conf.ini'
|
||||||
|
newvalues(/\S+\/\S+/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newproperty(:value) do
|
||||||
|
desc 'The value of the setting to be defined.'
|
||||||
|
munge do |value|
|
||||||
|
value = value.to_s.strip
|
||||||
|
value.capitalize! if value =~ /^(true|false)$/i
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
Puppet::Type.newtype(:mellanox_eswitchd_config) do
|
||||||
|
|
||||||
|
ensurable
|
||||||
|
|
||||||
|
newparam(:name, :namevar => true) do
|
||||||
|
desc 'Section/setting name to manage from /etc/eswitchd/eswitchd.conf'
|
||||||
|
newvalues(/\S+\/\S+/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newproperty(:value) do
|
||||||
|
desc 'The value of the setting to be defined.'
|
||||||
|
munge do |value|
|
||||||
|
value = value.to_s.strip
|
||||||
|
value.capitalize! if value =~ /^(true|false)$/i
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,70 @@
|
||||||
|
class mellanox_openstack::agent (
|
||||||
|
$physnet,
|
||||||
|
$physifc,
|
||||||
|
) {
|
||||||
|
include mellanox_openstack::params
|
||||||
|
|
||||||
|
$package = $::mellanox_openstack::params::neutron_mlnx_packages
|
||||||
|
$agent = $::mellanox_openstack::params::agent_service
|
||||||
|
$filters_dir = $::mellanox_openstack::params::filters_dir
|
||||||
|
$filters_file = $::mellanox_openstack::params::filters_file
|
||||||
|
$compute_service_name = $::mellanox_openstack::params::compute_service_name
|
||||||
|
$mlnx_agent_conf = $::mellanox_openstack::params::mlnx_agent_conf
|
||||||
|
|
||||||
|
# Only relevant for Debian since no package provides network.filters file
|
||||||
|
if $::osfamily == 'Debian' {
|
||||||
|
File {
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
}
|
||||||
|
|
||||||
|
file { $filters_dir :
|
||||||
|
ensure => directory,
|
||||||
|
mode => '0755',
|
||||||
|
}
|
||||||
|
|
||||||
|
file { $filters_file :
|
||||||
|
ensure => present,
|
||||||
|
mode => '0644',
|
||||||
|
source => 'puppet:///modules/mellanox_openstack/network.filters',
|
||||||
|
}
|
||||||
|
|
||||||
|
service { $compute_service_name :
|
||||||
|
ensure => running
|
||||||
|
}
|
||||||
|
|
||||||
|
File <| title == '/etc/nova/nova.conf' |> ->
|
||||||
|
File[$filters_dir] ->
|
||||||
|
File[$filters_file] ~>
|
||||||
|
Service[$compute_service_name]
|
||||||
|
}
|
||||||
|
|
||||||
|
file { $mlnx_agent_conf :
|
||||||
|
owner => 'neutron'
|
||||||
|
}
|
||||||
|
|
||||||
|
mellanox_agent_config {
|
||||||
|
'agent/rpc_support_old_agents' : value => true;
|
||||||
|
'eswitch/physical_interface_mappings' : value => "${physnet}:${physifc}";
|
||||||
|
}
|
||||||
|
|
||||||
|
package { $package :
|
||||||
|
ensure => installed,
|
||||||
|
}
|
||||||
|
|
||||||
|
service { $agent :
|
||||||
|
ensure => running,
|
||||||
|
enable => true,
|
||||||
|
hasstatus => true,
|
||||||
|
hasrestart => true,
|
||||||
|
}
|
||||||
|
|
||||||
|
Package[$package] ->
|
||||||
|
File[$mlnx_agent_conf] ->
|
||||||
|
Mellanox_agent_config <||> ~>
|
||||||
|
Service[$agent]
|
||||||
|
|
||||||
|
Package[$package] ~>
|
||||||
|
Service[$agent]
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
class mellanox_openstack::cinder (
|
||||||
|
$iser,
|
||||||
|
$iser_ip_address,
|
||||||
|
) {
|
||||||
|
include cinder::params
|
||||||
|
|
||||||
|
class { 'mellanox_openstack::cinder::cinder_conf' :
|
||||||
|
iser => $iser,
|
||||||
|
iser_ip_address => $iser_ip_address,
|
||||||
|
} ~>
|
||||||
|
service { $cinder::params::volume_service :
|
||||||
|
ensure => running
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class mellanox_openstack::cinder::cinder_conf (
|
||||||
|
$iser,
|
||||||
|
$iser_ip_address,
|
||||||
|
) {
|
||||||
|
include cinder::params
|
||||||
|
include mellanox_openstack::params
|
||||||
|
|
||||||
|
if $iser {
|
||||||
|
cinder_config { 'DEFAULT/volume_driver' :
|
||||||
|
value => 'cinder.volume.drivers.lvm.LVMISERDriver'
|
||||||
|
}
|
||||||
|
cinder_config { 'DEFAULT/iser_ip_address' :
|
||||||
|
value => $iser_ip_address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
class mellanox_openstack::compute (
|
||||||
|
$physnet,
|
||||||
|
$physifc,
|
||||||
|
) {
|
||||||
|
|
||||||
|
include nova::params
|
||||||
|
$libvirt_service_name = $nova::params::libvirt_service_name
|
||||||
|
$libvirt_package_name = $nova::params::libvirt_package_name
|
||||||
|
|
||||||
|
class { 'mellanox_openstack::eswitchd' :
|
||||||
|
physnet => $physnet,
|
||||||
|
physifc => $physifc,
|
||||||
|
}
|
||||||
|
|
||||||
|
class { 'mellanox_openstack::agent' :
|
||||||
|
physnet => $physnet,
|
||||||
|
physifc => $physifc,
|
||||||
|
}
|
||||||
|
|
||||||
|
package { $libvirt_package_name :
|
||||||
|
ensure => installed
|
||||||
|
}
|
||||||
|
|
||||||
|
service { $libvirt_service_name :
|
||||||
|
ensure => running
|
||||||
|
}
|
||||||
|
|
||||||
|
Package[$libvirt_package_name] ->
|
||||||
|
Service[$libvirt_service_name] ->
|
||||||
|
Class['mellanox_openstack::eswitchd'] ~>
|
||||||
|
Class['mellanox_openstack::agent']
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
class mellanox_openstack::controller (
|
||||||
|
$eswitch_vnic_type,
|
||||||
|
$eswitch_apply_profile_patch,
|
||||||
|
$mechanism_drivers,
|
||||||
|
) {
|
||||||
|
|
||||||
|
include neutron::params
|
||||||
|
$server_service = $neutron::params::server_service
|
||||||
|
|
||||||
|
neutron_plugin_ml2 {
|
||||||
|
'eswitch/vnic_type': value => $eswitch_vnic_type;
|
||||||
|
'eswitch/apply_profile_patch': value => $eswitch_apply_profile_patch;
|
||||||
|
'ml2/mechanism_drivers': value => "mlnx,${mechanism_drivers}";
|
||||||
|
}
|
||||||
|
|
||||||
|
service { $server_service :
|
||||||
|
ensure => running
|
||||||
|
}
|
||||||
|
|
||||||
|
Neutron_plugin_ml2 <||> ~>
|
||||||
|
Service[$server_service]
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
class mellanox_openstack::eswitchd (
|
||||||
|
$physnet,
|
||||||
|
$physifc,
|
||||||
|
) {
|
||||||
|
include mellanox_openstack::params
|
||||||
|
|
||||||
|
$package = $::mellanox_openstack::params::eswitchd_package
|
||||||
|
|
||||||
|
mellanox_eswitchd_config {
|
||||||
|
'DAEMON/fabrics': value => "${physnet}:${physifc}";
|
||||||
|
}
|
||||||
|
|
||||||
|
package { $package :
|
||||||
|
ensure => installed,
|
||||||
|
}
|
||||||
|
|
||||||
|
service { 'eswitchd' :
|
||||||
|
ensure => running,
|
||||||
|
enable => true,
|
||||||
|
hasstatus => true,
|
||||||
|
hasrestart => true,
|
||||||
|
}
|
||||||
|
|
||||||
|
Package[$package] ->
|
||||||
|
Mellanox_eswitchd_config <||> ~>
|
||||||
|
Service['eswitchd']
|
||||||
|
|
||||||
|
Package[$package] ~>
|
||||||
|
Service['eswitchd']
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
class mellanox_openstack {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
class mellanox_openstack::iser_rename (
|
||||||
|
$storage_parent,
|
||||||
|
$iser_interface_name,
|
||||||
|
) {
|
||||||
|
|
||||||
|
$interfaces_path = '/sys/class/net/'
|
||||||
|
$iser_script_dir = '/opt/iser'
|
||||||
|
$iser_rename_script = "$iser_script_dir/iser_rename.sh"
|
||||||
|
|
||||||
|
|
||||||
|
notify { $storage_parent : }
|
||||||
|
notify { $iser_interface_name : }
|
||||||
|
|
||||||
|
file { $iser_script_dir:
|
||||||
|
ensure => directory,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { $iser_rename_script:
|
||||||
|
ensure => file,
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '500',
|
||||||
|
content => template('mellanox_openstack/iser_rename.erb'),
|
||||||
|
}
|
||||||
|
|
||||||
|
exec { 'iser_rename':
|
||||||
|
command => "bash $iser_rename_script",
|
||||||
|
unless => "test -f $interfaces_path/$iser_interface_name",
|
||||||
|
path => ['/usr/bin','/usr/sbin','/bin','/sbin','/usr/local/bin'],
|
||||||
|
logoutput => true,
|
||||||
|
require => File[$iser_rename_script],
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
class mellanox_openstack::params {
|
||||||
|
|
||||||
|
$eswitchd_package = 'eswitchd'
|
||||||
|
$filters_dir = '/etc/nova/rootwrap.d'
|
||||||
|
$filters_file = "${filters_dir}/network.filters"
|
||||||
|
$mlnx_agent_conf = '/etc/neutron/plugins/mlnx/mlnx_conf.ini'
|
||||||
|
|
||||||
|
case $::osfamily {
|
||||||
|
'RedHat': {
|
||||||
|
$neutron_mlnx_packages = ['openstack-neutron-mellanox']
|
||||||
|
$agent_service = 'neutron-mlnx-agent'
|
||||||
|
$compute_service_name = 'openstack-nova-compute'
|
||||||
|
$openvswitch_mgmt_service = 'openvswitch'
|
||||||
|
}
|
||||||
|
'Debian': {
|
||||||
|
$neutron_mlnx_packages = ['neutron-plugin-mlnx','neutron-plugin-mlnx-agent']
|
||||||
|
$agent_service = 'neutron-plugin-mlnx-agent'
|
||||||
|
$compute_service_name = 'nova-compute'
|
||||||
|
$openvswitch_mgmt_service = 'openvswitch-switch'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "mellanox-mellanox_openstack",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"author": "mellanox",
|
||||||
|
"summary": "Mellanox module for supporting Mellanox hardware on Mirantis Fuel openstack deployment",
|
||||||
|
"license": "Apache 2.0",
|
||||||
|
"source": "",
|
||||||
|
"issues_url": null,
|
||||||
|
"project_page": null,
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"version_range": ">= 1.0.0",
|
||||||
|
"name": "puppetlabs-stdlib"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
dir = File.expand_path(File.dirname(__FILE__))
|
||||||
|
$LOAD_PATH.unshift File.join(dir, 'lib')
|
||||||
|
|
||||||
|
require 'mocha'
|
||||||
|
require 'puppet'
|
||||||
|
require 'rspec'
|
||||||
|
require 'spec/autorun'
|
||||||
|
|
||||||
|
Spec::Runner.configure do |config|
|
||||||
|
config.mock_with :mocha
|
||||||
|
end
|
||||||
|
|
||||||
|
# We need this because the RAL uses 'should' as a method. This
|
||||||
|
# allows us the same behaviour but with a different method name.
|
||||||
|
class Object
|
||||||
|
alias :must :should
|
||||||
|
end
|
|
@ -0,0 +1,98 @@
|
||||||
|
#!/usr/bin/bash
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
readonly SCOPE=`basename $0`
|
||||||
|
readonly UDEV_FILE='/etc/udev/rules.d/70-persistent-net.rules'
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
STORAGE_PORT='<%=@storage_parent%>'
|
||||||
|
ISER_NAME='<%=@iser_interface_name%>'
|
||||||
|
PARENT_FIRST_VF="/sys/class/net/$STORAGE_PORT/device/virtfn0"
|
||||||
|
|
||||||
|
# This functions print logs to /var/log/messages
|
||||||
|
function logger_print () {
|
||||||
|
priority=$1
|
||||||
|
msg=$2
|
||||||
|
logger -t $SCOPE "$priority: $msg"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check that a first probe VF exists
|
||||||
|
if [ ! -d $PARENT_FIRST_VF ]; then
|
||||||
|
logger_print error "Did not find probed ports of ${STORAGE_PORT}, skipping rename."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEVICES='/sys/class/net/*/device'
|
||||||
|
SON_BUS=`basename $(readlink /sys/class/net/$STORAGE_PORT/device/virtfn0)`
|
||||||
|
STORAGE_PORT_NUMBER=`cat /sys/class/net/$STORAGE_PORT/dev_id`
|
||||||
|
|
||||||
|
# Find the probe VF port that fits the storage ports number and BUS
|
||||||
|
for dev in $DEVICES; do
|
||||||
|
# Check for correct bus
|
||||||
|
CANDIDATE_BUS=`readlink -nq $dev`;
|
||||||
|
if [[ $CANDIDATE_BUS != *$SON_BUS* ]]; then
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for correct dev_id
|
||||||
|
CANDIDATE_DIRNAME=`dirname $dev`
|
||||||
|
PORT_NUMBER=`cat $CANDIDATE_DIRNAME/dev_id`
|
||||||
|
if [ $PORT_NUMBER = $STORAGE_PORT_NUMBER ]; then
|
||||||
|
PROBED_DIRNAME=`dirname $dev`
|
||||||
|
PROBED_PORT_NAME=`basename $PROBED_DIRNAME`
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Verify that we find the appropriate virtual port
|
||||||
|
if [ -z "$PROBED_PORT_NAME" ]; then
|
||||||
|
logger_print error "Did not find $STORAGE_PORT_NUMBER probed ports of $STORAGE_PORT, exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify that udev file exists
|
||||||
|
if [ ! -r "$UDEV_FILE" ]; then
|
||||||
|
logger_print error "Did not find $UDEV_FILE to rename iser port."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Persistantly rename the matched probed port
|
||||||
|
if [ $PROBED_PORT_NAME != $ISER_NAME ]; then
|
||||||
|
#Prepare line for udev
|
||||||
|
UDEV_LINE="SUBSYSTEM==\"net\", ACTION==\"add\", "
|
||||||
|
UDEV_LINE+="ATTR{dev_id}==\"$STORAGE_PORT_NUMBER\", KERNELS==\"$SON_BUS\", "
|
||||||
|
UDEV_LINE+="ATTR{type}==\"1\", KERNEL==\"eth*\", NAME=\"$ISER_NAME\""
|
||||||
|
|
||||||
|
# Change/add line in udev file
|
||||||
|
grep $PROBED_PORT_NAME $UDEV_FILE > /dev/null 2>&1
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
OLD_LINE_NUMBER=`grep -n $PROBED_PORT_NAME $UDEV_FILE | cut -d : -f 1`
|
||||||
|
eval "sed '"$OLD_LINE_NUMBER"d' -i $UDEV_FILE"
|
||||||
|
fi
|
||||||
|
echo $UDEV_LINE >> $UDEV_FILE
|
||||||
|
|
||||||
|
# restart OFED modules for udev changes to take effect
|
||||||
|
modprobe -r mlx4_en && modprobe mlx4_en
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger_print error "Mellanox drivers restart failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
logger_print info "Changed probed port name from $PROBED_PORT_NAME to $ISER_NAME."
|
||||||
|
else
|
||||||
|
logger_print info "Probed port name is configured properly to $ISER_NAME."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,12 @@
|
||||||
|
# The baseline for module testing used by Puppet Labs is that each manifest
|
||||||
|
# should have a corresponding test manifest that declares that class or defined
|
||||||
|
# type.
|
||||||
|
#
|
||||||
|
# Tests are then run by using puppet apply --noop (to check for compilation
|
||||||
|
# errors and view a log of events) or by fully applying the test in a virtual
|
||||||
|
# environment (to compare the resulting system state to the desired state).
|
||||||
|
#
|
||||||
|
# Learn more about module testing here:
|
||||||
|
# http://docs.puppetlabs.com/guides/tests_smoke.html
|
||||||
|
#
|
||||||
|
include mellanox_openstack
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
source ./common
|
||||||
|
CIRROS_PACKAGE_NAME='cirros-testvm-mellanox'
|
||||||
|
|
||||||
|
function install_cirros() {
|
||||||
|
if [ $DISTRO == 'redhat' ]; then
|
||||||
|
yum install -y $CIRROS_PACKAGE_NAME
|
||||||
|
elif [ $DISTRO == 'ubuntu' ]; then
|
||||||
|
apt-get install -y $CIRROS_PACKAGE_NAME
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ruby ./delete_images.rb &&
|
||||||
|
install_cirros &&
|
||||||
|
ruby /etc/puppet/modules/osnailyfacter/modular/astute/upload_cirros.rb 2>/dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger_print error "Replacing Cirros image with Mellanox-Cirros image failed"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
logger_print info "Cirros image was successfully replaced with Mellanox-Cirros image"
|
||||||
|
exit 0
|
||||||
|
fi
|
|
@ -0,0 +1,205 @@
|
||||||
|
#!/bin/bash -x
|
||||||
|
# Copyright 2015 Mellanox Technologies, Ltd
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
readonly SCRIPT_DIR=$(dirname "$0")
|
||||||
|
source $SCRIPT_DIR/common
|
||||||
|
readonly SCRIPT_MODE=$1
|
||||||
|
readonly FALLBACK_NUM_VFS=16
|
||||||
|
readonly NEW_KERNEL_PARAM="intel_iommu=on"
|
||||||
|
|
||||||
|
function get_port_type() {
|
||||||
|
if [ $DRIVER == 'mlx4_en' ]; then
|
||||||
|
port_type=2
|
||||||
|
elif [ $DRIVER == 'eth_ipoib' ]; then
|
||||||
|
port_type=1
|
||||||
|
fi
|
||||||
|
echo $port_type
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_num_probe_vfs () {
|
||||||
|
if [ $ISER == true ] && [ $DRIVER == 'mlx4_en' ]; then
|
||||||
|
probe_vfs=1
|
||||||
|
else
|
||||||
|
probe_vfs=0
|
||||||
|
fi
|
||||||
|
echo $probe_vfs
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculate_total_vfs () {
|
||||||
|
# validate num of vfs is an integer, 0 <= num <= 64
|
||||||
|
if [ "${USER_NUM_OF_VFS}" -ne "${USER_NUM_OF_VFS}" ] 2>/dev/null ||
|
||||||
|
[ "${USER_NUM_OF_VFS}" -gt ${MAX_VFS} ] ||
|
||||||
|
[ "${USER_NUM_OF_VFS}" -lt ${MIN_VFS} ]; then
|
||||||
|
logger_print error "Illegal number of VFs ${USER_NUM_OF_VFS}, value
|
||||||
|
should be an integer between ${MIN_VFS},${MAX_VFS}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
num_of_vfs=${USER_NUM_OF_VFS}
|
||||||
|
if [ $((${USER_NUM_OF_VFS} % 2)) -eq 1 ]; then
|
||||||
|
let num_of_vfs="${USER_NUM_OF_VFS} + 1" # number of vfs is odd and <= 64, then +1 is legal
|
||||||
|
fi
|
||||||
|
echo ${num_of_vfs}
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_modprobe_file () {
|
||||||
|
PROBE_VFS=`get_num_probe_vfs`
|
||||||
|
MLX4_CORE_FILE="/etc/modprobe.d/mlx4_core.conf"
|
||||||
|
PORT_TYPE=`get_port_type`
|
||||||
|
MLX4_CORE_STR="options mlx4_core
|
||||||
|
enable_64b_cqe_eqe=0
|
||||||
|
log_num_mgm_entry_size=-1
|
||||||
|
port_type_array=${PORT_TYPE},${PORT_TYPE}"
|
||||||
|
TOTAL_VFS=$1
|
||||||
|
if [[ $TOTAL_VFS -gt 0 ]]; then
|
||||||
|
MLX4_CORE_STR="${MLX4_CORE_STR} num_vfs=${TOTAL_VFS}"
|
||||||
|
if [[ $PROBE_VFS -gt 0 ]]; then
|
||||||
|
MLX4_CORE_STR="${MLX4_CORE_STR} probe_vf=${PROBE_VFS}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo ${MLX4_CORE_STR} > ${MLX4_CORE_FILE}
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_kernel_params () {
|
||||||
|
grub_file=`get_grub_file`
|
||||||
|
if [ "$DISTRO" == "redhat" ]; then
|
||||||
|
grub_file='/boot/grub/grub.conf'
|
||||||
|
kernel_line=`egrep 'kernel\s+/vmlinuz' ${grub_file} | grep -v '#'`
|
||||||
|
elif [ "$DISTRO" == "ubuntu" ]; then
|
||||||
|
grub_file='/boot/grub/grub.cfg'
|
||||||
|
kernel_line=$(echo "$(egrep 'linux\s+/vmlinuz' ${grub_file} | grep -v '#')" | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "Couldn't find kernel line in grub file" >&2 && return 1
|
||||||
|
fi
|
||||||
|
if ! grep -q ${NEW_KERNEL_PARAM} ${grub_file} ; then
|
||||||
|
line_num=$(echo "$(grep -n "${kernel_line}" ${grub_file} |cut -f1 -d: )" | head -1)
|
||||||
|
new_kernel_line="${kernel_line} ${NEW_KERNEL_PARAM}"
|
||||||
|
# delete original line
|
||||||
|
sed -i "${line_num}d" ${grub_file}
|
||||||
|
# insert the corrected line on the same line number
|
||||||
|
sed -i "${line_num}i\ ${new_kernel_line}" ${grub_file}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function burn_vfs_in_fw () {
|
||||||
|
total_vfs=$1
|
||||||
|
# required for mlxconfig to discover mlnx devices
|
||||||
|
service openibd start &>/dev/null
|
||||||
|
service mst start &>/dev/null
|
||||||
|
devices=$(mst status | grep pciconf | awk '{print $1}')
|
||||||
|
for dev in $devices; do
|
||||||
|
logger_print debug "device=$dev"
|
||||||
|
flint -d $dev dc | grep -i sriov | grep -i -q true &> /dev/null
|
||||||
|
sriov_enabled=$?
|
||||||
|
current_num_of_vfs=`flint -d $dev dc | grep -i total_vfs | awk '{print $3}'`
|
||||||
|
if [ $sriov_enabled -eq 0 ] 2>/dev/null; then
|
||||||
|
logger_print debug "Detected SR-IOV is already enabled"
|
||||||
|
else
|
||||||
|
logger_print debug "Detected SR-IOV is disabled"
|
||||||
|
fi
|
||||||
|
if [ "$total_vfs" -ne "$current_num_of_vfs" ] 2>/dev/null; then
|
||||||
|
logger_print debug "Current allowed number of VFs is ${current_num_of_vfs}, required number is ${total_vfs}"
|
||||||
|
mlxconfig -y -d $dev s SRIOV_EN=1 NUM_OF_VFS=$total_vfs 2>&1 >/dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger_print error "Failed changing number of VFs in FW for HCA ${dev}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
logger_print debug "Current number of VFs is correctly set to ${current_num_of_vfs} in FW."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
service mst stop &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_sriov_required () {
|
||||||
|
[ $SRIOV == true ] ||
|
||||||
|
( [ $ISER == true ] && [ $DRIVER == 'mlx4_en' ] )
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
function configure_sriov () {
|
||||||
|
if is_sriov_required; then
|
||||||
|
# Calculate the total amount of virtual functions, based on user seclection
|
||||||
|
total_vfs=`calculate_total_vfs`
|
||||||
|
if [ -z ${total_vfs} ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
logger_print info "Configuring ${total_vfs} virtual functions
|
||||||
|
(only even number is currently supported)"
|
||||||
|
set_modprobe_file $total_vfs &&
|
||||||
|
set_kernel_params &&
|
||||||
|
burn_vfs_in_fw $total_vfs
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
logger_print info "Skipping SR-IOV configuration"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate_sriov () {
|
||||||
|
logger_print info "Validating SR-IOV is enabled, and the required
|
||||||
|
amount of virtual functions exist"
|
||||||
|
# get number of VFs
|
||||||
|
current_num_vfs=`lspci | grep -i mellanox | grep -i virtual | wc -l`
|
||||||
|
total_vfs=`calculate_total_vfs`
|
||||||
|
if [ -z ${total_vfs} ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# check if kernel was loaded with the new parameter
|
||||||
|
grub_file=`get_grub_file`
|
||||||
|
grep ${NEW_KERNEL_PARAM} /proc/cmdline
|
||||||
|
has_kernel_param_status=$?
|
||||||
|
if [ $has_kernel_param_status -eq 0 ]; then
|
||||||
|
if [ $current_num_vfs -eq $total_vfs ]; then
|
||||||
|
logger_print info "Successfully verified SR-IOV is enabled with ${current_num_vfs} VFs"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
logger_print error "Kernel did not come up with the kernel parameter: ${NEW_KERNEL_PARAM},
|
||||||
|
SR-IOV configuration failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# fallback only if kernel param exists and amount of vfs is not as expcted
|
||||||
|
logger_print error "Failed , trying to fallback to ${FALLBACK_NUM_VFS}"
|
||||||
|
set_modprobe_file $FALLBACK_NUM_VFS
|
||||||
|
service openibd restart &> /dev/null
|
||||||
|
current_num_vfs=`lspci | grep -i mellanox | grep -i virtual | wc -l`
|
||||||
|
if [ $current_num_vfs -eq $FALLBACK_NUM_VFS ]; then
|
||||||
|
logger_print info "Fallback to ${FALLBACK_NUM_VFS} succeeded"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
logger_print error "Failed to configure SR-IOV"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#################
|
||||||
|
|
||||||
|
case $SCRIPT_MODE in
|
||||||
|
'configure')
|
||||||
|
configure_sriov
|
||||||
|
;;
|
||||||
|
'validate')
|
||||||
|
validate_sriov
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logger_print error "Unsupported execution mode ${SCRIPT_MODE}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit $?
|
|
@ -1,6 +1,24 @@
|
||||||
attributes:
|
attributes:
|
||||||
test:
|
sriov:
|
||||||
value: "test"
|
value: false
|
||||||
label: "test"
|
label: "Neutron SR-IOV plugin"
|
||||||
weight: 1
|
weight: 60
|
||||||
|
type: "checkbox"
|
||||||
|
restrictions:
|
||||||
|
- "settings:common.libvirt_type.value != 'kvm' or not (cluster:net_provider == 'neutron' and networking_parameters:segmentation_type == 'vlan')"
|
||||||
|
iser:
|
||||||
|
value: false
|
||||||
|
label: "iSER protocol for volumes (Cinder)"
|
||||||
|
description: "High performance block storage: Cinder volumes over iSER protocol (iSCSI over RDMA). This feature requires SR-IOV capabilities in the NIC, and will use a dedicated virtual function for the storage network."
|
||||||
|
weight: 11
|
||||||
|
type: "checkbox"
|
||||||
|
restrictions:
|
||||||
|
- "settings:storage.volumes_lvm.value != true or settings:common.libvirt_type.value != 'kvm'"
|
||||||
|
num_of_vfs:
|
||||||
|
value: "16"
|
||||||
|
label: "Number of virtual NICs"
|
||||||
|
description: "Note that one virtual function will be reserved to the storage network, in case of choosing iSER."
|
||||||
|
weight: 70
|
||||||
type: "text"
|
type: "text"
|
||||||
|
restrictions:
|
||||||
|
- "settings:mellanox-plugin.sriov.value == false"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Plugin name
|
# Plugin name
|
||||||
name: mellanox_plugin
|
name: mellanox-plugin
|
||||||
|
|
||||||
# Human-readable name for your plugin
|
# Human-readable name for your plugin
|
||||||
title: Mellanox Openstack features
|
title: Mellanox Openstack features
|
||||||
|
|
||||||
# Plugin version
|
# Plugin version
|
||||||
version: 0.1.1
|
version: 0.1.6
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
description: Enable features over Mellanox hardware
|
description: Enable features over Mellanox hardware
|
||||||
|
@ -29,12 +29,12 @@ groups: ['storage::cinder', 'hypervisor']
|
||||||
releases:
|
releases:
|
||||||
- os: ubuntu
|
- os: ubuntu
|
||||||
version: 2014.2-6.1
|
version: 2014.2-6.1
|
||||||
mode: ['ha', 'multinode']
|
mode: ['ha']
|
||||||
deployment_scripts_path: deployment_scripts/
|
deployment_scripts_path: deployment_scripts/
|
||||||
repository_path: repositories/ubuntu
|
repository_path: repositories/ubuntu
|
||||||
- os: centos
|
- os: centos
|
||||||
version: 2014.2-6.1
|
version: 2014.2-6.1
|
||||||
mode: ['ha', 'multinode']
|
mode: ['ha']
|
||||||
deployment_scripts_path: deployment_scripts/
|
deployment_scripts_path: deployment_scripts/
|
||||||
repository_path: repositories/centos
|
repository_path: repositories/centos
|
||||||
|
|
||||||
|
|
|
@ -29,17 +29,54 @@ function download {
|
||||||
PREFIX_URL=mellanox_plugin/bootstrap
|
PREFIX_URL=mellanox_plugin/bootstrap
|
||||||
BUILD_DIR=bootstrap
|
BUILD_DIR=bootstrap
|
||||||
;;
|
;;
|
||||||
|
'rpm')
|
||||||
|
PREFIX_URL=mellanox_plugin/repositories/centos/Packages
|
||||||
|
BUILD_DIR=repositories/centos/Packages
|
||||||
|
;;
|
||||||
|
'deb')
|
||||||
|
PREFIX_URL=mellanox_plugin/repositories/ubuntu
|
||||||
|
BUILD_DIR=repositories/ubuntu
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Can't download ${FILE_NAME}. File of type ${FILE_TYPE} is not supported."
|
echo "Can't download ${FILE_NAME}. File of type ${FILE_TYPE} is not supported."
|
||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
wget http://${REPOSITORY_HOST}/${PREFIX_URL}/${FILE_NAME} -P ${PLUGIN_DIR}/${BUILD_DIR}
|
URL="http://${REPOSITORY_HOST}/${PREFIX_URL}/${FILE_NAME}"
|
||||||
|
DEST_DIR="${PLUGIN_DIR}/${BUILD_DIR}"
|
||||||
|
wget ${URL} -P ${DEST_DIR}
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Failed fetching package from: ${URL} to ${DEST_DIR}" >&2
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# download bootstrap files
|
|
||||||
rm -rf ${PLUGIN_DIR}/bootstrap/*
|
|
||||||
for f in `cat ${PLUGIN_DIR}/requirements-bootstrap.txt`; do
|
|
||||||
download bootstrap $f
|
|
||||||
done
|
|
||||||
|
|
||||||
exit 0
|
function get_packages() {
|
||||||
|
file_type=$1
|
||||||
|
directory=$2
|
||||||
|
files=$3
|
||||||
|
rm -rf $directory
|
||||||
|
mkdir $directory
|
||||||
|
for f in $files; do
|
||||||
|
download $file_type $f
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
rpm_dir="${PLUGIN_DIR}/repositories/centos/Packages/"
|
||||||
|
rpm_files="cirros-testvm-mellanox-0.3.2-3.el6.x86_64.rpm
|
||||||
|
eswitchd-0.11-3.el6.x86_64.rpm
|
||||||
|
mlnx-ofed-fuel-2.3-2.0.6.el6.x86_64.rpm
|
||||||
|
redhat-rpm-config-9.0.3-42.el6.centos.noarch.rpm"
|
||||||
|
get_packages "rpm" "$rpm_dir" "$rpm_files"
|
||||||
|
|
||||||
|
deb_dir="${PLUGIN_DIR}/repositories/ubuntu/"
|
||||||
|
deb_files="cirros-testvm-mellanox_0.3.2-ubuntu3_amd64.deb
|
||||||
|
eswitchd_0.10-3_amd64.deb
|
||||||
|
mlnx-ofed-fuel_2.3-2.0.6_amd64.deb"
|
||||||
|
get_packages "deb" "$deb_dir" "$deb_files"
|
||||||
|
|
||||||
|
bootstrap_dir="${PLUGIN_DIR}/bootstrap/"
|
||||||
|
bootstrap_files="initramfs.img
|
||||||
|
linux
|
||||||
|
.ofed
|
||||||
|
.kernel"
|
||||||
|
get_packages "bootstrap" "$bootstrap_dir" "$bootstrap_files"
|
||||||
|
|
|
@ -9,13 +9,13 @@ if [ -d "/var/www/nailgun/bootstrap/" ]; then
|
||||||
mv /var/www/nailgun/bootstrap/initramfs.img /opt/old_bootstrap_image/
|
mv /var/www/nailgun/bootstrap/initramfs.img /opt/old_bootstrap_image/
|
||||||
mv /var/www/nailgun/bootstrap/linux /opt/old_bootstrap_image/
|
mv /var/www/nailgun/bootstrap/linux /opt/old_bootstrap_image/
|
||||||
fi
|
fi
|
||||||
\cp $(ls /var/www/nailgun/plugins/mellanox_plugin*/bootstrap/initramfs.img) /var/www/nailgun/bootstrap/
|
\cp $(ls /var/www/nailgun/plugins/mellanox-plugin*/bootstrap/initramfs.img) /var/www/nailgun/bootstrap/
|
||||||
\cp $(ls /var/www/nailgun/plugins/mellanox_plugin*/bootstrap/linux) /var/www/nailgun/bootstrap/
|
\cp $(ls /var/www/nailgun/plugins/mellanox-plugin*/bootstrap/linux) /var/www/nailgun/bootstrap/
|
||||||
command -v dockerctl >/dev/null 2>&1
|
command -v dockerctl >/dev/null 2>&1
|
||||||
if [ $? -eq 0 ];then
|
if [ $? -eq 0 ];then
|
||||||
dockerctl copy /var/www/nailgun/bootstrap/initramfs.img cobbler:/var/lib/tftpboot/images/bootstrap/initramfs.img
|
dockerctl copy /var/www/nailgun/bootstrap/initramfs.img cobbler:/var/lib/tftpboot/images/bootstrap/initramfs.img
|
||||||
dockerctl copy /var/www/nailgun/bootstrap/linux cobbler:/var/lib/tftpboot/images/bootstrap/linux
|
dockerctl copy /var/www/nailgun/bootstrap/linux cobbler:/var/lib/tftpboot/images/bootstrap/linux
|
||||||
\cp $(ls /var/www/nailgun/plugins/mellanox_plugin*/scripts/reboot_bootstrap_nodes) /sbin/
|
\cp $(ls /var/www/nailgun/plugins/mellanox-plugin*/scripts/reboot_bootstrap_nodes) /sbin/
|
||||||
echo " `tput bold`Bootstrap discovery image has been replaced for detecting Mellanox Infiniband HW."
|
echo " `tput bold`Bootstrap discovery image has been replaced for detecting Mellanox Infiniband HW."
|
||||||
echo " please reboot your old bootstrap nodes ('reboot_bootstrap_nodes [-e environment_id] [-a] [-h]' can be used).`tput sgr0`"
|
echo " please reboot your old bootstrap nodes ('reboot_bootstrap_nodes [-e environment_id] [-a] [-h]' can be used).`tput sgr0`"
|
||||||
fi
|
fi
|
||||||
|
|
95
tasks.yaml
95
tasks.yaml
|
@ -1,6 +1,97 @@
|
||||||
|
# Log a notice about pre_deployment start
|
||||||
- role: '*'
|
- role: '*'
|
||||||
stage: pre_deployment
|
stage: pre_deployment
|
||||||
type: shell
|
type: shell
|
||||||
parameters:
|
parameters:
|
||||||
cmd: echo all > /tmp/plugin.all
|
cmd: ./log_stage.sh pre_deployment
|
||||||
timeout: 42
|
timeout: 5
|
||||||
|
# This is a workaround: during the plugin pre_deployment stage
|
||||||
|
# there is no symbolic link from astute.yaml to <role>.yaml.
|
||||||
|
# Since the data that the plugin uses is common to all <role>.yaml files,
|
||||||
|
# this script links astute.yaml to any <role>.yaml on each node.
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: ./link_astute_file.sh
|
||||||
|
timeout: 5
|
||||||
|
# Add relevant settings for Mellanox manifests to mellanox plugin section in
|
||||||
|
# hiera, to make the data easily accessible and independent of astute.yaml
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: ./mellanox_settings.py
|
||||||
|
timeout: 10
|
||||||
|
# Install OFED + FW upgrade
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: ./install_ofed.sh
|
||||||
|
timeout: 1200
|
||||||
|
# Configure number of VFs according to the user decision:
|
||||||
|
# change modprobe file + IOMMU in grub file + change VFs num in FW
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: ./sriov.sh configure
|
||||||
|
timeout: 60
|
||||||
|
# Reboot due to OFED installation / IOMMU configuration
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: reboot
|
||||||
|
parameters:
|
||||||
|
timeout: 420
|
||||||
|
# change modprobe file + IOMMU in grub file + change VFs num in FW
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: ./sriov.sh validate
|
||||||
|
timeout: 60
|
||||||
|
# Rename iSER interface
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: puppet
|
||||||
|
parameters:
|
||||||
|
puppet_manifest: puppet/manifests/iser_rename.pp
|
||||||
|
puppet_modules: puppet/modules:/etc/puppet/modules
|
||||||
|
timeout: 60
|
||||||
|
# Log a notice about post_deployment start
|
||||||
|
- role: '*'
|
||||||
|
stage: post_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: ./log_stage.sh post_deployment
|
||||||
|
timeout: 5
|
||||||
|
# Execute post_deployment manifest for each role
|
||||||
|
- role: ['controller', 'primary-controller']
|
||||||
|
stage: post_deployment
|
||||||
|
type: puppet
|
||||||
|
parameters:
|
||||||
|
puppet_manifest: puppet/manifests/controller.pp
|
||||||
|
puppet_modules: puppet/modules:/etc/puppet/modules
|
||||||
|
timeout: 360
|
||||||
|
- role: ['compute']
|
||||||
|
stage: post_deployment
|
||||||
|
type: puppet
|
||||||
|
parameters:
|
||||||
|
puppet_manifest: puppet/manifests/compute.pp
|
||||||
|
puppet_modules: puppet/modules:/etc/puppet/modules
|
||||||
|
timeout: 360
|
||||||
|
- role: ['cinder']
|
||||||
|
stage: post_deployment
|
||||||
|
type: puppet
|
||||||
|
parameters:
|
||||||
|
puppet_manifest: puppet/manifests/cinder.pp
|
||||||
|
puppet_modules: puppet/modules:/etc/puppet/modules
|
||||||
|
timeout: 360
|
||||||
|
# Override the testvm with Mellanox Cirros TestVM
|
||||||
|
- role: ['controller', 'primary-controller']
|
||||||
|
stage: post_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: ./replace_cirros.sh
|
||||||
|
timeout: 180
|
||||||
|
|
Loading…
Reference in New Issue