summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--capabilities-map.yaml5
-rw-r--r--ci/scripts/freeipa_setup.sh2
-rw-r--r--deployed-server/ctlplane-port.yaml28
-rw-r--r--deployed-server/deployed-server.yaml30
-rwxr-xr-xdeployed-server/scripts/get-occ-config.sh9
-rw-r--r--docker/services/nova-libvirt.yaml5
-rw-r--r--environments/neutron-ml2-fujitsu-cfab.yaml21
-rw-r--r--environments/updates/README.md3
-rw-r--r--environments/updates/update-from-deployed-server-newton.yaml2
-rw-r--r--overcloud-resource-registry-puppet.j2.yaml1
-rw-r--r--puppet/major_upgrade_steps.j2.yaml6
-rw-r--r--puppet/services/database/mysql.yaml3
-rw-r--r--puppet/services/neutron-plugin-ml2-fujitsu-cfab.yaml73
-rw-r--r--puppet/services/nova-base.yaml4
-rw-r--r--puppet/services/pacemaker/database/mysql.yaml4
-rw-r--r--puppet/services/tripleo-packages.yaml8
-rw-r--r--puppet/upgrade_config.yaml1
-rw-r--r--releasenotes/source/_static/.placeholder0
-rw-r--r--releasenotes/source/conf.py264
-rw-r--r--releasenotes/source/index.rst18
-rw-r--r--releasenotes/source/unreleased.rst5
-rw-r--r--requirements.txt2
-rw-r--r--roles_data.yaml1
-rw-r--r--test-requirements.txt5
-rwxr-xr-xtools/releasenotes_tox.sh28
-rwxr-xr-xtools/tox_install.sh30
-rw-r--r--tox.ini3
28 files changed, 551 insertions, 13 deletions
diff --git a/.gitignore b/.gitignore
index 0925145c..cea6064d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,6 @@ puppet/compute-config.yaml
puppet/controller-config.yaml
puppet/objectstorage-config.yaml
puppet/post.yaml
+
+# Files created by releasenotes build
+releasenotes/build
diff --git a/capabilities-map.yaml b/capabilities-map.yaml
index ae747621..330832e5 100644
--- a/capabilities-map.yaml
+++ b/capabilities-map.yaml
@@ -355,6 +355,11 @@ topics:
description: Enables PLUMgrid extensions
requires:
- overcloud-resource-registry-puppet.yaml
+ - file: environments/neutron-ml2-fujitsu-cfab.yaml
+ title: Fujitsu Neutron plugin for C-Fabric
+ description: Enable C-Fabric in the overcloud
+ requires:
+ - overcloud-resource-registry-puppet.yaml
- title: Nova Extensions
description:
diff --git a/ci/scripts/freeipa_setup.sh b/ci/scripts/freeipa_setup.sh
index 9f5f2dc6..6906a2dd 100644
--- a/ci/scripts/freeipa_setup.sh
+++ b/ci/scripts/freeipa_setup.sh
@@ -24,7 +24,7 @@ echo "nameserver 8.8.4.4" >> /etc/resolv.conf
yum -q -y remove openstack-dashboard
# Install the needed packages
-yum -q install -y ipa-server ipa-server-dns epel-release rng-tools mod_nss
+yum -q install -y ipa-server ipa-server-dns epel-release rng-tools mod_nss git
yum -q install -y haveged
# Prepare hostname
diff --git a/deployed-server/ctlplane-port.yaml b/deployed-server/ctlplane-port.yaml
new file mode 100644
index 00000000..7b5cdf11
--- /dev/null
+++ b/deployed-server/ctlplane-port.yaml
@@ -0,0 +1,28 @@
+heat_template_version: ocata
+
+parameters:
+ network:
+ type: string
+ default: ctlplane
+ name:
+ type: string
+ replacement_policy:
+ type: string
+ default: AUTO
+
+resources:
+
+ ControlPlanePort:
+ type: OS::Neutron::Port
+ properties:
+ network: ctlplane
+ name:
+ list_join:
+ - '-'
+ - - {get_param: name}
+ - port
+ replacement_policy: AUTO
+
+outputs:
+ fixed_ips:
+ value: {get_attr: [ControlPlanePort, fixed_ips]}
diff --git a/deployed-server/deployed-server.yaml b/deployed-server/deployed-server.yaml
index 2929c5eb..77968f6c 100644
--- a/deployed-server/deployed-server.yaml
+++ b/deployed-server/deployed-server.yaml
@@ -38,6 +38,12 @@ parameters:
type: json
description: Optional scheduler hints to pass to nova
default: {}
+ UpgradeInitCommand:
+ type: string
+ description: |
+ Command or script snippet to run on all overcloud nodes to
+ initialize the upgrade process. E.g. a repository switch.
+ default: ''
resources:
deployed-server:
@@ -46,6 +52,25 @@ resources:
name: {get_param: name}
software_config_transport: {get_param: software_config_transport}
+ UpgradeInitConfig:
+ type: OS::Heat::SoftwareConfig
+ properties:
+ group: script
+ config:
+ list_join:
+ - ''
+ - - "#!/bin/bash\n\n"
+ - "if [[ -f /etc/resolv.conf.save ]] ; then rm /etc/resolv.conf.save; fi\n\n"
+ - get_param: UpgradeInitCommand
+
+ UpgradeInitDeployment:
+ type: OS::Heat::SoftwareDeployment
+ properties:
+ name: UpgradeInitDeployment
+ server: {get_resource: deployed-server}
+ config: {get_resource: UpgradeInitConfig}
+
+
InstanceIdConfig:
type: OS::Heat::StructuredConfig
properties:
@@ -58,6 +83,7 @@ resources:
properties:
config: {get_resource: InstanceIdConfig}
server: {get_resource: deployed-server}
+ depends_on: UpgradeInitDeployment
HostsEntryConfig:
type: OS::Heat::SoftwareConfig
@@ -80,7 +106,7 @@ resources:
config: {get_resource: HostsEntryConfig}
server: {get_resource: deployed-server}
- ControlPlanePortImpl:
+ ControlPlanePort:
type: OS::TripleO::DeployedServer::ControlPlanePort
properties:
network: ctlplane
@@ -97,6 +123,6 @@ outputs:
networks:
value:
ctlplane:
- - {get_attr: [ControlPlanePortImpl, fixed_ips, 0, ip_address]}
+ - {get_attr: [ControlPlanePort, fixed_ips, 0, ip_address]}
name:
value: {get_attr: [HostsEntryDeployment, hostname]}
diff --git a/deployed-server/scripts/get-occ-config.sh b/deployed-server/scripts/get-occ-config.sh
index 404244b1..6c196f97 100755
--- a/deployed-server/scripts/get-occ-config.sh
+++ b/deployed-server/scripts/get-occ-config.sh
@@ -79,7 +79,14 @@ for role in $OVERCLOUD_ROLES; do
server_stack=$(openstack stack resource show $stack $server_resource_name -c physical_resource_id -f value)
done
- deployed_server_metadata_url=$(openstack stack resource metadata $server_stack deployed-server | jq -r '.["os-collect-config"].request.metadata_url')
+ while true; do
+ deployed_server_metadata_url=$(openstack stack resource metadata $server_stack deployed-server | jq -r '.["os-collect-config"].request.metadata_url')
+ if [ "$deployed_server_metadata_url" = "null" ]; then
+ continue
+ else
+ break
+ fi
+ done
echo "======================"
echo "$role$i os-collect-config.conf configuration:"
diff --git a/docker/services/nova-libvirt.yaml b/docker/services/nova-libvirt.yaml
index 2dfeed59..a40a21fd 100644
--- a/docker/services/nova-libvirt.yaml
+++ b/docker/services/nova-libvirt.yaml
@@ -55,6 +55,11 @@ outputs:
volumes:
- /var/lib/etc-data/json-config/nova-libvirt.json:/var/lib/kolla/config_files/config.json
- /var/lib/etc-data/libvirt/libvirtd.conf:/var/lib/kolla/config_files/libvirtd.conf
+ # NOTE(mandre) Ideally the qemu.conf file is mounted in
+ # /var/lib/kolla/config_files and copied to the right place but
+ # copy-json.py doesn't allow us to do that without appending the
+ # file as an additional config on the CLI
+ - /var/lib/etc-data/libvirt/qemu.conf:/etc/libvirt/qemu.conf:ro
- /etc/localtime:/etc/localtime:ro
- /lib/modules:/lib/modules:ro
- /run:/run
diff --git a/environments/neutron-ml2-fujitsu-cfab.yaml b/environments/neutron-ml2-fujitsu-cfab.yaml
new file mode 100644
index 00000000..f14f7ee2
--- /dev/null
+++ b/environments/neutron-ml2-fujitsu-cfab.yaml
@@ -0,0 +1,21 @@
+# A Heat environment file which can be used to enable Fujitsu C-Fabric
+# plugin, configured via puppet
+resource_registry:
+ OS::TripleO::Services::NeutronML2FujitsuCfab: ../puppet/services/neutron-plugin-ml2-fujitsu-cfab.yaml
+
+parameter_defaults:
+ # Fixed
+ NeutronMechanismDrivers: ['openvswitch','fujitsu_cfab']
+ NeutronTypeDrivers: 'vlan'
+ NeutronNetworkType: 'vlan'
+
+ # Required
+ NeutronFujitsuCfabAddress: '192.168.0.1'
+ NeutronFujitsuCfabUserName: 'admin'
+ NeutronFujitsuCfabPassword:
+
+ # Optional
+ #NeutronFujitsuCfabPhysicalNetworks:
+ #NeutronFujitsuCfabSharePprofile:
+ #NeutronFujitsuCfabPprofilePrefix:
+ #NeutronFujitsuCfabSaveConfig:
diff --git a/environments/updates/README.md b/environments/updates/README.md
index 426d7329..93714ed8 100644
--- a/environments/updates/README.md
+++ b/environments/updates/README.md
@@ -10,3 +10,6 @@ Contents
**update-from-publicvip-on-ctlplane.yaml**
To be used if the PublicVirtualIP resource was deployed as an additional VIP on the 'ctlplane'.
+
+**update-from-deloyed-server-newton.yaml**
+ To be used when updating from the deployed-server template from Newton.
diff --git a/environments/updates/update-from-deployed-server-newton.yaml b/environments/updates/update-from-deployed-server-newton.yaml
new file mode 100644
index 00000000..6fe3a4cb
--- /dev/null
+++ b/environments/updates/update-from-deployed-server-newton.yaml
@@ -0,0 +1,2 @@
+resource_registry:
+ OS::TripleO::DeployedServer::ControlPlanePort: ../../deployed-server/ctlplane-port.yaml
diff --git a/overcloud-resource-registry-puppet.j2.yaml b/overcloud-resource-registry-puppet.j2.yaml
index c1738101..fcc2dd2f 100644
--- a/overcloud-resource-registry-puppet.j2.yaml
+++ b/overcloud-resource-registry-puppet.j2.yaml
@@ -230,6 +230,7 @@ resource_registry:
OS::TripleO::Services::ContrailDatabase: puppet/services/network/contrail-database.yaml
OS::TripleO::Services::ContrailWebui: puppet/services/network/contrail-webui.yaml
OS::TripleO::Services::Zaqar: OS::Heat::None
+ OS::TripleO::Services::NeutronML2FujitsuCfab: OS::Heat::None
parameter_defaults:
EnablePackageInstall: false
diff --git a/puppet/major_upgrade_steps.j2.yaml b/puppet/major_upgrade_steps.j2.yaml
index b70f5c71..9430a704 100644
--- a/puppet/major_upgrade_steps.j2.yaml
+++ b/puppet/major_upgrade_steps.j2.yaml
@@ -19,7 +19,7 @@ resources:
# Upgrade Steps for all roles
# FIXME(shardy): would be nice to make the number of steps configurable
-{% for step in range(1, 8) %}
+{% for step in range(0, 8) %}
{% for role in roles %}
# Step {{step}} resources
{{role.name}}UpgradeConfig_Step{{step}}:
@@ -28,7 +28,7 @@ resources:
# serialization, but the event output is easier to follow if we
# do, and there should be minimal performance hit (creating the
# config is cheap compared to the time to apply the deployment).
- {% if step > 1 %}
+ {% if step > 0 %}
depends_on:
{% for dep in roles %}
- {{dep.name}}Upgrade_Step{{step -1}}
@@ -40,7 +40,7 @@ resources:
{{role.name}}Upgrade_Step{{step}}:
type: OS::Heat::StructuredDeploymentGroup
- {% if step > 1 %}
+ {% if step > 0 %}
depends_on:
{% for dep in roles %}
- {{dep.name}}Upgrade_Step{{step -1}}
diff --git a/puppet/services/database/mysql.yaml b/puppet/services/database/mysql.yaml
index 5eefe6bd..7e12894f 100644
--- a/puppet/services/database/mysql.yaml
+++ b/puppet/services/database/mysql.yaml
@@ -95,6 +95,9 @@ outputs:
step_config: |
include ::tripleo::profile::base::database::mysql
upgrade_tasks:
+ - name: Check for galera root password
+ tags: step0
+ file: path=/root/.my.cnf state=file
- name: Stop service
tags: step2
service: name=mariadb state=stopped
diff --git a/puppet/services/neutron-plugin-ml2-fujitsu-cfab.yaml b/puppet/services/neutron-plugin-ml2-fujitsu-cfab.yaml
new file mode 100644
index 00000000..afb8cf44
--- /dev/null
+++ b/puppet/services/neutron-plugin-ml2-fujitsu-cfab.yaml
@@ -0,0 +1,73 @@
+heat_template_version: 2017-02-24
+
+description: >
+ Configure hieradata for Fujitsu C-Fabric plugin configuration
+
+parameters:
+ ServiceNetMap:
+ default: {}
+ description: Mapping of service_name -> network name. Typically set
+ via parameter_defaults in the resource registry. This
+ mapping overrides those in ServiceNetMapDefaults.
+ type: json
+ DefaultPasswords:
+ default: {}
+ type: json
+ EndpointMap:
+ default: {}
+ description: Mapping of service endpoint -> protocol. Typically set
+ via parameter_defaults in the resource registry.
+ type: json
+ NeutronFujitsuCfabAddress:
+ description: 'The address of the C-Fabric to telnet to.'
+ type: string
+ NeutronFujitsuCfabUserName:
+ description: 'The C-Fabric username to use.'
+ type: string
+ NeutronFujitsuCfabPassword:
+ description: 'The C-Fabric password to use.'
+ type: string
+ hidden: true
+ NeutronFujitsuCfabPhysicalNetworks:
+ description: 'List of <physical_network>:<vfab_id> tuples specifying physical_network names and corresponding vfab ids.'
+ type: comma_delimited_list
+ default: ''
+ NeutronFujitsuCfabSharePprofile:
+ description: '"Whether to share a C-Fabric pprofile among Neutron ports using the same VLAN ID.'
+ type: boolean
+ default: false
+ NeutronFujitsuCfabPprofilePrefix:
+ description: 'The prefix string for pprofile name.'
+ type: string
+ default: ''
+ NeutronFujitsuCfabSaveConfig:
+ description: 'Whether to save configuration.'
+ type: boolean
+ default: true
+
+resources:
+
+ NeutronMl2Base:
+ type: ./neutron-plugin-ml2.yaml
+ properties:
+ ServiceNetMap: {get_param: ServiceNetMap}
+ DefaultPasswords: {get_param: DefaultPasswords}
+ EndpointMap: {get_param: EndpointMap}
+
+outputs:
+ role_data:
+ description: Role data for Fujitsu Cfab ML2 Driver
+ value:
+ service_name: neutron_plugin_ml2_fujitsu_cfab
+ config_settings:
+ map_merge:
+ - get_attr: [NeutronMl2Base, role_data, config_settings]
+ - neutron::plugins::ml2::fujitsu::cfab::address: {get_param: NeutronFujitsuCfabAddress}
+ neutron::plugins::ml2::fujitsu::cfab::username: {get_param: NeutronFujitsuCfabUserName}
+ neutron::plugins::ml2::fujitsu::cfab::password: {get_param: NeutronFujitsuCfabPassword}
+ neutron::plugins::ml2::fujitsu::cfab::physical_networks: {get_param: NeutronFujitsuCfabPhysicalNetworks}
+ neutron::plugins::ml2::fujitsu::cfab::share_pprofile: {get_param: NeutronFujitsuCfabSharePprofile}
+ neutron::plugins::ml2::fujitsu::cfab::pprofile_prefix: {get_param: NeutronFujitsuCfabPprofilePrefix}
+ neutron::plugins::ml2::fujitsu::cfab::save_config: {get_param: NeutronFujitsuCfabSaveConfig}
+ step_config: |
+ include ::tripleo::profile::base::neutron::plugins::ml2
diff --git a/puppet/services/nova-base.yaml b/puppet/services/nova-base.yaml
index bf8e46be..dabb1355 100644
--- a/puppet/services/nova-base.yaml
+++ b/puppet/services/nova-base.yaml
@@ -129,10 +129,6 @@ outputs:
- nova::upgrade_level_compute: {get_param: UpgradeLevelNovaCompute}
service_config_settings:
mysql:
- # NOTE(aschultz): this should be configurable if/when we support more
- # complex cell v2 configurations. For now, this is the default cell
- # created for the cell v2 configuration
- nova::db::mysql_api::setup_cell0: true
nova::rabbit_password: {get_param: RabbitPassword}
nova::rabbit_userid: {get_param: RabbitUserName}
nova::rabbit_use_ssl: {get_param: RabbitClientUseSSL}
diff --git a/puppet/services/pacemaker/database/mysql.yaml b/puppet/services/pacemaker/database/mysql.yaml
index af95dbd1..511a01ab 100644
--- a/puppet/services/pacemaker/database/mysql.yaml
+++ b/puppet/services/pacemaker/database/mysql.yaml
@@ -53,3 +53,7 @@ outputs:
get_param: [ServiceNetMap, MysqlNetwork]
step_config: |
include ::tripleo::profile::pacemaker::database::mysql
+ upgrade_tasks:
+ - name: Check for galera root password
+ tags: step0
+ file: path=/root/.my.cnf state=file
diff --git a/puppet/services/tripleo-packages.yaml b/puppet/services/tripleo-packages.yaml
index da6e3083..737be829 100644
--- a/puppet/services/tripleo-packages.yaml
+++ b/puppet/services/tripleo-packages.yaml
@@ -33,6 +33,14 @@ outputs:
step_config: |
include ::tripleo::packages
upgrade_tasks:
+ - name: Check yum for rpm-python present
+ tags: step0
+ yum: "name=rpm-python state=present"
+ register: rpm_python_check
+ - name: Fail when rpm-python wasn't present
+ fail: msg="rpm-python package was not present before this run! Check environment before re-running"
+ when: rpm_python_check.changed != false
+ tags: step0
- name: Update all packages
tags: step3
yum: name=* state=latest
diff --git a/puppet/upgrade_config.yaml b/puppet/upgrade_config.yaml
index 499160e5..e892d813 100644
--- a/puppet/upgrade_config.yaml
+++ b/puppet/upgrade_config.yaml
@@ -35,6 +35,7 @@ resources:
template: "stepSTEP"
params:
STEP: {get_param: step}
+ modulepath: /usr/share/ansible-modules
inputs:
- name: role
config: {get_attr: [AnsibleConfig, value]}
diff --git a/releasenotes/source/_static/.placeholder b/releasenotes/source/_static/.placeholder
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/releasenotes/source/_static/.placeholder
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
new file mode 100644
index 00000000..8da995b0
--- /dev/null
+++ b/releasenotes/source/conf.py
@@ -0,0 +1,264 @@
+# -*- coding: utf-8 -*-
+# 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.
+#
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'oslosphinx',
+ 'reno.sphinxext',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'tripleo-heat-templates Release Notes'
+copyright = u'2017, TripleO Developers'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The full version, including alpha/beta/rc tags.
+release = '6.0.0.0b3'
+# The short X.Y version.
+version = '6.0.0'
+
+# The full version, including alpha/beta/rc tags.
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'tripleo-heat-templatesReleaseNotesdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'tripleo-heat-templatesReleaseNotes.tex', u'tripleo-heat-templates Release Notes Documentation',
+ u'2016, TripleO Developers', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'tripleo-heat-templatesreleasenotes', u'tripleo-heat-templates Release Notes Documentation',
+ [u'2016, TripleO Developers'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'tripleo-heat-templatesReleaseNotes', u'tripleo-heat-templates Release Notes Documentation',
+ u'2016, TripleO Developers', 'tripleo-heat-templatesReleaseNotes', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+# -- Options for Internationalization output ------------------------------
+locale_dirs = ['locale/']
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
new file mode 100644
index 00000000..9767dad2
--- /dev/null
+++ b/releasenotes/source/index.rst
@@ -0,0 +1,18 @@
+================================================
+Welcome to tripleo-heat-templates Release Notes!
+================================================
+
+Contents
+========
+
+.. toctree::
+ :maxdepth: 2
+
+ unreleased
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst
new file mode 100644
index 00000000..2334dd5c
--- /dev/null
+++ b/releasenotes/source/unreleased.rst
@@ -0,0 +1,5 @@
+==============================
+ Current Series Release Notes
+==============================
+
+ .. release-notes::
diff --git a/requirements.txt b/requirements.txt
index 555b240d..057aa287 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,5 +2,5 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
pbr>=1.8 # Apache-2.0
-Jinja2>=2.8 # BSD License (3 clause)
+Jinja2!=2.9.0,!=2.9.1,!=2.9.2,!=2.9.3,!=2.9.4,>=2.8 # BSD License (3 clause)
six>=1.9.0 # MIT
diff --git a/roles_data.yaml b/roles_data.yaml
index 4ff88ec3..8b820665 100644
--- a/roles_data.yaml
+++ b/roles_data.yaml
@@ -101,6 +101,7 @@
- OS::TripleO::Services::PankoApi
- OS::TripleO::Services::Zaqar
- OS::TripleO::Services::OVNDBs
+ - OS::TripleO::Services::NeutronML2FujitsuCfab
- name: Compute
CountDefault: 1
diff --git a/test-requirements.txt b/test-requirements.txt
index faf4893f..06bce5a2 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,5 +2,8 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
PyYAML>=3.10.0 # MIT
-Jinja2>=2.8 # BSD License (3 clause)
+Jinja2!=2.9.0,!=2.9.1,!=2.9.2,!=2.9.3,!=2.9.4,>=2.8 # BSD License (3 clause)
six>=1.9.0 # MIT
+sphinx!=1.3b1,<1.4,>=1.2.1 # BSD
+oslosphinx>=4.7.0 # Apache-2.0
+reno>=1.8.0 # Apache-2.0
diff --git a/tools/releasenotes_tox.sh b/tools/releasenotes_tox.sh
new file mode 100755
index 00000000..4fecfd92
--- /dev/null
+++ b/tools/releasenotes_tox.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+rm -rf releasenotes/build
+
+sphinx-build -a -E -W \
+ -d releasenotes/build/doctrees \
+ -b html \
+ releasenotes/source releasenotes/build/html
+BUILD_RESULT=$?
+
+UNCOMMITTED_NOTES=$(git status --porcelain | \
+ awk '$1 == "M" && $2 ~ /releasenotes\/notes/ {print $2}')
+
+if [ "${UNCOMMITTED_NOTES}" ]
+then
+ cat <<EOF
+
+REMINDER: The following changes to release notes have not been committed:
+
+${UNCOMMITTED_NOTES}
+
+While that may be intentional, keep in mind that release notes are built from
+committed changes, not the working directory.
+
+EOF
+fi
+
+exit ${BUILD_RESULT}
diff --git a/tools/tox_install.sh b/tools/tox_install.sh
new file mode 100755
index 00000000..e61b63a8
--- /dev/null
+++ b/tools/tox_install.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+# Client constraint file contains this client version pin that is in conflict
+# with installing the client from source. We should remove the version pin in
+# the constraints file before applying it for from-source installation.
+
+CONSTRAINTS_FILE="$1"
+shift 1
+
+set -e
+
+# NOTE(tonyb): Place this in the tox enviroment's log dir so it will get
+# published to logs.openstack.org for easy debugging.
+localfile="$VIRTUAL_ENV/log/upper-constraints.txt"
+
+if [[ "$CONSTRAINTS_FILE" != http* ]]; then
+ CONSTRAINTS_FILE="file://$CONSTRAINTS_FILE"
+fi
+# NOTE(tonyb): need to add curl to bindep.txt if the project supports bindep
+curl "$CONSTRAINTS_FILE" --insecure --progress-bar --output "$localfile"
+
+pip install -c"$localfile" openstack-requirements
+
+# This is the main purpose of the script: Allow local installation of
+# the current repo. It is listed in constraints file and thus any
+# install will be constrained and we need to unconstrain it.
+edit-constraints "$localfile" -- "$CLIENT_NAME"
+
+pip install -c"$localfile" -U "$@"
+exit $?
diff --git a/tox.ini b/tox.ini
index c8a912b8..969f21d4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -17,3 +17,6 @@ commands =
[testenv:templates]
commands = python ./tools/process-templates.py
+
+[testenv:releasenotes]
+commands = bash -c tools/releasenotes_tox.sh