Merge "Add SDF files in Octopus"
authorJulien <zhang.jun3g@zte.com.cn>
Mon, 5 Mar 2018 03:27:39 +0000 (03:27 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Mon, 5 Mar 2018 03:27:39 +0000 (03:27 +0000)
35 files changed:
INFO
config/installers/fuel/pod_config.yml.j2
config/pdf/idf-pod1.schema.yaml
config/utils/gen_config_lib.py [new file with mode: 0644]
config/utils/generate_config.py
config/utils/validate_schema.py
docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-FDIO.png [new file with mode: 0644]
docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-OVS.png [new file with mode: 0644]
docs/release/scenario-lifecycle/ODL Generic Scenarios Evolution.png [new file with mode: 0644]
docs/release/scenario-lifecycle/create-sdf.png [new file with mode: 0644]
docs/release/scenario-lifecycle/creating-scenarios.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/current-status.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/deployment-options.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/feature-compatibility-nosdn.png [new file with mode: 0644]
docs/release/scenario-lifecycle/feature-compatibility-odl.png [new file with mode: 0644]
docs/release/scenario-lifecycle/generic-scenarios.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/index.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/mano-scenarios.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/parent-child-relations.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/parent-child.png [new file with mode: 0644]
docs/release/scenario-lifecycle/pdf-and-sdf.png [new file with mode: 0644]
docs/release/scenario-lifecycle/scenario-descriptor-files.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/scenario-overview.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/scenario-tree+idea.png [new file with mode: 0644]
docs/release/scenario-lifecycle/scenario-tree-danube.png [new file with mode: 0644]
docs/release/scenario-lifecycle/scenario-tree.png [new file with mode: 0644]
docs/release/scenario-lifecycle/sibling.png [new file with mode: 0644]
docs/release/scenario-lifecycle/specific-scenarios.rst [new file with mode: 0644]
docs/release/scenario-lifecycle/workflows.rst [new file with mode: 0644]
labs/arm/idf-pod6.yaml
labs/lf/idf-pod4.yaml [new file with mode: 0644]
labs/lf/idf-pod5.yaml
labs/lf/pod4.yaml [new file with mode: 0644]
labs/lf/pod5.yaml
labs/zte/idf-pod1.yaml

diff --git a/INFO b/INFO
index 3f003bc..2ebe872 100644 (file)
--- a/INFO
+++ b/INFO
@@ -2,8 +2,8 @@ Project: Testbed infrastructure (Pharos)
 Project Creation Date: January 8, 2015
 Project Category: Integration & Testing
 Lifecycle State: Mature
-Primary Contact: Jack Morgan (jack.morgan@intel.com)
-Project Lead: Jack Morgan (jack.morgan@intel.com)
+Primary Contact: Julien Zhang (zhang.jun3g@zte.com.cn)
+Project Lead: Julien Zhang (zhang.jun3g@zte.com.cn)
 Jira Project Name: Testbed infrastructure project
 Jira Project Prefix: PHAROS
 Mailing list tag: [pharos]
@@ -25,4 +25,5 @@ Trevor Cooper <trevor.cooper@intel.com>
 Link to TSC approval of the project: http://meetbot.opnfv.org/meetings/opnfv-meeting/
 Link(s) to approval of additional committers:
 http://lists.opnfv.org/pipermail/opnfv-tech-discuss/2016-May/010567.html
+https://lists.opnfv.org/pipermail/opnfv-tsc/2018-February/004105.html
 Via email, RT Ticket: 23593
index dfa9679..9a6b4be 100644 (file)
 # which accompanies this distribution, and is available at
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
-{%- set net_admin = conf.idf.net_config.admin.network %}
-{%- set net_mgmt = conf.idf.net_config.mgmt.network %}
-{%- set net_private = conf.idf.net_config.private.network %}
-{%- set net_public = conf.idf.net_config.public.network %}
-{%- set net_public_mask = conf.idf.net_config.public.mask %}
-{%- set vlan_mgmt = conf.idf.net_config.mgmt.vlan %}
-{%- set vlan_private = conf.idf.net_config.private.vlan %}
-{%- if conf.idf.net_config.public.dns is defined %}
-    {%- set dns_public = conf.idf.net_config.public.dns %}
+{%- set net = conf.idf.net_config %}
+{%- set net_admin = [net.admin.network, net.admin.mask] | join("/")  %}
+{%- set net_mgmt = [net.mgmt.network, net.mgmt.mask] | join("/")  %}
+{%- set net_private = [net.private.network, net.private.mask] | join("/")  %}
+{%- set net_public =  [net.public.network, net.public.mask] | join("/")  %}
+{%- set networks = [net_admin, net_mgmt, net_private, net_public] %}
+
+{%- set vlan_mgmt = net.mgmt.vlan %}
+{%- set vlan_private = net.private.vlan %}
+{%- set pxe_interface = net.admin.interface %}
+
+{%- if net.public.dns is defined %}
+    {%- set dns_public = net.public.dns %}
+{%- else %}
+    {%- set dns_public = [ '8.8.8.8', '8.8.4.4' ] %}
 {%- endif %}
-{%- set pxe_interface = conf.idf.net_config.admin.interface %}
-{%- if conf.idf.net_config.public.gateway is defined %}
-    {%- set net_public_gw = conf.idf.net_config.public.gateway %}
+
+{%- if net.public.gateway is defined %}
+    {%- set net_public_gw = net.public.gateway %}
 {%- endif %}
 {%- if conf.idf.fuel.network.public_pool is defined %}
     {%- set net_public_pool_start = conf.idf.fuel.network.public_pool.start_ip %}
     {%- set net_public_pool_end = conf.idf.fuel.network.public_pool.end_ip %}
 {%- endif %}
+
 {%- if conf.idf.fuel.maas is defined %}
     {%- set maas_timeout_comissioning = conf.idf.fuel.maas.timeout_comissioning %}
     {%- set maas_timeout_deploying = conf.idf.fuel.maas.timeout_deploying %}
+{%- else %}
+    {%- set maas_timeout_comissioning = 10 %}
+    {%- set maas_timeout_deploying = 15 %}
 {%- endif %}
 
-{%- if dns_public is not defined %}
-    {%- set dns_public = [ '8.8.8.8', '8.8.4.4' ] %}
-{%- endif %}
-{%- if net_public_gw is not defined %}
-    {%- set net_public_gw =  net_public | ipaddr_index('1') %}
-{%- endif %}
+{%- set cmp_nodes =  3 %}
+
+{%- set net_admin_hosts = [
+    'opnfv_infra_config_pxe_address',
+    'opnfv_infra_maas_node01_deploy_address',
+    'opnfv_infra_maas_pxe_start_address'] %}
+
+{%- set net_mgmt_hosts = [
+    'opnfv_infra_config_address',
+    'opnfv_infra_maas_node01_address',
+    'opnfv_openstack_proxy_control_address',
+    'opnfv_openstack_proxy_node01_control_address',
+    'opnfv_openstack_proxy_node02_control_address',
+    'opnfv_openstack_gateway_node01_address',
+    'opnfv_openstack_gateway_node02_address',
+    'opnfv_openstack_gateway_node03_address',
+    'opnfv_infra_kvm_address',
+    'opnfv_infra_kvm_node01_address',
+    'opnfv_infra_kvm_node02_address',
+    'opnfv_infra_kvm_node03_address',
+    'opnfv_openstack_database_address',
+    'opnfv_openstack_database_node01_address',
+    'opnfv_openstack_database_node02_address',
+    'opnfv_openstack_database_node03_address',
+    'opnfv_openstack_message_queue_address',
+    'opnfv_openstack_message_queue_node01_address',
+    'opnfv_openstack_message_queue_node02_address',
+    'opnfv_openstack_message_queue_node03_address',
+    'opnfv_openstack_telemetry_address',
+    'opnfv_openstack_telemetry_node01_address',
+    'opnfv_openstack_telemetry_node02_address',
+    'opnfv_openstack_telemetry_node03_address',
+    'opnfv_openstack_control_address',
+    'opnfv_openstack_control_node01_address',
+    'opnfv_openstack_control_node02_address',
+    'opnfv_openstack_control_node03_address',
+    'opnfv_opendaylight_server_node01_single_address',
+    'opnfv_stacklight_monitor_address',
+    'opnfv_stacklight_monitor_node01_address',
+    'opnfv_stacklight_monitor_node02_address',
+    'opnfv_stacklight_monitor_node03_address',
+    'opnfv_stacklight_log_address',
+    'opnfv_stacklight_log_node01_address',
+    'opnfv_stacklight_log_node02_address',
+    'opnfv_stacklight_log_node03_address',
+    'opnfv_stacklight_telemetry_address',
+    'opnfv_stacklight_telemetry_node01_address',
+    'opnfv_stacklight_telemetry_node02_address',
+    'opnfv_stacklight_telemetry_node03_address'] %}
+
+{%- set net_public_hosts = [
+    'opnfv_openstack_proxy_address',
+    'opnfv_openstack_proxy_node01_address',
+    'opnfv_openstack_proxy_node02_address',
+    'opnfv_openstack_gateway_node01_external_address',
+    'opnfv_openstack_gateway_node02_external_address',
+    'opnfv_openstack_gateway_node03_external_address',
+    'opnfv_openstack_control_node01_external_address',
+    'opnfv_openstack_control_node02_external_address',
+    'opnfv_openstack_control_node03_external_address'] %}
+
+{%- set net_private_hosts = [
+    'opnfv_openstack_gateway_node01_tenant_address',
+    'opnfv_openstack_gateway_node02_tenant_address',
+    'opnfv_openstack_gateway_node03_tenant_address'] %}
+
+{%- set hosts = {
+    net_admin: net_admin_hosts,
+    net_mgmt: net_mgmt_hosts,
+    net_private: net_private_hosts,
+    net_public: net_public_hosts } %}
+
+{%- set start_ip = {
+    net_admin: 1,
+    net_mgmt: 1,
+    net_private: 1,
+    net_public: 1 } %}
+
+{%- set total_public_hosts = net_public_hosts | length + cmp_nodes  %}
 {%- if net_public_pool_start is not defined or net_public_pool_end is not defined %}
-    {%- set net_public_pool_start = net_public | ipaddr_index('80') %}
-    {%- set net_public_pool_end = net_public | ipaddr_index('100') %}
-{%- endif %}
-{%- if maas_timeout_comissioning is not defined or maas_timeout_deploying is not defined %}
-    {%- set maas_timeout_comissioning = 10 %}
-    {%- set maas_timeout_deploying = 15 %}
+    {%- set net_public_pool_start = net_public | ipnet_hostaddr(total_public_hosts + start_ip[net_public] +1) %}
+    {%- set net_public_pool_end = net_public | ipnet_hostmax -1  %}
 {%- endif %}
+
 ---
 parameters:
   _param:
 
+    opnfv_maas_timeout_comissioning: {{ maas_timeout_comissioning }}
+    opnfv_maas_timeout_deploying: {{ maas_timeout_deploying }}
+
     opnfv_jump_bridge_admin: {{ conf.idf.fuel.jumphost.bridges.admin }}
     opnfv_jump_bridge_mgmt: {{ conf.idf.fuel.jumphost.bridges.mgmt }}
     opnfv_jump_bridge_private: {{ conf.idf.fuel.jumphost.bridges.private }}
     opnfv_jump_bridge_public: {{ conf.idf.fuel.jumphost.bridges.public }}
 
-    opnfv_infra_config_address: {{ net_mgmt | ipaddr_index(100) }}
-    opnfv_infra_config_pxe_address: {{ net_admin | ipaddr_index(2) }}
-    opnfv_infra_maas_node01_address: {{ net_mgmt | ipaddr_index(3) }}
-    opnfv_infra_maas_node01_deploy_address: {{ net_admin | ipaddr_index(3) }}
-    opnfv_infra_kvm_address: {{ net_mgmt | ipaddr_index(140) }}
-    opnfv_infra_kvm_node01_address: {{ net_mgmt | ipaddr_index(141) }}
-    opnfv_infra_kvm_node02_address: {{ net_mgmt | ipaddr_index(142) }}
-    opnfv_infra_kvm_node03_address: {{ net_mgmt | ipaddr_index(143) }}
-
-    opnfv_infra_maas_pxe_network_address: {{ net_admin }}
-    opnfv_infra_maas_pxe_start_address: {{ net_admin | ipaddr_index(4) }}
-    opnfv_infra_maas_pxe_end_address: {{ net_admin | ipaddr_index(100) }}
-
-    opnfv_openstack_gateway_node01_address: {{ net_mgmt | ipaddr_index(124) }}
-    opnfv_openstack_gateway_node02_address: {{ net_mgmt | ipaddr_index(125) }}
-    opnfv_openstack_gateway_node03_address: {{ net_mgmt | ipaddr_index(126) }}
-    opnfv_openstack_gateway_node01_tenant_address: {{ net_private | ipaddr_index(124) }}
-    opnfv_openstack_gateway_node02_tenant_address: {{ net_private | ipaddr_index(125) }}
-    opnfv_openstack_gateway_node03_tenant_address: {{ net_private | ipaddr_index(126) }}
-    opnfv_openstack_gateway_node01_external_address: {{ net_public | ipaddr_index(124) }}
-    opnfv_openstack_gateway_node02_external_address: {{ net_public | ipaddr_index(125) }}
-    opnfv_openstack_gateway_node03_external_address: {{ net_public | ipaddr_index(126) }}
-    opnfv_openstack_proxy_address: {{ net_public | ipaddr_index(103) }}
-    opnfv_openstack_proxy_node01_address: {{ net_public | ipaddr_index(104) }}
-    opnfv_openstack_proxy_node02_address: {{ net_public | ipaddr_index(105) }}
-    opnfv_openstack_proxy_control_address: {{ net_mgmt | ipaddr_index(103) }}
-    opnfv_openstack_proxy_node01_control_address: {{ net_mgmt | ipaddr_index(104) }}
-    opnfv_openstack_proxy_node02_control_address: {{ net_mgmt | ipaddr_index(105) }}
-    opnfv_openstack_control_address: {{ net_mgmt | ipaddr_index(10) }}
-    opnfv_openstack_control_node01_address: {{ net_mgmt | ipaddr_index(11) }}
-    opnfv_openstack_control_node02_address: {{ net_mgmt | ipaddr_index(12) }}
-    opnfv_openstack_control_node03_address: {{ net_mgmt | ipaddr_index(13) }}
-    opnfv_openstack_control_node01_external_address: {{ net_public | ipaddr_index(11) }}
-    opnfv_openstack_control_node02_external_address: {{ net_public | ipaddr_index(12) }}
-    opnfv_openstack_control_node03_external_address: {{ net_public | ipaddr_index(13) }}
-    opnfv_openstack_database_address: {{ net_mgmt | ipaddr_index(50) }}
-    opnfv_openstack_database_node01_address: {{ net_mgmt | ipaddr_index(51) }}
-    opnfv_openstack_database_node02_address: {{ net_mgmt | ipaddr_index(52) }}
-    opnfv_openstack_database_node03_address: {{ net_mgmt | ipaddr_index(53) }}
-    opnfv_openstack_message_queue_address: {{ net_mgmt | ipaddr_index(40) }}
-    opnfv_openstack_message_queue_node01_address: {{ net_mgmt | ipaddr_index(41) }}
-    opnfv_openstack_message_queue_node02_address: {{ net_mgmt | ipaddr_index(42) }}
-    opnfv_openstack_message_queue_node03_address: {{ net_mgmt | ipaddr_index(43) }}
-    opnfv_openstack_telemetry_address: {{ net_mgmt | ipaddr_index(75) }}
-    opnfv_openstack_telemetry_node01_address: {{ net_mgmt | ipaddr_index(76) }}
-    opnfv_openstack_telemetry_node02_address: {{ net_mgmt | ipaddr_index(77) }}
-    opnfv_openstack_telemetry_node03_address: {{ net_mgmt | ipaddr_index(78) }}
-    opnfv_openstack_compute_node01_single_address: {{ net_mgmt | ipaddr_index(101) }}
-    opnfv_openstack_compute_node02_single_address: {{ net_mgmt | ipaddr_index(102) }}
-    opnfv_openstack_compute_node03_single_address: {{ net_mgmt | ipaddr_index(103) }}
-    opnfv_openstack_compute_node01_control_address: {{ net_mgmt | ipaddr_index(101) }}
-    opnfv_openstack_compute_node02_control_address: {{ net_mgmt | ipaddr_index(102) }}
-    opnfv_openstack_compute_node03_control_address: {{ net_mgmt | ipaddr_index(103) }}
-    opnfv_openstack_compute_node01_tenant_address: {{ net_private | ipaddr_index(101) }}
-    opnfv_openstack_compute_node02_tenant_address: {{ net_private | ipaddr_index(102) }}
-    opnfv_openstack_compute_node03_tenant_address: {{ net_private | ipaddr_index(103) }}
-    opnfv_openstack_compute_node01_external_address: {{ net_public | ipaddr_index(101) }}
-    opnfv_openstack_compute_node02_external_address: {{ net_public | ipaddr_index(102) }}
-
-    opnfv_opendaylight_server_node01_single_address: {{ net_mgmt | ipaddr_index(111) }}
-
-    opnfv_net_public: {{ net_public }}/{{ net_public_mask }}
-    opnfv_net_public_mask: {{ net_public_mask | netmask }}
+    opnfv_infra_maas_pxe_network_address: {{ net.admin.network }}
+    opnfv_infra_maas_pxe_end_address: {{ net_admin | ipnet_hostmax }}
+    opnfv_net_public: {{ net_public }}
+    opnfv_net_public_mask: {{ net_public | ipnet_netmask }}
     opnfv_net_public_gw: {{ net_public_gw }}
     opnfv_net_public_pool_start: {{ net_public_pool_start }}
     opnfv_net_public_pool_end: {{ net_public_pool_end }}
     opnfv_name_servers: {{ dns_public }}
     opnfv_dns_server01: '{{ dns_public[0] }}'
-
     opnfv_net_mgmt_vlan: {{ vlan_mgmt }}
     opnfv_net_tenant_vlan: {{ vlan_private }}
 
-    opnfv_maas_timeout_comissioning: {{ maas_timeout_comissioning }}
-    opnfv_maas_timeout_deploying: {{ maas_timeout_deploying }}
+{%- for network in networks %}
+{%- for key in hosts[network] %}
+{%- set i = loop.index  + start_ip[network] %}
+    {{key}}: {{ network | ipnet_hostaddr(i) }}
+{%- endfor %}
+{%- endfor %}
+
+{%- for cmp in range(1, cmp_nodes +1) %}
+  {%- set n = '%02d' | format(cmp) %}
+    {%- set mgmt = net_mgmt_hosts | length + start_ip[net_mgmt] + loop.index %}
+    {%- set pub = net_public_hosts | length + start_ip[net_public] + loop.index %}
+    {%- set pri = net_private_hosts | length + start_ip[net_private] + loop.index %}
+    opnfv_openstack_compute_node{{n}}_single_address: {{ net_mgmt | ipnet_hostaddr(mgmt) }}
+    opnfv_openstack_compute_node{{n}}_control_address: {{ net_mgmt | ipnet_hostaddr(mgmt) }}
+    opnfv_openstack_compute_node{{n}}_tenant_address: {{ net_private | ipnet_hostaddr(pri) }}
+    opnfv_openstack_compute_node{{n}}_external_address: {{ net_public | ipnet_hostaddr(pub) }}
+{%- endfor %}
 
-    opnfv_maas_node01_architecture: '{{ conf.nodes.0.node.arch | dpkg_arch }}/generic'
-    opnfv_maas_node01_power_address: {{ conf.nodes.0.remote_management.address.rsplit('/')[0] }}
-    opnfv_maas_node01_power_type: {{ conf.nodes.0.remote_management.type }}
-    opnfv_maas_node01_power_user: {{ conf.nodes.0.remote_management.user }}
-    opnfv_maas_node01_power_password: {{ conf.nodes.0.remote_management.pass }}
-    opnfv_maas_node01_interface_mac: '{{ conf.nodes.0.interfaces[pxe_interface].mac_address }}'
-
-    opnfv_maas_node02_architecture: '{{ conf.nodes.1.node.arch | dpkg_arch }}/generic'
-    opnfv_maas_node02_power_address: {{ conf.nodes.1.remote_management.address.rsplit('/')[0] }}
-    opnfv_maas_node02_power_type: {{ conf.nodes.1.remote_management.type }}
-    opnfv_maas_node02_power_user: {{ conf.nodes.1.remote_management.user }}
-    opnfv_maas_node02_power_password: {{ conf.nodes.1.remote_management.pass }}
-    opnfv_maas_node02_interface_mac: '{{ conf.nodes.1.interfaces[pxe_interface].mac_address }}'
-
-    opnfv_maas_node03_architecture: '{{ conf.nodes.2.node.arch | dpkg_arch }}/generic'
-    opnfv_maas_node03_power_address: {{ conf.nodes.2.remote_management.address.rsplit('/')[0] }}
-    opnfv_maas_node03_power_type: {{ conf.nodes.2.remote_management.type }}
-    opnfv_maas_node03_power_user: {{ conf.nodes.2.remote_management.user }}
-    opnfv_maas_node03_power_password: {{ conf.nodes.2.remote_management.pass }}
-    opnfv_maas_node03_interface_mac: '{{ conf.nodes.2.interfaces[pxe_interface].mac_address }}'
-
-    opnfv_maas_node04_architecture: '{{ conf.nodes.3.node.arch | dpkg_arch }}/generic'
-    opnfv_maas_node04_power_address: {{ conf.nodes.3.remote_management.address.rsplit('/')[0] }}
-    opnfv_maas_node04_power_type: {{ conf.nodes.3.remote_management.type }}
-    opnfv_maas_node04_power_user: {{ conf.nodes.3.remote_management.user }}
-    opnfv_maas_node04_power_password: {{ conf.nodes.3.remote_management.pass }}
-    opnfv_maas_node04_interface_mac: '{{ conf.nodes.3.interfaces[pxe_interface].mac_address }}'
-
-    opnfv_maas_node05_architecture: '{{ conf.nodes.4.node.arch | dpkg_arch }}/generic'
-    opnfv_maas_node05_power_address: {{ conf.nodes.4.remote_management.address.rsplit('/')[0] }}
-    opnfv_maas_node05_power_type: {{ conf.nodes.4.remote_management.type }}
-    opnfv_maas_node05_power_user: {{ conf.nodes.4.remote_management.user }}
-    opnfv_maas_node05_power_password: {{ conf.nodes.4.remote_management.pass }}
-    opnfv_maas_node05_interface_mac: '{{ conf.nodes.4.interfaces[pxe_interface].mac_address }}'
+{%- for node in conf.nodes %}
+  {%- set n = '%02d' | format(loop.index) %}
+    opnfv_maas_node{{n}}_architecture: '{{ node.node.arch | dpkg_arch }}/generic'
+    opnfv_maas_node{{n}}_power_address: {{ node.remote_management.address.rsplit('/')[0] }}
+    opnfv_maas_node{{n}}_power_type: {{ node.remote_management.type }}
+    opnfv_maas_node{{n}}_power_user: {{ node.remote_management.user }}
+    opnfv_maas_node{{n}}_power_password: {{ node.remote_management.pass }}
+    opnfv_maas_node{{n}}_interface_mac: '{{ node.interfaces[pxe_interface].mac_address }}'
+{%- endfor %}
index 0705fcc..857749c 100644 (file)
@@ -14,14 +14,14 @@ definitions:
     v0.1:
       # NOTE: I hope this is going away soon, so I won't model it yet
       type: 'object'
-  daisy:
-    v0.1:
-      type: 'object'
-      # NOTE: To be properly modeled by Daisy maintainers
   compass:
     v0.1:
       type: 'object'
       # NOTE: To be properly modeled by Compass4NFV maintainers
+  daisy:
+    v0.1:
+      type: 'object'
+      # NOTE: To be properly modeled by Daisy maintainers
   fuel:
     v0.1:
       type: 'object'
@@ -73,8 +73,67 @@ definitions:
                 additionalProperties: false
           required: ['node']
           additionalProperties: false
+        reclass:  # Optional
+          type: 'object'
+          properties:
+            node:
+              type: 'array'
+              items:
+                type: 'object'
+                properties:
+                  compute_params:
+                    type: 'object'
+                    properties:
+                      common:  # Optional
+                        type: 'object'
+                        properties: &compute_params_common_properties
+                          nova_cpu_pinning:  # Optional
+                            type: 'string'
+                          compute_hugepages_size:
+                            type: 'string'
+                            enum: ['2M', '1G']
+                          compute_hugepages_count:
+                            type: 'number'
+                          compute_hugepages_mount:
+                            type: 'string'
+                          compute_kernel_isolcpu:  # Optional
+                            type: 'string'
+                          compute_ovs_pmd_cpu_mask:  # Optional
+                            type: ['string', 'number']
+                          compute_ovs_memory_channels:  # Optional
+                            type: ['string', 'number']
+                        required: ['compute_hugepages_size', 'compute_hugepages_count',
+                                   'compute_hugepages_mount']
+                        additionalProperties: false
+                      dpdk:  # Optional
+                        type: 'object'
+                        properties:
+                          <<: *compute_params_common_properties
+                          compute_dpdk_driver:
+                            type: 'string'
+                          compute_ovs_dpdk_socket_mem:
+                            type: ['string', 'number']
+                          compute_ovs_dpdk_lcore_mask:
+                            type: ['string', 'number']
+                          dpdk0_driver:
+                            type: 'string'
+                          dpdk0_n_rxq:
+                            type: 'number'
+                        required: ['compute_dpdk_driver', 'dpdk0_driver', 'dpdk0_n_rxq',
+                                   'compute_ovs_dpdk_socket_mem',
+                                   'compute_ovs_dpdk_lcore_mask']
+                        additionalProperties: false
+                    additionalProperties: false
+                required: ['compute_params']
+                additionalProperties: false
+          required: ['node']
+          additionalProperties: false
       required: ['jumphost', 'network']
       additionalProperties: false
+  osa:
+    v0.1:
+      type: 'object'
+      # NOTE: To be properly modeled by XCI maintainers
 
 ##############################################################################
 # Top-level structure:
@@ -94,14 +153,16 @@ properties:
         type: 'array'
         items:
           type: 'string'
-          enum: ['apex', 'compass4nfv', 'daisy', 'fuel', 'joid']
+          enum: ['apex', 'compass4nfv', 'daisy', 'fuel', 'joid', 'osa']
       net_config:
         type: 'object'
-      fuel:
+      compass:
         type: 'object'
       daisy:
         type: 'object'
-      compass:
+      fuel:
+        type: 'object'
+      osa:
         type: 'object'
     required: ['version']
     additionalProperties: false
@@ -114,16 +175,20 @@ properties:
         properties:
           net_config:
             $ref: '#/definitions/net_config/v0.1'
-          fuel:
-            $ref: '#/definitions/fuel/v0.1'
-          daisy:
-            $ref: '#/definitions/daisy/v0.1'
           compass:
             $ref: '#/definitions/compass/v0.1'
+          daisy:
+            $ref: '#/definitions/daisy/v0.1'
+          fuel:
+            $ref: '#/definitions/fuel/v0.1'
+          osa:
+            $ref: '#/definitions/osa/v0.1'
       fuel:
         required: ['net_config']
       daisy:
         required: ['net_config']
+      osa:
+        required: ['net_config']
 
 # Do not allow any properties not defined here. This lets us catch typos.
 additionalProperties: false
diff --git a/config/utils/gen_config_lib.py b/config/utils/gen_config_lib.py
new file mode 100644 (file)
index 0000000..1e7229b
--- /dev/null
@@ -0,0 +1,224 @@
+##############################################################################
+# Copyright (c) 2018 OPNFV and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+"""Library for generate_config functions and custom jinja2 filters"""
+
+import logging
+from ipaddress import IPv4Network, IPv4Address
+
+
+def load_custom_filters(environment):
+    """Load all defined filters into the jinja2 enviroment"""
+
+    # TODO deprecate ipaddr_index and netmask for the better ipnet ones
+    filter_list = {
+        'dpkg_arch': filter_dpkg_arch,
+        'storage_size_num': filter_storage_size_num,
+        'ipnet_hostaddr': filter_ipnet_hostaddr,
+        'ipnet_hostmin': filter_ipnet_hostmin,
+        'ipnet_hostmax': filter_ipnet_hostmax,
+        'ipnet_broadcast': filter_ipnet_broadcast,
+        'ipnet_netmask': filter_ipnet_netmask,
+        'ipnet_contains_ip': filter_ipnet_contains_ip,
+        'ipnet_contains_iprange': filter_ipnet_contains_iprange,
+        'ipnet_range_size': filter_ipnet_range_size,
+        'ipaddr_index': filter_ipaddr_index,
+        'netmask': filter_netmask
+    }
+
+    for name, function in filter_list.items():
+        environment.filters[name] = function
+
+
+def filter_dpkg_arch(arch, to_dpkg=True):
+    """Convert DPKG-compatible from processor arch and vice-versa"""
+
+    # Processor architecture (as reported by $(uname -m))
+    # vs DPKG architecture mapping
+    dpkg_arch_table = {
+        'aarch64': 'arm64',
+        'x86_64': 'amd64',
+    }
+    arch_dpkg_table = dict(
+        zip(dpkg_arch_table.values(), dpkg_arch_table.keys()))
+
+    if to_dpkg:
+        return dpkg_arch_table[arch]
+    else:
+        return arch_dpkg_table[arch]
+
+
+def filter_storage_size_num(size_str):
+    """Convert human-readable size string to a string convertible to float"""
+
+    # pattern: '^[1-9][\d\.]*[MGT]B?$', multiplier=1000 (not KiB)
+    if size_str.endswith('B'):
+        size_str = size_str[:-1]
+    try:
+        size_num = 1000000
+        for multiplier in ['M', 'G', 'T']:
+            if size_str.endswith(multiplier):
+                return '{:.2f}'.format(size_num * float(size_str[:-1]))
+            size_num = size_num * 1000
+        return '{:.2f}'.format(float(size_str))
+    except ValueError as ex:
+        logging.error(size_str + " is not a valid size string")
+        raise
+
+
+def filter_ipnet_hostaddr(network_cidr, index):
+    """Return the host IP address on given index from an IP network"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+    try:
+        return IPv4Network(network_cidr_str)[index]
+    except ValueError as ex:
+        logging.error(network_cidr_str + " is not a valid network address")
+        raise
+    except IndexError as ex:
+        logging.error(network_cidr_str + " has not enough range for "
+                      + str(index) + " host IPs.")
+        raise
+
+
+def filter_ipnet_broadcast(network_cidr):
+    """Return broadcast IP address from given IP network"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+    try:
+        return IPv4Network(network_cidr_str).broadcast_address
+    except ValueError as ex:
+        logging.error(network_cidr_str + " is not a valid network address")
+        raise
+
+
+def filter_ipnet_hostmin(network_cidr):
+    """Return the first host IP address from given IP network"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+    try:
+        return IPv4Network(network_cidr_str)[1]
+    except ValueError as ex:
+        logging.error(network_cidr_str + " is not a valid network address")
+        raise
+
+
+def filter_ipnet_hostmax(network_cidr):
+    """Return the last host IP address from given IP network"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+    try:
+        return IPv4Network(network_cidr_str)[-2]
+    except ValueError as ex:
+        logging.error(network_cidr_str + " is not a valid network address")
+        raise
+
+
+def filter_ipnet_netmask(network_cidr):
+    """Return the IP netmask from given IP network"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+    try:
+        return IPv4Network(network_cidr_str).netmask
+    except ValueError as ex:
+        logging.error(network_cidr_str + " is not a valid network address")
+        raise
+
+
+def filter_ipnet_contains_ip(network_cidr, ip_address):
+    """Check if an IP network cointains a given range"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+        ip_address_str = unicode(ip_address)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+        ip_address_str = str(ip_address)
+    try:
+        return IPv4Address(ip_address_str) in IPv4Network(network_cidr_str)
+    except ValueError as ex:
+        logging.error(network_cidr_str + " is not a valid network address")
+        raise
+
+
+def filter_ipnet_contains_iprange(network_cidr, range_start, range_end):
+    """Check if an IP network cointains a given range"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+        range_start_str = unicode(range_start)
+        range_end_str = unicode(range_end)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+        range_start_str = str(range_start)
+        range_end_str = str(range_end)
+    try:
+        ipnet = IPv4Network(network_cidr_str)
+        return (IPv4Address(range_start_str) in ipnet
+                and IPv4Address(range_end_str) in ipnet)
+    except ValueError as ex:
+        logging.error(network_cidr_str + " is not a valid network address")
+        raise
+
+
+def filter_ipnet_range_size(network_cidr, range_start, range_end):
+    """Get the size of an IP range between two IP addresses"""
+    try:
+        network_cidr_str = unicode(network_cidr)
+        range_start_str = unicode(range_start)
+        range_end_str = unicode(range_end)
+    except NameError as ex:
+        network_cidr_str = str(network_cidr)
+        range_start_str = str(range_start)
+        range_end_str = str(range_end)
+    try:
+        ipnet = IPv4Network(network_cidr_str)
+        ip1 = IPv4Address(range_start_str)
+        ip2 = IPv4Address(range_end_str)
+
+        if ip1 in ipnet and ip2 in ipnet:
+            index1 = list(ipnet.hosts()).index(ip1)
+            index2 = list(ipnet.hosts()).index(ip2)
+            ip_range_size = index2 - index1 + 1
+            return ip_range_size
+        else:
+            raise ValueError
+    except ValueError as ex:
+        logging.error(range_start_str + " and " + range_end_str +
+                      " are not valid IP addresses for range inside " +
+                      network_cidr_str)
+        raise
+
+
+# This filter is too simple and does not take network mask into account.
+# TODO Deprecate for filter_ipnet_hostaddr
+def filter_ipaddr_index(base_address, index):
+    """Return IP address in given network at given index"""
+    try:
+        base_address_str = unicode(base_address)
+    except NameError as ex:
+        base_address_str = str(base_address)
+    return IPv4Address(base_address_str) + int(index)
+
+
+# TODO deprecate for filter_ipnet_netmask
+def filter_netmask(prefix):
+    """Get netmask from prefix length integer"""
+    try:
+        prefix_str = unicode(prefix)
+    except NameError as ex:
+        prefix_str = str(prefix)
+    return IPv4Network("1.0.0.0/"+prefix_str).netmask
index b2b52f0..f45f788 100755 (executable)
@@ -7,89 +7,76 @@
 # which accompanies this distribution, and is available at
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
-"""This module does blah blah."""
+"""Generate configuration from PDF/IDF and jinja2 installer template"""
+
 import argparse
-import ipaddress
 import logging
-import os
+from os.path import abspath, exists, isfile, split
+from subprocess import CalledProcessError, check_output
+import gen_config_lib
 import yaml
 from jinja2 import Environment, FileSystemLoader
-from subprocess import CalledProcessError, check_output
+
 
 PARSER = argparse.ArgumentParser()
 PARSER.add_argument("--yaml", "-y", type=str, required=True)
-PARSER.add_argument("--jinja2", "-j", type=str, required=True)
+PARSER.add_argument("--jinja2", "-j", type=str, required=True, action='append')
+PARSER.add_argument("--includesdir", "-i", action='append', default=['/'])
+PARSER.add_argument("--batch", "-b", action='store_true')
+PARSER.add_argument("--verbose", "-v", action='count')
 ARGS = PARSER.parse_args()
 
-# Processor architecture vs DPKG architecture mapping
-DPKG_ARCH_TABLE = {
-    'aarch64': 'arm64',
-    'x86_64': 'amd64',
-}
-ARCH_DPKG_TABLE = dict(zip(DPKG_ARCH_TABLE.values(), DPKG_ARCH_TABLE.keys()))
+LOADER = yaml.CSafeLoader if yaml.__with_libyaml__ else yaml.SafeLoader
+ARGS.jinja2 = [abspath(x) for x in ARGS.jinja2]
 
-# Custom filter to allow simple IP address operations returning
-# a new address from an upper or lower (negative) index
-def ipaddr_index(base_address, index):
-    """Return IP address in given network at given index"""
-    try:
-        base_address_str = unicode(base_address)
-    #pylint: disable=unused-variable
-    except NameError as ex:
-        base_address_str = str(base_address)
-    return ipaddress.ip_address(base_address_str) + int(index)
+logging.basicConfig()
+LOGGER = logging.getLogger('generate_config')
+if ARGS.verbose:
+    LOGGER.setLevel(logging.INFO)
 
-# Custom filter to transform a prefix netmask to IP address format netmask
-def netmask(prefix):
-    """Get netmask from prefix length integer"""
-    try:
-        prefix_str = unicode(prefix)
-    except NameError as ex:
-        prefix_str = str(prefix)
-    return ipaddress.IPv4Network("1.0.0.0/"+prefix_str).netmask
-
-# Custom filter to convert between processor architecture
-# (as reported by $(uname -m)) and DPKG-style architecture
-def dpkg_arch(arch, to_dpkg=True):
-    """Return DPKG-compatible from processor arch and vice-versa"""
-    if to_dpkg:
-        return DPKG_ARCH_TABLE[arch]
-    else:
-        return ARCH_DPKG_TABLE[arch]
-
-ENV = Environment(loader=FileSystemLoader(os.path.dirname(ARGS.jinja2)))
-ENV.filters['ipaddr_index'] = ipaddr_index
-ENV.filters['netmask'] = netmask
-ENV.filters['dpkg_arch'] = dpkg_arch
+ENV = Environment(
+    loader=FileSystemLoader(ARGS.includesdir),
+    extensions=['jinja2.ext.do']
+)
+gen_config_lib.load_custom_filters(ENV)
 
 # Run `eyaml decrypt` on the whole file, but only if PDF data is encrypted
 # Note: eyaml return code is 0 even if keys are not available
 try:
-    if os.path.isfile(ARGS.yaml) and 'ENC[PKCS7' in open(ARGS.yaml).read():
-        DICT = yaml.safe_load(check_output(['eyaml', 'decrypt',
-                                            '-f', ARGS.yaml]))
+    if isfile(ARGS.yaml) and 'ENC[PKCS7' in open(ARGS.yaml).read():
+        DICT = yaml.load(check_output(['eyaml', 'decrypt',
+                                       '-f', ARGS.yaml]), Loader=LOADER)
 except CalledProcessError as ex:
-    logging.error('eyaml decryption failed! Fallback to raw data.')
+    LOGGER.error('eyaml decryption failed! Fallback to raw data.')
 except OSError as ex:
-    logging.warn('eyaml not found, skipping decryption. Fallback to raw data.')
+    LOGGER.warn('eyaml not found, skipping decryption. Fallback to raw data.')
 try:
     DICT['details']
 except (NameError, TypeError) as ex:
     with open(ARGS.yaml) as _:
-        DICT = yaml.safe_load(_)
+        DICT = yaml.load(_, Loader=LOADER)
 
 # If an installer descriptor file (IDF) exists, include it (temporary)
-IDF_PATH = '/idf-'.join(os.path.split(ARGS.yaml))
-if os.path.exists(IDF_PATH):
+IDF_PATH = '/idf-'.join(split(ARGS.yaml))
+if exists(IDF_PATH):
     with open(IDF_PATH) as _:
-        IDF = yaml.safe_load(_)
+        IDF = yaml.load(_, Loader=LOADER)
         DICT['idf'] = IDF['idf']
 
 # Print dictionary generated from yaml (uncomment for debug)
 # print(DICT)
 
-# Render template and print generated conf to console
-TEMPLATE = ENV.get_template(os.path.basename(ARGS.jinja2))
-
-#pylint: disable=superfluous-parens
-print(TEMPLATE.render(conf=DICT))
+for _j2 in ARGS.jinja2:
+    TEMPLATE = ENV.get_template(_j2)
+    OUTPUT = TEMPLATE.render(conf=DICT)
+    # Render template and write generated conf to file or stdout
+    if ARGS.batch:
+        if _j2.endswith('.j2'):
+            LOGGER.info('Parsing {}'.format(_j2))
+            with open(_j2[:-3], 'w') as _:
+                _.write(OUTPUT)
+        else:
+            LOGGER.warn('Skipping {}, name does not end in ".j2"'.format(_j2))
+    else:
+        # pylint: disable=superfluous-parens
+        print(OUTPUT)
index 42f475d..1676e15 100755 (executable)
@@ -11,21 +11,20 @@ import argparse
 import jsonschema
 import yaml
 
+
 PARSER = argparse.ArgumentParser()
 PARSER.add_argument("--yaml", "-y", type=str, required=True)
 PARSER.add_argument("--schema", "-s", type=str, required=True)
 ARGS = PARSER.parse_args()
+LOADER = yaml.CSafeLoader if yaml.__with_libyaml__ else yaml.SafeLoader
 
 with open(ARGS.yaml) as _:
-    _DICT = yaml.safe_load(_)
+    _DICT = yaml.load(_, Loader=LOADER)
 
 with open(ARGS.schema) as _:
-    _SCHEMA = yaml.safe_load(_)
+    _SCHEMA = yaml.load(_, Loader=LOADER)
+
 
-# Draft 4 (latest supported by py-jsonschema) does not support value-based
-# decisions properly, see related github issue:
-# https://github.com/json-schema-org/json-schema-spec/issues/64
-# Workaround: build 'version_x.y: true' on the fly based on 'version: x.y'
 def schema_version_workaround(node):
     """Traverse nested dictionaries and handle 'version' key where found."""
     if 'version' in node:
@@ -33,9 +32,14 @@ def schema_version_workaround(node):
     for item in node.items():
         if type(item) is dict:
             schema_version_workaround(item)
+
+# Draft 4 (latest supported by py-jsonschema) does not support value-based
+# decisions properly, see related github issue:
+# https://github.com/json-schema-org/json-schema-spec/issues/64
+# Workaround: build 'version_x.y: true' on the fly based on 'version: x.y'
 schema_version_workaround(_DICT)
 if 'idf' in _DICT:
-  schema_version_workaround(_DICT['idf'])
+    schema_version_workaround(_DICT['idf'])
 
 _VALIDATOR = jsonschema.Draft4Validator(_SCHEMA)
 for error in _VALIDATOR.iter_errors(_DICT):
diff --git a/docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-FDIO.png b/docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-FDIO.png
new file mode 100644 (file)
index 0000000..8ac9950
Binary files /dev/null and b/docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-FDIO.png differ
diff --git a/docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-OVS.png b/docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-OVS.png
new file mode 100644 (file)
index 0000000..15f3893
Binary files /dev/null and b/docs/release/scenario-lifecycle/From OS-BASIC to NOSDN-OVS.png differ
diff --git a/docs/release/scenario-lifecycle/ODL Generic Scenarios Evolution.png b/docs/release/scenario-lifecycle/ODL Generic Scenarios Evolution.png
new file mode 100644 (file)
index 0000000..6f2e0a4
Binary files /dev/null and b/docs/release/scenario-lifecycle/ODL Generic Scenarios Evolution.png differ
diff --git a/docs/release/scenario-lifecycle/create-sdf.png b/docs/release/scenario-lifecycle/create-sdf.png
new file mode 100644 (file)
index 0000000..c8a44ba
Binary files /dev/null and b/docs/release/scenario-lifecycle/create-sdf.png differ
diff --git a/docs/release/scenario-lifecycle/creating-scenarios.rst b/docs/release/scenario-lifecycle/creating-scenarios.rst
new file mode 100644 (file)
index 0000000..dbff9c1
--- /dev/null
@@ -0,0 +1,104 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Creating Scenarios
+--------------------
+
+General
+^^^^^^^^^
+
+A new scenario needs to be created, when a new combination of upstream
+components or features shall be supported, that cannot be provided with the
+existing scenarios in parallel to their existing features.
+
+Typically new scenarios are created as children of existing scenarios.
+They start as specific scenario and as they mature, they either merge back
+their features to the parent or promote to a generic scenario.
+
+Scenario Owners
+^^^^^^^^^^^^^^^^
+
+Each scenario must have an "owner". Scenario owners have the following responsibilities:
+
+* The scenario owner is responsible for the contents and usage of the scenario.
+* He shall define the contents for the scenario deployment:
+
+  * The components and their versions that need to be deployed
+  * Options for the deployment of such components, e.g. settings, optional features, ..
+  * Which installers to use
+  * Deployment options (HA, NOHA, hardware types, ..)
+
+* He shall define the usage of the scenario in the development process:
+
+  * Initiate integration to CI
+  * Define which testcases to run
+  * Applies that the scenario joins a release
+
+* The owner maintains the Scenario Descriptor File (SDF)
+* Drives for the scenario be supported by more installers
+
+The scenario owner of a specific scenario typically comes from the feature project
+that develops the features introduced by the scenario.
+
+The scenario owner of a generic scenario will need to drive more integration tasks than
+feature development. Thus he typically will come from a project with a broader scope
+than a single feature, e.g. a testing project.
+The scenario owner of a generic scenario needs to cover issues of all installers, so
+only in exceptional cases he will come from an installer project.
+
+Creating Generic Scenarios
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Generic scenarios provide stable and mature deployments of an OPNFV release. Therefore
+it is important to have generic scenarios in place that provide the main capabilities
+needed for NFV environments. On the other hand the number of generic scenarios needs
+to be limited because of resources.
+
+* Creation of a new generic scenario needs TSC consensus.
+* Typically the generic scenario is created by promoting an existing specific
+  scenario. Thus the only the additional information needs to be provided.
+* The scenario owner needs to verify that the scenario fulfills the above requirements.
+* Since specific scenarios typically are owned by the project who have initiated it,
+  and generic scenarios provide a much broader set of features, in many cases a
+  change of owner is appropriate. In most cases it will be appropriate to assign
+  a testing expert as scenario owner.
+
+Creating Specific Scenarios
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As already stated, typically specific scenarios are created as children of existing
+scenarios. The parent can be a generic or a specific scenario.
+
+Creation of specific scenarios shall be very easy and can be done any time. However,
+support might be low priority during a final release preparation, e.g. after a MS6.
+
+* The PTL of the project developing the feature(s) or integrating a component etc can
+  request the scenario (tbd from whom: CI or release manager, no need for TSC)
+* The PTL shall provide some justification why a new scenario is needed.
+  It will be approptiate to discuss that justification in the weekly technical
+  discussion meeting.
+* The PTL should have prepared that by finding support from one of the installers.
+* The PTL should explain from which "parent scenario" (see below) the work will start,
+  and what are the planned additions.
+* The PTL shall assign a unique name. Naming rules will be set by TSC.
+* The PTL shall provide some time schedule plans when the scenario wants to join
+  a release, when he expects the scenario merge to other scenarios, and he expects
+  the features may be made available in generic scenarios.
+  A scenario can join a release at the MS0 after its creation.
+* The PTL should explain the infrastructure requirements and clarify that sufficient
+  resources are available for the scenario.
+* The PTL shall assign a scenario owner.
+* The scenario owner shall maintain the scenario descriptor file according to the
+  template.
+* The scenario owner shall drive the necessary discussions with installers and testing
+  teams to get their support.
+* In case the scenario needs new keywords in the SDF, the scenario owner shall discuss
+  those with the installer teams and CI.
+* The scenario owner shall initiate the scenario be integrated in CI and 
+  participate in releases.
+* When the scenario joins a release this needs to be done in time for the relevant
+  milestones.
+
+
diff --git a/docs/release/scenario-lifecycle/current-status.rst b/docs/release/scenario-lifecycle/current-status.rst
new file mode 100644 (file)
index 0000000..c8da13a
--- /dev/null
@@ -0,0 +1,75 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Current Status
+---------------
+
+This chapter summarizes the scenario analysis to provide some background.
+It also defines the way to introduce the scenario processes.
+
+Arno
+^^^^^^^^
+
+In Arno release, the scenario concept was not created yet.
+Looking back, we can say we had one scenario with OpenStack, ODL and KVM,
+that could be deployed in two ways, by the two installers available in Arno.
+
+Brahmaputra
+^^^^^^^^^^^^^^^^
+
+In Brahmaputra, we added options for SDN (ONOS, OCL) and some optional
+features (sfc, sdnvpn, kvm, l3 enabled ODL).
+Thus we had 9 scenarios, some of them to be deployed with 2 installers,
+that planned to participate in the release. Not all of them succeeded.
+
+Colorado
+^^^^^^^^^^^^
+
+In Colorado more components and features were added to a total of 17
+combinations of components and features. Some were supported by one
+of the four installers, others by multiple installers. In addition HA
+and NOHA options were defined.
+This lead to 28 combinations that planned to participate.
+
+Danube
+^^^^^^^^^^
+
+In Danube the number of combinations of components and features increased
+to 24, but since installer support increased and more scenarios planned
+to provide HA and NOHA options, the number of combinations was 54.
+
+In addition to that some scenarios were defined later in during development
+and some scenarios worked on ARM support.
+
+This created the need to better understand relationships and
+incompatibilities of the scenarios to drive for a manageable process
+for scenarios.
+
+As a result the relationship between the scenarios can be
+visualized by a scenario tree.
+
+.. figure:: scenario-tree-danube.png
+
+The process for generic and specific scenarios is not in place for the
+Danube release yet. But the different branches of the scenario tree
+provide the candidates to define generic scenario during the timeframe
+of the next release.
+
+Euphrates
+^^^^^^^^^^
+
+tbd: statistics on Euphrates Scenarios
+
+During Euphrates timeframe, dynamic POD allocation is introduced in CI.
+This is a prerequisite to make use of the SDF in the CI pipeline.
+Therefore in this timeframe, scenario processes are introduced only in
+a documentation way and as support for release management.
+
+Also the definition of generic scenarios can be done.
+
+
+
+
+
diff --git a/docs/release/scenario-lifecycle/deployment-options.rst b/docs/release/scenario-lifecycle/deployment-options.rst
new file mode 100644 (file)
index 0000000..2c0a342
--- /dev/null
@@ -0,0 +1,128 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Deployment Options
+-------------------
+
+What are deployment options?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. Editors note: Some installers call it settings. Prefer options, because it allows
+.. cases with multiple options.
+
+During the analysis of scenario definitions in Colorado and Danube releases, it became
+visible, that HA and NOHA deployment of otherwise identical scenarios shouldn't be
+called different scenarios.
+
+This understanding leads to the definition of another kind of attributes
+in scenario definitions. Many scenarios can be deployed in different ways:
+
+* **HA** configuration of OpenStack modules (that is redundancy using multiple
+  controllers running OpenStack services) versus NOHA with only a single controller
+  running a single instance of each OpenStack service
+* Some scenarios can be deployed on intel and on ARM **hardware**.
+* We can see the **installation tools** in the same way. Independent of the installer
+  that was used for the deployment of a scenario, the same functionality will be
+  provided and we can run the same testcases.
+
+Please note that a scenario can support multiple deployment options. And a scenario
+definition must specify at least one option of each type.
+
+In future there will be more deployment options, e.g. redundancy models or other
+clustering options of SDN controllers, or upscaling compute or control nodes.
+
+CI Pipeline needs to test all configuration options of a scenario.
+
+* Development cycles (verify-jobs, daily, weekly) don‘t need to run all
+  options each time
+* Release testing must cover all those combinations of configuration options that
+  will be part of the release. Typically the HA configurations are released on
+  bare metal with the allowed hardware options and all installers that can deploy
+  those. Release of an NOHA option should be an exception, e.g. for a scenarios
+  that are not mature yet.
+* Virtual deployments are not mentioned here. All scenarios should allow virtual
+  deployment where applicable.
+  But in release testing, bare metal deployment will be necessary.
+  CI will use virtual deployments as much as appropriate for resource reasons.
+
+
+Deployment options or new scenarios
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In general we can say that a different scenario is needed when the set of components
+is changed (or in some cases a general deploy-time configuration of a component). If
+we deploy the same components in a different way, we can define this via deployment
+options.
+
+**Examples**
+
+* Deploying different SDN controller or data plane (OVS/FD.IO) requires different
+  scenario.
+* HA/NOHA will deploy the same components on different number of nodes, so it is a
+  deployment option.
+* Different hardware types should not lead to new scenarios. Typically the same
+  scenario can be deployed on multiple hardware.
+
+
+HA and NOHA
+^^^^^^^^^^^^^
+
+Both, HA and NOHA options of a scenario are important.
+
+* HA deployment is important to be released in major OPNFV releases, because
+  telco deployments typically have strong requirements on availability.
+* NOHA deployments require less resources and are sufficient for many use cases.
+  For instance sandbox testing can be done easier and also automatic verification
+  in the CI pipeline can make use of it.
+* Generic scenarios shall support the HA and NOHA option.
+* Specific scenarios can focus on the NOHA option if their features are independent
+  from the controller redundancy. But before merging with generic scenarios, they
+  should provide both options.
+
+
+Hardware types
+^^^^^^^^^^^^^^^^^
+
+In its first releases, OPNFV could be deployed on Intel hardware only. Later, support
+for ARM hardware was added and now 5 scenarios can already be deployed on both.
+
+
+Virtual deployment
+^^^^^^^^^^^^^^^^^^^^^^
+
+Many, but not all scenarios can be deployed on virtual PODs. Therefore the scenario
+definition shall specify whether virtual deployment is possible.
+
+Typically a virtual HA deployment shall look very much the same as a bare-metal HA
+deployment, that is the distribution of modules on nodes/VMs is similar. But there
+might be cases where there are differences. Thus, the scenario specification needs
+to provide the data for each separately.
+
+
+Deployment tools
+^^^^^^^^^^^^^^^^^^^
+
+Deployment tools (installers) are in a very similar relation to the scenarios.
+Each scenario can be deployed by one or more installer. Thus we can specify the
+installers for a scenario as a deployment option.
+
+However, the installers need additional detailed information for the deployment.
+Every installer may not support the same HA, hardware, virtualization options,
+or same distribution of modules. Each deployment may look slightly different
+per installer.
+
+The scenario definition needs to provide such information in a way it can be easily
+consumed by the installers.
+
+
+
+Other deployment options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This set of deployment options is based on what is required by Danube scenarios.
+Future releases will most likely introduce additional deployment options.
+
+
+
diff --git a/docs/release/scenario-lifecycle/feature-compatibility-nosdn.png b/docs/release/scenario-lifecycle/feature-compatibility-nosdn.png
new file mode 100644 (file)
index 0000000..09520aa
Binary files /dev/null and b/docs/release/scenario-lifecycle/feature-compatibility-nosdn.png differ
diff --git a/docs/release/scenario-lifecycle/feature-compatibility-odl.png b/docs/release/scenario-lifecycle/feature-compatibility-odl.png
new file mode 100644 (file)
index 0000000..600082a
Binary files /dev/null and b/docs/release/scenario-lifecycle/feature-compatibility-odl.png differ
diff --git a/docs/release/scenario-lifecycle/generic-scenarios.rst b/docs/release/scenario-lifecycle/generic-scenarios.rst
new file mode 100644 (file)
index 0000000..f159c0c
--- /dev/null
@@ -0,0 +1,53 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Generic Scenarios
+------------------
+
+Generic scenarios provide a stable environment for users who want to base their
+products on them.
+
+* Generic scenarios provide a basic combination of upstream components together
+  with the superset of possible mature features that can be deployed on them.
+* Generic scenarios should be supported by all installers.
+* All generic scenarios in a release should have the same common major versions
+  of the included upstream components.
+  These upstream versions can then be seen as the upstream versions for the
+  release. E.g. that way we can say: “OPNFV xxx contains OpenStack abc,
+  ODL def, ONOS ghi, OVS jkl“.
+  But most installers cannot directly reference any
+  upstream version. This may lead to minor differences.
+  Nevertheless features and test cases require all installers using the same
+  major versions.
+* Generic scenarios should use stable sources
+  and lock the versions before the release by either pointing to a tag or sha1.
+  According to the LF badging program it should be possible to reproduce
+  the release from source again.
+  Thus the upstream repos should be in safe locations.
+  Also only tagged source versions should be used for the release, so the
+  release can be reproduced identically for different purposes such as
+  reproducing a baug reported by users and issuing the fix appropriately,
+  even after the upstream project has applied patches.
+  .. Editors note: There is discussion ongoing in INFRA and SEC working groups how
+  .. to realize this. Thus the description is still a bit vague. Details will be
+  .. added later either here or in some INFRA document.
+* Generic scenarios should be stable and mature. Therefore they will be tested more
+  thoroughly and run special release testing so a high level of stability can be
+  provided.
+* Generic scenarios will live through many OPNFV releases.
+* More resources will be allocated to maintaining generic scenarios and they will
+  have priority for CI resources.
+  .. Editors note: Discussion ongoing in INFRA about toolchain issues.
+
+Note: in some cases it might be difficult for an installer to support all generic
+scenarios immediately. In this case an exception can be defined, but the installer
+has to provide a plan how to achieve support for all generic scenarios.
+
+Note: in some cases, upstream projects don‘t have proper CI process with
+tagged stable versions. Also some installers‘ way of working doesn‘t allow
+selecting the repo and tag. Thus a stepwise approach will be necessary to
+fulfill this requirement.
+
+
diff --git a/docs/release/scenario-lifecycle/index.rst b/docs/release/scenario-lifecycle/index.rst
new file mode 100644 (file)
index 0000000..c1a9a52
--- /dev/null
@@ -0,0 +1,24 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+**********************
+Scenario Lifecycle
+**********************
+
+Contents:
+
+.. toctree::
+   :numbered:
+   :maxdepth: 4
+
+   scenario-overview.rst
+   generic-scenarios.rst
+   specific-scenarios.rst
+   parent-child-relations.rst
+   creating-scenarios.rst
+   deployment-options.rst
+   mano-scenarios.rst
+   current-status.rst
+   scenario-descriptor-files.rst
+   workflows.rst
diff --git a/docs/release/scenario-lifecycle/mano-scenarios.rst b/docs/release/scenario-lifecycle/mano-scenarios.rst
new file mode 100644 (file)
index 0000000..0eee143
--- /dev/null
@@ -0,0 +1,31 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+MANO Scenarios
+---------------
+
+Since OPNFV organizes all deployments using scenarios, also MANO components need
+to be covered by scenarios.
+
+On the other side all NFVI/VIM level scenarios need to be orchestrated using a
+set of components from the NFVO and VNFM layer.
+
+The idea here is therefore to specify for a MANO scenario:
+
+* The MANO components to deploy
+* A list of supported NFVI/VIM level scenarios that can be orchestrated
+  using this MANO scenario.
+
+The MANO test cases will define the VNFs to use.
+
+MANO scenarios will have more work to do if they require new nodes to be deployed on.
+They should include this aspect in their resource planning/requests and contact
+Infra/Pharos in case that a change of the Pharos spec is needed and new PODs need
+to be made available based on the amended spec.
+
+More details need to be investigated as we gain experience with the MANO scenarios
+
+
+
diff --git a/docs/release/scenario-lifecycle/parent-child-relations.rst b/docs/release/scenario-lifecycle/parent-child-relations.rst
new file mode 100644 (file)
index 0000000..ca15619
--- /dev/null
@@ -0,0 +1,62 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Parent - Child Relations
+-------------------------
+
+In many cases, development adds a feature to an existing scenario by adding additional
+components. This is called creating a child scenario from a parent.
+
+* Parent scenarios typically are more stable than children.
+* Children should plan to merge their feature back to the parent.
+* Merge back will often add components to the parent.
+
+.. figure:: parent-child.png
+
+* Child scenarios can be part of releases.
+* Child scenarios should merge back to their parent after 2 releases.
+* If a child scenario lives through several releases, it might be desirable
+  to “rebase/cherrypick” a child scenario to follow changes in the parent scenario.
+* Child scenarios typically support a smaller number of deployment options than
+  their parent
+
+Child scenarios are specific scenarios. Parent scenarios can be generic or specific
+scenarios.
+
+Child scenarios can be created any time. If they want to join a release, they have
+to be created before MS0 of that release.
+
+
+Siblings
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In some cases it could make more sense to create a sibling rather than a child
+(e.g. if expected that merging back to parent will be difficult).
+In other words, the content of a child scenario will be incompatible with content
+of the parent scenario.
+In that case, the child scenario should rather become a new branch instead of
+merging back to the parent.
+
+.. figure:: sibling.png
+
+Typically the sibling uses alternate components/solutions than the parent – in
+long term it might evolve into a new generic scenario, that is a new branch
+in the scenario tree.
+
+Creation of the sibling shall not be gated. It should be covered in the scope of
+an approved project, so there cannot be too big surprises.
+
+But at a certain time the new scenario will want to change its status from a
+specific scenario to a generic scenario. This move will need TSC approval.
+For the application, the scenario owner shall demonstrate that the scenario
+fulfills the requirements of a generic scenario (see later).
+
+Examples: SDN controller options, Container technologies, data plane solutions,
+MANO solutions.
+
+Please note that from time to time, the TSC will need to review the
+set of generic scenarios and "branches" in the scenario tree.
+
+
diff --git a/docs/release/scenario-lifecycle/parent-child.png b/docs/release/scenario-lifecycle/parent-child.png
new file mode 100644 (file)
index 0000000..2f71149
Binary files /dev/null and b/docs/release/scenario-lifecycle/parent-child.png differ
diff --git a/docs/release/scenario-lifecycle/pdf-and-sdf.png b/docs/release/scenario-lifecycle/pdf-and-sdf.png
new file mode 100644 (file)
index 0000000..729c5a4
Binary files /dev/null and b/docs/release/scenario-lifecycle/pdf-and-sdf.png differ
diff --git a/docs/release/scenario-lifecycle/scenario-descriptor-files.rst b/docs/release/scenario-lifecycle/scenario-descriptor-files.rst
new file mode 100644 (file)
index 0000000..b6c44f7
--- /dev/null
@@ -0,0 +1,228 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Scenario Descriptor Files
+----------------------------
+
+What are Scenario Descriptor Files?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Every scenario is described in its own descriptor file.
+The scenario descriptor file will be used by several parties:
+
+* Installer tools will read from it the list of components to be installed
+  and the configuration (e.g. deployment options and necessary details) to use.
+* The dynamic CI process will read from it the prerequisites of the scenario
+  to select the resource that has the needed capabilities for the deployment.
+  It will also select the installer
+  from the list of supported installers and the other deployment options as
+  supported in their combination.
+
+  The dynamic CI process will provide the installers with the deployment option
+  to use for a particular deployment.
+
+* The scenario owner needs to provide the descriptor file.
+
+  When compiling it the scenario owner typically needs to work together with
+  the installers, so the installers will support the required components and
+  options.
+* The testing framework can read from the scenario descriptor file necessary
+  information to know which features can be tested on the scenario.
+* The scenario descriptor file will also contain some maintenance information
+
+
+Structure of the file
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The scenario descriptor file is a yaml file. The syntax will allow to specify
+additional descriptor files, to make it better readable or structure common
+configurations across multiple scenarios.
+
+The file has following main sections:
+
+* metadata (owner, history, description)
+* list of components (names, versions, submodules)
+* deployment options (HA/NOHA, hardware&virtualization, installers, including
+  possible combinations and necessary details)
+* other prerequisites (e.g. memory requirement more than pharos spec)
+* list of features to be tested
+
+More information to be provided in next version of this document. The file will
+be defined based on the installer-specific files for scenario specification
+used by the 4 installers in Danube release. Thus it will be made sure that the
+information needed by the installers will be covered.
+
+All scenario files will be stored in a central repo, e.g. Octopus. There will
+also be a commented template to help create scenario descriptor files.
+
+
+Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In Danube timeframe only Fuel installer has some metadata in the descriptor file.
+The new template contains:
+
+* Unique name
+
+  This is a free name, there is a recommendation to take fish for names, matching
+  OPNFV release naming with rivers.
+
+* A free text title
+
+  This should be a short descriptive text telling the main purpose
+
+* A version number for the descriptor file
+
+  Three digits, separated with dots, as used by Fuel in Danube
+
+* Creation date
+* Comment
+
+  The file should contain a clear description of the purpose of the scenario,
+  including the main benefits and major features.
+  If applicable, the parent scenario should be mentioned.
+
+* First OPNFV version to use the scenario
+* Author/Owner
+
+* A list of additional contact persons, e.g. from installers or major components
+
+Components
+^^^^^^^^^^^^^^^^
+
+In this section all components are listed together with their version.
+For some components in addtion submodules can be listed.
+
+More details will be added.
+
+
+Deployment options
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This section will list the supported deployment options. In each category at least
+one option must be supported.
+
+* hardware (cpu) types (intel or ARM)
+* Virtualization (bare-metal or vPOD)
+* availability (HA or NOHA)
+
+  This subsection needs to specify also what does an HA deployment need, e.g.:
+
+::
+
+  availability:
+
+    - type: HA
+        nodes:
+          - name: host1
+            roles:
+              - openstack-controller
+              - odl
+              - ceph-adm
+              - ceph-mon
+          - name: host2
+            roles:
+              - openstack-controller
+              - odl
+              - ceph-adm
+              - ceph-mon
+          - name: host3
+            roles:
+              - openstack-controller
+              - odl
+              - ceph-adm
+              - ceph-mon
+          - name: host4
+              - openstack-compute
+              - ceph-osd
+          - name: host5
+              - openstack-compute
+              - ceph-osd
+    - type: NOHA
+        hosts:
+          - name: host1
+            roles:
+              - openstack-controller
+              - odl
+              - ceph-adm
+              - ceph-mon
+          - name: host2
+              - openstack-compute
+              - ceph-osd
+          - name: host3
+              - openstack-compute
+              - ceph-osd
+
+
+
+* deployment tool (apex, compass, fuel, daisy, joid)
+
+  In the section for each deployment tool, the combinations of the first three
+  options have to be listed, e.g.:
+
+::
+
+  deployment-tools:
+
+    - type: fuel
+         cpu: intel
+         pod: baremetal
+         availability: HA
+    - type: fuel
+         cpu: intel
+         pod: virtual
+         availability: HA
+    - type: fuel
+         cpu: intel
+         pod: virtual
+         availability: NOHA
+
+Please note that this allows easy definition of other availability options
+including scaling and redundant configuration of SDN controllers.
+
+
+Prerequisites
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This section will list additional prerequisites. Currently there is only
+one case where a scenario has additional prerequisites to the Pharos spec.
+E.g. a component could requires more RAM on the nodes than defined in
+Pharos spec.
+In general it should be preferred to issue such requirements to pharos
+using the pharos change request process, but in some cases in might be
+better to specify additional prerequisites.
+
+Another use case for these prerequisites will be usage of specilized
+hardware, e.g. for acceleration. This needs further study.
+
+The section can be empty or omitted.
+
+
+Testcases
+^^^^^^^^^^^^^^^^
+
+This section will provide information for functest and yardstick to decide
+on the proper test cases for the scenario.
+
+More details will be added.
+
+
+Shared settings
+^^^^^^^^^^^^^^^^
+
+This descriptor file might get quite long and complex. Also some of the settings
+will be shared between several scenarios, e.g. a long OpenStack module list.
+
+Therefore it shall be possible to reference another file like a macro.
+In that case all the file content is included in that place, e.g.:
+
+::
+
+  availability:
+
+    - type: HA
+        file: odl-ha-configuration.yaml
+
+
diff --git a/docs/release/scenario-lifecycle/scenario-overview.rst b/docs/release/scenario-lifecycle/scenario-overview.rst
new file mode 100644 (file)
index 0000000..4a7ff7a
--- /dev/null
@@ -0,0 +1,166 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+.. Scenario Lifecycle
+.. ==========================================
+
+Note: This document is still work in progress.
+
+Overview
+-------------
+
+Problem Statement:
+^^^^^^^^^^^^^^^^^^^
+
+OPNFV provides the NFV reference platform in different variants, where
+each variant is called a "scenario".
+
+OPNFV introduces scenarios in order to provide a way to deploy the stack
+using different combinations of upstream components, or to provide
+different sets of pre-defined configuration options for these
+components.
+
+In some cases a scenario is introduced in order to provide isolation of
+a specific development effort from other ongoing development efforts,
+similar to the purpose of a branch in a code repository.
+
+A certain amount of effort and resources is required in order to include
+a scenario in a release. The number of scenarios has increased over
+time, so it is necessary to identify ways to manage the number of
+scenarios and to avoid that their number grows infinitely. To enable
+this, we have to clearly define how to handle the lifecycle of
+scenarios, i.e. how to create, how to terminate, etc.
+
+
+Scenario types:
+^^^^^^^^^^^^^^^^^^^
+Some OPNFV scenarios have an experimental nature, since they introduce
+new technologies or features that are not yet mature or well integrated
+enough to provide a stable release. Nevertheless there also needs to be
+a way to provide the user with the opportunity to try these new features
+in an OPNFV release context.
+
+Other scenarios are used to provide stable environments for users
+desiring a certain combination of upstream components or interested in
+particular capabilities or use cases.
+
+The new OPNFV scenario lifecycle process proposed herein will support
+this by defining two types of scenarios:
+
+* **Generic scenarios** cover a stable set of common features provided
+by different components and target long-term usage and maintenance of
+the scenario. Only stable versions of upstream components are allowed to
+be deployed in a generic scenario. Across all generic scenarios in a
+given OPNFV release, the same version of a given upstream component
+should be deployed. Creation of generic scenarios and promotion of
+specific to generic scenario requires TSC approval, see section 5.
+Generic scenarios will get priority over specific scenarios in terms of
+maintenance effort and CI resources.
+
+* **Specific scenarios** are needed during development to introduce new
+upstream components or new features. They are typically derived from a
+generic scenario and are intended to bring their features back into the
+parent generic scenario once they are mature enough. It is also possible
+that multiple specific scenarios are merged before bringing them back to
+the parent scenario, for example in order to test and develop the
+integration of two specific features in isolation. Specific scenarios
+can consume unreleased upstream versions or apply midstream patches.
+Creation of specific scenarios is not gated, but if a project intends to
+release a specific scenario, it has to indicate that in its release plan
+at milestone MS1. The scenario itself can be created at any time, by
+means of a simple request by a PTL to the release manager.
+
+OPNFV scenarios are deployed using one of the OPNFV installer tools.
+Deploying a scenario will normally be supported by multiple installers.
+The capabilities provided by the resulting deployments should be
+identical. The set of tests to run and their results should be the same,
+independent of the installer that had been used. Performance or other
+behavioral aspects outside the scope of existing OPNFV tests could be
+different.
+
+
+Parent-child and sibling relations:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When a developer decides to define a new scenario, he typically will
+take one of the existing scenarios and do some changes, such as:
+
+* add additional components
+* change a deploy-time configuration
+* use a component in a more experimental version or with midstream
+patches applied
+
+In this case the already existing scenario is called a "parent" and the
+new scenario would be a "child".
+
+Typically parent scenarios are generic scenarios, but it is possible to
+derive from specific scenarios as well. it is expected that the child
+scenario develops its additions over some time up to a sufficient
+maturity, and then merges back to the parent. This way a continuous
+evolution of the generic scenarios as well as a manageable overall
+number of scenairos is ensured.
+
+In some cases a child scenario will diverge from its parent in a way
+that cannot easily be combined with the parent. Therefore, is is also
+possible to "promote" a scenario from specific to generic. If this is
+foreseeable upfront, the specific scenario can also be derived as a
+sibling rather that child.
+
+Promoting a scenario from specific to generic or creating a new generic
+scenario requires TSC approval. This document defines a process for
+this, see section 5.
+
+
+Scenario deployment options:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Many OPNFV scenarios can be deployed in different variants that do not
+justify creation of separate scenarios. An example would be HA (high
+availability) or non-HA configuration of otherwise identical scenarios.
+HA configurations deploy some components according to a redundancy
+model. Deployment options will also be used if the same scenario can be
+deployed on multiple types of hardware, i.e. Intel and ARM.
+
+In these cases multiple deployment options are defined for the same
+scenario. The set of distinguishable deployment option types (e.g.
+redundancy, processor architecture, etc.) will be pre-determined and
+each scenario will have to define at least one option for each option
+type.
+
+It is emphasized that virtual deployments vs. bare-metal deployments are
+intentionally not considered as deployment options. This should be a
+transparent feature of the installer based on the same scenario
+definition.
+
+For generic scenarios, there are certain expectations on the set of
+supported deployment options, e.g. a generic scenario should support at
+least an HA deployment and preferably both HA and non-HA.
+
+
+Scenario descriptor file:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Every scenario will be described in a scenario descriptor yaml file.
+This file shall contain all the necessary information for different users, such
+as the installers (which components to deploy etc.),
+the ci process (resource requirements in order to identify the right pod, machines, etc.).
+
+The scenario descriptor file will also document which installer
+can be used for a scenario and how the CI process can trigger automatic deployment
+for a scenario via one of the supported installers.
+
+
+MANO scenarios:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In early OPNFV releases, scenarios covered components of the infrastructure,
+that is NFVI and VIM.
+With the introduction of MANO, an additional dimension for scenarios is needed.
+The same MANO components need to be used together with each of the infrastructure
+scenarios. Thus MANO scenarios will define the MANO components and a list of
+infrastructure scenarios to work with. Please note that MANO scenarios follow
+the same lifecycle and rules for generic and specific scenarios like the
+infrastructure scenarios.
+
diff --git a/docs/release/scenario-lifecycle/scenario-tree+idea.png b/docs/release/scenario-lifecycle/scenario-tree+idea.png
new file mode 100644 (file)
index 0000000..b6d4d8a
Binary files /dev/null and b/docs/release/scenario-lifecycle/scenario-tree+idea.png differ
diff --git a/docs/release/scenario-lifecycle/scenario-tree-danube.png b/docs/release/scenario-lifecycle/scenario-tree-danube.png
new file mode 100644 (file)
index 0000000..54c111e
Binary files /dev/null and b/docs/release/scenario-lifecycle/scenario-tree-danube.png differ
diff --git a/docs/release/scenario-lifecycle/scenario-tree.png b/docs/release/scenario-lifecycle/scenario-tree.png
new file mode 100644 (file)
index 0000000..619b5a3
Binary files /dev/null and b/docs/release/scenario-lifecycle/scenario-tree.png differ
diff --git a/docs/release/scenario-lifecycle/sibling.png b/docs/release/scenario-lifecycle/sibling.png
new file mode 100644 (file)
index 0000000..82d4805
Binary files /dev/null and b/docs/release/scenario-lifecycle/sibling.png differ
diff --git a/docs/release/scenario-lifecycle/specific-scenarios.rst b/docs/release/scenario-lifecycle/specific-scenarios.rst
new file mode 100644 (file)
index 0000000..5f426e7
--- /dev/null
@@ -0,0 +1,34 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Specific Scenarios
+------------------
+
+Specific scenarios are used for OPNFV development and help to isolate a path of development.
+
+* Specific scenarios typically focus on a feature or topic.
+* Specific scenarios allow to advance in development for their main feature without
+  de-stabilizing other features.
+* Specific scenarios provide additional flexibility in their handling to allow the
+  development be agile.
+* Specific scenarios can use new version of their main upstream component or even
+  apply midstream patches during OPNFV deployment, i.e. the deployable artifact
+  is created via cross community CI or even only in OPNFV and not upstream.
+* Specific scenarios should have a limited life time. After a few releases, the feature
+  development should have matured and the feature made available different configurations
+  if possible. Typically the scenario then should be merged with other scenarios, best
+  with generic scenarios.
+* Normally specific scenarios will be released within the major OPNFV releases. But
+  they don't need to fulfill maturity requirements (stable upstream versions and repos,
+  stability testing), and can deviate in the used upstream versions.
+* In exceptional cases we might release a specific scenario independently, in case there
+  is a need. Thus specific scenarios provide a way to a more DevOps-like process.
+* Specific scenarios will likely have a shorter support period after release as they are of
+  interest to a smaller user community vs generic scenarios.
+* They will be granted less CI resources than generic scenarios, e.g. for periodic
+  CI jobs.
+* We may need to prioritize resources post-release for maintenance / regression testing.
+
+
diff --git a/docs/release/scenario-lifecycle/workflows.rst b/docs/release/scenario-lifecycle/workflows.rst
new file mode 100644 (file)
index 0000000..c07b0f7
--- /dev/null
@@ -0,0 +1,70 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) 2017 OPNFV Ulrich Kleber (Huawei)
+
+
+Workflows
+----------
+
+Summary
+^^^^^^^^
+
+The general principle can be summarized by the following diagram:
+
+.. figure:: pdf-and-sdf.png
+
+Workflows for Scenario Owners
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The scenario owner creates the descriptor file based on the template.
+
+.. figure:: create-sdf.png
+
+Create new scenario from scratch
++++++++++++++++++++++++++++++++++++++++++++++++++
+
+This workflow will be exceptional.
+Most scenarios can easier start as children of an existing scenario;
+thus the author (scenario owner) can derive the SDF from the parent.
+But scenarios introducing new technologies affecting the whole architecture,
+e.g.containers, or higher level scenarios (e.g.MANO and Multisite which
+reference existing scenarios) can start without a parent.
+
+The following steps need to be done:
+
+  #. (Project team) Define set of components that need to be deployed
+  #. (Project) Find installers that can deploy the components
+  #. (Project&installer&CI) Agree on new keywords in SDF (e.g. component, feature name)
+  #. (Project) Assign owner
+  #. (Owner) Edit SDF, submit to octopus repo
+  #. (Owner) register scenario to participate in release as appropriate
+  #. (Owner&CI-team) Adapt jenkins triggers, so new scenario can be scheduled in valid installer/POD/Options combination(s).
+  #. (Installer-team) test deployment of components
+  #. (Project-team) Define test cases; register in test db
+
+Create child scenario by adding feature to existing scenario
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Add additional installer to a specific scenario
+++++++++++++++++++++++++++++++++++++++++++++++++
+
+Add additional hardware or availability option to a scenario
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Merge child scenario back to parent
+++++++++++++++++++++++++++++++++++++
+
+Promote specific scenario to generic scenario
+++++++++++++++++++++++++++++++++++++++++++++++
+
+Introduce SDF for existing Danube/Euphrates scenarios
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+Workflows for Installers
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Workflows for CI Tools
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
index 80e49d1..d9f9e73 100644 (file)
@@ -30,7 +30,7 @@ idf:
       network: 10.2.0.0
       mask: 24
     private:
-      interface: 1
+      interface: 2
       vlan: 2325
       network: 10.1.0.0
       mask: 24
@@ -81,3 +81,29 @@ idf:
           busaddr: *busaddr
         - interfaces: *interfaces
           busaddr: *busaddr
+    reclass:
+      node:
+        - compute_params: &compute_params
+            common:
+              nova_cpu_pinning: &nova_cpu_pinning_common "1,2,3,4,5,6,7,8,9,10,11,12"
+              compute_hugepages_size: 2M
+              compute_hugepages_count: 8192
+              compute_hugepages_mount: /mnt/hugepages_2M
+              compute_kernel_isolcpu: *nova_cpu_pinning_common
+            dpdk:
+              nova_cpu_pinning: "5-7,13-15"
+              compute_hugepages_size: 2M
+              compute_hugepages_count: 8192
+              compute_hugepages_mount: /mnt/hugepages_2M
+              compute_kernel_isolcpu: 2,3,5,6,7,10,11,13,14,15
+              compute_dpdk_driver: vfio
+              compute_ovs_pmd_cpu_mask: "0xc04"
+              compute_ovs_dpdk_socket_mem: "2048"
+              compute_ovs_dpdk_lcore_mask: "0x8"
+              compute_ovs_memory_channels: "2"
+              dpdk0_driver: vfio-pci
+              dpdk0_n_rxq: 2
+        - compute_params: *compute_params
+        - compute_params: *compute_params
+        - compute_params: *compute_params
+        - compute_params: *compute_params
diff --git a/labs/lf/idf-pod4.yaml b/labs/lf/idf-pod4.yaml
new file mode 100644 (file)
index 0000000..09939d2
--- /dev/null
@@ -0,0 +1,74 @@
+##############################################################################
+# Copyright (c) 2018 Linux Foundation, Enea AB and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+### LF POD 4 installer descriptor file ###
+
+idf:
+  version: 0.1
+  net_config:
+    oob:
+      interface: 0
+      ip-range: 172.30.8.83-172.30.8.88
+      vlan: 410
+    admin:
+      interface: 0
+      vlan: native
+      network: 192.168.12.0
+      mask: 24
+    mgmt:
+      interface: 1
+      vlan: 450
+      network: 192.168.3.0
+      mask: 24
+    storage:
+      interface: 2
+      vlan: 451
+      network: 192.168.4.0
+      mask: 24
+    private:
+      interface: 1
+      vlan: 452
+      network: 192.168.5.0
+      mask: 24
+    public:
+      interface: 2
+      vlan: 414
+      network: 172.30.12.64
+      mask: 26
+      gateway: 172.30.12.1
+      dns:
+        - 8.8.8.8
+        - 8.8.4.4
+  fuel:
+    jumphost:
+      bridges:
+        admin: 'pxebr'
+        mgmt: 'br-ctl'
+        private: ~
+        public: ~
+    network:
+      node:
+        # Ordered-list, index should be in sync with node index in PDF
+        - interfaces: &interfaces
+            # Ordered-list, index should be in sync with interface index in PDF
+            - 'eno1'
+            - 'eno3'
+            - 'eno4'
+          busaddr: &busaddr
+            # Bus-info reported by `ethtool -i ethX`
+            - '0000:04:00.0'
+            - '0000:02:00.0'
+            - '0000:02:00.1'
+        - interfaces: *interfaces
+          busaddr: *busaddr
+        - interfaces: *interfaces
+          busaddr: *busaddr
+        - interfaces: *interfaces
+          busaddr: *busaddr
+        - interfaces: *interfaces
+          busaddr: *busaddr
index fb93fde..c1af4ed 100644 (file)
@@ -18,30 +18,32 @@ idf:
     admin:
       interface: 0
       vlan: native
-      network: 10.20.0.128
-      mask: 25
-      gateway: 10.20.0.129
-      dns: 10.20.0.129
+      network: 192.168.11.0
+      mask: 24
     mgmt:
       interface: 1
       vlan: 450
-      network: 192.168.0.128
-      mask: 25
+      network: 192.168.0.0
+      mask: 24
     storage:
       interface: 2
       vlan: 451
-      network: 192.168.1.128
-      mask: 25
+      network: 192.168.1.0
+      mask: 24
     private:
       interface: 1
       vlan: 452
-      network: 192.168.2.128
-      mask: 25
+      network: 192.168.2.0
+      mask: 24
     public:
       interface: 2
       vlan: 415
       network: 172.30.13.64
       mask: 26
+      gateway: 172.30.13.1
+      dns:
+        - 8.8.8.8
+        - 8.8.4.4
   fuel:
     jumphost:
       bridges:
diff --git a/labs/lf/pod4.yaml b/labs/lf/pod4.yaml
new file mode 100644 (file)
index 0000000..2163c9c
--- /dev/null
@@ -0,0 +1,161 @@
+##############################################################################
+# Copyright (c) 2018 Linux Foundation, Enea AB and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+### LF POD 4 descriptor file ###
+
+version: 1.0
+details:
+  pod_owner: Trevor Bramwell
+  contact: tbramwell@linuxfoundation.org
+  lab: Linux Foundation
+  location: Portland, Oregon, USA
+  type: development
+  link: https://wiki.opnfv.org/display/pharos/LF+POD+4
+jumphost:
+  name: pod4-jump
+  node: &nodeparams
+    type: baremetal
+    vendor: Intel Corporation
+    model: S2600WT2R
+    arch: x86_64
+    cpus: 88
+    cpu_cflags: haswell
+    cores: 22
+    memory: 62G
+  disks: &disks
+    - name: 'disk1'
+      disk_capacity: 480G
+      disk_type: ssd
+      disk_interface: sata
+      disk_rotation: 0
+  os: centos-7
+  remote_params: &remote_params
+    type: ipmi
+    versions:
+      - 2.0
+    user: admin
+    pass: octopus
+  remote_management:
+    <<: *remote_params
+    address: 172.30.8.83
+    mac_address: "a4:bf:01:01:b0:bb"
+  interfaces:
+    - mac_address: "a4:bf:01:01:b0:b9"
+      speed: 1gb
+      address: 192.168.12.1
+      name: 'nic1'
+      features: 'dpdk|sriov'
+    - mac_address: "00:1e:67:fd:9a:04"
+      speed: 10gb
+      features: 'dpdk|sriov'
+      name: 'nic2'
+    - mac_address: "00:1e:67:fd:9a:05"
+      speed: 10gb
+      features: 'dpdk|sriov'
+      name: 'nic3'
+nodes:
+  - name: pod4-node1
+    node: *nodeparams
+    disks: *disks
+    remote_management:
+      <<: *remote_params
+      address: 172.30.8.84
+      mac_address: "a4:bf:01:01:ab:b6"
+    interfaces:
+      - mac_address: "a4:bf:01:01:ab:b4"
+        speed: 1gb
+        features: 'dpdk|sriov'
+        name: 'nic1'
+      - mac_address: "00:1e:67:fd:9b:32"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic2'
+      - mac_address: "00:1e:67:fd:9b:33"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic3'
+  - name: pod4-node2
+    node: *nodeparams
+    disks: *disks
+    remote_management:
+      <<: *remote_params
+      address: 172.30.8.85
+      mac_address: "a4:bf:01:01:b6:97"
+    interfaces:
+      - mac_address: "a4:bf:01:01:b6:95"
+        speed: 1gb
+        features: 'dpdk|sriov'
+        name: 'nic1'
+      - mac_address: "00:1e:67:fd:98:e2"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic2'
+      - mac_address: "00:1e:67:fd:98:e3"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic3'
+  - name: pod4-node3
+    node: *nodeparams
+    disks: *disks
+    remote_management:
+      <<: *remote_params
+      address: 172.30.8.86
+      mac_address: "a4:bf:01:01:66:fe"
+    interfaces:
+      - mac_address: "a4:bf:01:01:66:fc"
+        speed: 1gb
+        features: 'dpdk|sriov'
+        name: 'nic1'
+      - mac_address: "00:1e:67:fd:9c:c8"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic2'
+      - mac_address: "00:1e:67:fd:9c:c9"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic3'
+  - name: pod4-node4
+    node: *nodeparams
+    disks: *disks
+    remote_management:
+      <<: *remote_params
+      address: 172.30.8.87
+      mac_address: "a4:bf:01:01:b2:f5"
+    interfaces:
+      - mac_address: "a4:bf:01:01:b2:f3"
+        speed: 1gb
+        features: 'dpdk|sriov'
+        name: 'nic1'
+      - mac_address: "00:1e:67:fd:9b:38"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic2'
+      - mac_address: "00:1e:67:fd:9b:39"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic3'
+  - name: pod4-node5
+    node: *nodeparams
+    disks: *disks
+    remote_management:
+      <<: *remote_params
+      address: 172.30.8.88
+      mac_address: "a4:bf:01:01:b5:11"
+    interfaces:
+      - mac_address: "a4:bf:01:01:b5:0f"
+        speed: 1gb
+        features: 'dpdk|sriov'
+        name: 'nic1'
+      - mac_address: "00:1e:67:fd:99:40"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic2'
+      - mac_address: "00:1e:67:fd:99:41"
+        speed: 10gb
+        features: 'dpdk|sriov'
+        name: 'nic3'
index 61ca3eb..47ebc9e 100644 (file)
@@ -18,7 +18,7 @@ details:
   link: https://wiki.opnfv.org/display/pharos/LF+POD+5
 jumphost:
   name: pod5-jump
-  node: &nodeparas
+  node: &nodeparams
     type: baremetal
     vendor: Intel Corporation
     model: S2600WT2R
@@ -48,7 +48,7 @@ jumphost:
     - mac_address: "a4:bf:01:01:ad:71"
       speed: 1gb
       features: 'dpdk|sriov'
-      address: 10.20.0.129
+      address: 192.168.11.1
       name: 'nic1'
     - mac_address: "00:1e:67:fd:9c:c2"
       speed: 10gb
@@ -60,7 +60,7 @@ jumphost:
       name: 'nic3'
 nodes:
   - name: pod5-node1
-    node: *nodeparas
+    node: *nodeparams
     disks: *disks
     remote_management:
       <<: *remote_params
@@ -80,7 +80,7 @@ nodes:
         features: 'dpdk|sriov'
         name: 'nic3'
   - name: pod5-node2
-    node: *nodeparas
+    node: *nodeparams
     disks: *disks
     remote_management:
       <<: *remote_params
@@ -100,7 +100,7 @@ nodes:
         features: 'dpdk|sriov'
         name: 'nic3'
   - name: pod5-node3
-    node: *nodeparas
+    node: *nodeparams
     disks: *disks
     remote_management:
       <<: *remote_params
@@ -120,7 +120,7 @@ nodes:
         features: 'dpdk|sriov'
         name: 'nic3'
   - name: pod5-node4
-    node: *nodeparas
+    node: *nodeparams
     disks: *disks
     remote_management:
       <<: *remote_params
@@ -140,7 +140,7 @@ nodes:
         features: 'dpdk|sriov'
         name: 'nic3'
   - name: pod5-node5
-    node: *nodeparas
+    node: *nodeparams
     disks: *disks
     remote_management:
       <<: *remote_params
index 9118ae6..a7428fd 100644 (file)
@@ -47,7 +47,7 @@ idf:
     jumphost:
       bridges:
         admin: 'br6'
-        mgmt: 'br-mgmt'
+        mgmt: ~
         private: ~
         public: 'br-external'
     network: