summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules8
-rw-r--r--Makefile4
-rw-r--r--TODO.md1
-rwxr-xr-xci/build.sh6
-rwxr-xr-xci/deploy.sh31
-rw-r--r--ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dea.yaml1051
-rw-r--r--ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dha.yaml79
-rw-r--r--ci/deploy/templates/enea/armbandlab/vms/fuel.xml77
-rw-r--r--patches/fuel-plugin-qemu/0001-Fix-apt-cache-and-qemu-version-handling.patch28
-rw-r--r--patches/opnfv-fuel/0007-Allow-customizing-fuel-plugin-opendaylight.patch (renamed from patches/opnfv-fuel/0009-Allow-customizing-fuel-plugin-opendaylight.patch)0
-rw-r--r--patches/opnfv-fuel/0007-Allow-customizing-fuel-plugin-qemu.patch21
-rw-r--r--patches/opnfv-fuel/0008-Allow-customizing-fuel-plugin-ovsnfv.patch22
-rw-r--r--patches/opnfv-fuel/0008-Separate-armband-repo-comp-from-upstream-RPM-repos.patch (renamed from patches/opnfv-fuel/0010-Separate-armband-repo-comp-from-upstream-RPM-repos.patch)0
-rw-r--r--patches/opnfv-fuel/0009-f_repobuild-Makefile-Use-python-debian-from-pip.patch (renamed from patches/opnfv-fuel/0011-f_repobuild-Makefile-Use-python-debian-from-pip.patch)0
-rw-r--r--patches/opnfv-fuel/0010-deployment.py-stdout-not-consumed-when-deploying-cha.patch66
-rw-r--r--patches/opnfv-fuel/0011-common.py-catch-stderr-in-exec_cmd.patch40
-rw-r--r--patches/opnfv-fuel/0012-deploy.sh-do-not-expect-a-parameter-for-h.patch47
-rw-r--r--patches/opnfv-fuel/0013-VirtualFuel-Add-temp_dir-and-vm_name-attributes.patch57
-rw-r--r--patches/opnfv-fuel/0014-virtual_fuel-factor-out-image-creation-into-a-method.patch35
-rw-r--r--patches/opnfv-fuel/0015-virtual_fuel-initial-support-for-libvirt-volumes.patch209
-rw-r--r--patches/opnfv-fuel/0016-Remove-check-for-root.patch79
-rw-r--r--patches/opnfv-fuel/0017-virtual_fuel-make-vm_template-an-attibute.patch33
-rw-r--r--patches/opnfv-fuel/0018-virtual_fuel-add-XML-tree-as-attribute-of-VirtualFue.patch102
-rw-r--r--patches/opnfv-fuel/0019-transplant-Generate-extra-interfaces-config-file.patch107
-rw-r--r--patches/opnfv-fuel/0020-deploy.sh-no-need-to-set-umask-0000.patch33
-rw-r--r--patches/opnfv-fuel/0021-common.py-allow-specifying-number-of-attempts-in-exe.patch70
-rw-r--r--patches/opnfv-fuel/0022-ipmi_adapter-simplify-retry-if-command-fails.patch171
-rw-r--r--patches/opnfv-fuel/0023-deploy.py-add-multiple-bridges-support.patch69
-rw-r--r--patches/opnfv-fuel/0024-deploy.sh-allow-specifying-several-bridges.patch47
-rw-r--r--patches/opnfv-fuel/0025-Fuel-VM-for-the-Enea-Armband-lab.patch106
-rw-r--r--patches/opnfv-fuel/0026-f_repobuild-Repeat-mirror-build-up-to-ten-times.patch73
m---------upstream/fuel-plugin-ovsnfv0
m---------upstream/fuel-plugin-qemu0
33 files changed, 1378 insertions, 1294 deletions
diff --git a/.gitmodules b/.gitmodules
index 4f159866..5124f69a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -22,14 +22,6 @@
path = upstream/fuel-mirror
url = https://github.com/openstack/fuel-mirror.git
branch = stable/8.0
-[submodule "fuel-plugin-qemu"]
- path = upstream/fuel-plugin-qemu
- url = https://github.com/openstack/fuel-plugin-qemu.git
- branch = master
-[submodule "fuel-plugin-ovsnfv"]
- path = upstream/fuel-plugin-ovsnfv
- url = https://gerrit.opnfv.org/gerrit/p/ovsnfv.git
- branch = stable/brahmaputra
[submodule "fuel-plugin-opendaylight"]
path = upstream/fuel-plugin-opendaylight
url = https://github.com/openstack/fuel-plugin-opendaylight.git
diff --git a/Makefile b/Makefile
index c59f8304..1e123a82 100644
--- a/Makefile
+++ b/Makefile
@@ -64,8 +64,6 @@ build:
FUEL_AGENT_REPO=${root}/upstream/fuel-agent \
FUEL_NAILGUN_AGENT_REPO=${root}/upstream/fuel-nailgun-agent \
FUEL_MIRROR_REPO=${root}/upstream/fuel-mirror \
- QEMU_REPO=${root}/upstream/fuel-plugin-qemu \
- OVSNFV_DPDK_REPO=${root}/upstream/fuel-plugin-ovsnfv \
ODL_REPO=${root}/upstream/fuel-plugin-opendaylight \
ODL_CHANGE= \
FUELLIB_COMMIT=HEAD \
@@ -73,8 +71,6 @@ build:
FUEL_AGENT_COMMIT=HEAD \
FUEL_NAILGUN_AGENT_COMMIT=HEAD \
FUEL_MIRROR_COMMIT=HEAD \
- QEMU_BRANCH=HEAD \
- OVSNFV_DPDK_BRANCH=armband-workbench \
ODL_BRANCH=armband-workbench \
PRODUCT_VERSION=8.0 \
PRODUCT_NAME=mos \
diff --git a/TODO.md b/TODO.md
index c5cff4da..ad9c4937 100644
--- a/TODO.md
+++ b/TODO.md
@@ -7,7 +7,6 @@ Cleanup tasks
* [arm64-master] Fix license in ubuntu_1404_arm64.pp
* [arm64-master] Look into default ubuntu_debootstrap change in cobbler.pp
* [arm64-master] [fuel-agent] Package and repo update for arm64 in [2] (?)
-* [fuel] Add QEMU_VERSION for fuel-plugin-qemu
* [arm64-master] change docker repo in `upstream/fuel/build/config.mk`,
perhaps by figuring out current architecture with `uname -m`
diff --git a/ci/build.sh b/ci/build.sh
index 38be2547..fbaa7261 100755
--- a/ci/build.sh
+++ b/ci/build.sh
@@ -37,10 +37,10 @@ make REVSTATE="${OPNFV_ARTIFACT_VERSION}" release ||
write_gitinfo >> ${BUILD_BASE}/gitinfo_armband.txt
-echo "Copying results to $OUTPUT_DIR"
+echo "Moving results to $OUTPUT_DIR"
sort ${BUILD_BASE}/gitinfo*.txt > ${OUTPUT_DIR}/gitinfo.txt
-cp ${RESULT_DIR}/*.iso ${OUTPUT_DIR}/
-cp ${RESULT_DIR}/*.iso.txt ${OUTPUT_DIR}/
+mv ${RESULT_DIR}/*.iso ${OUTPUT_DIR}/
+mv ${RESULT_DIR}/*.iso.txt ${OUTPUT_DIR}/
# We need to build our own ODL plugin, and when this happens, fuel
# renames the iso to unofficial-opnfv-${REVSTATE}.iso, so here we remove
diff --git a/ci/deploy.sh b/ci/deploy.sh
new file mode 100755
index 00000000..5f258c80
--- /dev/null
+++ b/ci/deploy.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+#
+# (c) 2016 Enea Software AB
+#
+# 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
+#
+set -e
+
+cd $WORKSPACE
+make submodules-init
+make patches-import
+
+# source local environment variables
+if ! [ -z $LAB_CONFIG_URL ]; then
+ local_env=${LAB_CONFIG_URL}/labs/${TARGET_LAB}/${TARGET_POD}/fuel/config/local_env
+ # try to fetch this file, but don't create it if it does not exist.
+ # We add "|| true" to ignore the curl error when the file does not exist
+ echo "curl -s -f -O $local_env || true"
+ curl -s -f -O $local_env || true
+ local_env=$(basename $local_env)
+ if [ -e $local_env ]; then
+ echo "-- Sourcing local environment file"
+ source $local_env
+ fi
+fi
+
+cd upstream/fuel/ci
+./deploy.sh $@
diff --git a/ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dea.yaml b/ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dea.yaml
deleted file mode 100644
index 4fe4cdad..00000000
--- a/ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dea.yaml
+++ /dev/null
@@ -1,1051 +0,0 @@
-
-title: Deployment Environment Adapter (DEA)
-# DEA API version supported
-version: 1.1
-created: Wed Mar 30 12:10:46 2016
-comment: Some comment
-environment:
- name: ha-ceph-odl
- net_segment_type: tun
-wanted_release: Liberty on Ubuntu 14.04 (aarch64)
-nodes:
-- id: 1
- interfaces: interfaces_1
- role: controller,opendaylight
- transformations: transformations_1
-- id: 2
- interfaces: interfaces_1
- role: ceph-osd,controller
- transformations: transformations_1
-- id: 3
- interfaces: interfaces_1
- role: ceph-osd,controller
- transformations: transformations_1
-- id: 4
- interfaces: interfaces_2
- role: ceph-osd,compute
- transformations: transformations_2
-- id: 5
- interfaces: interfaces_2
- role: ceph-osd,compute
- transformations: transformations_2
-interfaces_1:
- eth1:
- - fuelweb_admin
- eth2:
- - public
- - management
- - storage
- - private
-interfaces_2:
- eth0:
- - fuelweb_admin
- eth3:
- - public
- - management
- - storage
- - private
-transformations_1:
- transformations:
- - action: add-br
- name: br-fw-admin
- - action: add-br
- name: br-mgmt
- - action: add-br
- name: br-storage
- - action: add-br
- name: br-ex
- - action: add-br
- name: br-floating
- provider: ovs
- - action: add-patch
- bridges:
- - br-floating
- - br-ex
- mtu: 65000
- provider: ovs
- - action: add-br
- name: br-mesh
- - action: add-port
- bridge: br-fw-admin
- name: eth1
- - action: add-port
- bridge: br-ex
- name: eth2
- - action: add-port
- bridge: br-mgmt
- name: eth2.101
- - action: add-port
- bridge: br-storage
- name: eth2.102
- - action: add-port
- bridge: br-mesh
- name: eth2.103
-transformations_2:
- transformations:
- - action: add-br
- name: br-fw-admin
- - action: add-br
- name: br-mgmt
- - action: add-br
- name: br-storage
- - action: add-br
- name: br-mesh
- - action: add-port
- bridge: br-fw-admin
- name: eth0
- - action: add-port
- bridge: br-mgmt
- name: eth3.101
- - action: add-port
- bridge: br-storage
- name: eth3.102
- - action: add-port
- bridge: br-mesh
- name: eth3.103
-fuel:
- ADMIN_NETWORK:
- dhcp_pool_end: 10.20.0.254
- dhcp_pool_start: 10.20.0.3
- ipaddress: 10.20.0.2
- netmask: 255.255.255.0
- DNS_DOMAIN: domain.tld
- DNS_SEARCH: domain.tld
- DNS_UPSTREAM: 8.8.8.8
- FUEL_ACCESS:
- password: admin
- user: admin
- HOSTNAME: fuel
- NTP1: 0.fuel.pool.ntp.org
- NTP2: 1.fuel.pool.ntp.org
- NTP3: 2.fuel.pool.ntp.org
-network:
- networking_parameters:
- base_mac: fa:16:3e:00:00:00
- configuration_template: null
- dns_nameservers:
- - 8.8.4.4
- - 8.8.8.8
- floating_name: admin_floating_net
- floating_ranges:
- - - 10.0.2.126
- - 10.0.2.150
- gre_id_range:
- - 2
- - 65535
- internal_cidr: 192.168.111.0/24
- internal_gateway: 192.168.111.1
- internal_name: admin_internal_net
- net_l23_provider: ovs
- segmentation_type: tun
- vlan_range:
- - 1000
- - 1030
- networks:
- - cidr: 10.0.2.0/24
- gateway: 10.0.2.254
- ip_ranges:
- - - 10.0.2.100
- - 10.0.2.125
- meta:
- cidr: 10.0.2.0/24
- configurable: true
- floating_range_var: floating_ranges
- ip_range:
- - 10.0.2.100
- - 10.0.2.125
- map_priority: 1
- name: public
- notation: ip_ranges
- render_addr_mask: public
- render_type: null
- use_gateway: true
- vips:
- - haproxy
- - vrouter
- vlan_start: null
- name: public
- vlan_start: null
- - cidr: 192.168.1.0/24
- gateway: null
- ip_ranges:
- - - 192.168.1.1
- - 192.168.1.254
- meta:
- cidr: 192.168.1.0/24
- configurable: true
- map_priority: 2
- name: storage
- notation: cidr
- render_addr_mask: storage
- render_type: cidr
- use_gateway: false
- vlan_start: 102
- name: storage
- vlan_start: 102
- - cidr: 192.168.0.0/24
- gateway: null
- ip_ranges:
- - - 192.168.0.1
- - 192.168.0.254
- meta:
- cidr: 192.168.0.0/24
- configurable: true
- map_priority: 2
- name: management
- notation: cidr
- render_addr_mask: internal
- render_type: cidr
- use_gateway: false
- vips:
- - haproxy
- - vrouter
- vlan_start: 101
- name: management
- vlan_start: 101
- - cidr: 192.168.2.0/24
- gateway: null
- ip_ranges:
- - - 192.168.2.1
- - 192.168.2.254
- meta:
- cidr: 192.168.2.0/24
- configurable: true
- map_priority: 2
- name: private
- notation: cidr
- render_addr_mask: null
- render_type: cidr
- seg_type: tun
- use_gateway: false
- vlan_start: 103
- name: private
- vlan_start: 103
- - cidr: 10.20.0.0/24
- gateway: 10.20.0.2
- ip_ranges:
- - - 10.20.0.3
- - 10.20.0.254
- meta:
- configurable: false
- map_priority: 0
- notation: ip_ranges
- render_addr_mask: null
- render_type: null
- unmovable: true
- use_gateway: true
- name: fuelweb_admin
- vlan_start: null
-settings:
- editable:
- access:
- email:
- description: Email address for Administrator
- label: Email
- regex:
- error: Invalid email
- source: ^\S+@\S+$
- type: text
- value: admin@localhost
- weight: 40
- metadata:
- group: general
- label: Access
- weight: 10
- password:
- description: Password for Administrator
- label: Password
- regex:
- error: Empty password
- source: \S
- type: password
- value: admin
- weight: 20
- tenant:
- description: Tenant (project) name for Administrator
- label: Tenant
- regex:
- error: Invalid tenant name
- source: ^(?!services$)(?!nova$)(?!glance$)(?!keystone$)(?!neutron$)(?!cinder$)(?!swift$)(?!ceph$)(?!ironic$)(?![Gg]uest$)(?!.*
- +.*$).+
- type: text
- value: admin
- weight: 30
- user:
- description: Username for Administrator
- label: Username
- regex:
- error: Invalid username
- source: ^(?!services$)(?!nova$)(?!glance$)(?!keystone$)(?!neutron$)(?!cinder$)(?!swift$)(?!ceph$)(?!ironic$)(?![Gg]uest$)(?!.*
- +.*$).+
- type: text
- value: admin
- weight: 10
- additional_components:
- ceilometer:
- description: If selected, Ceilometer component will be installed
- label: Install Ceilometer
- type: checkbox
- value: false
- weight: 60
- heat:
- description: ''
- label: ''
- type: hidden
- value: true
- weight: 50
- ironic:
- description: If selected, Ironic component will be installed
- label: Install Ironic
- restrictions:
- - cluster:net_provider != 'neutron' or networking_parameters:segmentation_type != 'vlan': Ironic
- requires Neutron with VLAN segmentation.
- - settings:storage.images_ceph.value == true and settings:storage.objects_ceph.value == false: Ironic
- requires Swift or RadosGW for Glance images.
- type: checkbox
- value: false
- weight: 80
- metadata:
- group: openstack_services
- label: Additional Components
- weight: 20
- mongo:
- description: If selected, You can use external Mongo DB as ceilometer backend
- label: Use external Mongo DB
- restrictions:
- - settings:additional_components.ceilometer.value == false
- type: checkbox
- value: false
- weight: 70
- murano:
- description: If selected, Murano component will be installed
- label: Install Murano
- type: checkbox
- value: false
- weight: 20
- murano-cfapi:
- description: If selected, Murano service broker will be installed
- label: Install Murano service broker for Cloud Foundry
- restrictions:
- - condition: settings:additional_components.murano.value == false
- message: Murano should be enabled
- - action: hide
- condition: not ('experimental' in version:feature_groups)
- type: checkbox
- value: false
- weight: 30
- murano_glance_artifacts_plugin:
- description: If selected glance artifact repository will be enabled
- label: Enable glance artifact repository
- restrictions:
- - condition: settings:additional_components.murano.value == false
- message: Murano should be enabled
- - action: hide
- condition: not ('experimental' in version:feature_groups)
- type: checkbox
- value: false
- weight: 40
- sahara:
- description: If selected, Sahara component will be installed
- label: Install Sahara
- type: checkbox
- value: false
- weight: 10
- common:
- auth_key:
- description: Public key(s) to include in authorized_keys on deployed nodes
- group: security
- label: Public Key
- type: textarea
- value: ''
- weight: 70
- auto_assign_floating_ip:
- description: If selected, OpenStack will automatically assign a floating IP
- to a new instance
- group: network
- label: Auto assign floating IP
- restrictions:
- - action: hide
- condition: cluster:net_provider == 'neutron'
- type: checkbox
- value: false
- weight: 40
- debug:
- description: Debug logging mode provides more information, but requires more
- disk space.
- group: logging
- label: OpenStack debug logging
- type: checkbox
- value: false
- weight: 20
- libvirt_type:
- group: compute
- label: Hypervisor type
- type: radio
- value: kvm
- values:
- - data: kvm
- description: Choose this type of hypervisor if you run OpenStack on hardware
- label: KVM
- - data: qemu
- description: Choose this type of hypervisor if you run OpenStack on virtual
- hosts.
- label: QEMU
- weight: 30
- metadata:
- label: Common
- weight: 10
- nova_quota:
- description: Quotas are used to limit CPU and memory usage for tenants. Enabling
- quotas will increase load on the Nova database.
- group: compute
- label: Nova quotas
- type: checkbox
- value: false
- weight: 30
- puppet_debug:
- description: Debug puppet logging mode provides more information, but requires
- more disk space.
- group: logging
- label: Puppet debug logging
- type: checkbox
- value: true
- weight: 20
- resume_guests_state_on_host_boot:
- description: Whether to resume previous guests state when the host reboots.
- If enabled, this option causes guests assigned to the host to resume their
- previous state. If the guest was running a restart will be attempted when
- nova-compute starts. If the guest was not running previously, a restart
- will not be attempted.
- group: compute
- label: Resume guests state on host boot
- type: checkbox
- value: true
- weight: 50
- task_deploy:
- description: Enables new deployment engine based on cross-node dependencies
- for deployment tasks which allows to deploy all nodes simultaneously. Works
- only for deployment tasks with version >= 2.0.0.
- label: Enable task based deploy
- restrictions:
- - action: hide
- condition: not ('experimental' in version:feature_groups)
- type: checkbox
- value: false
- weight: 11
- use_cow_images:
- description: For most cases you will want qcow format. If it's disabled, raw
- image format will be used to run VMs. OpenStack with raw format currently
- does not support snapshotting.
- group: storage
- label: Use qcow format for images
- type: checkbox
- value: true
- weight: 60
- use_vcenter:
- type: hidden
- value: false
- weight: 30
- corosync:
- group:
- description: ''
- label: Group
- type: text
- value: 226.94.1.1
- weight: 10
- metadata:
- group: general
- label: Corosync
- restrictions:
- - action: hide
- condition: 'true'
- weight: 50
- port:
- description: ''
- label: Port
- type: text
- value: '12000'
- weight: 20
- verified:
- description: Set True only if multicast is configured correctly on router.
- label: Need to pass network verification.
- type: checkbox
- value: false
- weight: 10
- external_dns:
- dns_list:
- description: List of upstream DNS servers, separated by comma
- label: DNS list
- regex:
- error: Invalid IP address list
- source: ^\*$|^(?:\d|1?\d\d|2[0-4]\d|25[0-5])(?:\.(?:\d|1?\d\d|2[0-4]\d|25[0-5])){3}(?:\s*,\s*(?:\d|1?\d\d|2[0-4]\d|25[0-5])(?:\.(?:\d|1?\d\d|2[0-4]\d|25[0-5])){3})*$
- type: text
- value: 8.8.8.8
- weight: 10
- metadata:
- group: network
- label: Host OS DNS Servers
- weight: 30
- external_mongo:
- hosts_ip:
- description: IP Addresses of MongoDB. Use comma to split IPs
- label: MongoDB hosts IP
- regex:
- error: Invalid hosts ip sequence
- source: ^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?),)*((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
- type: text
- value: ''
- weight: 30
- metadata:
- group: openstack_services
- label: External MongoDB
- restrictions:
- - action: hide
- condition: settings:additional_components.mongo.value == false
- message: Ceilometer and MongoDB are not enabled on the Additional Components
- section
- weight: 20
- mongo_db_name:
- description: Mongo database name
- label: Database name
- regex:
- error: Invalid database name
- source: ^\w+$
- type: text
- value: ceilometer
- weight: 30
- mongo_password:
- description: Mongo database password
- label: Password
- regex:
- error: Password contains spaces
- source: ^\S*$
- type: password
- value: ceilometer
- weight: 30
- mongo_replset:
- description: Name for Mongo replication set
- label: Replset
- type: text
- value: ''
- weight: 30
- mongo_user:
- description: Mongo database username
- label: Username
- regex:
- error: Empty username
- source: ^\w+$
- type: text
- value: ceilometer
- weight: 30
- external_ntp:
- metadata:
- group: network
- label: Host OS NTP Servers
- weight: 40
- ntp_list:
- description: List of upstream NTP servers, separated by comma
- label: NTP server list
- regex:
- error: Invalid NTP server list
- source: ^\s*(?:(?:\w+(?:-+\w+)*\.)+[a-z]+|\d{1,3}(?:\.\d{1,3}){3})\s*(?:,\s*(?:(?:\w+(?:-+\w+)*\.)+[a-z]+|\d{1,3}(\.\d{1,3}){3})\s*)*$
- type: text
- value: 0.fuel.pool.ntp.org, 1.fuel.pool.ntp.org, 2.fuel.pool.ntp.org
- weight: 10
- kernel_params:
- kernel:
- description: Default kernel parameters
- label: Initial parameters
- type: text
- value: console=ttyAMA0,115200 console=ttyS0,115200 net.ifnames=0 biosdevname=0
- rootdelay=90 nomodeset
- metadata:
- group: general
- label: Kernel parameters
- weight: 60
- murano_settings:
- metadata:
- group: openstack_services
- label: Murano Settings
- restrictions:
- - action: hide
- condition: settings:additional_components.murano.value == false
- message: Murano is not enabled on the Additional Components section
- weight: 20
- murano_repo_url:
- description: ''
- label: Murano Repository URL
- type: text
- value: http://storage.apps.openstack.org/
- weight: 10
- neutron_advanced_configuration:
- metadata:
- group: network
- label: Neutron Advanced Configuration
- restrictions:
- - action: hide
- condition: cluster:net_provider != 'neutron'
- weight: 20
- neutron_dvr:
- description: Enable Distributed Virtual Routers in Neutron
- label: Neutron DVR
- restrictions:
- - ? networking_parameters:segmentation_type != 'vlan' and settings:neutron_advanced_configuration.neutron_l2_pop.value
- == false
- : DVR requires L2 population to be enabled.
- type: checkbox
- value: false
- weight: 20
- neutron_l2_pop:
- description: Enable L2 population mechanism in Neutron
- label: Neutron L2 population
- restrictions:
- - action: hide
- condition: networking_parameters:segmentation_type == 'vlan'
- type: checkbox
- value: false
- weight: 10
- neutron_l3_ha:
- description: 'Enable High Availability features for Virtual Routers in Neutron
-
- Requires at least 2 Controller nodes to function properly
-
- '
- label: Neutron L3 HA
- restrictions:
- - condition: settings:neutron_advanced_configuration.neutron_dvr.value ==
- true
- message: Neutron DVR must be disabled in order to use Neutron L3 HA
- type: checkbox
- value: false
- weight: 30
- neutron_mellanox:
- metadata:
- enabled: true
- group: network
- label: Mellanox Neutron components
- restrictions:
- - action: hide
- condition: not ('experimental' in version:feature_groups)
- toggleable: false
- weight: 50
- plugin:
- label: Mellanox drivers and SR-IOV plugin
- type: radio
- value: disabled
- values:
- - data: disabled
- description: If selected, Mellanox drivers, Neutron and Cinder plugin will
- not be installed.
- label: Mellanox drivers and plugins disabled
- restrictions:
- - settings:storage.iser.value == true
- - data: drivers_only
- description: If selected, Mellanox Ethernet drivers will be installed to
- support networking over Mellanox NIC. Mellanox Neutron plugin will not
- be installed.
- label: Install only Mellanox drivers
- restrictions:
- - settings:common.libvirt_type.value != 'kvm'
- - data: ethernet
- description: If selected, both Mellanox Ethernet drivers and Mellanox network
- acceleration (Neutron) plugin will be installed.
- label: Install Mellanox drivers and SR-IOV plugin
- restrictions:
- - settings:common.libvirt_type.value != 'kvm' or not (cluster:net_provider
- == 'neutron' and networking_parameters:segmentation_type == 'vlan')
- weight: 60
- vf_num:
- description: Note that one virtual function will be reserved to the storage
- network, in case of choosing iSER.
- label: Number of virtual NICs
- restrictions:
- - settings:neutron_mellanox.plugin.value != 'ethernet'
- type: text
- value: '16'
- weight: 70
- opendaylight:
- metadata:
- chosen_id: 1
- class: plugin
- default: false
- enabled: true
- label: OpenDaylight plugin
- toggleable: true
- versions:
- - enable_gbp:
- label: GBP features
- type: checkbox
- value: false
- weight: 14
- enable_l3_odl:
- label: Use ODL to manage L3 traffic
- restrictions:
- - networking_parameters:segmentation_type == 'vlan': Use tunneling segmentation
- type.
- - settings:public_network_assignment.assign_to_all_nodes.value == false: Assign
- public network to all nodes
- type: checkbox
- value: false
- weight: 12
- enable_sfc:
- label: SFC features
- type: checkbox
- value: false
- weight: 13
- metadata:
- always_editable: false
- odl_features:
- default:
- - config
- - standard
- - region
- - package
- - kar
- - ssh
- - management
- gbp:
- - odl-groupbasedpolicy-base
- - odl-groupbasedpolicy-ofoverlay
- ovs:
- - odl-ovsdb-openstack
- - odl-restconf-all
- - odl-aaa-authn
- - odl-dlux-all
- sfc:
- - odl-sfc-core
- - odl-sfc-sb-rest
- - odl-sfc-ui
- - odl-sfc-netconf
- - odl-sfc-ovs
- - odl-sfcofl2
- - odl-sfc-test-consumer
- vpn:
- - odl-vpnservice-api
- - odl-vpnservice-impl
- - odl-vpnservice-impl-rest
- - odl-vpnservice-impl-ui
- - odl-vpnservice-core
- - odl-vpnservice-openstack
- plugin_id: 1
- plugin_version: 0.8.0
- restrictions:
- - cluster:net_provider != 'neutron': Only neutron is supported by OpenDaylight
- rest_api_port:
- description: Port on which ODL REST API will be available.
- label: Port number
- regex:
- error: Invalid port number
- source: ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
- type: text
- value: '8282'
- weight: 40
- weight: 70
- provision:
- metadata:
- group: general
- label: Provision
- restrictions:
- - action: hide
- condition: 'true'
- weight: 80
- method:
- type: hidden
- value: image
- public_network_assignment:
- assign_to_all_nodes:
- description: When disabled, public network will be assigned to controllers
- only
- label: Assign public network to all nodes
- type: checkbox
- value: false
- weight: 10
- metadata:
- group: network
- label: Public network assignment
- restrictions:
- - action: hide
- condition: cluster:net_provider != 'neutron'
- weight: 10
- public_ssl:
- cert_data:
- description: Certificate and private key data, concatenated into a single
- file
- label: Certificate
- restrictions:
- - action: hide
- condition: (settings:public_ssl.cert_source.value != 'user_uploaded') or
- (settings:public_ssl.horizon.value == false and settings:public_ssl.services.value
- == false)
- type: file
- value: ''
- weight: 40
- cert_source:
- description: From where we'll get certificate and private key
- label: Select source for certificate
- restrictions:
- - action: hide
- condition: settings:public_ssl.horizon.value == false and settings:public_ssl.services.value
- == false
- type: radio
- value: self_signed
- values:
- - data: self_signed
- description: Generate private key and certificate that will be signed by
- this key
- label: Self-signed
- - data: user_uploaded
- description: Use pre-generated key and certificate
- label: I have my own keypair with certificate
- weight: 30
- horizon:
- description: Secure access to Horizon enabling HTTPS instead of HTTP
- label: HTTPS for Horizon
- restrictions:
- - settings:public_ssl.services.value == false: TLS for OpenStack public endpoints
- should be enabled
- type: checkbox
- value: true
- weight: 20
- hostname:
- description: Your DNS entries should point to this name. Self-signed certificates
- also will use this hostname
- label: DNS hostname for public TLS endpoints
- restrictions:
- - action: hide
- condition: settings:public_ssl.horizon.value == false and settings:public_ssl.services.value
- == false
- type: text
- value: public.fuel.local
- weight: 50
- metadata:
- group: security
- label: Public TLS
- weight: 110
- services:
- description: Enable TLS termination on HAProxy for OpenStack services
- label: TLS for OpenStack public endpoints
- type: checkbox
- value: true
- weight: 10
- repo_setup:
- metadata:
- always_editable: true
- group: general
- label: Repositories
- weight: 50
- repos:
- description: 'Please note: the first repository will be considered the operating
- system mirror that will be used during node provisioning.
-
- To create a local repository mirror on the Fuel master node, please follow
- the instructions provided by running "fuel-createmirror --help" on the Fuel
- master node.
-
- Please make sure your Fuel master node has Internet access to the repository
- before attempting to create a mirror.
-
- For more details, please refer to the documentation (https://docs.mirantis.com/openstack/fuel/fuel-8.0/operations.html#external-ubuntu-ops).
-
- '
- extra_priority: null
- type: custom_repo_configuration
- value:
- - name: ubuntu
- priority: null
- section: main universe multiverse
- suite: trusty
- type: deb
- uri: http://ports.ubuntu.com/
- - name: ubuntu-updates
- priority: null
- section: main universe multiverse
- suite: trusty-updates
- type: deb
- uri: http://ports.ubuntu.com/
- - name: ubuntu-security
- priority: null
- section: main universe multiverse
- suite: trusty-security
- type: deb
- uri: http://ports.ubuntu.com/
- - name: mos
- priority: 1050
- section: main restricted
- suite: mos8.0
- type: deb
- uri: http://10.20.0.2:8080/liberty-8.0/ubuntu/x86_64
- - name: mos-updates
- priority: 1050
- section: main restricted
- suite: mos8.0-updates
- type: deb
- uri: http://linux.enea.com/mos-repos/ubuntu/8.0
- - name: mos-security
- priority: 1050
- section: main restricted
- suite: mos8.0-security
- type: deb
- uri: http://linux.enea.com/mos-repos/ubuntu/8.0
- - name: mos-holdback
- priority: 1100
- section: main restricted
- suite: mos8.0-holdback
- type: deb
- uri: http://linux.enea.com/mos-repos/ubuntu/8.0
- - name: Auxiliary
- priority: 1150
- section: main restricted
- suite: auxiliary
- type: deb
- uri: http://10.20.0.2:8080/liberty-8.0/ubuntu/auxiliary
- storage:
- ephemeral_ceph:
- description: Configures Nova to store ephemeral volumes in RBD. This works
- best if Ceph is enabled for volumes and images, too. Enables live migration
- of all types of Ceph backed VMs (without this option, live migration will
- only work with VMs launched from Cinder volumes).
- label: Ceph RBD for ephemeral volumes (Nova)
- type: checkbox
- value: true
- weight: 75
- images_ceph:
- description: Configures Glance to use the Ceph RBD backend to store images.
- If enabled, this option will prevent Swift from installing.
- label: Ceph RBD for images (Glance)
- restrictions:
- - settings:storage.images_vcenter.value == true: Only one Glance backend could
- be selected.
- type: checkbox
- value: true
- weight: 30
- images_vcenter:
- description: Configures Glance to use the vCenter/ESXi backend to store images.
- If enabled, this option will prevent Swift from installing.
- label: VMware vCenter/ESXi datastore for images (Glance)
- restrictions:
- - action: hide
- condition: settings:common.use_vcenter.value != true
- - condition: settings:storage.images_ceph.value == true
- message: Only one Glance backend could be selected.
- type: checkbox
- value: false
- weight: 35
- iser:
- description: 'High performance block storage: Cinder volumes over iSER protocol
- (iSCSI over RDMA). This feature requires SR-IOV capabilities in the NIC,
- and will use a dedicated virtual function for the storage network.'
- label: iSER protocol for volumes (Cinder)
- restrictions:
- - settings:storage.volumes_lvm.value != true or settings:common.libvirt_type.value
- != 'kvm'
- - action: hide
- condition: not ('experimental' in version:feature_groups)
- type: checkbox
- value: false
- weight: 11
- metadata:
- group: storage
- label: Storage Backends
- weight: 60
- objects_ceph:
- description: Configures RadosGW front end for Ceph RBD. This exposes S3 and
- Swift API Interfaces. If enabled, this option will prevent Swift from installing.
- label: Ceph RadosGW for objects (Swift API)
- type: checkbox
- value: true
- weight: 80
- osd_pool_size:
- description: Configures the default number of object replicas in Ceph. This
- number must be equal to or lower than the number of deployed 'Storage -
- Ceph OSD' nodes.
- label: Ceph object replication factor
- regex:
- error: Invalid number
- source: ^[1-9]\d*$
- type: text
- value: '3'
- weight: 85
- volumes_block_device:
- description: High performance block device storage. It is recommended to have
- at least one Storage - Cinder Block Device
- label: Cinder Block device driver
- restrictions:
- - settings:storage.volumes_ceph.value == true
- type: checkbox
- value: false
- weight: 15
- volumes_ceph:
- description: Configures Cinder to store volumes in Ceph RBD images.
- label: Ceph RBD for volumes (Cinder)
- restrictions:
- - settings:storage.volumes_lvm.value == true or settings:storage.volumes_block_device.value
- == true
- type: checkbox
- value: true
- weight: 20
- volumes_lvm:
- description: It is recommended to have at least one Storage - Cinder LVM node.
- label: Cinder LVM over iSCSI for volumes
- restrictions:
- - settings:storage.volumes_ceph.value == true
- type: checkbox
- value: false
- weight: 10
- syslog:
- metadata:
- enabled: false
- group: logging
- label: Syslog
- toggleable: true
- weight: 50
- syslog_port:
- description: Remote syslog port
- label: Port
- regex:
- error: Invalid syslog port
- source: ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
- type: text
- value: '514'
- weight: 20
- syslog_server:
- description: Remote syslog hostname
- label: Hostname
- regex:
- error: Invalid hostname
- source: ^[a-zA-Z\d]+[-\.\da-zA-Z]*$
- type: text
- value: ''
- weight: 10
- syslog_transport:
- label: Syslog transport protocol
- type: radio
- value: tcp
- values:
- - data: udp
- description: ''
- label: UDP
- - data: tcp
- description: ''
- label: TCP
- weight: 30
- workloads_collector:
- enabled:
- type: hidden
- value: true
- metadata:
- group: general
- label: Workloads Collector User
- restrictions:
- - action: hide
- condition: 'true'
- weight: 10
- password:
- type: password
- value: jgOV4m6sRbgFTvlf5SbwrayA
- tenant:
- type: text
- value: services
- user:
- type: text
- value: fuel_stats_user
diff --git a/ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dha.yaml b/ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dha.yaml
deleted file mode 100644
index c11fda06..00000000
--- a/ci/deploy/config/labs/enealab/armband-pod1/fuel/config/dha.yaml
+++ /dev/null
@@ -1,79 +0,0 @@
-
-title: Deployment Hardware Adapter (DHA)
-# DHA API version supported
-version: 1.1
-created: Wed Mar 30 12:10:46 2016
-comment: Some comment
-
-# Adapter to use for this definition
-# adapter: [ipmi|libvirt]
-adapter:
-
-# Node list.
-# Mandatory properties are id and role.
-# All other properties are adapter specific.
-# For Non-Fuel nodes controlled by:
-# - ipmi adapter you need to provide:
-# pxeMac
-# ipmiIp
-# ipmiUser
-# ipmiPass
-# - libvirt adapter you need to provide:
-# libvirtName: <whatever>
-# libvirtTemplate: [libvirt/vms/controller.xml | libvirt/vms/compute.xml]
-#
-# For the Fuel Node you need to provide:
-# libvirtName: <whatever>
-# libvirtTemplate: libvirt/vms/fuel.xml
-# isFuel: yes
-# username: root
-# password: r00tme
-
-nodes:
-- id: 1
- ipmiIp: null
- ipmiPass: null
- ipmiUser: null
- libvirtName: null
- libvirtTemplate: null
- pxeMac: 00:01:73:02:3b:29
-- id: 2
- ipmiIp: null
- ipmiPass: null
- ipmiUser: null
- libvirtName: null
- libvirtTemplate: null
- pxeMac: 00:01:73:02:3a:dd
-- id: 3
- ipmiIp: null
- ipmiPass: null
- ipmiUser: null
- libvirtName: null
- libvirtTemplate: null
- pxeMac: 00:01:73:02:36:d5
-- id: 4
- ipmiIp: null
- ipmiPass: null
- ipmiUser: null
- libvirtName: null
- libvirtTemplate: null
- pxeMac: 68:05:ca:3d:93:14
-- id: 5
- ipmiIp: null
- ipmiPass: null
- ipmiUser: null
- libvirtName: null
- libvirtTemplate: null
- pxeMac: 68:05:ca:3a:de:0b
-# Adding the Fuel node as node id 6
-# which may not be correct - please adjust as needed.
-- id: 6
- isFuel: true
- libvirtName: null
- libvirtTemplate: null
- password: r00tme
- username: root
-disks:
- compute: 100G
- controller: 100G
- fuel: 100G
diff --git a/ci/deploy/templates/enea/armbandlab/vms/fuel.xml b/ci/deploy/templates/enea/armbandlab/vms/fuel.xml
deleted file mode 100644
index cd6b4305..00000000
--- a/ci/deploy/templates/enea/armbandlab/vms/fuel.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<domain type='kvm' id='121'>
- <name>fuel</name>
- <memory unit='KiB'>8388608</memory>
- <currentMemory unit='KiB'>8388608</currentMemory>
- <vcpu placement='static'>4</vcpu>
- <resource>
- <partition>/machine</partition>
- </resource>
- <os>
- <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
- <bootmenu enable='no'/>
- </os>
- <features>
- <acpi/>
- <apic/>
- </features>
- <cpu mode='host-model'>
- <model fallback='allow'/>
- </cpu>
- <clock offset='utc'>
- <timer name='rtc' tickpolicy='catchup'/>
- <timer name='pit' tickpolicy='delay'/>
- <timer name='hpet' present='no'/>
- </clock>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>restart</on_crash>
- <pm>
- <suspend-to-mem enabled='no'/>
- <suspend-to-disk enabled='no'/>
- </pm>
- <devices>
- <emulator>/usr/libexec/qemu-kvm</emulator>
- <disk type='block' device='cdrom'>
- <driver name='qemu' type='raw'/>
- <target dev='hdc' bus='ide'/>
- <readonly/>
- </disk>
- <disk type='file' device='disk'>
- <driver name='qemu' type='qcow2' cache='writeback'/>
- <source file='fuel8.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <controller type='usb' index='0'>
- </controller>
- <controller type='pci' index='0' model='pci-root'/>
- <interface type='bridge'>
- <source bridge='admin_br0'/>
- <target dev='vnet9'/>
- <model type='virtio'/>
- <alias name='net0'/>
- </interface>
- <interface type='bridge'>
- <source bridge='public_br0'/>
- <target dev='vnet10'/>
- <model type='virtio'/>
- <alias name='net1'/>
- </interface>
- <serial type='pty'>
- <source path='/dev/pts/0'/>
- <target port='0'/>
- </serial>
- <console type='pty' tty='/dev/pts/0'>
- <source path='/dev/pts/0'/>
- <target type='serial' port='0'/>
- </console>
- <input type='mouse' bus='ps2'/>
- <input type='keyboard' bus='ps2'/>
- <graphics type='spice' port='5906' autoport='yes' listen='127.0.0.1'>
- <listen type='address' address='127.0.0.1'/>
- </graphics>
- <video>
- <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'/>
- </video>
- <memballoon model='virtio'/>
- </devices>
-</domain>
diff --git a/patches/fuel-plugin-qemu/0001-Fix-apt-cache-and-qemu-version-handling.patch b/patches/fuel-plugin-qemu/0001-Fix-apt-cache-and-qemu-version-handling.patch
deleted file mode 100644
index 9a77c3a3..00000000
--- a/patches/fuel-plugin-qemu/0001-Fix-apt-cache-and-qemu-version-handling.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Stanislaw Kardach <stanislaw.kardach@caviumnetworks.com>
-Date: Fri, 4 Mar 2016 14:26:43 +0100
-Subject: [PATCH] Fix apt cache and qemu version handling
-
----
- qemu/build-qemu.sh | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/qemu/build-qemu.sh b/qemu/build-qemu.sh
-index 652939e..f54f486 100755
---- a/qemu/build-qemu.sh
-+++ b/qemu/build-qemu.sh
-@@ -1,11 +1,12 @@
- #!/bin/bash
- wget http://wiki.qemu-project.org/download/qemu-2.2.1.tar.bz2
-+sudo apt-get update -y
- sudo apt-get build-dep qemu -y
- sudo apt-get install devscripts -y
- sudo apt-get install dpkg-dev -y
--apt-get source qemu -y
--dpkg-source -x qemu_2.0.0+dfsg-2ubuntu1.21.dsc
--cd qemu-2.0.0+dfsg; uupdate -v 2.2.1 ../qemu-2.2.1.tar.bz2
-+apt-get source qemu=2.0.0 -y
-+dpkg-source -x qemu_2.0.0*.dsc
-+cd qemu-2.0.0*; uupdate -v 2.2.1 ../qemu-2.2.1.tar.bz2
- cd ../qemu-2.2.1;echo "">> debian/patches/series
- sed -i 's/seccomp="yes"/seccomp="no"/' configure
- debian/rules build
diff --git a/patches/opnfv-fuel/0009-Allow-customizing-fuel-plugin-opendaylight.patch b/patches/opnfv-fuel/0007-Allow-customizing-fuel-plugin-opendaylight.patch
index c47b166c..c47b166c 100644
--- a/patches/opnfv-fuel/0009-Allow-customizing-fuel-plugin-opendaylight.patch
+++ b/patches/opnfv-fuel/0007-Allow-customizing-fuel-plugin-opendaylight.patch
diff --git a/patches/opnfv-fuel/0007-Allow-customizing-fuel-plugin-qemu.patch b/patches/opnfv-fuel/0007-Allow-customizing-fuel-plugin-qemu.patch
deleted file mode 100644
index 4ce6d83e..00000000
--- a/patches/opnfv-fuel/0007-Allow-customizing-fuel-plugin-qemu.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Stanislaw Kardach <stanislaw.kardach@caviumnetworks.com>
-Date: Fri, 4 Mar 2016 14:27:48 +0100
-Subject: [PATCH] Allow customizing fuel-plugin-qemu
-
----
- build/f_isoroot/f_qemupluginbuild/config.mk | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/build/f_isoroot/f_qemupluginbuild/config.mk b/build/f_isoroot/f_qemupluginbuild/config.mk
-index 0b84654..e7fb65a 100644
---- a/build/f_isoroot/f_qemupluginbuild/config.mk
-+++ b/build/f_isoroot/f_qemupluginbuild/config.mk
-@@ -7,6 +7,6 @@
- # http://www.apache.org/licenses/LICENSE-2.0
- ##############################################################################
-
--QEMU_BRANCH=c35ce3377bcf382a4e36f1df49758100cd2910b1
--QEMU_REPO=https://review.openstack.org/openstack/fuel-plugin-qemu
-+QEMU_BRANCH:=c35ce3377bcf382a4e36f1df49758100cd2910b1
-+QEMU_REPO:=https://review.openstack.org/openstack/fuel-plugin-qemu
- QEMU_CHANGE=
diff --git a/patches/opnfv-fuel/0008-Allow-customizing-fuel-plugin-ovsnfv.patch b/patches/opnfv-fuel/0008-Allow-customizing-fuel-plugin-ovsnfv.patch
deleted file mode 100644
index c427394f..00000000
--- a/patches/opnfv-fuel/0008-Allow-customizing-fuel-plugin-ovsnfv.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Stanislaw Kardach <stanislaw.kardach@caviumnetworks.com>
-Date: Sat, 5 Mar 2016 15:08:10 +0100
-Subject: [PATCH] Allow customizing fuel-plugin-ovsnfv
-
----
- build/f_isoroot/f_ovsnfv-dpdk-pluginbuild/config.mk | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/build/f_isoroot/f_ovsnfv-dpdk-pluginbuild/config.mk b/build/f_isoroot/f_ovsnfv-dpdk-pluginbuild/config.mk
-index 1893fce..f29dab5 100644
---- a/build/f_isoroot/f_ovsnfv-dpdk-pluginbuild/config.mk
-+++ b/build/f_isoroot/f_ovsnfv-dpdk-pluginbuild/config.mk
-@@ -7,7 +7,7 @@
- # http://www.apache.org/licenses/LICENSE-2.0
- ##############################################################################
-
--OVSNFV_DPDK_BRANCH=stable/brahmaputra
--OVSNFV_DPDK_REPO=https://gerrit.opnfv.org/gerrit/p/ovsnfv.git
-+OVSNFV_DPDK_BRANCH:=stable/brahmaputra
-+OVSNFV_DPDK_REPO:=https://gerrit.opnfv.org/gerrit/p/ovsnfv.git
- OVSNFV_DPDK_DIR=fuel-plugin-ovsnfv
- OVSNFV_DPDK_CHANGE=
diff --git a/patches/opnfv-fuel/0010-Separate-armband-repo-comp-from-upstream-RPM-repos.patch b/patches/opnfv-fuel/0008-Separate-armband-repo-comp-from-upstream-RPM-repos.patch
index 670e8728..670e8728 100644
--- a/patches/opnfv-fuel/0010-Separate-armband-repo-comp-from-upstream-RPM-repos.patch
+++ b/patches/opnfv-fuel/0008-Separate-armband-repo-comp-from-upstream-RPM-repos.patch
diff --git a/patches/opnfv-fuel/0011-f_repobuild-Makefile-Use-python-debian-from-pip.patch b/patches/opnfv-fuel/0009-f_repobuild-Makefile-Use-python-debian-from-pip.patch
index f84b4c0c..f84b4c0c 100644
--- a/patches/opnfv-fuel/0011-f_repobuild-Makefile-Use-python-debian-from-pip.patch
+++ b/patches/opnfv-fuel/0009-f_repobuild-Makefile-Use-python-debian-from-pip.patch
diff --git a/patches/opnfv-fuel/0010-deployment.py-stdout-not-consumed-when-deploying-cha.patch b/patches/opnfv-fuel/0010-deployment.py-stdout-not-consumed-when-deploying-cha.patch
new file mode 100644
index 00000000..584413ec
--- /dev/null
+++ b/patches/opnfv-fuel/0010-deployment.py-stdout-not-consumed-when-deploying-cha.patch
@@ -0,0 +1,66 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] deployment.py: stdout not consumed when deploying changes
+
+During the automatic deployment, when the environment is ready to be
+deployed, the deploy.py script will spawn a shell process that will
+perform the command "fuel deploy-changes". The standard output of this
+process is then piped to a "tee" process, which redirects the output
+to the standard output of the shell process, and to a file named
+cloud.log. The file is monitored by the deploy script to find out the
+status of the deployment, and print it to the log file of the automatic
+deployment script, including percentages for each node being
+provisioned. However, the deploy script never consumes the standard
+output of the shell process. If the shell process produces enough
+output, its standard output buffer will fill up, thus making the tee
+process block trying to write to its standard output, and the cloud.log
+file will not be updated. At this point, the deploy process, which is
+monitoring cloud.log, will not detect any progress in the deployment,
+and eventually it will time out and assume the deployment failed,
+although it might have finished fine after that.
+
+The solution here is to remove the "tee" process from the shell command,
+and instead redirect standard output to the cloud.log file.
+Another solution would be to actually parse the standard output of the
+shell command from the deploy script itself, but that would require a
+bit more work, as reading a line at a time might block the script.
+
+Finally, with this patch the cloud.log file won't be deleted unless the
+shell process has already finished.
+
+Change-Id: I03a77be42d220b1606e48fc4ca35e22d73a6e583
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/cloud/deployment.py | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/deploy/cloud/deployment.py b/deploy/cloud/deployment.py
+index 306abf0..0127d2a 100644
+--- a/deploy/cloud/deployment.py
++++ b/deploy/cloud/deployment.py
+@@ -101,8 +101,8 @@ class Deployment(object):
+ LOG_FILE = 'cloud.log'
+
+ log('Starting deployment of environment %s' % self.env_id)
+- run_proc('fuel --env %s deploy-changes | strings | tee %s'
+- % (self.env_id, LOG_FILE))
++ p = run_proc('fuel --env %s deploy-changes | strings > %s'
++ % (self.env_id, LOG_FILE))
+
+ ready = False
+ for i in range(int(self.deploy_timeout)):
+@@ -119,7 +119,13 @@ class Deployment(object):
+ break
+ else:
+ time.sleep(SLEEP_TIME)
+- delete(LOG_FILE)
++
++ p.poll()
++ if p.returncode == None:
++ log('The process deploying the changes has not yet finished.')
++ log('''The file %s won't be deleted''' % LOG_FILE)
++ else:
++ delete(LOG_FILE)
+
+ if ready:
+ log('Environment %s successfully deployed' % self.env_id)
diff --git a/patches/opnfv-fuel/0011-common.py-catch-stderr-in-exec_cmd.patch b/patches/opnfv-fuel/0011-common.py-catch-stderr-in-exec_cmd.patch
new file mode 100644
index 00000000..918a1192
--- /dev/null
+++ b/patches/opnfv-fuel/0011-common.py-catch-stderr-in-exec_cmd.patch
@@ -0,0 +1,40 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] common.py: catch stderr in exec_cmd
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/common.py | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/deploy/common.py b/deploy/common.py
+index 787a21a..41b4e27 100644
+--- a/deploy/common.py
++++ b/deploy/common.py
+@@ -38,20 +38,20 @@ LOG.addHandler(out_handler)
+ os.chmod(LOGFILE, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
+
+ def exec_cmd(cmd, check=True):
+- nul_f = open(os.devnull, 'w')
+ process = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE,
+- stderr=nul_f,
++ stderr=subprocess.PIPE,
+ shell=True)
+- nul_f.close()
+- response = process.communicate()[0].strip()
++ (response, stderr) = process.communicate()
+ return_code = process.returncode
++ response = response.strip()
+ if check:
+ if return_code > 0:
++ stderr = stderr.strip()
+ print "Failed command: " + str(cmd)
+- print "Command returned response: " + str(response)
++ print "Command returned response: " + str(stderr)
+ print "Command return code: " + str(return_code)
+- raise Exception(response)
++ raise Exception(stderr)
+ else:
+ print "Command: " + str(cmd)
+ print str(response)
diff --git a/patches/opnfv-fuel/0012-deploy.sh-do-not-expect-a-parameter-for-h.patch b/patches/opnfv-fuel/0012-deploy.sh-do-not-expect-a-parameter-for-h.patch
new file mode 100644
index 00000000..f515aab6
--- /dev/null
+++ b/patches/opnfv-fuel/0012-deploy.sh-do-not-expect-a-parameter-for-h.patch
@@ -0,0 +1,47 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] deploy.sh: do not expect a parameter for -h
+
+If -h was given as a parameter to the script, it would report an error
+as it expected a parameter, and if it was called as the only parameter,
+it would run deploy.py as if "old style" parameters had been given, thus
+showing the usage for the python script, instead of the expected usage
+message for this script.
+
+Update the usage message to include -h.
+
+Change-Id: I0930936962c1cb479ec4409ff114cd60a386b276
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ ci/deploy.sh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/ci/deploy.sh b/ci/deploy.sh
+index d83bba2..dc13f1c 100755
+--- a/ci/deploy.sh
++++ b/ci/deploy.sh
+@@ -40,6 +40,7 @@ OPTIONS:
+ -f Deploy on existing Fuel master
+ -e Do not launch environment deployment
+ -F Do only create a Fuel master
++ -h Print this message and exit
+ -H No health check
+ -l Lab-name
+ -p Pod-name
+@@ -62,6 +63,7 @@ Input parameters to the build script is:
+ -f Deploy on existing Fuel master
+ -e Do not launch environment deployment
+ -F Do only create a Fuel master
++-h Print this message and exit
+ -H Do not run fuel built in health-check after successfull deployment
+ -l Lab name as defined in the configuration directory, e.g. lf
+ -p POD name as defined in the configuration directory, e.g. pod-1
+@@ -116,7 +118,7 @@ DRY_RUN=0
+ ############################################################################
+ # BEGIN of main
+ #
+-while getopts "b:B:dfFHl:p:s:S:i:h:e" OPTION
++while getopts "b:B:dfFHl:p:s:S:i:he" OPTION
+ do
+ case $OPTION in
+ b)
diff --git a/patches/opnfv-fuel/0013-VirtualFuel-Add-temp_dir-and-vm_name-attributes.patch b/patches/opnfv-fuel/0013-VirtualFuel-Add-temp_dir-and-vm_name-attributes.patch
new file mode 100644
index 00000000..83d6e292
--- /dev/null
+++ b/patches/opnfv-fuel/0013-VirtualFuel-Add-temp_dir-and-vm_name-attributes.patch
@@ -0,0 +1,57 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] VirtualFuel: Add temp_dir and vm_name attributes
+
+These two variables are defined in one of the methods right now. They
+will be useful to other methods too, so we add them as attributes to the
+object here.
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/environments/virtual_fuel.py | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/deploy/environments/virtual_fuel.py b/deploy/environments/virtual_fuel.py
+index cb3bc6c..966bb91 100644
+--- a/deploy/environments/virtual_fuel.py
++++ b/deploy/environments/virtual_fuel.py
+@@ -25,6 +25,12 @@ class VirtualFuel(ExecutionEnvironment):
+ def __init__(self, storage_dir, pxe_bridge, dha_file, root_dir):
+ super(VirtualFuel, self).__init__(storage_dir, dha_file, root_dir)
+ self.pxe_bridge = pxe_bridge
++ self.temp_dir = tempfile.mkdtemp()
++ self.vm_name = self.dha.get_node_property(self.fuel_node_id,
++ 'libvirtName')
++
++ def __del__(self):
++ delete(self.temp_dir)
+
+ def set_vm_nic(self, temp_vm_file):
+ with open(temp_vm_file) as f:
+@@ -46,23 +52,20 @@ class VirtualFuel(ExecutionEnvironment):
+ vm_xml.write(f, pretty_print=True, xml_declaration=True)
+
+ def create_vm(self):
+- temp_dir = tempfile.mkdtemp()
+- vm_name = self.dha.get_node_property(self.fuel_node_id, 'libvirtName')
+ vm_template = '%s/%s' % (self.root_dir,
+ self.dha.get_node_property(
+ self.fuel_node_id, 'libvirtTemplate'))
+ check_file_exists(vm_template)
+- disk_path = '%s/%s.raw' % (self.storage_dir, vm_name)
++ disk_path = '%s/%s.raw' % (self.storage_dir, self.vm_name)
+ disk_sizes = self.dha.get_disks()
+ disk_size = disk_sizes['fuel']
+ exec_cmd('qemu-img create -f qcow2 %s %s' % (disk_path, disk_size))
+- temp_vm_file = '%s/%s' % (temp_dir, vm_name)
++ temp_vm_file = '%s/%s' % (self.temp_dir, self.vm_name)
+ exec_cmd('cp %s %s' % (vm_template, temp_vm_file))
+ self.set_vm_nic(temp_vm_file)
+ vm_definition_overwrite = self.dha.get_vm_definition('fuel')
+- self.define_vm(vm_name, temp_vm_file, disk_path,
++ self.define_vm(self.vm_name, temp_vm_file, disk_path,
+ vm_definition_overwrite)
+- delete(temp_dir)
+
+ def setup_environment(self):
+ check_if_root()
diff --git a/patches/opnfv-fuel/0014-virtual_fuel-factor-out-image-creation-into-a-method.patch b/patches/opnfv-fuel/0014-virtual_fuel-factor-out-image-creation-into-a-method.patch
new file mode 100644
index 00000000..4e1f583b
--- /dev/null
+++ b/patches/opnfv-fuel/0014-virtual_fuel-factor-out-image-creation-into-a-method.patch
@@ -0,0 +1,35 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] virtual_fuel: factor out image creation into a method
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/environments/virtual_fuel.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/deploy/environments/virtual_fuel.py b/deploy/environments/virtual_fuel.py
+index 966bb91..82c4e47 100644
+--- a/deploy/environments/virtual_fuel.py
++++ b/deploy/environments/virtual_fuel.py
+@@ -51,15 +51,20 @@ class VirtualFuel(ExecutionEnvironment):
+ with open(temp_vm_file, 'w') as f:
+ vm_xml.write(f, pretty_print=True, xml_declaration=True)
+
++ def create_image(self, disk_path, disk_size):
++ exec_cmd('qemu-img create -f qcow2 %s %s' % (disk_path, disk_size))
++
+ def create_vm(self):
+ vm_template = '%s/%s' % (self.root_dir,
+ self.dha.get_node_property(
+ self.fuel_node_id, 'libvirtTemplate'))
+ check_file_exists(vm_template)
++
+ disk_path = '%s/%s.raw' % (self.storage_dir, self.vm_name)
+ disk_sizes = self.dha.get_disks()
+ disk_size = disk_sizes['fuel']
+- exec_cmd('qemu-img create -f qcow2 %s %s' % (disk_path, disk_size))
++ self.create_image(disk_path, disk_size)
++
+ temp_vm_file = '%s/%s' % (self.temp_dir, self.vm_name)
+ exec_cmd('cp %s %s' % (vm_template, temp_vm_file))
+ self.set_vm_nic(temp_vm_file)
diff --git a/patches/opnfv-fuel/0015-virtual_fuel-initial-support-for-libvirt-volumes.patch b/patches/opnfv-fuel/0015-virtual_fuel-initial-support-for-libvirt-volumes.patch
new file mode 100644
index 00000000..87266ef8
--- /dev/null
+++ b/patches/opnfv-fuel/0015-virtual_fuel-initial-support-for-libvirt-volumes.patch
@@ -0,0 +1,209 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] virtual_fuel: initial support for libvirt volumes
+
+This patch introduces the ability to create volumes on the libvirt host
+where the Fuel VM is being deployed. For now a default pool is used,
+but the idea is to allow this to be configured.
+
+Since all virsh commands honor LIBVIRT_DEFAULT_URI, we use this
+environment variable to detect wheter we should create a volume or not.
+The rationale being that this environment variable will only be set if
+the user wants to do the VM deployment on a remote libvirt host.
+
+All this could also be done using scp and a user directory on the host
+machine, but using pools allows us to take advantage of libvirt's
+policies and file permissions.
+
+CHANGE: before this patch, the file system image was named like the VM:
+vm_name.raw. This patch introduces a change and adds a timestamp suffix
+to the image: vm_name-timestamp.raw. This is so to avoid collisions with
+an image with the same name on the remote pool. It may also be useful to
+keep around old images for later testing, while the VM definition can
+likely be the same.
+
+FIXME: This patch will use a pool called "jenkins" in the libvirt
+server, and it will fail if it is not present. This is a requirement
+that should be amended in the future, and properly documented.
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/deploy.py | 5 +++
+ deploy/dha_adapters/libvirt_adapter.py | 28 +++++++++++++++++
+ deploy/environments/virtual_fuel.py | 57 +++++++++++++++++++++++++++++-----
+ deploy/install_fuel_master.py | 8 +++--
+ 4 files changed, 88 insertions(+), 10 deletions(-)
+
+diff --git a/deploy/deploy.py b/deploy/deploy.py
+index f86f2be..265e888 100755
+--- a/deploy/deploy.py
++++ b/deploy/deploy.py
+@@ -243,6 +243,11 @@ class AutoDeploy(object):
+
+
+ def check_bridge(pxe_bridge, dha_path):
++ # Assume that bridges on remote nodes exists, we could ssh but
++ # the remote user might not have a login shell.
++ if os.environ.get('LIBVIRT_DEFAULT_URI'):
++ return
++
+ with io.open(dha_path) as yaml_file:
+ dha_struct = yaml.load(yaml_file)
+ if dha_struct['adapter'] != 'libvirt':
+diff --git a/deploy/dha_adapters/libvirt_adapter.py b/deploy/dha_adapters/libvirt_adapter.py
+index 85913ac..8f3042c 100644
+--- a/deploy/dha_adapters/libvirt_adapter.py
++++ b/deploy/dha_adapters/libvirt_adapter.py
+@@ -11,6 +11,7 @@
+ from lxml import etree
+ from hardware_adapter import HardwareAdapter
+ import tempfile
++import os
+
+ from common import (
+ log,
+@@ -23,6 +24,13 @@ DEV = {'pxe': 'network',
+ 'disk': 'hd',
+ 'iso': 'cdrom'}
+
++vol_xml_template = '''<volume type='file'>
++ <name>%s</name>
++ <capacity unit='%s'>%s</capacity>
++ <target>
++ <format type='%s'/>
++ </target>
++</volume>'''
+
+ class LibvirtAdapter(HardwareAdapter):
+
+@@ -140,3 +148,23 @@ class LibvirtAdapter(HardwareAdapter):
+
+ def get_virt_net_conf_dir(self):
+ return self.dha_struct['virtNetConfDir']
++
++ def upload_iso(self, iso_file):
++ size = os.path.getsize(iso_file)
++ vol_name = os.path.basename(iso_file)
++ vol_xml = vol_xml_template % (vol_name, 'bytes', str(size), 'raw')
++ fd, fname = tempfile.mkstemp(text=True, suffix='deploy')
++ os.write(fd, vol_xml)
++ os.close(fd)
++
++ log(vol_xml)
++ pool = 'jenkins' # FIXME
++ exec_cmd('virsh vol-create --pool %s %s' % (pool, fname))
++ vol_path = exec_cmd('virsh vol-path --pool %s %s' % (pool, vol_name))
++
++ exec_cmd('virsh vol-upload %s %s' % (vol_path, iso_file),
++ attempts=5, delay=10, verbose=True)
++
++ delete(fname)
++
++ return vol_path
+diff --git a/deploy/environments/virtual_fuel.py b/deploy/environments/virtual_fuel.py
+index 82c4e47..56d6f98 100644
+--- a/deploy/environments/virtual_fuel.py
++++ b/deploy/environments/virtual_fuel.py
+@@ -11,14 +11,33 @@
+ from lxml import etree
+ from execution_environment import ExecutionEnvironment
+ import tempfile
++import os
++import re
+
+ from common import (
+ exec_cmd,
+ check_file_exists,
+ check_if_root,
+ delete,
++ log,
+ )
+
++vol_xml_template = '''<volume type='file'>
++ <name>%s</name>
++ <capacity unit='%s'>%s</capacity>
++ <target>
++ <format type='%s'/>
++ </target>
++</volume>'''
++
++def get_size_and_unit(s):
++ p = re.compile('^(\d+)\s*(\D+)')
++ m = p.match(s)
++ if m == None:
++ return None, None
++ size = m.groups()[0]
++ unit = m.groups()[1]
++ return size, unit
+
+ class VirtualFuel(ExecutionEnvironment):
+
+@@ -51,19 +70,41 @@ class VirtualFuel(ExecutionEnvironment):
+ with open(temp_vm_file, 'w') as f:
+ vm_xml.write(f, pretty_print=True, xml_declaration=True)
+
++ def create_volume(self, pool, name, su, img_type='qcow2'):
++ log('Creating image using Libvirt volumes in pool %s, name: %s' %
++ (pool, name))
++ size, unit = get_size_and_unit(su)
++ if size == None:
++ err('Could not determine size and unit of %s' % s)
++
++ vol_xml = vol_xml_template % (name, unit, str(size), img_type)
++ fname = os.path.join(self.temp_dir, '%s_vol.xml' % name)
++ with file(fname, 'w') as f:
++ f.write(vol_xml)
++
++ exec_cmd('virsh vol-create --pool %s %s' % (pool, fname))
++ vol_path = exec_cmd('virsh vol-path --pool %s %s' % (pool, name))
++
++ delete(fname)
++
++ return vol_path
++
+ def create_image(self, disk_path, disk_size):
+- exec_cmd('qemu-img create -f qcow2 %s %s' % (disk_path, disk_size))
++ if os.environ.get('LIBVIRT_DEFAULT_URI') == None:
++ exec_cmd('qemu-img create -f qcow2 %s %s' % (disk_path, disk_size))
++ else:
++ pool = 'jenkins' # FIXME
++ name = os.path.basename(disk_path)
++ disk_path = self.create_volume(pool, name, disk_size)
+
+- def create_vm(self):
+- vm_template = '%s/%s' % (self.root_dir,
+- self.dha.get_node_property(
+- self.fuel_node_id, 'libvirtTemplate'))
+- check_file_exists(vm_template)
++ return disk_path
+
+- disk_path = '%s/%s.raw' % (self.storage_dir, self.vm_name)
++ def create_vm(self):
++ stamp = time.strftime("%Y%m%d%H%M%S")
++ disk_path = '%s/%s-%s.raw' % (self.storage_dir, self.vm_name, stamp)
+ disk_sizes = self.dha.get_disks()
+ disk_size = disk_sizes['fuel']
+- self.create_image(disk_path, disk_size)
++ disk_path = self.create_image(disk_path, disk_size)
+
+ temp_vm_file = '%s/%s' % (self.temp_dir, self.vm_name)
+ exec_cmd('cp %s %s' % (vm_template, temp_vm_file))
+diff --git a/deploy/install_fuel_master.py b/deploy/install_fuel_master.py
+index 4f6a052..1c1bf05 100644
+--- a/deploy/install_fuel_master.py
++++ b/deploy/install_fuel_master.py
+@@ -54,8 +54,12 @@ class InstallFuelMaster(object):
+
+ self.dha.node_power_off(self.fuel_node_id)
+
+- log('Zero the MBR')
+- self.dha.node_zero_mbr(self.fuel_node_id)
++ if os.environ.get('LIBVIRT_DEFAULT_URI'):
++ log('Upload ISO to pool')
++ self.iso_file = self.dha.upload_iso(self.iso_file)
++ else:
++ log('Zero the MBR')
++ self.dha.node_zero_mbr(self.fuel_node_id)
+
+ self.dha.node_set_boot_order(self.fuel_node_id, ['disk', 'iso'])
+
diff --git a/patches/opnfv-fuel/0016-Remove-check-for-root.patch b/patches/opnfv-fuel/0016-Remove-check-for-root.patch
new file mode 100644
index 00000000..4c24bb0e
--- /dev/null
+++ b/patches/opnfv-fuel/0016-Remove-check-for-root.patch
@@ -0,0 +1,79 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] Remove check for root
+
+---
+ ci/deploy.sh | 5 -----
+ deploy/deploy-config.py | 1 -
+ deploy/deploy.py | 2 --
+ deploy/environments/virtual_fuel.py | 2 --
+ 4 files changed, 10 deletions(-)
+
+diff --git a/ci/deploy.sh b/ci/deploy.sh
+index dc13f1c..343d499 100755
+--- a/ci/deploy.sh
++++ b/ci/deploy.sh
+@@ -193,11 +193,6 @@ do
+ esac
+ done
+
+-if [[ $EUID -ne 0 ]]; then
+- echo "This script must be run as root" 1>&2
+- exit 1
+-fi
+-
+ if [ -z $BASE_CONFIG_URI ] || [ -z $TARGET_LAB ] || \
+ [ -z $TARGET_POD ] || [ -z $DEPLOY_SCENARIO ] || \
+ [ -z $ISO ]; then
+diff --git a/deploy/deploy-config.py b/deploy/deploy-config.py
+index 65d51b2..88a1111 100644
+--- a/deploy/deploy-config.py
++++ b/deploy/deploy-config.py
+@@ -40,7 +40,6 @@ from common import (
+ check_file_exists,
+ create_dir_if_not_exists,
+ delete,
+- check_if_root,
+ ArgParser,
+ )
+
+diff --git a/deploy/deploy.py b/deploy/deploy.py
+index 265e888..ff4582a 100755
+--- a/deploy/deploy.py
++++ b/deploy/deploy.py
+@@ -32,7 +32,6 @@ from common import (
+ check_file_exists,
+ create_dir_if_not_exists,
+ delete,
+- check_if_root,
+ ArgParser,
+ )
+
+@@ -230,7 +229,6 @@ class AutoDeploy(object):
+ return 0
+
+ def run(self):
+- check_if_root()
+ if self.cleanup_only:
+ self.cleanup_execution_environment()
+ else:
+diff --git a/deploy/environments/virtual_fuel.py b/deploy/environments/virtual_fuel.py
+index 56d6f98..f07207f 100644
+--- a/deploy/environments/virtual_fuel.py
++++ b/deploy/environments/virtual_fuel.py
+@@ -17,7 +17,6 @@ import re
+ from common import (
+ exec_cmd,
+ check_file_exists,
+- check_if_root,
+ delete,
+ log,
+ )
+@@ -114,7 +113,6 @@ class VirtualFuel(ExecutionEnvironment):
+ vm_definition_overwrite)
+
+ def setup_environment(self):
+- check_if_root()
+ self.cleanup_environment()
+ self.create_vm()
+
diff --git a/patches/opnfv-fuel/0017-virtual_fuel-make-vm_template-an-attibute.patch b/patches/opnfv-fuel/0017-virtual_fuel-make-vm_template-an-attibute.patch
new file mode 100644
index 00000000..db602029
--- /dev/null
+++ b/patches/opnfv-fuel/0017-virtual_fuel-make-vm_template-an-attibute.patch
@@ -0,0 +1,33 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] virtual_fuel: make vm_template an attibute
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/environments/virtual_fuel.py | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/deploy/environments/virtual_fuel.py b/deploy/environments/virtual_fuel.py
+index f07207f..92a234c 100644
+--- a/deploy/environments/virtual_fuel.py
++++ b/deploy/environments/virtual_fuel.py
+@@ -46,6 +46,10 @@ class VirtualFuel(ExecutionEnvironment):
+ self.temp_dir = tempfile.mkdtemp()
+ self.vm_name = self.dha.get_node_property(self.fuel_node_id,
+ 'libvirtName')
++ self.vm_template = '%s/%s' % (self.root_dir,
++ self.dha.get_node_property(
++ self.fuel_node_id, 'libvirtTemplate'))
++ check_file_exists(self.vm_template)
+
+ def __del__(self):
+ delete(self.temp_dir)
+@@ -106,7 +110,7 @@ class VirtualFuel(ExecutionEnvironment):
+ disk_path = self.create_image(disk_path, disk_size)
+
+ temp_vm_file = '%s/%s' % (self.temp_dir, self.vm_name)
+- exec_cmd('cp %s %s' % (vm_template, temp_vm_file))
++ exec_cmd('cp %s %s' % (self.vm_template, temp_vm_file))
+ self.set_vm_nic(temp_vm_file)
+ vm_definition_overwrite = self.dha.get_vm_definition('fuel')
+ self.define_vm(self.vm_name, temp_vm_file, disk_path,
diff --git a/patches/opnfv-fuel/0018-virtual_fuel-add-XML-tree-as-attribute-of-VirtualFue.patch b/patches/opnfv-fuel/0018-virtual_fuel-add-XML-tree-as-attribute-of-VirtualFue.patch
new file mode 100644
index 00000000..ebaad984
--- /dev/null
+++ b/patches/opnfv-fuel/0018-virtual_fuel-add-XML-tree-as-attribute-of-VirtualFue.patch
@@ -0,0 +1,102 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] virtual_fuel: add XML tree as attribute of VirtualFuel
+
+Now the VM XML definition tree is an attribute of the object, this way
+it can be used by all methods without having to re-read the file from
+the file.
+
+Methods added:
+update_vm_template_file: Flushes the contents of the in-memory XML
+ representation of the VM to the backing file.
+
+del_vm_nics: Deletes all interfaces from the VM
+
+add_vm_nic: Adds a new NIC to the VM, it now takes the name of the
+ bridge as a parameter.
+
+Add a function to flush the contents of the in-memory XML representation
+to the file update_vm_template_file
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/environments/virtual_fuel.py | 37 +++++++++++++++++++++++++------------
+ 1 file changed, 25 insertions(+), 12 deletions(-)
+
+diff --git a/deploy/environments/virtual_fuel.py b/deploy/environments/virtual_fuel.py
+index 92a234c..b68577e 100644
+--- a/deploy/environments/virtual_fuel.py
++++ b/deploy/environments/virtual_fuel.py
+@@ -13,6 +13,7 @@ from execution_environment import ExecutionEnvironment
+ import tempfile
+ import os
+ import re
++import time
+
+ from common import (
+ exec_cmd,
+@@ -50,28 +51,38 @@ class VirtualFuel(ExecutionEnvironment):
+ self.dha.get_node_property(
+ self.fuel_node_id, 'libvirtTemplate'))
+ check_file_exists(self.vm_template)
++ with open(self.vm_template) as f:
++ self.vm_xml = etree.parse(f)
++
++ self.temp_vm_file = '%s/%s' % (self.temp_dir, self.vm_name)
++ self.update_vm_template_file()
+
+ def __del__(self):
+ delete(self.temp_dir)
+
+- def set_vm_nic(self, temp_vm_file):
+- with open(temp_vm_file) as f:
+- vm_xml = etree.parse(f)
+- interfaces = vm_xml.xpath('/domain/devices/interface')
++ def update_vm_template_file(self):
++ with open(self.temp_vm_file, "wc") as f:
++ self.vm_xml.write(f, pretty_print=True, xml_declaration=True)
++
++ def del_vm_nics(self):
++ interfaces = self.vm_xml.xpath('/domain/devices/interface')
+ for interface in interfaces:
+ interface.getparent().remove(interface)
++
++ def add_vm_nic(self, bridge):
+ interface = etree.Element('interface')
+ interface.set('type', 'bridge')
+ source = etree.SubElement(interface, 'source')
+- source.set('bridge', self.pxe_bridge)
++ source.set('bridge', bridge)
+ model = etree.SubElement(interface, 'model')
+ model.set('type', 'virtio')
+- devices = vm_xml.xpath('/domain/devices')
++
++ devices = self.vm_xml.xpath('/domain/devices')
+ if devices:
+ device = devices[0]
+ device.append(interface)
+- with open(temp_vm_file, 'w') as f:
+- vm_xml.write(f, pretty_print=True, xml_declaration=True)
++ else:
++ err('No devices!')
+
+ def create_volume(self, pool, name, su, img_type='qcow2'):
+ log('Creating image using Libvirt volumes in pool %s, name: %s' %
+@@ -109,11 +120,13 @@ class VirtualFuel(ExecutionEnvironment):
+ disk_size = disk_sizes['fuel']
+ disk_path = self.create_image(disk_path, disk_size)
+
+- temp_vm_file = '%s/%s' % (self.temp_dir, self.vm_name)
+- exec_cmd('cp %s %s' % (self.vm_template, temp_vm_file))
+- self.set_vm_nic(temp_vm_file)
++ self.del_vm_nics()
++ self.add_vm_nic(self.pxe_bridge)
++ self.update_vm_template_file()
++
+ vm_definition_overwrite = self.dha.get_vm_definition('fuel')
+- self.define_vm(self.vm_name, temp_vm_file, disk_path,
++
++ self.define_vm(self.vm_name, self.temp_vm_file, disk_path,
+ vm_definition_overwrite)
+
+ def setup_environment(self):
diff --git a/patches/opnfv-fuel/0019-transplant-Generate-extra-interfaces-config-file.patch b/patches/opnfv-fuel/0019-transplant-Generate-extra-interfaces-config-file.patch
new file mode 100644
index 00000000..b6a351e4
--- /dev/null
+++ b/patches/opnfv-fuel/0019-transplant-Generate-extra-interfaces-config-file.patch
@@ -0,0 +1,107 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 17:58:56 +0200
+Subject: [PATCH] transplant: Generate extra interfaces config file
+
+The DEA override may contain a IFCGF_<interface> section in its 'fuel:'
+section, containing the necessary keys to produce a ifcfg-<interface>
+file, like in this example:
+
+fuel:
+ IFCFG_ETH1:
+ device: eth1
+ ipaddress: 10.0.1.10
+ netmask: 255.255.255.0
+ gateway: 10.0.1.254
+
+FIXME: In order for Network Manager to use the newly added interfaces
+for outgoing traffic and honor their GATEWAY setting (e.g. if we just
+added one public interface), the default route on admin iface (most of
+the time called eth0) should be disabled. For now, we assume the admin
+interface is always "eth0".
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+Signed-off-by: Alexandu Avadanii <alexandru.avadanii@enea.com>
+---
+ deploy/transplant_fuel_settings.py | 37 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+diff --git a/deploy/transplant_fuel_settings.py b/deploy/transplant_fuel_settings.py
+index e57a4fb..9a65cf6 100644
+--- a/deploy/transplant_fuel_settings.py
++++ b/deploy/transplant_fuel_settings.py
+@@ -11,10 +11,14 @@
+ import sys
+ import io
+ import yaml
++import re
++import os
+ from dea import DeploymentEnvironmentAdapter
+
+ from common import (
+ check_file_exists,
++ exec_cmd,
++ log,
+ )
+
+ ASTUTE_YAML = '/etc/fuel/astute.yaml'
+@@ -35,15 +39,45 @@ def parse_arguments():
+ check_file_exists(dea_file)
+ return dea_file
+
++def write_ifcfg_file(key, fuel_conf):
++ config = ('BOOTPROTO=none\n'
++ 'ONBOOT=yes\n'
++ 'TYPE=Ethernet\n'
++ 'NM_CONTROLLED=yes\n')
++ for skey in ('ipaddress', 'device', 'netmask', 'gateway'):
++ if not fuel_conf[key].get(skey):
++ log('Warning: missing key %s for %s' % (skey, key))
++ config += '%s=\n' % skey.upper()
++ elif skey == 'ipaddress':
++ config += 'IPADDR=%s\n' % fuel_conf[key][skey]
++ else:
++ config += '%s=%s\n' % (skey.upper(), fuel_conf[key][skey])
++
++ fname = os.path.join('/etc/sysconfig/network-scripts/',
++ key.lower().replace('_','-'))
++ with open(fname, 'wc') as f:
++ f.write(config)
+
+ def transplant(dea, astute):
+ fuel_conf = dea.get_fuel_config()
++ require_network_restart = False
+ for key in fuel_conf.iterkeys():
+ if key == 'ADMIN_NETWORK':
+ for skey in fuel_conf[key].iterkeys():
+ astute[key][skey] = fuel_conf[key][skey]
++ elif re.match('^IFCFG', key):
++ log('Adding interface configuration for: %s' % key.lower())
++ require_network_restart = True
++ write_ifcfg_file(key, fuel_conf)
++ if astute.has_key(key):
++ astute.pop(key, None)
+ else:
+ astute[key] = fuel_conf[key]
++ if require_network_restart:
++ admin_ifcfg = '/etc/sysconfig/network-scripts/ifcfg-eth0'
++ exec_cmd('echo "DEFROUTE=no" >> %s' % admin_ifcfg)
++ log('At least one interface was reconfigured, restart network manager')
++ exec_cmd('systemctl restart network')
+ return astute
+
+
+@@ -51,11 +85,14 @@ def main():
+ dea_file = parse_arguments()
+ check_file_exists(ASTUTE_YAML)
+ dea = DeploymentEnvironmentAdapter(dea_file)
++ log('Reading astute file %s' % ASTUTE_YAML)
+ with io.open(ASTUTE_YAML) as stream:
+ astute = yaml.load(stream)
++ log('Initiating transplant')
+ transplant(dea, astute)
+ with io.open(ASTUTE_YAML, 'w') as stream:
+ yaml.dump(astute, stream, default_flow_style=False)
++ log('Transplant done')
+
+
+ if __name__ == '__main__':
diff --git a/patches/opnfv-fuel/0020-deploy.sh-no-need-to-set-umask-0000.patch b/patches/opnfv-fuel/0020-deploy.sh-no-need-to-set-umask-0000.patch
new file mode 100644
index 00000000..241f3078
--- /dev/null
+++ b/patches/opnfv-fuel/0020-deploy.sh-no-need-to-set-umask-0000.patch
@@ -0,0 +1,33 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Fri, 6 May 2016 03:07:40 +0200
+Subject: [PATCH] deploy.sh: no need to set umask 0000
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ ci/deploy.sh | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/ci/deploy.sh b/ci/deploy.sh
+index 343d499..34ecc57 100755
+--- a/ci/deploy.sh
++++ b/ci/deploy.sh
+@@ -76,9 +76,6 @@ Input parameters to the build script is:
+ -i .iso image to be deployed (needs to be provided in a URI
+ style, it can be a local resource: file:// or a remote resource http(s)://)
+
+-NOTE: Root priviledges are needed for this script to run
+-
+-
+ Examples:
+ sudo `basename $0` -b file:///home/jenkins/lab-config -l lf -p pod1 -s ha_odl-l3_heat_ceilometer -i file:///home/jenkins/myiso.iso
+ EOF
+@@ -207,9 +204,6 @@ fi
+ # Enable the automatic exit trap
+ trap do_exit SIGINT SIGTERM EXIT
+
+-# Set no restrictive umask so that Jenkins can removeeee any residuals
+-umask 0000
+-
+ clean
+
+ pushd ${DEPLOY_DIR} > /dev/null
diff --git a/patches/opnfv-fuel/0021-common.py-allow-specifying-number-of-attempts-in-exe.patch b/patches/opnfv-fuel/0021-common.py-allow-specifying-number-of-attempts-in-exe.patch
new file mode 100644
index 00000000..d799723e
--- /dev/null
+++ b/patches/opnfv-fuel/0021-common.py-allow-specifying-number-of-attempts-in-exe.patch
@@ -0,0 +1,70 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Fri, 6 May 2016 03:28:26 +0200
+Subject: [PATCH] common.py: allow specifying number of attempts in exec_cmd
+
+Some commands executed by exec_cmd may fail because of a temporary
+cause, and it may be desirable to retry the same command several times
+until it succeeds. One example of this are the ipmitool commands, which
+may fail temorarily on some targets if they get too many requests
+simultaneously.
+
+In this patch two new optional parameters are introduced to the function
+signature, which do not break backward compatibility:
+ attempts: which indicates how many times the command should be run if
+ it returns a non-zero value*, and defaults to 1 (as today).
+ delay: which indicates the delay in seconds between attempts, and
+ defaults to 5 seconds.
+ verbose: It will print the remaining attempts left for the current
+ command if set to True.
+
+* It may be desirable to add yet another parameter to indicate what
+ return value should be considered an error, but zero for now seems a
+ reasonable default
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/common.py | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/deploy/common.py b/deploy/common.py
+index 41b4e27..3cd3e0e 100644
+--- a/deploy/common.py
++++ b/deploy/common.py
+@@ -16,6 +16,7 @@ import argparse
+ import shutil
+ import stat
+ import errno
++import time
+
+ N = {'id': 0, 'status': 1, 'name': 2, 'cluster': 3, 'ip': 4, 'mac': 5,
+ 'roles': 6, 'pending_roles': 7, 'online': 8, 'group_id': 9}
+@@ -37,13 +38,22 @@ out_handler.setFormatter(formatter)
+ LOG.addHandler(out_handler)
+ os.chmod(LOGFILE, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
+
+-def exec_cmd(cmd, check=True):
+- process = subprocess.Popen(cmd,
+- stdout=subprocess.PIPE,
+- stderr=subprocess.PIPE,
+- shell=True)
+- (response, stderr) = process.communicate()
+- return_code = process.returncode
++def exec_cmd(cmd, check=True, attempts=1, delay=5, verbose=False):
++ # a negative value means forever
++ while attempts != 0:
++ attempts = attempts - 1
++ process = subprocess.Popen(cmd,
++ stdout=subprocess.PIPE,
++ stderr=subprocess.PIPE,
++ shell=True)
++ (response, stderr) = process.communicate()
++ return_code = process.returncode
++ if return_code == 0 or attempts == 0:
++ break
++ time.sleep(delay)
++ if verbose:
++ log('%d attempts left: %s' % (attempts, cmd))
++
+ response = response.strip()
+ if check:
+ if return_code > 0:
diff --git a/patches/opnfv-fuel/0022-ipmi_adapter-simplify-retry-if-command-fails.patch b/patches/opnfv-fuel/0022-ipmi_adapter-simplify-retry-if-command-fails.patch
new file mode 100644
index 00000000..c1617f04
--- /dev/null
+++ b/patches/opnfv-fuel/0022-ipmi_adapter-simplify-retry-if-command-fails.patch
@@ -0,0 +1,171 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Fri, 6 May 2016 12:09:58 +0200
+Subject: [PATCH] ipmi_adapter: simplify, retry if command fails
+
+The method get_node_state has been added to the The IpmiAdapter class.
+
+In addition, now the power on/off methods will try several times to
+perform their IPMI command before giving up, instead of bailing out at
+the first error.
+
+After the power on/off command is completed, the method will wait until
+the node is in the desired state.
+
+FIXME: a command could potentially take several minutes if the defaults
+are used; each IPMI command can take 1 minutes, and there can be three
+commands issued per operation, one of them may be retried 20 times with
+the current defaults. Ideally we would use eventlet or something alike
+to allow each command a limited time to execute:
+ with eventlet.timeout.Timeout(seconds) as t:
+ power_on/off_command
+
+FIXME: There is a potential dead-lock situation by issuing the command
+and then checking the status, as someone could have intervened in
+between the two commands.
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/dha_adapters/ipmi_adapter.py | 101 +++++++++++++++---------------------
+ 1 file changed, 42 insertions(+), 59 deletions(-)
+
+diff --git a/deploy/dha_adapters/ipmi_adapter.py b/deploy/dha_adapters/ipmi_adapter.py
+index 8fda4f9..283bd57 100644
+--- a/deploy/dha_adapters/ipmi_adapter.py
++++ b/deploy/dha_adapters/ipmi_adapter.py
+@@ -1,5 +1,6 @@
+ ###############################################################################
+ # Copyright (c) 2015 Ericsson AB and others.
++# (c) 2016 Enea Software AB
+ # szilard.cserey@ericsson.com
+ # All rights reserved. This program and the accompanying materials
+ # are made available under the terms of the Apache License, Version 2.0
+@@ -20,8 +21,10 @@ from common import (
+
+ class IpmiAdapter(HardwareAdapter):
+
+- def __init__(self, yaml_path):
++ def __init__(self, yaml_path, attempts=20, delay=3):
+ super(IpmiAdapter, self).__init__(yaml_path)
++ self.attempts = attempts
++ self.delay = delay
+
+ def get_access_info(self, node_id):
+ ip = self.get_node_property(node_id, 'ipmiIp')
+@@ -40,69 +43,46 @@ class IpmiAdapter(HardwareAdapter):
+ mac_list.append(self.get_node_property(node_id, 'pxeMac').lower())
+ return mac_list
+
++ def node_get_state(self, node_id):
++ state = exec_cmd('%s chassis power status' % self.ipmi_cmd(node_id),
++ attempts=self.attempts, delay=self.delay,
++ verbose=True)
++ return state
++
++ def __node_power_cmd__(self, node_id, cmd):
++ expected = 'Chassis Power is %s' % cmd
++ if self.node_get_state(node_id) == expected:
++ return
++
++ pow_cmd = '%s chassis power %s' % (self.ipmi_cmd(node_id), cmd)
++ exec_cmd(pow_cmd, attempts=self.attempts, delay=self.delay,
++ verbose=True)
++
++ attempts = self.attempts
++ while attempts:
++ state = self.node_get_state(node_id)
++ attempts -= 1
++ if state == expected:
++ return
++ elif attempts != 0:
++ # reinforce our will, but allow the command to fail,
++ # we know our message got across once already...
++ exec_cmd(pow_cmd, check=False)
++
++ err('Could not set chassis %s for node %s' % (cmd, node_id))
++
+ def node_power_on(self, node_id):
+- WAIT_LOOP = 200
+- SLEEP_TIME = 3
+ log('Power ON Node %s' % node_id)
+- cmd_prefix = self.ipmi_cmd(node_id)
+- state = exec_cmd('%s chassis power status' % cmd_prefix)
+- if state == 'Chassis Power is off':
+- exec_cmd('%s chassis power on' % cmd_prefix)
+- done = False
+- for i in range(WAIT_LOOP):
+- state, _ = exec_cmd('%s chassis power status' % cmd_prefix,
+- False)
+- if state == 'Chassis Power is on':
+- done = True
+- break
+- else:
+- time.sleep(SLEEP_TIME)
+- if not done:
+- err('Could Not Power ON Node %s' % node_id)
++ self.__node_power_cmd__(node_id, 'on')
+
+ def node_power_off(self, node_id):
+- WAIT_LOOP = 200
+- SLEEP_TIME = 3
+ log('Power OFF Node %s' % node_id)
+- cmd_prefix = self.ipmi_cmd(node_id)
+- state = exec_cmd('%s chassis power status' % cmd_prefix)
+- if state == 'Chassis Power is on':
+- done = False
+- exec_cmd('%s chassis power off' % cmd_prefix)
+- for i in range(WAIT_LOOP):
+- state, _ = exec_cmd('%s chassis power status' % cmd_prefix,
+- False)
+- if state == 'Chassis Power is off':
+- done = True
+- break
+- else:
+- time.sleep(SLEEP_TIME)
+- if not done:
+- err('Could Not Power OFF Node %s' % node_id)
++ self.__node_power_cmd__(node_id, 'off')
+
+ def node_reset(self, node_id):
+- WAIT_LOOP = 600
+ log('RESET Node %s' % node_id)
+- cmd_prefix = self.ipmi_cmd(node_id)
+- state = exec_cmd('%s chassis power status' % cmd_prefix)
+- if state == 'Chassis Power is on':
+- was_shut_off = False
+- done = False
+- exec_cmd('%s chassis power reset' % cmd_prefix)
+- for i in range(WAIT_LOOP):
+- state, _ = exec_cmd('%s chassis power status' % cmd_prefix,
+- False)
+- if state == 'Chassis Power is off':
+- was_shut_off = True
+- elif state == 'Chassis Power is on' and was_shut_off:
+- done = True
+- break
+- time.sleep(1)
+- if not done:
+- err('Could Not RESET Node %s' % node_id)
+- else:
+- err('Cannot RESET Node %s because it\'s not Active, state: %s'
+- % (node_id, state))
++ cmd = '%s chassis power reset' % self.ipmi_cmd(node_id)
++ exec_cmd(cmd, attempts=self.attempts, delay=self.delay, verbose=True)
+
+ def node_set_boot_order(self, node_id, boot_order_list):
+ log('Set boot order %s on Node %s' % (boot_order_list, node_id))
+@@ -111,9 +91,12 @@ class IpmiAdapter(HardwareAdapter):
+ for dev in boot_order_list:
+ if dev == 'pxe':
+ exec_cmd('%s chassis bootdev pxe options=persistent'
+- % cmd_prefix)
++ % cmd_prefix, attempts=self.attempts, delay=self.delay,
++ verbose=True)
+ elif dev == 'iso':
+- exec_cmd('%s chassis bootdev cdrom' % cmd_prefix)
++ exec_cmd('%s chassis bootdev cdrom' % cmd_prefix,
++ attempts=self.attempts, delay=self.delay, verbose=True)
+ elif dev == 'disk':
+ exec_cmd('%s chassis bootdev disk options=persistent'
+- % cmd_prefix)
++ % cmd_prefix, attempts=self.attempts, delay=self.delay,
++ verbose=True)
diff --git a/patches/opnfv-fuel/0023-deploy.py-add-multiple-bridges-support.patch b/patches/opnfv-fuel/0023-deploy.py-add-multiple-bridges-support.patch
new file mode 100644
index 00000000..376a7221
--- /dev/null
+++ b/patches/opnfv-fuel/0023-deploy.py-add-multiple-bridges-support.patch
@@ -0,0 +1,69 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Fri, 6 May 2016 04:32:06 +0200
+Subject: [PATCH] deploy.py: add multiple bridges support
+
+Some Fuel VMs may need more than one network interface. To be able to do
+that, we now allow the user to specify the "-b" paramter (bridge)
+multiple times, creating a new NIC for each one of them.
+
+The NICs are created in the same order as they are given in the command
+line.
+
+There is no change in behavior from earlier versions, pxebr will still
+be the default bridge if none is specified.
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ deploy/deploy.py | 10 +++++++---
+ deploy/environments/virtual_fuel.py | 3 ++-
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/deploy/deploy.py b/deploy/deploy.py
+index ff4582a..041ba2f 100755
+--- a/deploy/deploy.py
++++ b/deploy/deploy.py
+@@ -312,8 +312,8 @@ def parse_arguments():
+ parser.add_argument('-s', dest='storage_dir', action='store',
+ default='%s/images' % CWD,
+ help='Storage Directory [default: images]')
+- parser.add_argument('-b', dest='pxe_bridge', action='store',
+- default='pxebr',
++ parser.add_argument('-b', dest='pxe_bridge', action='append',
++ default=[],
+ help='Linux Bridge for booting up the Fuel Master VM '
+ '[default: pxebr]')
+ parser.add_argument('-p', dest='fuel_plugins_dir', action='store',
+@@ -332,6 +332,9 @@ def parse_arguments():
+ args = parser.parse_args()
+ log(args)
+
++ if not args.pxe_bridge:
++ args.pxe_bridge = ['pxebr']
++
+ check_file_exists(args.dha_file)
+
+ if not args.cleanup_only:
+@@ -343,7 +346,8 @@ def parse_arguments():
+ check_file_exists(args.iso_file)
+ log('Using image directory: %s' % args.storage_dir)
+ create_dir_if_not_exists(args.storage_dir)
+- check_bridge(args.pxe_bridge, args.dha_file)
++ for bridge in args.pxe_bridge:
++ check_bridge(bridge, args.dha_file)
+
+ kwargs = {'no_fuel': args.no_fuel, 'fuel_only': args.fuel_only,
+ 'no_health_check': args.no_health_check,
+diff --git a/deploy/environments/virtual_fuel.py b/deploy/environments/virtual_fuel.py
+index b68577e..6b673d0 100644
+--- a/deploy/environments/virtual_fuel.py
++++ b/deploy/environments/virtual_fuel.py
+@@ -121,7 +121,8 @@ class VirtualFuel(ExecutionEnvironment):
+ disk_path = self.create_image(disk_path, disk_size)
+
+ self.del_vm_nics()
+- self.add_vm_nic(self.pxe_bridge)
++ for bridge in self.pxe_bridge:
++ self.add_vm_nic(bridge)
+ self.update_vm_template_file()
+
+ vm_definition_overwrite = self.dha.get_vm_definition('fuel')
diff --git a/patches/opnfv-fuel/0024-deploy.sh-allow-specifying-several-bridges.patch b/patches/opnfv-fuel/0024-deploy.sh-allow-specifying-several-bridges.patch
new file mode 100644
index 00000000..b10effee
--- /dev/null
+++ b/patches/opnfv-fuel/0024-deploy.sh-allow-specifying-several-bridges.patch
@@ -0,0 +1,47 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Fri, 6 May 2016 04:39:44 +0200
+Subject: [PATCH] deploy.sh: allow specifying several bridges
+
+It might be desirable to add several bridges to the fuel VM, so we let
+the user specify -B more than once, and honor that when calling
+deploy.py. We also make it possible to specify a comma separated list of
+bridges, as in: -B br1,br2, for convenience for the Jenkins jobs.
+
+There is a change in behavior from the previous version, and that is
+that it may call the deploy.py python script with more than one instance
+of the "-b" parameter.
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ ci/deploy.sh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/ci/deploy.sh b/ci/deploy.sh
+index 34ecc57..c9b836b 100755
+--- a/ci/deploy.sh
++++ b/ci/deploy.sh
+@@ -57,7 +57,10 @@ and provides a fairly simple mechanism to execute a deployment.
+ Input parameters to the build script is:
+ -b Base URI to the configuration directory (needs to be provided in a URI
+ style, it can be a local resource: file:// or a remote resource http(s)://)
+--B PXE Bridge for booting of Fuel master, default is pxebr
++-B PXE Bridge for booting of Fuel master. It can be specified several times,
++ or as a comma separated list of bridges, or both: -B br1 -B br2,br3
++ One NIC connected to each specified bridge will be created in the Fuel VM,
++ in the same order as provided in the command line. The default is pxebr.
+ -d Dry-run - Produces deploy config files (config/dea.yaml and
+ config/dha.yaml), but does not execute deploy
+ -f Deploy on existing Fuel master
+@@ -130,9 +133,9 @@ do
+ fi
+ ;;
+ B)
+- if [[ ${OPTARG} ]]; then
+- PXE_BRIDGE="-b ${OPTARG}"
+- fi
++ for bridge in ${OPTARG//,/ }; do
++ PXE_BRIDGE+=" -b $bridge"
++ done
+ ;;
+ d)
+ DRY_RUN=1
diff --git a/patches/opnfv-fuel/0025-Fuel-VM-for-the-Enea-Armband-lab.patch b/patches/opnfv-fuel/0025-Fuel-VM-for-the-Enea-Armband-lab.patch
new file mode 100644
index 00000000..fbcd11d1
--- /dev/null
+++ b/patches/opnfv-fuel/0025-Fuel-VM-for-the-Enea-Armband-lab.patch
@@ -0,0 +1,106 @@
+From: Josep Puigdemont <josep.puigdemont@enea.com>
+Date: Wed, 4 May 2016 14:27:23 +0200
+Subject: [PATCH] Fuel VM for the Enea Armband lab
+
+This is the initial VM description fit for Enea's Armband lab.
+
+Signed-off-by: Josep Puigdemont <josep.puigdemont@enea.com>
+---
+ .../hardware_environment/vms/enea_lab/fuel.xml | 88 ++++++++++++++++++++++
+ 1 file changed, 88 insertions(+)
+ create mode 100644 deploy/templates/hardware_environment/vms/enea_lab/fuel.xml
+
+diff --git a/deploy/templates/hardware_environment/vms/enea_lab/fuel.xml b/deploy/templates/hardware_environment/vms/enea_lab/fuel.xml
+new file mode 100644
+index 0000000..8773ed4
+--- /dev/null
++++ b/deploy/templates/hardware_environment/vms/enea_lab/fuel.xml
+@@ -0,0 +1,88 @@
++<domain type='kvm' id='1'>
++ <name>fuel</name>
++ <memory unit='KiB'>8290304</memory>
++ <currentMemory unit='KiB'>8290304</currentMemory>
++ <vcpu placement='static'>8</vcpu>
++ <resource>
++ <partition>/machine</partition>
++ </resource>
++ <os>
++ <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
++ <boot dev='cdrom'/>
++ <boot dev='hd'/>
++ <bootmenu enable='no'/>
++ </os>
++ <features>
++ <acpi/>
++ <apic/>
++ <pae/>
++ </features>
++ <cpu mode='host-model'>
++ <model fallback='allow'/>
++ </cpu>
++ <clock offset='utc'>
++ <timer name='rtc' tickpolicy='catchup'/>
++ <timer name='pit' tickpolicy='delay'/>
++ <timer name='hpet' present='no'/>
++ </clock>
++ <on_poweroff>destroy</on_poweroff>
++ <on_reboot>restart</on_reboot>
++ <on_crash>restart</on_crash>
++ <pm>
++ <suspend-to-mem enabled='no'/>
++ <suspend-to-disk enabled='no'/>
++ </pm>
++ <devices>
++ <emulator>/usr/libexec/qemu-kvm</emulator>
++ <disk type='file' device='disk'>
++ <driver name='qemu' type='qcow2'/>
++ <target dev='vda' bus='virtio'/>
++ </disk>
++ <disk type='block' device='cdrom'>
++ <driver name='qemu' type='raw'/>
++ <target dev='hdb' bus='ide'/>
++ <readonly/>
++ </disk>
++ <controller type='usb' index='0' model='ich9-ehci1'>
++ </controller>
++ <controller type='usb' index='0' model='ich9-uhci1'>
++ <master startport='0'/>
++ </controller>
++ <controller type='usb' index='0' model='ich9-uhci2'>
++ <master startport='2'/>
++ </controller>
++ <controller type='usb' index='0' model='ich9-uhci3'>
++ <master startport='4'/>
++ </controller>
++ <controller type='pci' index='0' model='pci-root'>
++ </controller>
++ <controller type='ide' index='0'>
++ </controller>
++ <controller type='virtio-serial' index='0'>
++ </controller>
++ <interface type='bridge'>
++ <model type='virtio'/>
++ </interface>
++ <interface type='bridge'>
++ <model type='virtio'/>
++ </interface>
++ <serial type='pty'>
++ <source path='/dev/pts/0'/>
++ <target port='0'/>
++ </serial>
++ <console type='pty' tty='/dev/pts/0'>
++ <source path='/dev/pts/0'/>
++ <target type='serial' port='0'/>
++ </console>
++ <input type='mouse' bus='ps2'/>
++ <input type='keyboard' bus='ps2'/>
++ <graphics type='vnc' port='5906' autoport='yes' listen='127.0.0.1'>
++ <listen type='address' address='127.0.0.1'/>
++ </graphics>
++ <video>
++ <model type='vga' vram='16384' heads='1'/>
++ </video>
++ <memballoon model='virtio'>
++ </memballoon>
++ </devices>
++</domain>
diff --git a/patches/opnfv-fuel/0026-f_repobuild-Repeat-mirror-build-up-to-ten-times.patch b/patches/opnfv-fuel/0026-f_repobuild-Repeat-mirror-build-up-to-ten-times.patch
new file mode 100644
index 00000000..0b1f92f1
--- /dev/null
+++ b/patches/opnfv-fuel/0026-f_repobuild-Repeat-mirror-build-up-to-ten-times.patch
@@ -0,0 +1,73 @@
+From: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
+Date: Sun, 8 May 2016 22:37:43 +0200
+Subject: [PATCH] f_repobuild: Repeat mirror build up to ten times.
+
+OPNFV ISO build uses fuel-mirror to create a local Ubuntu
+partial mirror in nailgun.
+
+Work around temporary mirror issue (e.g. during rsync) by
+retrying mirror build up to 10 times.
+
+Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
+---
+ build/f_isoroot/f_repobuild/Makefile | 6 +++++-
+ build/f_isoroot/f_repobuild/fuel_mirror_loop | 26 ++++++++++++++++++++++++++
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+ create mode 100755 build/f_isoroot/f_repobuild/fuel_mirror_loop
+
+diff --git a/build/f_isoroot/f_repobuild/Makefile b/build/f_isoroot/f_repobuild/Makefile
+index 5e7157b..9abe9bb 100644
+--- a/build/f_isoroot/f_repobuild/Makefile
++++ b/build/f_isoroot/f_repobuild/Makefile
+@@ -23,6 +23,9 @@ export OPENSTACK_VERSION
+ .PHONY: all
+ all: nailgun
+
++nailgun_mirror:
++ sudo fuel-mirror --debug --config ./opnfv-config.yaml create --group ubuntu --pattern=ubuntu
++
+ nailgun:
+ sudo apt-get install -y git libxml2-dev libxslt-dev python-dev python-pip libz-dev libyaml-dev createrepo python-yaml
+ # python-debian from Ubuntu can't parse foreign arch relationships, use pip
+@@ -35,7 +38,8 @@ nailgun:
+ sudo pip install ./fuel-mirror
+ sudo pip install ./fuel-mirror/contrib/fuel_mirror
+ ./opnfv_mirror_conf.py
+- sudo fuel-mirror --debug --config ./opnfv-config.yaml create --group ubuntu --pattern=ubuntu
++ # Repeat mirror build up to ten times
++ sudo -E ./fuel_mirror_loop
+ sudo chmod -R 755 /var/www/nailgun
+ cp -Rp /var/www/nailgun .
+ # On the end we want to have ubuntu repository in mirrors/ubuntu directory
+diff --git a/build/f_isoroot/f_repobuild/fuel_mirror_loop b/build/f_isoroot/f_repobuild/fuel_mirror_loop
+new file mode 100755
+index 0000000..f123cf2
+--- /dev/null
++++ b/build/f_isoroot/f_repobuild/fuel_mirror_loop
+@@ -0,0 +1,26 @@
++#!/bin/bash
++##############################################################################
++# Copyright (c) 2016 Ericsson AB and others.
++# Copyright (c) 2016 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
++##############################################################################
++
++maxcount=10
++cnt=0
++rc=1
++while [ $cnt -lt $maxcount ] && [ $rc -ne 0 ]
++do
++ cnt=$[cnt + 1]
++ echo -e "\n\n\n*** Starting mirror build attempt # $cnt"
++ make nailgun_mirror
++ rc=$?
++ if [ $rc -ne 0 ]; then
++ echo "### Mirror build failed with rc $rc ###"
++ else
++ echo "### Mirror build successful at attempt # $cnt"
++ fi
++done
++exit $rc
diff --git a/upstream/fuel-plugin-ovsnfv b/upstream/fuel-plugin-ovsnfv
deleted file mode 160000
-Subproject 8a312b9535b2f3fe721139ed37722a13d1a940b
diff --git a/upstream/fuel-plugin-qemu b/upstream/fuel-plugin-qemu
deleted file mode 160000
-Subproject 1eb8bf930e2ec6e64526e95fcb21124f7401a24