diff options
Diffstat (limited to 'fuel/deploy')
52 files changed, 5767 insertions, 2486 deletions
diff --git a/fuel/deploy/README b/fuel/deploy/README new file mode 100644 index 000000000..167078bf8 --- /dev/null +++ b/fuel/deploy/README @@ -0,0 +1,186 @@ + +======== PREREQUISITES ======== + +the following dependencies and python modules are required to be installed: + +- for Ubuntu: + +sudo apt-get install -y libvirt-bin qemu-kvm python-pip fuseiso mkisofs +sudo apt-get install -y python-dev libz-dev libxml2-dev libxslt-dev +sudo pip install pyyaml netaddr paramiko lxml scp pycrypto ecdsa + +During libvirt install the user is added to the libvirtd group, so you have to +logout then login back again + + +======== PREPARE and RUN the OPNFV Autodeployment ======== + + +--- Step.1 Prepare the DEA and DHA configuration files and the OPNFV ISO file + +Make sure that you are using the right DEA - Deployment Environment Adapter and +DHA - Deployment Hardware Adapter configuration files, the ones provided are only templates +you will have to modify them according to your needs + +- If wou wish to deploy OPNFV cloud environment on top of KVM/Libvirt + virtualization use as example the following configuration files: + + * SR1 configuration files + + => templates/virtual_environment/conf/ha + dea.yaml + dha.yaml + + + * ARNO configuration files + + => templates/virtual_environment/old_conf/ha + dea.yaml + dha.yaml + + => templates/virtual_environment/old_conf/multinode + dea.yaml + dha.yaml + + +- If you wish to deploy OPNFV cloud environment on hardware + use as example the following configuration files: + + * SR1 configuration files + + => templates/hardware_environment/conf/ericsson_montreal_lab/ha + dea.yaml + dha.yaml + + => templates/hardware_environment/conf/linux_foundation_lab/pod1/ha + dea.yaml + dha.yaml + + => templates/hardware_environment/conf/linux_foundation_lab/pod2/ha + dea.yaml + dha.yaml + + + * ARNO configuration files + + => templates/hardware_environment/old_conf/ericsson_montreal_lab/ha + dea.yaml + dha.yaml + + => templates/hardware_environment/old_conf/ericsson_montreal_lab/multinode + dea.yaml + dha.yaml + + => templates/hardware_environment/old_conf/linux_foundation_lab/ha + dea.yaml + dha.yaml + + => templates/hardware_environment/old_conf/linux_foundation_lab/multinode + dea.yaml + dha.yaml + + +--- Step.2 Run Autodeployment --- + +usage: python deploy.py [-h] [-nf] [-nh] [-fo] [-co] [-c] [-iso [ISO_FILE]] + [-dea [DEA_FILE]] [-dha [DHA_FILE]] [-s STORAGE_DIR] + [-b PXE_BRIDGE] [-p FUEL_PLUGINS_DIR] + +optional arguments: + -h, --help show this help message and exit + -nf Do not install Fuel Master (and Node VMs when using libvirt) + -nh Don't run health check after deployment + -fo Install Fuel Master only (and Node VMs when using libvirt) + -co Cleanup VMs and Virtual Networks according to what is + defined in DHA + -c Cleanup after deploy + -iso [ISO_FILE] ISO File [default: OPNFV.iso] + -dea [DEA_FILE] Deployment Environment Adapter: dea.yaml + -dha [DHA_FILE] Deployment Hardware Adapter: dha.yaml + -s STORAGE_DIR Storage Directory [default: images] + -b PXE_BRIDGE Linux Bridge for booting up the Fuel Master VM + [default: pxebr] + -p FUEL_PLUGINS_DIR Fuel Plugins directory + + +* EXAMPLES: + +- Install Fuel Master and deploy OPNFV Cloud from scratch on Hardware Environment: + + sudo python deploy.py -iso ~/ISO/opnfv.iso -dea ~/CONF/hardware/dea.yaml -dha ~/CONF/hardware/dha.yaml -s /mnt/images -b pxebr + + +- Install Fuel Master and deploy OPNFV Cloud from scratch on Virtual Environment: + + sudo python deploy.py -iso ~/ISO/opnfv.iso -dea ~/CONF/virtual/dea.yaml -dha ~/CONF/virtual/dha.yaml -s /mnt/images + + +- Deploy OPNFV Cloud on an already active Environment where Fuel Master VM is running so no need to install Fuel again: + + sudo python deploy.py -nf -dea ~/CONF/virtual/dea.yaml -dha ~/CONF/virtual/dha.yaml + + => with plugin installation + sudo python deploy.py -nf -dea ~/CONF/virtual/dea.yaml -dha ~/CONF/virtual/dha.yaml + + => with cleanup after deployment is finished + sudo python deploy.py -nf -dea ~/CONF/virtual/dea.yaml -dha ~/CONF/virtual/dha.yaml -c + + => no healthcheck after deployment is completed + sudo python deploy.py -nf -dea ~/CONF/virtual/dea.yaml -dha ~/CONF/virtual/dha.yaml -nh + + +- Install Fuel Master only (and Node VMs when using virtual environment): + + => for virtual environment: + sudo python deploy.py -iso ~/ISO/opnfv.iso -dea ~/CONF/virtual/dea.yaml -dha ~/CONF/virtual/dha.yaml -s /mnt/images + + => for hardware environment: + sudo python deploy.py -iso ~/ISO/opnfv.iso -dea ~/CONF/hardware/dea.yaml -dha ~/CONF/hardware/dha.yaml -s /mnt/images -b pxebr + + +- Cleanup a running OPNFV environment: + + sudo python deploy.py -co -dha ~/CONF/virtual/dha.yaml + + +* WARNINGS: + +=> If optional argument -s <storage_dir> is not specified, Autodeployment will use +"<current_working_dir>/images" as default, and it will create it, if it hasn't been created before + +=> If optional argument -b <pxe_bridge> is not specified, Autodeployment will use "pxebr" as default, +if the bridge does not exist, the application will terminate with an error message + +=> If argument -iso [ISO_FILE] is not specified, Autodeployment will use "<current_working_dir>/OPNFV.iso" +as default, if the iso file does not exist, the application will terminate with an error message + +=> If argument -dea [DEA_FILE] is not specified, Autodeployment will use "<current_working_dir>/dea.yaml" +as default, if DEA file does not exist, the application will terminate with an error message + +=> If argument -dha [DHA_FILE] is not specified, Autodeployment will use "<current_working_dir>/dha.yaml" +as default, if DHA file does not exist, the application will terminate with an error message + +=> Optional argument -b PXE_BRIDGE is not required for Autodeployment in virtual environment, + even if it is specified it will not be used at all because virtual environment is using a different virtual network setup + +=> If optional argument -p FUEL_PLUGINS_DIR is not specified, no external plugins will be installed in Fuel + + +--- Networking considerations --- + +For Virtual Environment: + +There are some NAT, IPTABLE conflicts on the edge of libvirt bridging and Fuel Master +according to http://wiki.libvirt.org/page/Networking +netfilter on the bridges should be disabled + +Add these lines to /etc/sysctl.conf + +cat >> /etc/sysctl.conf <<EOF +net.bridge.bridge-nf-call-ip6tables = 0 +net.bridge.bridge-nf-call-iptables = 0 +net.bridge.bridge-nf-call-arptables = 0 +EOF + +and then reload configuration: +sysctl -p /etc/sysctl.conf diff --git a/fuel/deploy/README.txt b/fuel/deploy/README.txt deleted file mode 100644 index d392f8f65..000000000 --- a/fuel/deploy/README.txt +++ /dev/null @@ -1,71 +0,0 @@ - -======== How to prepare and run the OPNFV Autodeployment ======= - -in fuel/build/deploy run these: - - - ---- Step.1 Install prerequisites - -sudo ./install-ubuntu-packages.sh - - - - - - ---- Step.2-A If wou want to deploy OPNFV cloud environment on top of KVM/Libvirt virtualization - run the following environment setup script - -sudo python setup_environment.py <storage_directory> <path_to_dha_file> - -Example: - sudo python setup_environment.py /mnt/images dha.yaml - - - - - - ---- Step.2-B If you want to deploy OPNFV cloud environment on baremetal run the - following environment setup script - -sudo python setup_vfuel.py <storage_directory> <path_to_dha_file> - -Example: - sudo python setup_vfuel.py /mnt/images dha.yaml - - -WARNING!: -setup_vfuel.py adds the following snippet into /etc/network/interfaces -making sure to replace in setup_vfuel.py interfafe 'p1p1.20' with your actual outbound -interface in order to provide network access to the Fuel master for DNS and NTP. - -iface vfuelnet inet static - bridge_ports em1 - address 10.40.0.1 - netmask 255.255.255.0 - pre-down iptables -t nat -D POSTROUTING --out-interface p1p1.20 -j MASQUERADE -m comment --comment "vfuelnet" - pre-down iptables -D FORWARD --in-interface vfuelnet --out-interface p1p1.20 -m comment --comment "vfuelnet" - post-up iptables -t nat -A POSTROUTING --out-interface p1p1.20 -j MASQUERADE -m comment --comment "vfuelnet" - post-up iptables -A FORWARD --in-interface vfuelnet --out-interface p1p1.20 -m comment --comment "vfuelnet" - - - - - - ---- Step.3 Start Autodeployment -Make sure you use the right Deployment Environment Adapter and -Deployment Hardware Adaper configuration files: - - - for baremetal: baremetal/dea.yaml baremetal/dha.yaml - - - for libvirt: libvirt/dea.yaml libvirt/dha.yaml - - -sudo python deploy.py [-nf] <isofile> <deafile> <dhafile> - -Example: - sudo python deploy.py ~/ISO/opnfv.iso baremetal/dea.yaml baremetal/dha.yaml - diff --git a/fuel/deploy/__init__.py b/fuel/deploy/__init__.py index e69de29bb..fb73157f9 100644 --- a/fuel/deploy/__init__.py +++ b/fuel/deploy/__init__.py @@ -0,0 +1,8 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### diff --git a/fuel/deploy/baremetal/dea.yaml b/fuel/deploy/baremetal/dea.yaml deleted file mode 100644 index eb3019cab..000000000 --- a/fuel/deploy/baremetal/dea.yaml +++ /dev/null @@ -1,982 +0,0 @@ -title: Deployment Environment Adapter (DEA) -# DEA API version supported -version: 1.1 -created: Tue May 5 15:33:07 UTC 2015 -comment: Test environment Ericsson Montreal -environment_name: opnfv -environment_mode: multinode -wanted_release: Juno on Ubuntu 12.04.4 -nodes: -- id: 1 - interfaces: interface1 - transformations: controller1 - role: controller -- id: 2 - interfaces: interface1 - transformations: compute1 - role: compute -fuel: - ADMIN_NETWORK: - ipaddress: 10.40.0.2 - netmask: 255.255.255.0 - dhcp_pool_start: 10.40.0.3 - dhcp_pool_end: 10.40.0.254 - DNS_UPSTREAM: 10.118.32.193 - DNS_DOMAIN: opnfvericsson.ca - DNS_SEARCH: opnfvericsson.ca - FUEL_ACCESS: - user: admin - password: admin - HOSTNAME: opnfv - NTP1: 0.ca.pool.ntp.org - NTP2: 1.ca.pool.ntp.org - NTP3: 2.ca.pool.ntp.org -interfaces: - interface1: - eth0: - - fuelweb_admin - eth2: - - public - - management - - storage - - private -transformations: - controller1: - - action: add-br - name: br-eth0 - - action: add-port - bridge: br-eth0 - name: eth0 - - action: add-br - name: br-eth1 - - action: add-port - bridge: br-eth1 - name: eth1 - - action: add-br - name: br-eth2 - - action: add-port - bridge: br-eth2 - name: eth2 - - action: add-br - name: br-eth3 - - action: add-port - bridge: br-eth3 - name: eth3 - - action: add-br - name: br-eth4 - - action: add-port - bridge: br-eth4 - name: eth4 - - action: add-br - name: br-eth5 - - action: add-port - bridge: br-eth5 - name: eth5 - - action: add-br - name: br-ex - - action: add-br - name: br-mgmt - - action: add-br - name: br-storage - - action: add-br - name: br-fw-admin - - action: add-patch - bridges: - - br-eth2 - - br-storage - tags: - - 220 - - 0 - vlan_ids: - - 220 - - 0 - - action: add-patch - bridges: - - br-eth2 - - br-mgmt - tags: - - 320 - - 0 - vlan_ids: - - 320 - - 0 - - action: add-patch - bridges: - - br-eth0 - - br-fw-admin - trunks: - - 0 - - action: add-patch - bridges: - - br-eth2 - - br-ex - tags: - - 120 - - 0 - vlan_ids: - - 120 - - 0 - - action: add-br - name: br-prv - - action: add-patch - bridges: - - br-eth2 - - br-prv - compute1: - - action: add-br - name: br-eth0 - - action: add-port - bridge: br-eth0 - name: eth0 - - action: add-br - name: br-eth1 - - action: add-port - bridge: br-eth1 - name: eth1 - - action: add-br - name: br-eth2 - - action: add-port - bridge: br-eth2 - name: eth2 - - action: add-br - name: br-eth3 - - action: add-port - bridge: br-eth3 - name: eth3 - - action: add-br - name: br-eth4 - - action: add-port - bridge: br-eth4 - name: eth4 - - action: add-br - name: br-eth5 - - action: add-port - bridge: br-eth5 - name: eth5 - - action: add-br - name: br-mgmt - - action: add-br - name: br-storage - - action: add-br - name: br-fw-admin - - action: add-patch - bridges: - - br-eth2 - - br-storage - tags: - - 220 - - 0 - vlan_ids: - - 220 - - 0 - - action: add-patch - bridges: - - br-eth2 - - br-mgmt - tags: - - 320 - - 0 - vlan_ids: - - 320 - - 0 - - action: add-patch - bridges: - - br-eth0 - - br-fw-admin - trunks: - - 0 - - action: add-br - name: br-prv - - action: add-patch - bridges: - - br-eth2 - - br-prv -opnfv: - compute: {} - controller: {} -network: - networking_parameters: - base_mac: fa:16:3e:00:00:00 - dns_nameservers: - - 10.118.32.193 - - 8.8.8.8 - floating_ranges: - - - 172.16.0.130 - - 172.16.0.254 - gre_id_range: - - 2 - - 65535 - internal_cidr: 192.168.111.0/24 - internal_gateway: 192.168.111.1 - net_l23_provider: ovs - segmentation_type: vlan - vlan_range: - - 2022 - - 2023 - networks: - - cidr: 172.16.0.0/24 - gateway: 172.16.0.1 - ip_ranges: - - - 172.16.0.2 - - 172.16.0.126 - meta: - assign_vip: true - cidr: 172.16.0.0/24 - configurable: true - floating_range_var: floating_ranges - ip_range: - - 172.16.0.2 - - 172.16.0.126 - map_priority: 1 - name: public - notation: ip_ranges - render_addr_mask: public - render_type: null - use_gateway: true - vlan_start: null - name: public - vlan_start: 120 - - cidr: 192.168.0.0/24 - gateway: null - ip_ranges: - - - 192.168.0.2 - - 192.168.0.254 - meta: - assign_vip: true - 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 - vlan_start: 101 - name: management - vlan_start: 320 - - cidr: 192.168.1.0/24 - gateway: null - ip_ranges: - - - 192.168.1.2 - - 192.168.1.254 - meta: - assign_vip: false - 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: 220 - - cidr: null - gateway: null - ip_ranges: [] - meta: - assign_vip: false - configurable: false - map_priority: 2 - name: private - neutron_vlan_range: true - notation: null - render_addr_mask: null - render_type: null - seg_type: vlan - use_gateway: false - vlan_start: null - name: private - vlan_start: null - - cidr: 10.40.0.0/24 - gateway: null - ip_ranges: - - - 10.40.0.3 - - 10.40.0.254 - meta: - assign_vip: false - 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 - type: text - value: admin@localhost - weight: 40 - metadata: - label: Access - weight: 10 - password: - description: Password for Administrator - label: password - 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$)(?![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$)(?![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: 40 - heat: - description: '' - label: '' - type: hidden - value: true - weight: 30 - metadata: - label: Additional Components - weight: 20 - murano: - description: If selected, Murano component will be installed - label: Install Murano - restrictions: - - cluster:net_provider != 'neutron' - type: checkbox - value: false - weight: 20 - 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 - label: Public Key - type: text - value: '' - weight: 70 - auto_assign_floating_ip: - description: If selected, OpenStack will automatically assign a floating IP - to a new instance - label: Auto assign floating IP - restrictions: - - cluster:net_provider == 'neutron' - type: checkbox - value: false - weight: 40 - compute_scheduler_driver: - label: Scheduler driver - type: radio - value: nova.scheduler.filter_scheduler.FilterScheduler - values: - - data: nova.scheduler.filter_scheduler.FilterScheduler - description: Currently the most advanced OpenStack scheduler. See the OpenStack - documentation for details. - label: Filter scheduler - - data: nova.scheduler.simple.SimpleScheduler - description: This is 'naive' scheduler which tries to find the least loaded - host - label: Simple scheduler - weight: 40 - debug: - description: Debug logging mode provides more information, but requires more - disk space. - label: OpenStack debug logging - type: checkbox - value: false - weight: 20 - disable_offload: - description: If set, generic segmentation offload (gso) and generic receive - offload (gro) on physical nics will be disabled. See ethtool man. - label: Disable generic offload on physical nics - restrictions: - - action: hide - condition: cluster:net_provider == 'neutron' and networking_parameters:segmentation_type - == 'gre' - type: checkbox - value: true - weight: 80 - libvirt_type: - label: Hypervisor type - type: radio - value: kvm - values: - - data: kvm - description: Choose this type of hypervisor if you run OpenStack on hardware - label: KVM - restrictions: - - settings:common.libvirt_type.value == 'vcenter' - - data: qemu - description: Choose this type of hypervisor if you run OpenStack on virtual - hosts. - label: QEMU - restrictions: - - settings:common.libvirt_type.value == 'vcenter' - - data: vcenter - description: Choose this type of hypervisor if you run OpenStack in a vCenter - environment. - label: vCenter - restrictions: - - settings:common.libvirt_type.value != 'vcenter' or cluster:net_provider - == 'neutron' - weight: 30 - metadata: - label: Common - weight: 30 - nova_quota: - description: Quotas are used to limit CPU and memory usage for tenants. Enabling - quotas will increase load on the Nova database. - label: Nova quotas - type: checkbox - value: false - weight: 25 - 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. - label: Resume guests state on host boot - type: checkbox - value: true - weight: 60 - 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. - label: Use qcow format for images - type: checkbox - value: true - weight: 50 - corosync: - group: - description: '' - label: Group - type: text - value: 226.94.1.1 - weight: 10 - metadata: - 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 - type: text - value: 10.118.32.193, 8.8.8.8 - weight: 10 - metadata: - label: Upstream DNS - weight: 90 - external_ntp: - metadata: - label: Upstream NTP - weight: 100 - ntp_list: - description: List of upstream NTP servers, separated by comma - label: NTP servers list - type: text - value: 0.pool.ntp.org, 1.pool.ntp.org - weight: 10 - kernel_params: - kernel: - description: Default kernel parameters - label: Initial parameters - type: text - value: console=ttyS0,9600 console=tty0 rootdelay=90 nomodeset - weight: 45 - metadata: - label: Kernel parameters - weight: 40 - neutron_mellanox: - metadata: - enabled: true - label: Mellanox Neutron components - 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 - nsx_plugin: - connector_type: - description: Default network transport type to use - label: NSX connector type - type: select - value: stt - values: - - data: gre - label: GRE - - data: ipsec_gre - label: GRE over IPSec - - data: stt - label: STT - - data: ipsec_stt - label: STT over IPSec - - data: bridge - label: Bridge - weight: 80 - l3_gw_service_uuid: - description: UUID for the default L3 gateway service to use with this cluster - label: L3 service UUID - regex: - error: Invalid L3 gateway service UUID - source: '[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}' - type: text - value: '' - weight: 50 - metadata: - enabled: false - label: VMware NSX - restrictions: - - action: hide - condition: cluster:net_provider != 'neutron' or networking_parameters:net_l23_provider - != 'nsx' - weight: 20 - nsx_controllers: - description: One or more IPv4[:port] addresses of NSX controller node, separated - by comma (e.g. 10.40.30.2,192.168.110.254:443) - label: NSX controller endpoint - regex: - error: Invalid controller endpoints, specify valid IPv4[:port] pair - source: ^(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])(:(6553[0-5]|655[0-2][\d]|65[0-4][\d]{2}|6[0-4][\d]{3}|5[\d]{4}|[\d][\d]{0,3}))?(,(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])(:(6553[0-5]|655[0-2][\d]|65[0-4][\d]{2}|6[0-4][\d]{3}|5[\d]{4}|[\d][\d]{0,3}))?)*$ - type: text - value: '' - weight: 60 - nsx_password: - description: Password for Administrator - label: NSX password - regex: - error: Empty password - source: \S - type: password - value: '' - weight: 30 - nsx_username: - description: NSX administrator's username - label: NSX username - regex: - error: Empty username - source: \S - type: text - value: admin - weight: 20 - packages_url: - description: URL to NSX specific packages - label: URL to NSX bits - regex: - error: Invalid URL, specify valid HTTP/HTTPS URL with IPv4 address (e.g. - http://10.20.0.2/nsx) - source: ^https?://(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])(:(6553[0-5]|655[0-2][\d]|65[0-4][\d]{2}|6[0-4][\d]{3}|5[\d]{4}|[\d][\d]{0,3}))?(/.*)?$ - type: text - value: '' - weight: 70 - replication_mode: - description: '' - label: NSX cluster has Service nodes - type: checkbox - value: true - weight: 90 - transport_zone_uuid: - description: UUID of the pre-existing default NSX Transport zone - label: Transport zone UUID - regex: - error: Invalid transport zone UUID - source: '[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}' - type: text - value: '' - weight: 40 - provision: - metadata: - label: Provision - restrictions: - - action: hide - condition: not ('experimental' in version:feature_groups) - weight: 80 - method: - description: Which provision method to use for this cluster. - label: Provision method - type: radio - value: cobbler - values: - - data: image - description: Copying pre-built images on a disk. - label: Image - - data: cobbler - description: Install from scratch using anaconda or debian-installer. - label: Classic (use anaconda or debian-installer) - public_network_assignment: - assign_to_all_nodes: - description: When disabled, public network will be assigned to controllers - and zabbix-server only - label: Assign public network to all nodes - type: checkbox - value: false - weight: 10 - metadata: - label: Public network assignment - restrictions: - - action: hide - condition: cluster:net_provider != 'neutron' - weight: 50 - 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) - restrictions: - - settings:common.libvirt_type.value == 'vcenter' - type: checkbox - value: false - 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) - type: checkbox - value: false - 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: - - settings:common.libvirt_type.value != 'vcenter' - 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' - type: checkbox - value: false - weight: 11 - metadata: - label: Storage - 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) - restrictions: - - settings:storage.images_ceph.value == false - type: checkbox - value: false - 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*$ - restrictions: - - settings:common.libvirt_type.value == 'vcenter' - type: text - value: '2' - weight: 85 - vc_datacenter: - description: Inventory path to a datacenter. If you want to use ESXi host - as datastore, it should be "ha-datacenter". - label: Datacenter name - regex: - error: Empty datacenter - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 65 - vc_datastore: - description: Datastore associated with the datacenter. - label: Datastore name - regex: - error: Empty datastore - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 60 - vc_host: - description: IP Address of vCenter/ESXi - label: vCenter/ESXi IP - regex: - error: Specify valid IPv4 address - source: ^(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])$ - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 45 - vc_image_dir: - description: The name of the directory where the glance images will be stored - in the VMware datastore. - label: Datastore Images directory - regex: - error: Empty images directory - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: /openstack_glance - weight: 70 - vc_password: - description: vCenter/ESXi admin password - label: Password - regex: - error: Empty password - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: password - value: '' - weight: 55 - vc_user: - description: vCenter/ESXi admin username - label: Username - regex: - error: Empty username - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 50 - 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:common.libvirt_type.value - == 'vcenter' - type: checkbox - value: false - weight: 20 - volumes_lvm: - description: Requires 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 - volumes_vmdk: - description: Configures Cinder to store volumes via VMware vCenter. - label: VMware vCenter for volumes (Cinder) - restrictions: - - settings:common.libvirt_type.value != 'vcenter' or settings:storage.volumes_lvm.value - == true - type: checkbox - value: false - weight: 15 - syslog: - metadata: - label: Syslog - 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 - 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 - vcenter: - cluster: - description: vCenter cluster name. If you have multiple clusters, use comma - to separate names - label: Cluster - regex: - error: Invalid cluster list - source: ^([^,\ ]+([\ ]*[^,\ ])*)(,[^,\ ]+([\ ]*[^,\ ])*)*$ - type: text - value: '' - weight: 40 - datastore_regex: - description: The Datastore regexp setting specifies the data stores to use - with Compute. For example, "nas.*". If you want to use all available datastores, - leave this field blank - label: Datastore regexp - regex: - error: Invalid datastore regexp - source: ^(\S.*\S|\S|)$ - type: text - value: '' - weight: 50 - host_ip: - description: IP Address of vCenter - label: vCenter IP - regex: - error: Specify valid IPv4 address - source: ^(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])$ - type: text - value: '' - weight: 10 - metadata: - label: vCenter - restrictions: - - action: hide - condition: settings:common.libvirt_type.value != 'vcenter' - weight: 20 - use_vcenter: - description: '' - label: '' - type: hidden - value: true - weight: 5 - vc_password: - description: vCenter admin password - label: Password - regex: - error: Empty password - source: \S - type: password - value: admin - weight: 30 - vc_user: - description: vCenter admin username - label: Username - regex: - error: Empty username - source: \S - type: text - value: admin - weight: 20 - vlan_interface: - description: Physical ESXi host ethernet adapter for VLAN networking (e.g. - vmnic1). If empty "vmnic0" is used by default - label: ESXi VLAN interface - restrictions: - - action: hide - condition: cluster:net_provider != 'nova_network' or networking_parameters:net_manager - != 'VlanManager' - type: text - value: '' - weight: 60 - zabbix: - metadata: - label: Zabbix Access - restrictions: - - action: hide - condition: not ('experimental' in version:feature_groups) - weight: 70 - password: - description: Password for Zabbix Administrator - label: password - type: password - value: zabbix - weight: 20 - username: - description: Username for Zabbix Administrator - label: username - type: text - value: admin - weight: 10 diff --git a/fuel/deploy/baremetal/dha.yaml b/fuel/deploy/baremetal/dha.yaml deleted file mode 100644 index 6240f0794..000000000 --- a/fuel/deploy/baremetal/dha.yaml +++ /dev/null @@ -1,53 +0,0 @@ -title: Deployment Hardware Adapter (DHA) -# DHA API version supported -version: 1.1 -created: Mon May 4 09:03:46 UTC 2015 -comment: Test environment Ericsson Montreal - -# Adapter to use for this definition -adapter: ipmi - -# Node list. -# Mandatory properties are id and role. -# The MAC address of the PXE boot interface for Fuel is not -# mandatory to be defined. -# All other properties are adapter specific. - -nodes: -- id: 1 - pxeMac: 14:58:D0:54:7A:28 - ipmiIp: 10.118.32.205 - ipmiUser: username - ipmiPass: password -- id: 2 - pxeMac: 14:58:D0:55:E2:E0 - ipmiIp: 10.118.32.202 - ipmiUser: username - ipmiPass: password -# Adding the Fuel node as node id 3 which may not be correct - please -# adjust as needed. -- id: 3 - libvirtName: vFuel - libvirtTemplate: vFuel - isFuel: yes - username: root - password: r00tme - -# Deployment power on strategy -# all: Turn on all nodes at once. There will be no correlation -# between the DHA and DEA node numbering. MAC addresses -# will be used to select the node roles though. -# sequence: Turn on the nodes in sequence starting with the lowest order -# node and wait for the node to be detected by Fuel. Not until -# the node has been detected and assigned a role will the next -# node be turned on. -powerOnStrategy: sequence - -# If fuelCustomInstall is set to true, Fuel is assumed to be installed by -# calling the DHA adapter function "dha_fuelCustomInstall()" with two -# arguments: node ID and the ISO file name to deploy. The custom install -# function is then to handle all necessary logic to boot the Fuel master -# from the ISO and then return. -# Allowed values: true, false -fuelCustomInstall: true - diff --git a/fuel/deploy/cloud/configure_environment.py b/fuel/deploy/cloud/configure_environment.py index d0037d729..2d68c1ba8 100644 --- a/fuel/deploy/cloud/configure_environment.py +++ b/fuel/deploy/cloud/configure_environment.py @@ -1,6 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + import common -import os -import shutil from configure_settings import ConfigureSettings from configure_network import ConfigureNetwork @@ -14,6 +21,9 @@ exec_cmd = common.exec_cmd parse = common.parse err = common.err log = common.log +delete = common.delete +create_dir_if_not_exists = common.create_dir_if_not_exists + class ConfigureEnvironment(object): @@ -21,7 +31,6 @@ class ConfigureEnvironment(object): self.env_id = None self.dea = dea self.yaml_config_dir = yaml_config_dir - self.env_name = self.dea.get_property('environment_name') self.release_id = release_id self.node_id_roles_dict = node_id_roles_dict self.required_networks = [] @@ -36,21 +45,20 @@ class ConfigureEnvironment(object): def configure_environment(self): log('Configure environment') - if os.path.exists(self.yaml_config_dir): - log('Deleting existing config directory %s' % self.yaml_config_dir) - shutil.rmtree(self.yaml_config_dir) - log('Creating new config directory %s' % self.yaml_config_dir) - os.makedirs(self.yaml_config_dir) - - mode = self.dea.get_property('environment_mode') + delete(self.yaml_config_dir) + create_dir_if_not_exists(self.yaml_config_dir) + env_name = self.dea.get_env_name() + env_mode = self.dea.get_env_mode() + env_net_segment_type = self.dea.get_env_net_segment_type() log('Creating environment %s release %s, mode %s, network-mode neutron' - ', net-segment-type vlan' % (self.env_name, self.release_id, mode)) + ', net-segment-type %s' + % (env_name, self.release_id, env_mode, env_net_segment_type)) exec_cmd('fuel env create --name %s --release %s --mode %s ' - '--network-mode neutron --net-segment-type vlan' - % (self.env_name, self.release_id, mode)) + '--network-mode neutron --net-segment-type %s' + % (env_name, self.release_id, env_mode, env_net_segment_type)) - if not self.env_exists(self.env_name): - err('Failed to create environment %s' % self.env_name) + if not self.env_exists(env_name): + err('Failed to create environment %s' % env_name) self.config_settings() self.config_network() self.config_nodes() @@ -68,6 +76,3 @@ class ConfigureEnvironment(object): nodes = ConfigureNodes(self.yaml_config_dir, self.env_id, self.node_id_roles_dict, self.dea) nodes.config_nodes() - - - diff --git a/fuel/deploy/cloud/configure_network.py b/fuel/deploy/cloud/configure_network.py index 295eb90bd..00278949d 100644 --- a/fuel/deploy/cloud/configure_network.py +++ b/fuel/deploy/cloud/configure_network.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import common import yaml import io @@ -11,6 +21,8 @@ parse = common.parse err = common.err check_file_exists = common.check_file_exists log = common.log +backup = common.backup + class ConfigureNetwork(object): @@ -41,6 +53,7 @@ class ConfigureNetwork(object): network_yaml = ('%s/network_%s.yaml' % (self.yaml_config_dir, self.env_id)) check_file_exists(network_yaml) + backup(network_yaml) network_config = self.dea.get_property('network') @@ -58,4 +71,4 @@ class ConfigureNetwork(object): network.update(net_id[network['name']]) with io.open(network_yaml, 'w') as stream: - yaml.dump(network_config, stream, default_flow_style=False)
\ No newline at end of file + yaml.dump(network_config, stream, default_flow_style=False) diff --git a/fuel/deploy/cloud/configure_nodes.py b/fuel/deploy/cloud/configure_nodes.py index 4d1315a5c..e76d222c0 100644 --- a/fuel/deploy/cloud/configure_nodes.py +++ b/fuel/deploy/cloud/configure_nodes.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import common import yaml import io @@ -12,6 +22,7 @@ parse = common.parse err = common.err check_file_exists = common.check_file_exists log = common.log +backup = common.backup class ConfigureNodes(object): @@ -26,7 +37,7 @@ class ConfigureNodes(object): log('Configure nodes') for node_id, roles_blade in self.node_id_roles_dict.iteritems(): exec_cmd('fuel node set --node-id %s --role %s --env %s' - % (node_id, ','.join(roles_blade[0]), self.env_id)) + % (node_id, roles_blade[0], self.env_id)) self.download_deployment_config() for node_id, roles_blade in self.node_id_roles_dict.iteritems(): @@ -37,22 +48,20 @@ class ConfigureNodes(object): self.upload_deployment_config() def modify_node_network_schemes(self, node_id, roles_blade): - log('Modify node network transformations in environment %s' - % self.env_id) + log('Modify network transformations for node %s' % node_id) type = self.dea.get_node_property(roles_blade[1], 'transformations') - transformations = self.dea.get_transformations(type) - - for node_file in glob.glob('%s/deployment_%s/*_%s.yaml' - % (self.yaml_config_dir, self.env_id, - node_id)): + transformations = self.dea.get_property(type) + deployment_dir = '%s/deployment_%s' % ( + self.yaml_config_dir, self.env_id) + backup(deployment_dir) + for node_file in glob.glob(deployment_dir + '/*_%s.yaml' % node_id): with io.open(node_file) as stream: - node = yaml.load(stream) + node = yaml.load(stream) - node['network_scheme']['transformations'] = transformations + node['network_scheme'].update(transformations) with io.open(node_file, 'w') as stream: - yaml.dump(node, stream, default_flow_style=False) - + yaml.dump(node, stream, default_flow_style=False) def download_deployment_config(self): log('Download deployment config for environment %s' % self.env_id) @@ -79,6 +88,7 @@ class ConfigureNodes(object): interface_yaml = ('%s/node_%s/interfaces.yaml' % (self.yaml_config_dir, node_id)) check_file_exists(interface_yaml) + backup('%s/node_%s' % (self.yaml_config_dir, node_id)) with io.open(interface_yaml) as stream: interfaces = yaml.load(stream) @@ -86,10 +96,10 @@ class ConfigureNodes(object): net_name_id = {} for interface in interfaces: for network in interface['assigned_networks']: - net_name_id[network['name']] = network['id'] + net_name_id[network['name']] = network['id'] type = self.dea.get_node_property(roles_blade[1], 'interfaces') - interface_config = self.dea.get_interfaces(type) + interface_config = self.dea.get_property(type) for interface in interfaces: interface['assigned_networks'] = [] @@ -101,4 +111,4 @@ class ConfigureNodes(object): interface['assigned_networks'].append(net) with io.open(interface_yaml, 'w') as stream: - yaml.dump(interfaces, stream, default_flow_style=False)
\ No newline at end of file + yaml.dump(interfaces, stream, default_flow_style=False) diff --git a/fuel/deploy/cloud/configure_settings.py b/fuel/deploy/cloud/configure_settings.py index ac0afdc57..fa918fd3d 100644 --- a/fuel/deploy/cloud/configure_settings.py +++ b/fuel/deploy/cloud/configure_settings.py @@ -1,3 +1,12 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + import common import yaml import io @@ -11,6 +20,8 @@ parse = common.parse err = common.err check_file_exists = common.check_file_exists log = common.log +backup = common.backup + class ConfigureSettings(object): @@ -40,6 +51,7 @@ class ConfigureSettings(object): settings_yaml = ('%s/settings_%s.yaml' % (self.yaml_config_dir, self.env_id)) check_file_exists(settings_yaml) + backup(settings_yaml) settings = self.dea.get_property('settings') diff --git a/fuel/deploy/cloud/deploy.py b/fuel/deploy/cloud/deploy.py index c8714f8a6..705dda59c 100644 --- a/fuel/deploy/cloud/deploy.py +++ b/fuel/deploy/cloud/deploy.py @@ -1,7 +1,17 @@ -import time +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + +import os import yaml import io -import sys +import glob import common from dea import DeploymentEnvironmentAdapter @@ -19,188 +29,79 @@ parse = common.parse err = common.err check_file_exists = common.check_file_exists log = common.log +commafy = common.commafy +ArgParser = common.ArgParser + class Deploy(object): - def __init__(self, dea_file, macs_file): + def __init__(self, dea_file, blade_node_file, no_health_check): self.dea = DeploymentEnvironmentAdapter(dea_file) - self.macs_file = macs_file + self.blade_node_file = blade_node_file + self.no_health_check = no_health_check self.macs_per_blade = {} self.blades = self.dea.get_node_ids() - self.node_ids_dict = {} - self.node_id_roles_dict = {} - self.supported_release = None + self.blade_node_dict = {} + self.node_roles_dict = {} self.env_id = None - self.wanted_release = self.dea.get_wanted_release() - - def cleanup_fuel_environments(self, env_list): - WAIT_LOOP = 60 - SLEEP_TIME = 10 - for env in env_list: - log('Deleting environment %s' % env[E['id']]) - exec_cmd('fuel env --env %s --delete' % env[E['id']]) - all_env_erased = False - for i in range(WAIT_LOOP): - env_list = parse(exec_cmd('fuel env list')) - if env_list: - time.sleep(SLEEP_TIME) - else: - all_env_erased = True - break - if not all_env_erased: - err('Could not erase these environments %s' - % [(env[E['id']], env[E['status']]) for env in env_list]) - - def cleanup_fuel_nodes(self, node_list): - for node in node_list: - if node[N['status']] == 'discover': - log('Deleting node %s' % node[N['id']]) - exec_cmd('fuel node --node-id %s --delete-from-db' - % node[N['id']]) - exec_cmd('dockerctl shell cobbler cobbler system remove ' - '--name node-%s' % node[N['id']]) - - def check_previous_installation(self): - log('Check previous installation') - env_list = parse(exec_cmd('fuel env list')) - if env_list: - self.cleanup_fuel_environments(env_list) - node_list = parse(exec_cmd('fuel node list')) - if node_list: - self.cleanup_fuel_nodes(node_list) - - def check_supported_release(self): - log('Check supported release: %s' % self.wanted_release) - release_list = parse(exec_cmd('fuel release -l')) - for release in release_list: - if release[R['name']] == self.wanted_release: - self.supported_release = release - break - if not self.supported_release: - err('This Fuel does not contain the following release: %s' - % self.wanted_release) - - def check_prerequisites(self): - log('Check prerequisites') - self.check_supported_release() - self.check_previous_installation() - - def get_mac_addresses(self): - with io.open(self.macs_file, 'r') as stream: - self.macs_per_blade = yaml.load(stream) - - def find_mac_in_dict(self, mac): - for blade, mac_list in self.macs_per_blade.iteritems(): - if mac in mac_list: - return blade - - def all_blades_discovered(self): - for blade, node_id in self.node_ids_dict.iteritems(): - if not node_id: - return False - return True - - def not_discovered_blades_summary(self): - summary = '' - for blade, node_id in self.node_ids_dict.iteritems(): - if not node_id: - summary += '\n[blade %s]' % blade - return summary - - def node_discovery(self, node_list, discovered_macs): - for node in node_list: - if (node[N['status']] == 'discover' and - node[N['online']] == 'True' and - node[N['mac']] not in discovered_macs): - discovered_macs.append(node[N['mac']]) - blade = self.find_mac_in_dict(node[N['mac']]) - if blade: - log('Blade %s discovered as Node %s with MAC %s' - % (blade, node[N['id']], node[N['mac']])) - self.node_ids_dict[blade] = node[N['id']] - - def discovery_waiting_loop(self, discovered_macs): - WAIT_LOOP = 180 - SLEEP_TIME = 10 - all_discovered = False - for i in range(WAIT_LOOP): - node_list = parse(exec_cmd('fuel node list')) - if node_list: - self.node_discovery(node_list, discovered_macs) - if self.all_blades_discovered(): - all_discovered = True - break - else: - time.sleep(SLEEP_TIME) - return all_discovered - - def wait_for_discovered_blades(self): - log('Wait for discovered blades') - discovered_macs = [] - for blade in self.blades: - self.node_ids_dict[blade] = None - all_discovered = self.discovery_waiting_loop(discovered_macs) - if not all_discovered: - err('Not all blades have been discovered: %s' - % self.not_discovered_blades_summary()) + self.wanted_release = self.dea.get_property('wanted_release') + + def get_blade_node_mapping(self): + with io.open(self.blade_node_file, 'r') as stream: + self.blade_node_dict = yaml.load(stream) def assign_roles_to_cluster_node_ids(self): - self.node_id_roles_dict = {} - for blade, node_id in self.node_ids_dict.iteritems(): - role_list = [] - role = self.dea.get_node_role(blade) - if role == 'controller': - role_list.extend(['controller', 'mongo']) - elif role == 'compute': - role_list.extend(['compute']) - self.node_id_roles_dict[node_id] = (role_list, blade) + self.node_roles_dict = {} + for blade, node in self.blade_node_dict.iteritems(): + roles = commafy(self.dea.get_node_role(blade)) + self.node_roles_dict[node] = (roles, blade) def configure_environment(self): + release_list = parse(exec_cmd('fuel release -l')) + for release in release_list: + if release[R['name']] == self.wanted_release: + break config_env = ConfigureEnvironment(self.dea, YAML_CONF_DIR, - self.supported_release[R['id']], - self.node_id_roles_dict) + release[R['id']], + self.node_roles_dict) config_env.configure_environment() self.env_id = config_env.env_id def deploy_cloud(self): dep = Deployment(self.dea, YAML_CONF_DIR, self.env_id, - self.node_id_roles_dict) + self.node_roles_dict, self.no_health_check) dep.deploy() def deploy(self): - self.get_mac_addresses() - self.check_prerequisites() - self.wait_for_discovered_blades() + + self.get_blade_node_mapping() + self.assign_roles_to_cluster_node_ids() + self.configure_environment() - self.deploy_cloud() -def usage(): - print ''' - Usage: - python deploy.py <dea_file> <macs_file> + self.deploy_cloud() - Example: - python deploy.py dea.yaml macs.yaml - ''' def parse_arguments(): - if len(sys.argv) != 3: - log('Incorrect number of arguments') - usage() - sys.exit(1) - dea_file = sys.argv[-2] - macs_file = sys.argv[-1] - check_file_exists(dea_file) - check_file_exists(macs_file) - return dea_file, macs_file + parser = ArgParser(prog='python %s' % __file__) + parser.add_argument('-nh', dest='no_health_check', action='store_true', + default=False, + help='Don\'t run health check after deployment') + parser.add_argument('dea_file', action='store', + help='Deployment Environment Adapter: dea.yaml') + parser.add_argument('blade_node_file', action='store', + help='Blade Node mapping: blade_node.yaml') + args = parser.parse_args() + check_file_exists(args.dea_file) + check_file_exists(args.blade_node_file) + return (args.dea_file, args.blade_node_file, args.no_health_check) -def main(): - dea_file, macs_file = parse_arguments() - - deploy = Deploy(dea_file, macs_file) +def main(): + dea_file, blade_node_file, no_health_check = parse_arguments() + deploy = Deploy(dea_file, blade_node_file, no_health_check) deploy.deploy() if __name__ == '__main__': - main()
\ No newline at end of file + main() diff --git a/fuel/deploy/cloud/deployment.py b/fuel/deploy/cloud/deployment.py index cf56c3630..90f24fd0b 100644 --- a/fuel/deploy/cloud/deployment.py +++ b/fuel/deploy/cloud/deployment.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import common import os import shutil @@ -19,42 +29,13 @@ log = common.log class Deployment(object): - def __init__(self, dea, yaml_config_dir, env_id, node_id_roles_dict): + def __init__(self, dea, yaml_config_dir, env_id, node_id_roles_dict, + no_health_check): self.dea = dea self.yaml_config_dir = yaml_config_dir self.env_id = env_id self.node_id_roles_dict = node_id_roles_dict - - def download_deployment_info(self): - log('Download deployment info for environment %s' % self.env_id) - deployment_dir = '%s/deployment_%s' \ - % (self.yaml_config_dir, self.env_id) - if os.path.exists(deployment_dir): - shutil.rmtree(deployment_dir) - exec_cmd('fuel --env %s deployment --default --dir %s' - % (self.env_id, self.yaml_config_dir)) - - def upload_deployment_info(self): - log('Upload deployment info for environment %s' % self.env_id) - exec_cmd('fuel --env %s deployment --upload --dir %s' - % (self.env_id, self.yaml_config_dir)) - - def config_opnfv(self): - log('Configure OPNFV settings on environment %s' % self.env_id) - opnfv_compute = self.dea.get_opnfv('compute') - opnfv_controller = self.dea.get_opnfv('controller') - self.download_deployment_info() - for node_file in glob.glob('%s/deployment_%s/*.yaml' - % (self.yaml_config_dir, self.env_id)): - with io.open(node_file) as stream: - node = yaml.load(stream) - if node['role'] == 'compute': - node.update(opnfv_compute) - else: - node.update(opnfv_controller) - with io.open(node_file, 'w') as stream: - yaml.dump(node, stream, default_flow_style=False) - self.upload_deployment_info() + self.no_health_check = no_health_check def run_deploy(self): WAIT_LOOP = 180 @@ -75,7 +56,8 @@ class Deployment(object): if env[0][E['status']] == 'operational': ready = True break - elif env[0][E['status']] == 'error': + elif (env[0][E['status']] == 'error' + or env[0][E['status']] == 'stopped'): break else: time.sleep(SLEEP_TIME) @@ -102,12 +84,14 @@ class Deployment(object): def health_check(self): log('Now running sanity and smoke health checks') - exec_cmd('fuel health --env %s --check sanity,smoke --force' - % self.env_id) - log('Health checks passed !') + r = exec_cmd('fuel health --env %s --check sanity,smoke --force' + % self.env_id) + log(r) + if 'failure' in r: + err('Healthcheck failed!') def deploy(self): - self.config_opnfv() self.run_deploy() self.verify_node_status() - self.health_check()
\ No newline at end of file + if not self.no_health_check: + self.health_check() diff --git a/fuel/deploy/common.py b/fuel/deploy/common.py index 6dbda67f3..2a8c0d149 100644 --- a/fuel/deploy/common.py +++ b/fuel/deploy/common.py @@ -1,7 +1,20 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + import subprocess import sys import os import logging +import argparse +import shutil +import stat +import errno N = {'id': 0, 'status': 1, 'name': 2, 'cluster': 3, 'ip': 4, 'mac': 5, 'roles': 6, 'pending_roles': 7, 'online': 8} @@ -9,7 +22,7 @@ E = {'id': 0, 'status': 1, 'name': 2, 'mode': 3, 'release_id': 4, 'changes': 5, 'pending_release_id': 6} R = {'id': 0, 'name': 1, 'state': 2, 'operating_system': 3, 'version': 4} RO = {'name': 0, 'conflicts': 1} - +CWD = os.getcwd() LOG = logging.getLogger(__name__) LOG.setLevel(logging.DEBUG) formatter = logging.Formatter('%(message)s') @@ -19,6 +32,7 @@ LOG.addHandler(out_handler) out_handler = logging.FileHandler('autodeploy.log', mode='w') out_handler.setFormatter(formatter) LOG.addHandler(out_handler) +os.chmod('autodeploy.log', stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) def exec_cmd(cmd, check=True): process = subprocess.Popen(cmd, @@ -34,6 +48,7 @@ def exec_cmd(cmd, check=True): return response return response, return_code + def run_proc(cmd): process = subprocess.Popen(cmd, stdout=subprocess.PIPE, @@ -41,14 +56,16 @@ def run_proc(cmd): shell=True) return process + def parse(printout): parsed_list = [] lines = printout.splitlines() for l in lines[2:]: - parsed = [e.strip() for e in l.split('|')] - parsed_list.append(parsed) + parsed = [e.strip() for e in l.split('|')] + parsed_list.append(parsed) return parsed_list + def clean(lines): parsed_list = [] parsed = [] @@ -61,22 +78,76 @@ def clean(lines): parsed_list.append(parsed) return parsed if len(parsed_list) == 1 else parsed_list + def err(message): LOG.error('%s\n' % message) sys.exit(1) + +def warn(message): + LOG.warning('%s\n' % message) + + def check_file_exists(file_path): + if not os.path.dirname(file_path): + file_path = '%s/%s' % (CWD, file_path) if not os.path.isfile(file_path): err('ERROR: File %s not found\n' % file_path) + def check_dir_exists(dir_path): + if not os.path.dirname(dir_path): + dir_path = '%s/%s' % (CWD, dir_path) if not os.path.isdir(dir_path): err('ERROR: Directory %s not found\n' % dir_path) + +def create_dir_if_not_exists(dir_path): + if not os.path.isdir(dir_path): + log('Creating directory %s' % dir_path) + os.makedirs(dir_path) + + +def delete(f): + if os.path.isfile(f): + log('Deleting file %s' % f) + os.remove(f) + elif os.path.isdir(f): + log('Deleting directory %s' % f) + shutil.rmtree(f) + + +def commafy(comma_separated_list): + l = [c.strip() for c in comma_separated_list.split(',')] + return ','.join(l) + + def check_if_root(): r = exec_cmd('whoami') if r != 'root': err('You need be root to run this application') + def log(message): LOG.debug('%s\n' % message) + + +class ArgParser(argparse.ArgumentParser): + + def error(self, message): + sys.stderr.write('ERROR: %s\n' % message) + self.print_help() + sys.exit(2) + + +def backup(path): + src = path + dst = path + '_orig' + delete(dst) + try: + shutil.copytree(src, dst) + except OSError as e: + if e.errno == errno.ENOTDIR: + shutil.copy(src, dst) + else: + raise diff --git a/fuel/deploy/dea.py b/fuel/deploy/dea.py index 8066b6ae2..5f1a41547 100644 --- a/fuel/deploy/dea.py +++ b/fuel/deploy/dea.py @@ -1,8 +1,20 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import yaml import io import netaddr + class DeploymentEnvironmentAdapter(object): + def __init__(self, yaml_path): self.dea_struct = None self.parse_yaml(yaml_path) @@ -19,6 +31,15 @@ class DeploymentEnvironmentAdapter(object): with io.open(yaml_path) as yaml_file: self.dea_struct = yaml.load(yaml_file) + def get_env_name(self): + return self.get_property('environment')['name'] + + def get_env_mode(self): + return self.get_property('environment')['mode'] + + def get_env_net_segment_type(self): + return self.get_property('environment')['net_segment_type'] + def get_fuel_config(self): return self.dea_struct['fuel'] @@ -67,14 +88,12 @@ class DeploymentEnvironmentAdapter(object): def get_network_names(self): return self.network_names - def get_interfaces(self, type): - return self.dea_struct['interfaces'][type] - - def get_transformations(self, type): - return self.dea_struct['transformations'][type] - - def get_opnfv(self, role): - return {'opnfv': self.dea_struct['opnfv'][role]} + def get_dns_list(self): + settings = self.get_property('settings') + dns_list = settings['editable']['external_dns']['dns_list']['value'] + return [d.strip() for d in dns_list.split(',')] - def get_wanted_release(self): - return self.dea_struct['wanted_release']
\ No newline at end of file + def get_ntp_list(self): + settings = self.get_property('settings') + ntp_list = settings['editable']['external_ntp']['ntp_list']['value'] + return [n.strip() for n in ntp_list.split(',')] diff --git a/fuel/deploy/deploy.py b/fuel/deploy/deploy.py index 9d1a3d2c3..178ae76e2 100644 --- a/fuel/deploy/deploy.py +++ b/fuel/deploy/deploy.py @@ -1,33 +1,51 @@ -import sys +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import os -import shutil import io import re +import sys import netaddr +import yaml from dea import DeploymentEnvironmentAdapter from dha import DeploymentHardwareAdapter from install_fuel_master import InstallFuelMaster from deploy_env import CloudDeploy +from execution_environment import ExecutionEnvironment import common log = common.log exec_cmd = common.exec_cmd err = common.err +warn = common.warn check_file_exists = common.check_file_exists +check_dir_exists = common.check_dir_exists +create_dir_if_not_exists = common.create_dir_if_not_exists +delete = common.delete check_if_root = common.check_if_root +ArgParser = common.ArgParser FUEL_VM = 'fuel' -TMP_DIR = '%s/fueltmp' % os.getenv('HOME') PATCH_DIR = 'fuel_patch' -WORK_DIR = 'deploy' +WORK_DIR = '~/deploy' +CWD = os.getcwd() + class cd: + def __init__(self, new_path): self.new_path = os.path.expanduser(new_path) def __enter__(self): - self.saved_path = os.getcwd() + self.saved_path = CWD os.chdir(self.new_path) def __exit__(self, etype, value, traceback): @@ -36,31 +54,27 @@ class cd: class AutoDeploy(object): - def __init__(self, without_fuel, iso_file, dea_file, dha_file): - self.without_fuel = without_fuel + def __init__(self, no_fuel, fuel_only, no_health_check, cleanup_only, + cleanup, storage_dir, pxe_bridge, iso_file, dea_file, + dha_file, fuel_plugins_dir): + self.no_fuel = no_fuel + self.fuel_only = fuel_only + self.no_health_check = no_health_check + self.cleanup_only = cleanup_only + self.cleanup = cleanup + self.storage_dir = storage_dir + self.pxe_bridge = pxe_bridge self.iso_file = iso_file self.dea_file = dea_file self.dha_file = dha_file - self.dea = DeploymentEnvironmentAdapter(dea_file) + self.fuel_plugins_dir = fuel_plugins_dir + self.dea = (DeploymentEnvironmentAdapter(dea_file) + if not cleanup_only else None) self.dha = DeploymentHardwareAdapter(dha_file) self.fuel_conf = {} self.fuel_node_id = self.dha.get_fuel_node_id() - self.fuel_custom = self.dha.use_fuel_custom_install() self.fuel_username, self.fuel_password = self.dha.get_fuel_access() - - def setup_dir(self, dir): - self.cleanup_dir(dir) - os.makedirs(dir) - - def cleanup_dir(self, dir): - if os.path.isdir(dir): - shutil.rmtree(dir) - - def power_off_blades(self): - node_ids = self.dha.get_all_node_ids() - node_ids = list(set(node_ids) - set([self.fuel_node_id])) - for node_id in node_ids: - self.dha.node_power_off(node_id) + self.tmp_dir = None def modify_ip(self, ip_addr, index, val): ip_str = str(netaddr.IPAddress(ip_addr)) @@ -77,11 +91,9 @@ class AutoDeploy(object): self.fuel_conf['showmenu'] = 'yes' def install_fuel_master(self): - if self.without_fuel: - log('Not Installing Fuel Master') - return log('Install Fuel Master') - new_iso = '%s/deploy-%s' % (TMP_DIR, os.path.basename(self.iso_file)) + new_iso = '%s/deploy-%s' \ + % (self.tmp_dir, os.path.basename(self.iso_file)) self.patch_iso(new_iso) self.iso_file = new_iso self.install_iso() @@ -90,40 +102,36 @@ class AutoDeploy(object): fuel = InstallFuelMaster(self.dea_file, self.dha_file, self.fuel_conf['ip'], self.fuel_username, self.fuel_password, self.fuel_node_id, - self.iso_file, WORK_DIR) - if self.fuel_custom: - log('Custom Fuel install') - fuel.custom_install() - else: - log('Ordinary Fuel install') - fuel.install() + self.iso_file, WORK_DIR, + self.fuel_plugins_dir) + fuel.install() def patch_iso(self, new_iso): - tmp_orig_dir = '%s/origiso' % TMP_DIR - tmp_new_dir = '%s/newiso' % TMP_DIR + tmp_orig_dir = '%s/origiso' % self.tmp_dir + tmp_new_dir = '%s/newiso' % self.tmp_dir self.copy(tmp_orig_dir, tmp_new_dir) self.patch(tmp_new_dir, new_iso) def copy(self, tmp_orig_dir, tmp_new_dir): log('Copying...') - self.setup_dir(tmp_orig_dir) - self.setup_dir(tmp_new_dir) + os.makedirs(tmp_orig_dir) + os.makedirs(tmp_new_dir) exec_cmd('fuseiso %s %s' % (self.iso_file, tmp_orig_dir)) with cd(tmp_orig_dir): exec_cmd('find . | cpio -pd %s' % tmp_new_dir) with cd(tmp_new_dir): exec_cmd('fusermount -u %s' % tmp_orig_dir) - shutil.rmtree(tmp_orig_dir) + delete(tmp_orig_dir) exec_cmd('chmod -R 755 %s' % tmp_new_dir) def patch(self, tmp_new_dir, new_iso): log('Patching...') - patch_dir = '%s/%s' % (os.getcwd(), PATCH_DIR) + patch_dir = '%s/%s' % (CWD, PATCH_DIR) ks_path = '%s/ks.cfg.patch' % patch_dir with cd(tmp_new_dir): exec_cmd('cat %s | patch -p0' % ks_path) - shutil.rmtree('.rr_moved') + delete('.rr_moved') isolinux = 'isolinux/isolinux.cfg' log('isolinux.cfg before: %s' % exec_cmd('grep netmask %s' % isolinux)) @@ -149,51 +157,152 @@ class AutoDeploy(object): f.write(data) def deploy_env(self): - dep = CloudDeploy(self.dha, self.fuel_conf['ip'], self.fuel_username, - self.fuel_password, self.dea_file, WORK_DIR) - dep.deploy() + dep = CloudDeploy(self.dea, self.dha, self.fuel_conf['ip'], + self.fuel_username, self.fuel_password, + self.dea_file, WORK_DIR, self.no_health_check) + return dep.deploy() + + def setup_execution_environment(self): + exec_env = ExecutionEnvironment(self.storage_dir, self.pxe_bridge, + self.dha_file, self.dea) + exec_env.setup_environment() + + def cleanup_execution_environment(self): + exec_env = ExecutionEnvironment(self.storage_dir, self.pxe_bridge, + self.dha_file, self.dea) + exec_env.cleanup_environment() + + def create_tmp_dir(self): + self.tmp_dir = '%s/fueltmp' % CWD + delete(self.tmp_dir) + create_dir_if_not_exists(self.tmp_dir) def deploy(self): - check_if_root() - self.setup_dir(TMP_DIR) self.collect_fuel_info() - self.power_off_blades() - self.install_fuel_master() - self.cleanup_dir(TMP_DIR) - self.deploy_env() + if not self.no_fuel: + self.setup_execution_environment() + self.create_tmp_dir() + self.install_fuel_master() + if not self.fuel_only: + return self.deploy_env() + return True + + def run(self): + check_if_root() + if self.cleanup_only: + self.cleanup_execution_environment() + else: + deploy_success = self.deploy() + if self.cleanup: + self.cleanup_execution_environment() + return deploy_success + return True -def usage(): - print ''' - Usage: - python deploy.py [-nf] <isofile> <deafile> <dhafile> +def check_bridge(pxe_bridge, dha_path): + with io.open(dha_path) as yaml_file: + dha_struct = yaml.load(yaml_file) + if dha_struct['adapter'] != 'libvirt': + log('Using Linux Bridge %s for booting up the Fuel Master VM' + % pxe_bridge) + r = exec_cmd('ip link show %s' % pxe_bridge) + if pxe_bridge in r and 'state DOWN' in r: + err('Linux Bridge {0} is not Active, bring' + ' it UP first: [ip link set dev {0} up]'.format(pxe_bridge)) + + +def check_fuel_plugins_dir(dir): + msg = None + if not dir: + msg = 'Fuel Plugins Directory not specified!' + elif not os.path.isdir(dir): + msg = 'Fuel Plugins Directory does not exist!' + elif not os.listdir(dir): + msg = 'Fuel Plugins Directory is empty!' + if msg: + warn('%s No external plugins will be installed!' % msg) - Optional arguments: - -nf Do not install Fuel master - ''' def parse_arguments(): - if (len(sys.argv) < 4 or len(sys.argv) > 5 - or (len(sys.argv) == 5 and sys.argv[1] != '-nf')): - log('Incorrect number of arguments') - usage() - sys.exit(1) - without_fuel = False - if len(sys.argv) == 5 and sys.argv[1] == '-nf': - without_fuel = True - iso_file = sys.argv[-3] - dea_file = sys.argv[-2] - dha_file = sys.argv[-1] - check_file_exists(iso_file) - check_file_exists(dea_file) - check_file_exists(dha_file) - return (without_fuel, iso_file, dea_file, dha_file) + parser = ArgParser(prog='python %s' % __file__) + parser.add_argument('-nf', dest='no_fuel', action='store_true', + default=False, + help='Do not install Fuel Master (and Node VMs when ' + 'using libvirt)') + parser.add_argument('-nh', dest='no_health_check', action='store_true', + default=False, + help='Don\'t run health check after deployment') + parser.add_argument('-fo', dest='fuel_only', action='store_true', + default=False, + help='Install Fuel Master only (and Node VMs when ' + 'using libvirt)') + parser.add_argument('-co', dest='cleanup_only', action='store_true', + default=False, + help='Cleanup VMs and Virtual Networks according to ' + 'what is defined in DHA') + parser.add_argument('-c', dest='cleanup', action='store_true', + default=False, + help='Cleanup after deploy') + if {'-iso', '-dea', '-dha', '-h'}.intersection(sys.argv): + parser.add_argument('-iso', dest='iso_file', action='store', nargs='?', + default='%s/OPNFV.iso' % CWD, + help='ISO File [default: OPNFV.iso]') + parser.add_argument('-dea', dest='dea_file', action='store', nargs='?', + default='%s/dea.yaml' % CWD, + help='Deployment Environment Adapter: dea.yaml') + parser.add_argument('-dha', dest='dha_file', action='store', nargs='?', + default='%s/dha.yaml' % CWD, + help='Deployment Hardware Adapter: dha.yaml') + else: + parser.add_argument('iso_file', action='store', nargs='?', + default='%s/OPNFV.iso' % CWD, + help='ISO File [default: OPNFV.iso]') + parser.add_argument('dea_file', action='store', nargs='?', + default='%s/dea.yaml' % CWD, + help='Deployment Environment Adapter: dea.yaml') + parser.add_argument('dha_file', action='store', nargs='?', + default='%s/dha.yaml' % CWD, + help='Deployment Hardware Adapter: dha.yaml') + 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', + help='Linux Bridge for booting up the Fuel Master VM ' + '[default: pxebr]') + parser.add_argument('-p', dest='fuel_plugins_dir', action='store', + help='Fuel Plugins directory') -def main(): + args = parser.parse_args() + log(args) - without_fuel, iso_file, dea_file, dha_file = parse_arguments() + check_file_exists(args.dha_file) + + if not args.cleanup_only: + check_file_exists(args.dea_file) + check_fuel_plugins_dir(args.fuel_plugins_dir) + + if not args.no_fuel and not args.cleanup_only: + log('Using OPNFV ISO file: %s' % args.iso_file) + 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) + + kwargs = {'no_fuel': args.no_fuel, 'fuel_only': args.fuel_only, + 'no_health_check': args.no_health_check, + 'cleanup_only': args.cleanup_only, 'cleanup': args.cleanup, + 'storage_dir': args.storage_dir, 'pxe_bridge': args.pxe_bridge, + 'iso_file': args.iso_file, 'dea_file': args.dea_file, + 'dha_file': args.dha_file, + 'fuel_plugins_dir': args.fuel_plugins_dir} + return kwargs + + +def main(): + kwargs = parse_arguments() - d = AutoDeploy(without_fuel, iso_file, dea_file, dha_file) - d.deploy() + d = AutoDeploy(**kwargs) + sys.exit(d.run()) if __name__ == '__main__': - main()
\ No newline at end of file + main() diff --git a/fuel/deploy/deploy_env.py b/fuel/deploy/deploy_env.py index 9bc8fbb34..be8bed342 100644 --- a/fuel/deploy/deploy_env.py +++ b/fuel/deploy/deploy_env.py @@ -1,7 +1,18 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import os import io import yaml import glob +import time from ssh_client import SSHClient import common @@ -10,38 +21,48 @@ exec_cmd = common.exec_cmd err = common.err check_file_exists = common.check_file_exists log = common.log +parse = common.parse +commafy = common.commafy +N = common.N +E = common.E +R = common.R +RO = common.RO CLOUD_DEPLOY_FILE = 'deploy.py' +BLADE_RESTART_TIMES = 3 class CloudDeploy(object): - def __init__(self, dha, fuel_ip, fuel_username, fuel_password, dea_file, - work_dir): + def __init__(self, dea, dha, fuel_ip, fuel_username, fuel_password, + dea_file, work_dir, no_health_check): + self.dea = dea self.dha = dha self.fuel_ip = fuel_ip self.fuel_username = fuel_username self.fuel_password = fuel_password self.dea_file = dea_file self.work_dir = work_dir + self.no_health_check = no_health_check self.file_dir = os.path.dirname(os.path.realpath(__file__)) self.ssh = SSHClient(self.fuel_ip, self.fuel_username, self.fuel_password) - self.macs_file = '%s/macs.yaml' % self.file_dir + self.blade_node_file = '%s/blade_node.yaml' % self.file_dir self.node_ids = self.dha.get_node_ids() + self.wanted_release = self.dea.get_property('wanted_release') + self.blade_node_dict = {} + self.macs_per_blade = {} def upload_cloud_deployment_files(self): - dest ='~/%s/' % self.work_dir - with self.ssh as s: - s.exec_cmd('rm -rf %s' % self.work_dir, check=False) - s.exec_cmd('mkdir ~/%s' % self.work_dir) - s.scp_put(self.dea_file, dest) - s.scp_put(self.macs_file, dest) - s.scp_put('%s/common.py' % self.file_dir, dest) - s.scp_put('%s/dea.py' % self.file_dir, dest) + s.exec_cmd('rm -rf %s' % self.work_dir, False) + s.exec_cmd('mkdir %s' % self.work_dir) + s.scp_put(self.dea_file, self.work_dir) + s.scp_put(self.blade_node_file, self.work_dir) + s.scp_put('%s/common.py' % self.file_dir, self.work_dir) + s.scp_put('%s/dea.py' % self.file_dir, self.work_dir) for f in glob.glob('%s/cloud/*' % self.file_dir): - s.scp_put(f, dest) + s.scp_put(f, self.work_dir) def power_off_nodes(self): for node_id in self.node_ids: @@ -53,35 +74,173 @@ class CloudDeploy(object): def set_boot_order(self, boot_order_list): for node_id in self.node_ids: - self.dha.node_set_boot_order(node_id, boot_order_list) + self.dha.node_set_boot_order(node_id, boot_order_list[:]) def get_mac_addresses(self): - macs_per_node = {} + self.macs_per_blade = {} for node_id in self.node_ids: - macs_per_node[node_id] = self.dha.get_node_pxe_mac(node_id) - with io.open(self.macs_file, 'w') as stream: - yaml.dump(macs_per_node, stream, default_flow_style=False) + self.macs_per_blade[node_id] = self.dha.get_node_pxe_mac(node_id) def run_cloud_deploy(self, deploy_app): log('START CLOUD DEPLOYMENT') deploy_app = '%s/%s' % (self.work_dir, deploy_app) dea_file = '%s/%s' % (self.work_dir, os.path.basename(self.dea_file)) - macs_file = '%s/%s' % (self.work_dir, os.path.basename(self.macs_file)) + blade_node_file = '%s/%s' % ( + self.work_dir, os.path.basename(self.blade_node_file)) + with self.ssh as s: + status = s.run( + 'python %s %s %s %s' % ( + deploy_app, ('-nh' if self.no_health_check else ''), + dea_file, blade_node_file)) + return status + + def check_supported_release(self): + log('Check supported release: %s' % self.wanted_release) + found = False + release_list = parse(self.ssh.exec_cmd('fuel release -l')) + for release in release_list: + if release[R['name']] == self.wanted_release: + found = True + break + if not found: + err('This Fuel does not contain the following release: %s' + % self.wanted_release) + + def check_previous_installation(self): + log('Check previous installation') + env_list = parse(self.ssh.exec_cmd('fuel env list')) + if env_list: + self.cleanup_fuel_environments(env_list) + node_list = parse(self.ssh.exec_cmd('fuel node list')) + if node_list: + self.cleanup_fuel_nodes(node_list) + + def cleanup_fuel_environments(self, env_list): + WAIT_LOOP = 60 + SLEEP_TIME = 10 + for env in env_list: + log('Deleting environment %s' % env[E['id']]) + self.ssh.exec_cmd('fuel env --env %s --delete --force' + % env[E['id']]) + all_env_erased = False + for i in range(WAIT_LOOP): + env_list = parse(self.ssh.exec_cmd('fuel env list')) + if env_list: + time.sleep(SLEEP_TIME) + else: + all_env_erased = True + break + if not all_env_erased: + err('Could not erase these environments %s' + % [(env[E['id']], env[E['status']]) for env in env_list]) + + def cleanup_fuel_nodes(self, node_list): + for node in node_list: + if node[N['status']] == 'discover': + log('Deleting node %s' % node[N['id']]) + self.ssh.exec_cmd('fuel node --node-id %s --delete-from-db ' + '--force' % node[N['id']]) + self.ssh.exec_cmd('cobbler system remove --name node-%s' + % node[N['id']], False) + + def check_prerequisites(self): + log('Check prerequisites') with self.ssh: - self.ssh.run('python %s %s %s' % (deploy_app, dea_file, macs_file)) + self.check_supported_release() + self.check_previous_installation() - def deploy(self): + def wait_for_discovered_blades(self): + log('Wait for discovered blades') + discovered_macs = [] + restart_times = BLADE_RESTART_TIMES - self.power_off_nodes() + for blade in self.node_ids: + self.blade_node_dict[blade] = None + with self.ssh: + all_discovered = self.discovery_waiting_loop(discovered_macs) + + while not all_discovered and restart_times != 0: + restart_times -= 1 + for blade in self.get_not_discovered_blades(): + self.dha.node_reset(blade) + with self.ssh: + all_discovered = self.discovery_waiting_loop(discovered_macs) + + if not all_discovered: + err('Not all blades have been discovered: %s' + % self.not_discovered_blades_summary()) + + with io.open(self.blade_node_file, 'w') as stream: + yaml.dump(self.blade_node_dict, stream, default_flow_style=False) + + def discovery_waiting_loop(self, discovered_macs): + WAIT_LOOP = 360 + SLEEP_TIME = 10 + all_discovered = False + for i in range(WAIT_LOOP): + node_list = parse(self.ssh.exec_cmd('fuel node list')) + if node_list: + self.node_discovery(node_list, discovered_macs) + if self.all_blades_discovered(): + all_discovered = True + break + else: + time.sleep(SLEEP_TIME) + return all_discovered + + def node_discovery(self, node_list, discovered_macs): + for node in node_list: + if (node[N['status']] == 'discover' and + node[N['online']] == 'True' and + node[N['mac']] not in discovered_macs): + discovered_macs.append(node[N['mac']]) + blade = self.find_mac_in_dict(node[N['mac']]) + if blade: + log('Blade %s discovered as Node %s with MAC %s' + % (blade, node[N['id']], node[N['mac']])) + self.blade_node_dict[blade] = node[N['id']] + + def find_mac_in_dict(self, mac): + for blade, mac_list in self.macs_per_blade.iteritems(): + if mac in mac_list: + return blade + + def all_blades_discovered(self): + for blade, node_id in self.blade_node_dict.iteritems(): + if not node_id: + return False + return True + + def not_discovered_blades_summary(self): + summary = '' + for blade, node_id in self.blade_node_dict.iteritems(): + if not node_id: + summary += '\n[blade %s]' % blade + return summary + + def get_not_discovered_blades(self): + not_discovered_blades = [] + for blade, node_id in self.blade_node_dict.iteritems(): + if not node_id: + not_discovered_blades.append(blade) + return not_discovered_blades + + def set_boot_order_nodes(self): + self.power_off_nodes() self.set_boot_order(['pxe', 'disk']) - self.power_on_nodes() + def deploy(self): + + self.set_boot_order_nodes() + + self.check_prerequisites() + self.get_mac_addresses() - check_file_exists(self.macs_file) + self.wait_for_discovered_blades() self.upload_cloud_deployment_files() - self.run_cloud_deploy(CLOUD_DEPLOY_FILE) + return self.run_cloud_deploy(CLOUD_DEPLOY_FILE) diff --git a/fuel/deploy/dha.py b/fuel/deploy/dha.py index bf9a9512a..1feee6039 100644 --- a/fuel/deploy/dha.py +++ b/fuel/deploy/dha.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import yaml import io @@ -5,15 +15,20 @@ from dha_adapters.libvirt_adapter import LibvirtAdapter from dha_adapters.ipmi_adapter import IpmiAdapter from dha_adapters.hp_adapter import HpAdapter + class DeploymentHardwareAdapter(object): + def __new__(cls, yaml_path): with io.open(yaml_path) as yaml_file: dha_struct = yaml.load(yaml_file) type = dha_struct['adapter'] if cls is DeploymentHardwareAdapter: - if type == 'libvirt': return LibvirtAdapter(yaml_path) - if type == 'ipmi': return IpmiAdapter(yaml_path) - if type == 'hp': return HpAdapter(yaml_path) + if type == 'libvirt': + return LibvirtAdapter(yaml_path) + if type == 'ipmi': + return IpmiAdapter(yaml_path) + if type == 'hp': + return HpAdapter(yaml_path) return super(DeploymentHardwareAdapter, cls).__new__(cls) diff --git a/fuel/deploy/dha_adapters/__init__.py b/fuel/deploy/dha_adapters/__init__.py index e69de29bb..fb73157f9 100644 --- a/fuel/deploy/dha_adapters/__init__.py +++ b/fuel/deploy/dha_adapters/__init__.py @@ -0,0 +1,8 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### diff --git a/fuel/deploy/dha_adapters/hardware_adapter.py b/fuel/deploy/dha_adapters/hardware_adapter.py index 884e9ce98..29e04f182 100644 --- a/fuel/deploy/dha_adapters/hardware_adapter.py +++ b/fuel/deploy/dha_adapters/hardware_adapter.py @@ -1,7 +1,18 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + import yaml import io + class HardwareAdapter(object): + def __init__(self, yaml_path): self.dha_struct = None self.parse_yaml(yaml_path) @@ -34,18 +45,15 @@ class HardwareAdapter(object): node_ids.sort() return node_ids - def use_fuel_custom_install(self): - return self.dha_struct['fuelCustomInstall'] - def get_node_property(self, node_id, property_name): for node in self.dha_struct['nodes']: if node['id'] == node_id and property_name in node: return node[property_name] - def node_can_zero_mbr(self, node_id): - return self.get_node_property(node_id, 'nodeCanZeroMBR') - def get_fuel_access(self): for node in self.dha_struct['nodes']: if 'isFuel' in node and node['isFuel']: return node['username'], node['password'] + + def get_disks(self): + return self.dha_struct['disks'] diff --git a/fuel/deploy/dha_adapters/hp_adapter.py b/fuel/deploy/dha_adapters/hp_adapter.py index 8fc38ad5f..51f55f32b 100644 --- a/fuel/deploy/dha_adapters/hp_adapter.py +++ b/fuel/deploy/dha_adapters/hp_adapter.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import common from ipmi_adapter import IpmiAdapter from ssh_client import SSHClient @@ -10,6 +20,7 @@ DEV = {'pxe': 'bootsource5', ROOT = '/system1/bootconfig1' + class HpAdapter(IpmiAdapter): def __init__(self, yaml_path): @@ -19,7 +30,7 @@ class HpAdapter(IpmiAdapter): log('Set boot order %s on Node %s' % (boot_order_list, node_id)) ip, username, password = self.get_access_info(node_id) ssh = SSHClient(ip, username, password) - for order, dev in enumerate(boot_order_list): - with ssh as s: + with ssh as s: + for order, dev in enumerate(boot_order_list): s.exec_cmd('set %s/%s bootorder=%s' - % (ROOT, DEV[dev], order+1)) + % (ROOT, DEV[dev], order + 1)) diff --git a/fuel/deploy/dha_adapters/ipmi_adapter.py b/fuel/deploy/dha_adapters/ipmi_adapter.py index d97fd2ddb..25aa36ec9 100644 --- a/fuel/deploy/dha_adapters/ipmi_adapter.py +++ b/fuel/deploy/dha_adapters/ipmi_adapter.py @@ -1,8 +1,21 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import common +import time from hardware_adapter import HardwareAdapter log = common.log exec_cmd = common.exec_cmd +err = common.err + class IpmiAdapter(HardwareAdapter): @@ -27,28 +40,72 @@ class IpmiAdapter(HardwareAdapter): return mac_list 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) 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) def node_reset(self, node_id): - log('Reset Node %s' % 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)) def node_set_boot_order(self, node_id, boot_order_list): log('Set boot order %s on Node %s' % (boot_order_list, node_id)) + boot_order_list.reverse() cmd_prefix = self.ipmi_cmd(node_id) for dev in boot_order_list: if dev == 'pxe': diff --git a/fuel/deploy/dha_adapters/libvirt_adapter.py b/fuel/deploy/dha_adapters/libvirt_adapter.py index dde494635..b285c1676 100644 --- a/fuel/deploy/dha_adapters/libvirt_adapter.py +++ b/fuel/deploy/dha_adapters/libvirt_adapter.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import common from lxml import etree from hardware_adapter import HardwareAdapter @@ -10,6 +20,7 @@ DEV = {'pxe': 'network', 'disk': 'hd', 'iso': 'cdrom'} + class LibvirtAdapter(HardwareAdapter): def __init__(self, yaml_path): @@ -88,7 +99,8 @@ class LibvirtAdapter(HardwareAdapter): def node_eject_iso(self, node_id): vm_name = self.get_node_property(node_id, 'libvirtName') device = self.get_name_of_device(vm_name, 'cdrom') - exec_cmd('virsh change-media %s --eject %s' % (vm_name, device), False) + exec_cmd('virsh change-media %s --eject %s --config --live' + % (vm_name, device), False) def node_insert_iso(self, node_id, iso_file): vm_name = self.get_node_property(node_id, 'libvirtName') @@ -96,12 +108,6 @@ class LibvirtAdapter(HardwareAdapter): exec_cmd('virsh change-media %s --insert %s %s' % (vm_name, device, iso_file)) - def get_disks(self): - return self.dha_struct['disks'] - - def get_node_role(self, node_id): - return self.get_node_property(node_id, 'role') - def get_node_pxe_mac(self, node_id): mac_list = [] vm_name = self.get_node_property(node_id, 'libvirtName') @@ -125,3 +131,6 @@ class LibvirtAdapter(HardwareAdapter): device = target.get('dev') if device: return device + + def get_virt_net_conf_dir(self): + return self.dha_struct['virtNetConfDir'] diff --git a/fuel/deploy/install-ubuntu-packages.sh b/fuel/deploy/environments/__init__.py index 1ebd7c023..fb73157f9 100755..100644 --- a/fuel/deploy/install-ubuntu-packages.sh +++ b/fuel/deploy/environments/__init__.py @@ -1,18 +1,8 @@ -#!/bin/bash -############################################################################## +############################################################################### # Copyright (c) 2015 Ericsson AB and others. -# stefan.k.berg@ericsson.com -# jonas.bjurel@ericsson.com +# 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 # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -# Tools for installation on the libvirt server/base host -# -apt-get install -y libvirt-bin qemu-kvm tightvncserver virt-manager \ - sshpass fuseiso genisoimage blackbox xterm python-yaml python-netaddr \ - python-paramiko python-lxml python-pip -pip install scp -restart libvirt-bin
\ No newline at end of file +############################################################################### diff --git a/fuel/deploy/environments/execution_environment.py b/fuel/deploy/environments/execution_environment.py new file mode 100644 index 000000000..63be5cd11 --- /dev/null +++ b/fuel/deploy/environments/execution_environment.py @@ -0,0 +1,78 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + +from lxml import etree + +import common +from dha_adapters.libvirt_adapter import LibvirtAdapter + +exec_cmd = common.exec_cmd +err = common.err +log = common.log +check_dir_exists = common.check_dir_exists +check_file_exists = common.check_file_exists +check_if_root = common.check_if_root + + +class ExecutionEnvironment(object): + + def __init__(self, storage_dir, dha_file, root_dir): + self.storage_dir = storage_dir + self.dha = LibvirtAdapter(dha_file) + self.root_dir = root_dir + self.parser = etree.XMLParser(remove_blank_text=True) + self.fuel_node_id = self.dha.get_fuel_node_id() + + def delete_vm(self, node_id): + vm_name = self.dha.get_node_property(node_id, 'libvirtName') + r, c = exec_cmd('virsh dumpxml %s' % vm_name, False) + if c: + return + self.undefine_vm_delete_disk(r, vm_name) + + def undefine_vm_delete_disk(self, printout, vm_name): + disk_files = [] + xml_dump = etree.fromstring(printout, self.parser) + disks = xml_dump.xpath('/domain/devices/disk') + for disk in disks: + sources = disk.xpath('source') + for source in sources: + source_file = source.get('file') + if source_file: + disk_files.append(source_file) + log('Deleting VM %s with disks %s' % (vm_name, disk_files)) + exec_cmd('virsh destroy %s' % vm_name, False) + exec_cmd('virsh undefine %s' % vm_name, False) + for file in disk_files: + exec_cmd('rm -f %s' % file) + + def define_vm(self, vm_name, temp_vm_file, disk_path): + log('Creating VM %s with disks %s' % (vm_name, disk_path)) + with open(temp_vm_file) as f: + vm_xml = etree.parse(f) + names = vm_xml.xpath('/domain/name') + for name in names: + name.text = vm_name + uuids = vm_xml.xpath('/domain/uuid') + for uuid in uuids: + uuid.getparent().remove(uuid) + disks = vm_xml.xpath('/domain/devices/disk') + for disk in disks: + if (disk.get('type') == 'file' and + disk.get('device') == 'disk'): + sources = disk.xpath('source') + for source in sources: + disk.remove(source) + source = etree.Element('source') + source.set('file', disk_path) + disk.append(source) + with open(temp_vm_file, 'w') as f: + vm_xml.write(f, pretty_print=True, xml_declaration=True) + exec_cmd('virsh define %s' % temp_vm_file) diff --git a/fuel/deploy/environments/libvirt_environment.py b/fuel/deploy/environments/libvirt_environment.py new file mode 100644 index 000000000..785eeca7b --- /dev/null +++ b/fuel/deploy/environments/libvirt_environment.py @@ -0,0 +1,107 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + +from lxml import etree +import glob + +import common +from execution_environment import ExecutionEnvironment + +exec_cmd = common.exec_cmd +err = common.err +log = common.log +check_dir_exists = common.check_dir_exists +check_file_exists = common.check_file_exists +check_if_root = common.check_if_root + + +class LibvirtEnvironment(ExecutionEnvironment): + + def __init__(self, storage_dir, dha_file, dea, root_dir): + super(LibvirtEnvironment, self).__init__( + storage_dir, dha_file, root_dir) + self.dea = dea + self.network_dir = '%s/%s' % (self.root_dir, + self.dha.get_virt_net_conf_dir()) + self.node_ids = self.dha.get_all_node_ids() + self.net_names = self.collect_net_names() + + def create_storage(self, node_id, disk_path, disk_sizes): + if node_id == self.fuel_node_id: + disk_size = disk_sizes['fuel'] + else: + roles = self.dea.get_node_role(node_id) + role = 'controller' if 'controller' in roles else 'compute' + disk_size = disk_sizes[role] + exec_cmd('fallocate -l %s %s' % (disk_size, disk_path)) + + def create_vms(self): + temp_dir = exec_cmd('mktemp -d') + disk_sizes = self.dha.get_disks() + for node_id in self.node_ids: + vm_name = self.dha.get_node_property(node_id, 'libvirtName') + vm_template = '%s/%s' % (self.root_dir, + self.dha.get_node_property( + node_id, 'libvirtTemplate')) + check_file_exists(vm_template) + disk_path = '%s/%s.raw' % (self.storage_dir, vm_name) + self.create_storage(node_id, disk_path, disk_sizes) + temp_vm_file = '%s/%s' % (temp_dir, vm_name) + exec_cmd('cp %s %s' % (vm_template, temp_vm_file)) + self.define_vm(vm_name, temp_vm_file, disk_path) + exec_cmd('rm -fr %s' % temp_dir) + + def start_vms(self): + for node_id in self.node_ids: + self.dha.node_power_on(node_id) + + def create_networks(self): + for net_file in glob.glob('%s/*' % self.network_dir): + exec_cmd('virsh net-define %s' % net_file) + for net in self.net_names: + log('Creating network %s' % net) + exec_cmd('virsh net-autostart %s' % net) + exec_cmd('virsh net-start %s' % net) + + def delete_networks(self): + for net in self.net_names: + log('Deleting network %s' % net) + exec_cmd('virsh net-destroy %s' % net, False) + exec_cmd('virsh net-undefine %s' % net, False) + + def get_net_name(self, net_file): + with open(net_file) as f: + net_xml = etree.parse(f) + name_list = net_xml.xpath('/network/name') + for name in name_list: + net_name = name.text + return net_name + + def collect_net_names(self): + net_list = [] + for net_file in glob.glob('%s/*' % self.network_dir): + name = self.get_net_name(net_file) + net_list.append(name) + return net_list + + def delete_vms(self): + for node_id in self.node_ids: + self.delete_vm(node_id) + + def setup_environment(self): + check_dir_exists(self.network_dir) + self.cleanup_environment() + self.create_networks() + self.create_vms() + self.start_vms() + + def cleanup_environment(self): + self.delete_vms() + self.delete_networks() diff --git a/fuel/deploy/environments/virtual_fuel.py b/fuel/deploy/environments/virtual_fuel.py new file mode 100644 index 000000000..cb8be6371 --- /dev/null +++ b/fuel/deploy/environments/virtual_fuel.py @@ -0,0 +1,70 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + +from lxml import etree + +import common +from execution_environment import ExecutionEnvironment + +exec_cmd = common.exec_cmd +log = common.log +check_file_exists = common.check_file_exists +check_if_root = common.check_if_root + + +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 + + 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') + for interface in interfaces: + interface.getparent().remove(interface) + interface = etree.Element('interface') + interface.set('type', 'bridge') + source = etree.SubElement(interface, 'source') + source.set('bridge', self.pxe_bridge) + model = etree.SubElement(interface, 'model') + model.set('type', 'virtio') + devices = 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) + + def create_vm(self): + temp_dir = exec_cmd('mktemp -d') + 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_sizes = self.dha.get_disks() + disk_size = disk_sizes['fuel'] + exec_cmd('fallocate -l %s %s' % (disk_size, disk_path)) + temp_vm_file = '%s/%s' % (temp_dir, vm_name) + exec_cmd('cp %s %s' % (vm_template, temp_vm_file)) + self.set_vm_nic(temp_vm_file) + self.define_vm(vm_name, temp_vm_file, disk_path) + exec_cmd('rm -fr %s' % temp_dir) + + def setup_environment(self): + check_if_root() + self.cleanup_environment() + self.create_vm() + + def cleanup_environment(self): + self.delete_vm(self.fuel_node_id) diff --git a/fuel/deploy/execution_environment.py b/fuel/deploy/execution_environment.py new file mode 100644 index 000000000..e671463e4 --- /dev/null +++ b/fuel/deploy/execution_environment.py @@ -0,0 +1,46 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + +import yaml +import io +import os + +import common +from environments.libvirt_environment import LibvirtEnvironment +from environments.virtual_fuel import VirtualFuel + +exec_cmd = common.exec_cmd +err = common.err +log = common.log +check_dir_exists = common.check_dir_exists +check_file_exists = common.check_file_exists +check_if_root = common.check_if_root +ArgParser = common.ArgParser + + +class ExecutionEnvironment(object): + + def __new__(cls, storage_dir, pxe_bridge, dha_path, dea): + + with io.open(dha_path) as yaml_file: + dha_struct = yaml.load(yaml_file) + + type = dha_struct['adapter'] + + root_dir = os.path.dirname(os.path.realpath(__file__)) + + if cls is ExecutionEnvironment: + if type == 'libvirt': + return LibvirtEnvironment(storage_dir, dha_path, dea, root_dir) + + if type == 'ipmi' or type == 'hp': + return VirtualFuel(storage_dir, pxe_bridge, dha_path, root_dir) + + return super(ExecutionEnvironment, cls).__new__(cls) diff --git a/fuel/deploy/fuel_patch/ks.cfg.patch b/fuel/deploy/fuel_patch/ks.cfg.patch new file mode 100644 index 000000000..189695792 --- /dev/null +++ b/fuel/deploy/fuel_patch/ks.cfg.patch @@ -0,0 +1,19 @@ +*** ks.cfg.orig Wed Apr 15 21:47:09 2015 +--- ks.cfg Wed Apr 15 21:47:24 2015 +*************** +*** 35,41 **** + default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'` + + installdrive="undefined" +! forceformat="no" + for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + + set ${drives} ${removable_drives} +--- 35,41 ---- + default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'` + + installdrive="undefined" +! forceformat="yes" + for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + + set ${drives} ${removable_drives} diff --git a/fuel/deploy/install_fuel_master.py b/fuel/deploy/install_fuel_master.py index bb8e7e175..0e3c1c044 100644 --- a/fuel/deploy/install_fuel_master.py +++ b/fuel/deploy/install_fuel_master.py @@ -1,20 +1,37 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import common import time import os +import glob from ssh_client import SSHClient from dha_adapters.libvirt_adapter import LibvirtAdapter log = common.log err = common.err clean = common.clean +delete = common.delete TRANSPLANT_FUEL_SETTINGS = 'transplant_fuel_settings.py' BOOTSTRAP_ADMIN = '/usr/local/sbin/bootstrap_admin_node' +FUEL_CLIENT_CONFIG = '/etc/fuel/client/config.yaml' +PLUGINS_DIR = '~/plugins' +LOCAL_PLUGIN_FOLDER = '/opt/opnfv' + class InstallFuelMaster(object): - def __init__(self, dea_file, dha_file, fuel_ip, fuel_username, fuel_password, - fuel_node_id, iso_file, work_dir): + def __init__(self, dea_file, dha_file, fuel_ip, fuel_username, + fuel_password, fuel_node_id, iso_file, work_dir, + fuel_plugins_dir): self.dea_file = dea_file self.dha = LibvirtAdapter(dha_file) self.fuel_ip = fuel_ip @@ -22,7 +39,9 @@ class InstallFuelMaster(object): self.fuel_password = fuel_password self.fuel_node_id = fuel_node_id self.iso_file = iso_file + self.iso_dir = os.path.dirname(self.iso_file) self.work_dir = work_dir + self.fuel_plugins_dir = fuel_plugins_dir self.file_dir = os.path.dirname(os.path.realpath(__file__)) self.ssh = SSHClient(self.fuel_ip, self.fuel_username, self.fuel_password) @@ -32,21 +51,16 @@ class InstallFuelMaster(object): self.dha.node_power_off(self.fuel_node_id) - self.zero_mbr_set_boot_order() - - self.proceed_with_installation() - - def custom_install(self): - log('Start Custom Fuel Installation') - - self.dha.node_power_off(self.fuel_node_id) - 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']) - self.proceed_with_installation() + try: + self.proceed_with_installation() + except Exception as e: + self.post_install_cleanup() + err(e) def proceed_with_installation(self): log('Eject ISO') @@ -68,7 +82,7 @@ class InstallFuelMaster(object): log('Let the Fuel deployment continue') log('Found FUEL menu as PID %s, now killing it' % fuel_menu_pid) - self.ssh_exec_cmd('kill %s' % fuel_menu_pid) + self.ssh_exec_cmd('kill %s' % fuel_menu_pid, False) log('Wait until installation complete') self.wait_until_installation_completed() @@ -76,22 +90,36 @@ class InstallFuelMaster(object): log('Waiting for one minute for Fuel to stabilize') time.sleep(60) - log('Eject ISO') - self.dha.node_eject_iso(self.fuel_node_id) + self.delete_deprecated_fuel_client_config_from_fuel_6_1() + + self.collect_plugin_files() + + self.install_plugins() + + self.post_install_cleanup() log('Fuel Master installed successfully !') - def zero_mbr_set_boot_order(self): - if self.dha.node_can_zero_mbr(self.fuel_node_id): - log('Fuel Node %s capable of zeroing MBR so doing that...' - % self.fuel_node_id) - self.dha.node_zero_mbr(self.fuel_node_id) - self.dha.node_set_boot_order(self.fuel_node_id, ['disk', 'iso']) - elif self.dha.node_can_set_boot_order_live(self.fuel_node_id): - log('Node %s can change ISO boot order live' % self.fuel_node_id) - self.dha.node_set_boot_order(self.fuel_node_id, ['iso', 'disk']) - else: - err('No way to install Fuel node') + def collect_plugin_files(self): + with self.ssh as s: + s.exec_cmd('mkdir %s' % PLUGINS_DIR) + if self.fuel_plugins_dir: + for f in glob.glob('%s/*.rpm' % self.fuel_plugins_dir): + s.scp_put(f, PLUGINS_DIR) + else: + s.exec_cmd('cp %s/*.rpm %s' % (LOCAL_PLUGIN_FOLDER, + PLUGINS_DIR)) + + def install_plugins(self): + log('Installing Fuel Plugins') + with self.ssh as s: + r = s.exec_cmd('find %s -type f -name \'*.rpm\'' % PLUGINS_DIR) + for f in r.splitlines(): + log('Found plugin %s, installing ...' % f) + r, e = s.exec_cmd('fuel plugins --install %s' % f, False) + if e and 'does not update installed package' not in r: + raise Exception('Installation of Fuel Plugin %s ' + 'failed: %s' % (f, e)) def wait_for_node_up(self): WAIT_LOOP = 60 @@ -103,14 +131,14 @@ class InstallFuelMaster(object): success = True break except Exception as e: - log('EXCEPTION [%s] received when SSH-ing into Fuel VM %s ... ' - 'sleeping %s seconds' % (e, self.fuel_ip, SLEEP_TIME)) + log('Trying to SSH into Fuel VM %s ... sleeping %s seconds' + % (self.fuel_ip, SLEEP_TIME)) time.sleep(SLEEP_TIME) finally: self.ssh.close() if not success: - err('Could not SSH into Fuel VM %s' % self.fuel_ip) + raise Exception('Could not SSH into Fuel VM %s' % self.fuel_ip) def wait_until_fuel_menu_up(self): WAIT_LOOP = 60 @@ -127,39 +155,35 @@ class InstallFuelMaster(object): else: break if not fuel_menu_pid: - err('Could not find the Fuel Menu Process ID') + raise Exception('Could not find the Fuel Menu Process ID') return fuel_menu_pid def get_fuel_menu_pid(self, printout, search): - fuel_menu_pid = None for line in printout.splitlines(): - if search in line: - fuel_menu_pid = clean(line)[1] - break - return fuel_menu_pid + if line.endswith(search): + return clean(line)[1] - def ssh_exec_cmd(self, cmd): + def ssh_exec_cmd(self, cmd, check=True): with self.ssh: - ret = self.ssh.exec_cmd(cmd) + ret = self.ssh.exec_cmd(cmd, check=check) return ret def inject_own_astute_yaml(self): - dest ='~/%s/' % self.work_dir - with self.ssh as s: - s.exec_cmd('rm -rf %s' % self.work_dir, check=False) - s.exec_cmd('mkdir ~/%s' % self.work_dir) - s.scp_put(self.dea_file, dest) - s.scp_put('%s/common.py' % self.file_dir, dest) - s.scp_put('%s/dea.py' % self.file_dir, dest) - s.scp_put('%s/transplant_fuel_settings.py' % self.file_dir, dest) + s.exec_cmd('rm -rf %s' % self.work_dir, False) + s.exec_cmd('mkdir %s' % self.work_dir) + s.scp_put(self.dea_file, self.work_dir) + s.scp_put('%s/common.py' % self.file_dir, self.work_dir) + s.scp_put('%s/dea.py' % self.file_dir, self.work_dir) + s.scp_put('%s/transplant_fuel_settings.py' + % self.file_dir, self.work_dir) log('Modifying Fuel astute') - s.run('python ~/%s/%s ~/%s/%s' + s.run('python %s/%s %s/%s' % (self.work_dir, TRANSPLANT_FUEL_SETTINGS, self.work_dir, os.path.basename(self.dea_file))) def wait_until_installation_completed(self): - WAIT_LOOP = 180 + WAIT_LOOP = 360 SLEEP_TIME = 10 CMD = 'ps -ef | grep %s | grep -v grep' % BOOTSTRAP_ADMIN @@ -174,4 +198,21 @@ class InstallFuelMaster(object): time.sleep(SLEEP_TIME) if not install_completed: - err('Fuel installation did not complete') + raise Exception('Fuel installation did not complete') + + def post_install_cleanup(self): + log('Eject ISO file %s' % self.iso_file) + self.dha.node_eject_iso(self.fuel_node_id) + log('Remove ISO directory %s' % self.iso_dir) + delete(self.iso_dir) + + def delete_deprecated_fuel_client_config_from_fuel_6_1(self): + with self.ssh as s: + response, error = s.exec_cmd('fuel -v', False) + if (error and + 'DEPRECATION WARNING' in error and + '6.1.0' in error and + FUEL_CLIENT_CONFIG in error): + log('Delete deprecated fuel client config %s' % FUEL_CLIENT_CONFIG) + with self.ssh as s: + s.exec_cmd('rm %s' % FUEL_CLIENT_CONFIG, False) diff --git a/fuel/deploy/libvirt/dha.yaml b/fuel/deploy/libvirt/dha.yaml deleted file mode 100644 index ce61e534a..000000000 --- a/fuel/deploy/libvirt/dha.yaml +++ /dev/null @@ -1,80 +0,0 @@ -title: Deployment Hardware Adapter (DHA) -# DHA API version supported -version: 1.1 -created: Sat Apr 25 16:26:22 UTC 2015 -comment: Small libvirt setup - -# Adapter to use for this definition -adapter: libvirt - -# Node list. -# Mandatory fields are id and role. -# The MAC address of the PXE boot interface is not mandatory -# to be set, but the field must be present. -# All other fields are adapter specific. - -nodes: -- id: 1 - pxeMac: 52:54:00:aa:dd:84 - libvirtName: controller1 - libvirtTemplate: controller - role: controller -- id: 2 - pxeMac: 52:54:00:aa:dd:84 - libvirtName: controller2 - libvirtTemplate: controller - role: controller -- id: 3 - pxeMac: 52:54:00:aa:dd:84 - libvirtName: controller3 - libvirtTemplate: controller - role: controller -- id: 4 - pxeMac: 52:54:00:41:64:f3 - libvirtName: compute1 - libvirtTemplate: compute - role: compute -- id: 5 - pxeMac: 52:54:00:69:a0:79 - libvirtName: compute2 - libvirtTemplate: compute - role: compute -- id: 6 - pxeMac: 52:54:00:69:a0:79 - libvirtName: compute3 - libvirtTemplate: compute - role: compute -- id: 7 - pxeMac: 52:54:00:f8:b0:75 - libvirtName: fuel-master - libvirtTemplate: fuel-master - isFuel: yes - nodeCanZeroMBR: yes - nodeCanSetBootOrderLive: yes - username: root - password: r00tme - -disks: - fuel: 30G - controller: 30G - compute: 30G - -# Deployment power on strategy -# all: Turn on all nodes at once. There will be no correlation -# between the DHA and DEA node numbering. MAC addresses -# will be used to select the node roles though. -# sequence: Turn on the nodes in sequence starting with the lowest order -# node and wait for the node to be detected by Fuel. Not until -# the node has been detected and assigned a role will the next -# node be turned on. -powerOnStrategy: all - -# If fuelCustomInstall is set to true, Fuel is assumed to be installed by -# calling the DHA adapter function "dha_fuelCustomInstall()" with two -# arguments: node ID and the ISO file name to deploy. The custom install -# function is then to handle all necessary logic to boot the Fuel master -# from the ISO and then return. -# Allowed values: true, false - -fuelCustomInstall: false - diff --git a/fuel/deploy/reap.py b/fuel/deploy/reap.py new file mode 100644 index 000000000..c72b33cf9 --- /dev/null +++ b/fuel/deploy/reap.py @@ -0,0 +1,339 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + +import common +import time +import os +import yaml +import glob +import shutil + +N = common.N +E = common.E +R = common.R +ArgParser = common.ArgParser +exec_cmd = common.exec_cmd +parse = common.parse +err = common.err +log = common.log +delete = common.delete +commafy = common.commafy + +DEA_1 = ''' +title: Deployment Environment Adapter (DEA) +# DEA API version supported +version: 1.1 +created: {date} +comment: {comment} +''' + +DHA_1 = ''' +title: Deployment Hardware Adapter (DHA) +# DHA API version supported +version: 1.1 +created: {date} +comment: {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 +''' + +DHA_2 = ''' +# Adding the Fuel node as node id {node_id} +# which may not be correct - please adjust as needed. +''' + +DISKS = {'fuel': '30G', + 'controller': '30G', + 'compute': '30G'} + + +class Reap(object): + + def __init__(self, dea_file, dha_file, comment): + self.dea_file = dea_file + self.dha_file = dha_file + self.comment = comment + self.temp_dir = None + self.env = None + self.env_id = None + self.last_node = None + + def get_env(self): + env_list = parse(exec_cmd('fuel env')) + if len(env_list) > 1: + err('Not exactly one environment') + self.env = env_list[0] + self.env_id = self.env[E['id']] + + def download_config(self, config_type): + log('Download %s config for environment %s' + % (config_type, self.env_id)) + exec_cmd('fuel %s --env %s --download --dir %s' + % (config_type, self.env_id, self.temp_dir)) + + def write(self, file, text, newline=True): + mode = 'a' if os.path.isfile(file) else 'w' + with open(file, mode) as f: + f.write('%s%s' % (text, ('\n' if newline else ''))) + + def write_yaml(self, file, data, newline=True): + self.write(file, yaml.dump(data, default_flow_style=False).strip(), + newline) + + def get_node_by_id(self, node_list, node_id): + for node in node_list: + if node[N['id']] == node_id: + return node + + def reap_interface(self, node_id, interfaces): + interface, mac = self.get_interface(node_id) + if_name = None + if interfaces: + if_name = self.check_dict_exists(interfaces, interface) + if not if_name: + if_name = 'interfaces_%s' % str(len(interfaces) + 1) + interfaces[if_name] = interface + return if_name, mac + + def reap_transformation(self, node_id, roles, transformations): + main_role = 'controller' if 'controller' in roles else 'compute' + node_file = glob.glob('%s/deployment_%s/*%s_%s.yaml' + % (self.temp_dir, self.env_id, + main_role, node_id)) + tr_name = None + with open(node_file[0]) as f: + node_config = yaml.load(f) + transformation = {'transformations': + node_config['network_scheme']['transformations']} + if transformations: + tr_name = self.check_dict_exists(transformations, transformation) + if not tr_name: + tr_name = 'transformations_%s' % str(len(transformations) + 1) + transformations[tr_name] = transformation + return tr_name + + def check_dict_exists(self, main_dict, dict): + for key, val in main_dict.iteritems(): + if cmp(dict, val) == 0: + return key + + def reap_nodes_interfaces_transformations(self): + node_list = parse(exec_cmd('fuel node')) + real_node_ids = [node[N['id']] for node in node_list] + real_node_ids.sort() + min_node = real_node_ids[0] + + interfaces = {} + transformations = {} + dea_nodes = [] + dha_nodes = [] + + for real_node_id in real_node_ids: + node_id = int(real_node_id) - int(min_node) + 1 + self.last_node = node_id + node = self.get_node_by_id(node_list, real_node_id) + roles = commafy(node[N['roles']]) + if not roles: + err('Fuel Node %s has no role' % real_node_id) + dea_node = {'id': node_id, + 'role': roles} + dha_node = {'id': node_id} + if_name, mac = self.reap_interface(real_node_id, interfaces) + tr_name = self.reap_transformation(real_node_id, roles, + transformations) + dea_node.update( + {'interfaces': if_name, + 'transformations': tr_name}) + + dha_node.update( + {'pxeMac': mac if mac else None, + 'ipmiIp': None, + 'ipmiUser': None, + 'ipmiPass': None, + 'libvirtName': None, + 'libvirtTemplate': None}) + + dea_nodes.append(dea_node) + dha_nodes.append(dha_node) + + self.write_yaml(self.dha_file, {'nodes': dha_nodes}, False) + self.write_yaml(self.dea_file, {'nodes': dea_nodes}) + self.write_yaml(self.dea_file, interfaces) + self.write_yaml(self.dea_file, transformations) + self.reap_fuel_node_info() + self.write_yaml(self.dha_file, {'disks': DISKS}) + + def reap_fuel_node_info(self): + dha_nodes = [] + dha_node = { + 'id': self.last_node + 1, + 'libvirtName': None, + 'libvirtTemplate': None, + 'isFuel': True, + 'username': 'root', + 'password': 'r00tme'} + + dha_nodes.append(dha_node) + + self.write(self.dha_file, DHA_2.format(node_id=dha_node['id']), False) + self.write_yaml(self.dha_file, dha_nodes) + + def reap_environment_info(self): + network_file = ('%s/network_%s.yaml' + % (self.temp_dir, self.env_id)) + network = self.read_yaml(network_file) + env = {'environment': + {'name': self.env[E['name']], + 'mode': self.env[E['mode']], + 'net_segment_type': + network['networking_parameters']['segmentation_type']}} + self.write_yaml(self.dea_file, env) + wanted_release = None + rel_list = parse(exec_cmd('fuel release')) + for rel in rel_list: + if rel[R['id']] == self.env[E['release_id']]: + wanted_release = rel[R['name']] + self.write_yaml(self.dea_file, {'wanted_release': wanted_release}) + + def reap_fuel_settings(self): + data = self.read_yaml('/etc/fuel/astute.yaml') + fuel = {} + del data['ADMIN_NETWORK']['mac'] + del data['ADMIN_NETWORK']['interface'] + for key in ['ADMIN_NETWORK', 'HOSTNAME', 'DNS_DOMAIN', 'DNS_SEARCH', + 'DNS_UPSTREAM', 'NTP1', 'NTP2', 'NTP3', 'FUEL_ACCESS']: + fuel[key] = data[key] + for key in fuel['ADMIN_NETWORK'].keys(): + if key not in ['ipaddress', 'netmask', + 'dhcp_pool_start', 'dhcp_pool_end']: + del fuel['ADMIN_NETWORK'][key] + self.write_yaml(self.dea_file, {'fuel': fuel}) + + def reap_network_settings(self): + network_file = ('%s/network_%s.yaml' + % (self.temp_dir, self.env_id)) + data = self.read_yaml(network_file) + network = {} + network['networking_parameters'] = data['networking_parameters'] + network['networks'] = data['networks'] + for net in network['networks']: + del net['id'] + del net['group_id'] + self.write_yaml(self.dea_file, {'network': network}) + + def reap_settings(self): + settings_file = '%s/settings_%s.yaml' % (self.temp_dir, self.env_id) + settings = self.read_yaml(settings_file) + self.write_yaml(self.dea_file, {'settings': settings}) + + def get_interface(self, real_node_id): + exec_cmd('fuel node --node-id %s --network --download --dir %s' + % (real_node_id, self.temp_dir)) + interface_file = ('%s/node_%s/interfaces.yaml' + % (self.temp_dir, real_node_id)) + interfaces = self.read_yaml(interface_file) + interface_config = {} + pxe_mac = None + for interface in interfaces: + networks = [] + for network in interface['assigned_networks']: + networks.append(network['name']) + if network['name'] == 'fuelweb_admin': + pxe_mac = interface['mac'] + if networks: + interface_config[interface['name']] = networks + return interface_config, pxe_mac + + def read_yaml(self, yaml_file): + with open(yaml_file) as f: + data = yaml.load(f) + return data + + def intro(self): + delete(self.dea_file) + delete(self.dha_file) + self.temp_dir = exec_cmd('mktemp -d') + date = time.strftime('%c') + self.write(self.dea_file, + DEA_1.format(date=date, comment=self.comment), False) + self.write(self.dha_file, + DHA_1.format(date=date, comment=self.comment)) + self.get_env() + self.download_config('deployment') + self.download_config('settings') + self.download_config('network') + + def finale(self): + log('DEA file is available at %s' % self.dea_file) + log('DHA file is available at %s (this is just a template)' + % self.dha_file) + shutil.rmtree(self.temp_dir) + + def reap(self): + self.intro() + self.reap_environment_info() + self.reap_nodes_interfaces_transformations() + self.reap_fuel_settings() + self.reap_network_settings() + self.reap_settings() + self.finale() + + +def usage(): + print ''' + Usage: + python reap.py <dea_file> <dha_file> <comment> + ''' + + +def parse_arguments(): + parser = ArgParser(prog='python %s' % __file__) + parser.add_argument('dea_file', nargs='?', action='store', + default='dea.yaml', + help='Deployment Environment Adapter: dea.yaml') + parser.add_argument('dha_file', nargs='?', action='store', + default='dha.yaml', + help='Deployment Hardware Adapter: dha.yaml') + parser.add_argument('comment', nargs='?', action='store', help='Comment') + args = parser.parse_args() + return (args.dea_file, args.dha_file, args.comment) + + +def main(): + dea_file, dha_file, comment = parse_arguments() + + r = Reap(dea_file, dha_file, comment) + r.reap() + + +if __name__ == '__main__': + main() diff --git a/fuel/deploy/setup_environment.py b/fuel/deploy/setup_environment.py deleted file mode 100644 index 4e0e7ba37..000000000 --- a/fuel/deploy/setup_environment.py +++ /dev/null @@ -1,165 +0,0 @@ -import sys -from lxml import etree -import os -import glob -import common - -from dha import DeploymentHardwareAdapter - -exec_cmd = common.exec_cmd -err = common.err -log = common.log -check_dir_exists = common.check_dir_exists -check_file_exists = common.check_file_exists -check_if_root = common.check_if_root - - -class LibvirtEnvironment(object): - - def __init__(self, storage_dir, dha_file): - self.dha = DeploymentHardwareAdapter(dha_file) - self.storage_dir = storage_dir - self.parser = etree.XMLParser(remove_blank_text=True) - self.file_dir = os.path.dirname(os.path.realpath(__file__)) - self.network_dir = '%s/libvirt/networks' % self.file_dir - self.vm_dir = '%s/libvirt/vms' % self.file_dir - self.node_ids = self.dha.get_all_node_ids() - self.fuel_node_id = self.dha.get_fuel_node_id() - self.net_names = self.collect_net_names() - - def create_storage(self, node_id, disk_path, disk_sizes): - if node_id == self.fuel_node_id: - disk_size = disk_sizes['fuel'] - else: - role = self.dha.get_node_role(node_id) - disk_size = disk_sizes[role] - exec_cmd('fallocate -l %s %s' % (disk_size, disk_path)) - - def create_vms(self): - temp_dir = exec_cmd('mktemp -d') - disk_sizes = self.dha.get_disks() - for node_id in self.node_ids: - vm_name = self.dha.get_node_property(node_id, 'libvirtName') - vm_template = self.dha.get_node_property(node_id, - 'libvirtTemplate') - disk_path = '%s/%s.raw' % (self.storage_dir, vm_name) - self.create_storage(node_id, disk_path, disk_sizes) - self.define_vm(vm_name, vm_template, temp_dir, disk_path) - exec_cmd('rm -fr %s' % temp_dir) - - def define_vm(self, vm_name, vm_template, temp_dir, disk_path): - log('Creating VM %s with disks %s' % (vm_name, disk_path)) - temp_vm_file = '%s/%s' % (temp_dir, vm_name) - exec_cmd('cp %s/%s %s' % (self.vm_dir, vm_template, temp_vm_file)) - with open(temp_vm_file) as f: - vm_xml = etree.parse(f) - names = vm_xml.xpath('/domain/name') - for name in names: - name.text = vm_name - uuids = vm_xml.xpath('/domain/uuid') - for uuid in uuids: - uuid.getparent().remove(uuid) - disks = vm_xml.xpath('/domain/devices/disk') - for disk in disks: - sources = disk.xpath('source') - for source in sources: - source.set('file', disk_path) - with open(temp_vm_file, 'w') as f: - vm_xml.write(f, pretty_print=True, xml_declaration=True) - exec_cmd('virsh define %s' % temp_vm_file) - - def create_networks(self): - for net_file in glob.glob('%s/*' % self.network_dir): - exec_cmd('virsh net-define %s' % net_file) - for net in self.net_names: - log('Creating network %s' % net) - exec_cmd('virsh net-autostart %s' % net) - exec_cmd('virsh net-start %s' % net) - - def delete_networks(self): - for net in self.net_names: - log('Deleting network %s' % net) - exec_cmd('virsh net-destroy %s' % net, False) - exec_cmd('virsh net-undefine %s' % net, False) - - def get_net_name(self, net_file): - with open(net_file) as f: - net_xml = etree.parse(f) - name_list = net_xml.xpath('/network/name') - for name in name_list: - net_name = name.text - return net_name - - def collect_net_names(self): - net_list = [] - for net_file in glob.glob('%s/*' % self.network_dir): - name = self.get_net_name(net_file) - net_list.append(name) - return net_list - - def delete_vms(self): - for node_id in self.node_ids: - vm_name = self.dha.get_node_property(node_id, 'libvirtName') - r, c = exec_cmd('virsh dumpxml %s' % vm_name, False) - if c > 0: - log(r) - continue - self.undefine_vm_delete_disk(r, vm_name) - - def undefine_vm_delete_disk(self, printout, vm_name): - disk_files = [] - xml_dump = etree.fromstring(printout, self.parser) - disks = xml_dump.xpath('/domain/devices/disk') - for disk in disks: - sources = disk.xpath('source') - for source in sources: - source_file = source.get('file') - if source_file: - disk_files.append(source_file) - log('Deleting VM %s with disks %s' % (vm_name, disk_files)) - exec_cmd('virsh destroy %s' % vm_name, False) - exec_cmd('virsh undefine %s' % vm_name, False) - for file in disk_files: - exec_cmd('rm -f %s' % file) - - def setup_environment(self): - check_if_root() - check_dir_exists(self.network_dir) - check_dir_exists(self.vm_dir) - self.cleanup_environment() - self.create_vms() - self.create_networks() - - def cleanup_environment(self): - self.delete_vms() - self.delete_networks() - - -def usage(): - print ''' - Usage: - python setup_environment.py <storage_directory> <dha_file> - - Example: - python setup_environment.py /mnt/images dha.yaml - ''' - -def parse_arguments(): - if len(sys.argv) != 3: - log('Incorrect number of arguments') - usage() - sys.exit(1) - storage_dir = sys.argv[-2] - dha_file = sys.argv[-1] - check_dir_exists(storage_dir) - check_file_exists(dha_file) - return storage_dir, dha_file - -def main(): - storage_dir, dha_file = parse_arguments() - - virt = LibvirtEnvironment(storage_dir, dha_file) - virt.setup_environment() - -if __name__ == '__main__': - main()
\ No newline at end of file diff --git a/fuel/deploy/setup_vfuel.py b/fuel/deploy/setup_vfuel.py deleted file mode 100644 index 65ee01341..000000000 --- a/fuel/deploy/setup_vfuel.py +++ /dev/null @@ -1,143 +0,0 @@ -import sys -from lxml import etree -import os - -import common -from dha import DeploymentHardwareAdapter - -exec_cmd = common.exec_cmd -err = common.err -log = common.log -check_dir_exists = common.check_dir_exists -check_file_exists = common.check_file_exists -check_if_root = common.check_if_root - -VFUELNET = ''' -iface vfuelnet inet static - bridge_ports em1 - address 10.40.0.1 - netmask 255.255.255.0 - pre-down iptables -t nat -D POSTROUTING --out-interface p1p1.20 -j MASQUERADE -m comment --comment "vfuelnet" - pre-down iptables -D FORWARD --in-interface vfuelnet --out-interface p1p1.20 -m comment --comment "vfuelnet" - post-up iptables -t nat -A POSTROUTING --out-interface p1p1.20 -j MASQUERADE -m comment --comment "vfuelnet" - post-up iptables -A FORWARD --in-interface vfuelnet --out-interface p1p1.20 -m comment --comment "vfuelnet" -''' -VM_DIR = 'baremetal/vm' -FUEL_DISK_SIZE = '30G' -IFACE = 'vfuelnet' -INTERFACE_CONFIG = '/etc/network/interfaces' - -class VFuel(object): - - def __init__(self, storage_dir, dha_file): - self.dha = DeploymentHardwareAdapter(dha_file) - self.storage_dir = storage_dir - self.parser = etree.XMLParser(remove_blank_text=True) - self.fuel_node_id = self.dha.get_fuel_node_id() - self.file_dir = os.path.dirname(os.path.realpath(__file__)) - self.vm_dir = '%s/%s' % (self.file_dir, VM_DIR) - - def setup_environment(self): - check_if_root() - check_dir_exists(self.vm_dir) - self.setup_networking() - self.delete_vm() - self.create_vm() - - def setup_networking(self): - with open(INTERFACE_CONFIG) as f: - data = f.read() - if VFUELNET not in data: - log('Appending to file %s:\n %s' % (INTERFACE_CONFIG, VFUELNET)) - with open(INTERFACE_CONFIG, 'a') as f: - f.write('\n%s\n' % VFUELNET) - if exec_cmd('ip link show | grep %s' % IFACE): - log('Bring DOWN interface %s' % IFACE) - exec_cmd('ifdown %s' % IFACE, False) - log('Bring UP interface %s' % IFACE) - exec_cmd('ifup %s' % IFACE, False) - - def delete_vm(self): - vm_name = self.dha.get_node_property(self.fuel_node_id, 'libvirtName') - r, c = exec_cmd('virsh dumpxml %s' % vm_name, False) - if c > 0: - log(r) - return - self.undefine_vm_delete_disk(r, vm_name) - - def undefine_vm_delete_disk(self, printout, vm_name): - disk_files = [] - xml_dump = etree.fromstring(printout, self.parser) - disks = xml_dump.xpath('/domain/devices/disk') - for disk in disks: - sources = disk.xpath('source') - for source in sources: - source_file = source.get('file') - if source_file: - disk_files.append(source_file) - log('Deleting VM %s with disks %s' % (vm_name, disk_files)) - exec_cmd('virsh destroy %s' % vm_name, False) - exec_cmd('virsh undefine %s' % vm_name, False) - for file in disk_files: - exec_cmd('rm -f %s' % file) - - def create_vm(self): - temp_dir = exec_cmd('mktemp -d') - vm_name = self.dha.get_node_property(self.fuel_node_id, 'libvirtName') - vm_template = self.dha.get_node_property(self.fuel_node_id, - 'libvirtTemplate') - disk_path = '%s/%s.raw' % (self.storage_dir, vm_name) - exec_cmd('fallocate -l %s %s' % (FUEL_DISK_SIZE, disk_path)) - self.define_vm(vm_name, vm_template, temp_dir, disk_path) - exec_cmd('rm -fr %s' % temp_dir) - - def define_vm(self, vm_name, vm_template, temp_dir, disk_path): - log('Creating VM %s with disks %s' % (vm_name, disk_path)) - temp_vm_file = '%s/%s' % (temp_dir, vm_name) - exec_cmd('cp %s/%s %s' % (self.vm_dir, vm_template, temp_vm_file)) - with open(temp_vm_file) as f: - vm_xml = etree.parse(f) - names = vm_xml.xpath('/domain/name') - for name in names: - name.text = vm_name - uuids = vm_xml.xpath('/domain/uuid') - for uuid in uuids: - uuid.getparent().remove(uuid) - disks = vm_xml.xpath('/domain/devices/disk') - for disk in disks: - sources = disk.xpath('source') - for source in sources: - source.set('file', disk_path) - with open(temp_vm_file, 'w') as f: - vm_xml.write(f, pretty_print=True, xml_declaration=True) - exec_cmd('virsh define %s' % temp_vm_file) - - -def usage(): - print ''' - Usage: - python setup_vfuel.py <storage_directory> <dha_file> - - Example: - python setup_vfuel.py /mnt/images dha.yaml - ''' - -def parse_arguments(): - if len(sys.argv) != 3: - log('Incorrect number of arguments') - usage() - sys.exit(1) - storage_dir = sys.argv[-2] - dha_file = sys.argv[-1] - check_dir_exists(storage_dir) - check_file_exists(dha_file) - return storage_dir, dha_file - -def main(): - storage_dir, dha_file = parse_arguments() - - vfuel = VFuel(storage_dir, dha_file) - vfuel.setup_environment() - -if __name__ == '__main__': - main() diff --git a/fuel/deploy/ssh_client.py b/fuel/deploy/ssh_client.py index 9ea227aea..0f6b8c7ea 100644 --- a/fuel/deploy/ssh_client.py +++ b/fuel/deploy/ssh_client.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import paramiko import common import scp @@ -6,6 +16,7 @@ TIMEOUT = 600 log = common.log err = common.err + class SSHClient(object): def __init__(self, host, username, password): @@ -18,7 +29,8 @@ class SSHClient(object): self.client = paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.client.connect(self.host, username=self.username, - password=self.password, timeout=timeout) + password=self.password, look_for_keys=False, + timeout=timeout) def close(self): if self.client is not None: @@ -32,7 +44,7 @@ class SSHClient(object): def __exit__(self, type, value, traceback): self.close() - def exec_cmd(self, command, sudo=False, timeout=TIMEOUT, check=True): + def exec_cmd(self, command, check=True, sudo=False, timeout=TIMEOUT): if sudo and self.username != 'root': command = "sudo -S -p '' %s" % command stdin, stdout, stderr = self.client.exec_command(command, @@ -60,16 +72,15 @@ class SSHClient(object): if chan.recv_ready(): data = chan.recv(1024) while data: - print data + log(data.strip()) data = chan.recv(1024) if chan.recv_stderr_ready(): error_buff = chan.recv_stderr(1024) while error_buff: - print error_buff + log(error_buff.strip()) error_buff = chan.recv_stderr(1024) - exit_status = chan.recv_exit_status() - log('Exit status %s' % exit_status) + return chan.recv_exit_status() def scp_get(self, remote, local='.', dir=False): try: diff --git a/fuel/deploy/templates/hardware_environment/conf/ericsson_montreal_lab/dea.yaml b/fuel/deploy/templates/hardware_environment/conf/ericsson_montreal_lab/dea.yaml new file mode 100644 index 000000000..23b2809ae --- /dev/null +++ b/fuel/deploy/templates/hardware_environment/conf/ericsson_montreal_lab/dea.yaml @@ -0,0 +1,844 @@ +title: Deployment Environment Adapter (DEA) +# DEA API version supported +version: +created: +comment: Config for Ericsson Montreal Lab - HA deployment with Ceph and Opendaylight +environment: + name: opnfv + mode: ha + net_segment_type: gre +wanted_release: Juno on Ubuntu 14.04.1 +nodes: +- id: 1 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 2 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 3 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 4 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +- id: 5 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +- id: 6 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +fuel: + ADMIN_NETWORK: + ipaddress: 10.20.0.2 + netmask: 255.255.0.0 + dhcp_pool_start: 10.20.0.3 + dhcp_pool_end: 10.20.0.254 + DNS_UPSTREAM: 10.118.32.193 + DNS_DOMAIN: opnfvericsson.ca + DNS_SEARCH: opnfvericsson.ca + FUEL_ACCESS: + user: admin + password: admin + HOSTNAME: opnfv + NTP1: 10.118.34.219 + NTP2: + NTP3: +interfaces_1: + eth0: + - fuelweb_admin + eth2: + - 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: eth0 + - action: add-port + bridge: br-mgmt + name: eth2.320 + - action: add-port + bridge: br-storage + name: eth2.220 + - action: add-port + bridge: br-mesh + name: eth2.20 + - action: add-port + bridge: br-ex + name: eth0 +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: eth2.320 + - action: add-port + bridge: br-storage + name: eth2.220 + - action: add-port + bridge: br-mesh + name: eth2.20 +network: + management_vip: 192.168.0.2 + management_vrouter_vip: 192.168.0.3 + networking_parameters: + base_mac: fa:16:3e:00:00:00 + dns_nameservers: + - 10.118.32.193 + floating_ranges: + - - 10.118.34.226 + - 10.118.34.230 + gre_id_range: + - 2 + - 65535 + internal_cidr: 192.168.111.0/24 + internal_gateway: 192.168.111.1 + net_l23_provider: ovs + segmentation_type: gre + vlan_range: + - 2022 + - 2023 + networks: + - cidr: 10.118.34.192/24 + gateway: 10.118.34.193 + ip_ranges: + - - 10.118.34.220 + - 10.118.34.225 + meta: + cidr: 172.16.0.0/24 + configurable: true + floating_range_var: floating_ranges + ip_range: + - 172.16.0.2 + - 172.16.0.126 + 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.2.0/24 + gateway: null + ip_ranges: + - - 192.168.2.2 + - 192.168.2.254 + meta: + assign_vip: 192.168.2.0/24 + configurable: true + map_priority: 2 + name: private + notation: cidr + render_addr_mask: private + render_type: cidr + seg_type: gre + use_gateway: false + vlan_start: 103 + name: private + vlan_start: 20 + - 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: 320 + - cidr: 192.168.1.0/24 + gateway: null + ip_ranges: + - - 192.168.1.2 + - 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: 220 + - cidr: 10.20.0.0/16 + 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 + public_vip: 10.118.34.220 + public_vrouter_vip: 10.118.34.221 +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: + 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$)(?![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$)(?![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: 40 + heat: + description: '' + label: '' + type: hidden + value: true + weight: 30 + metadata: + 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: 40 + murano: + description: If selected, Murano component will be installed + label: Install Murano + restrictions: + - cluster:net_provider != 'neutron' + type: checkbox + value: false + weight: 20 + 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 + 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 + 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. + label: OpenStack debug logging + type: checkbox + value: false + weight: 20 + libvirt_type: + 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: 30 + nova_quota: + description: Quotas are used to limit CPU and memory usage for tenants. Enabling + quotas will increase load on the Nova database. + label: Nova quotas + type: checkbox + value: false + weight: 25 + puppet_debug: + description: Debug puppet logging mode provides more information, but requires + more disk space. + 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. + label: Resume guests state on host boot + type: checkbox + value: true + weight: 60 + 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. + label: Use qcow format for images + type: checkbox + value: true + weight: 50 + use_vcenter: + type: hidden + value: false + weight: 30 + corosync: + group: + description: '' + label: Group + type: text + value: 226.94.1.1 + weight: 10 + metadata: + 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: 10.118.32.193 + weight: 10 + metadata: + label: Host OS DNS Servers + weight: 90 + 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: + label: External MongoDB + restrictions: + - action: hide + condition: settings:additional_components.mongo.value == false + 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: + label: Host OS NTP Servers + weight: 100 + 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: 10.118.34.219 + weight: 10 + kernel_params: + kernel: + description: Default kernel parameters + label: Initial parameters + type: text + value: console=ttyS0,9600 console=tty0 net.ifnames=0 biosdevname=0 rootdelay=90 + nomodeset + weight: 45 + metadata: + label: Kernel parameters + weight: 40 + murano_settings: + metadata: + label: Murano Settings + restrictions: + - action: hide + condition: settings:additional_components.murano.value == false + weight: 20 + murano_repo_url: + description: '' + label: Murano Repository URL + type: text + value: http://storage.apps.openstack.org/ + weight: 10 + neutron_mellanox: + metadata: + enabled: true + 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: + enabled: true + label: OpenDaylight plugin + plugin_id: 1 + restrictions: + - cluster:net_provider != 'neutron': Only neutron is supported by OpenDaylight + toggleable: true + weight: 70 + 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 + use_vxlan: + description: Configure neutron to use VXLAN tunneling + label: Use vxlan + restrictions: + - action: disable + condition: networking_parameters:segmentation_type == 'vlan' + message: Neutron with GRE segmentation required + type: checkbox + value: true + weight: 20 + vni_range_end: + description: VXLAN VNI IDs range end + label: VNI range end + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10000' + weight: 31 + vni_range_start: + description: VXLAN VNI IDs range start + label: VNI range start + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10' + weight: 30 + provision: + metadata: + label: Provision + weight: 80 + method: + description: Which provision method to use for this cluster. + label: Provision method + type: radio + value: image + values: + - data: image + description: Copying pre-built images on a disk. + label: Image + - data: cobbler + description: Install from scratch using anaconda or debian-installer. + label: (DEPRECATED) Classic (use anaconda or debian-installer) + 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: + label: Public network assignment + restrictions: + - action: hide + condition: cluster:net_provider != 'neutron' + weight: 50 + repo_setup: + metadata: + always_editable: true + 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-6.1/operations.html#external-ubuntu-ops). + + ' + extra_priority: null + type: custom_repo_configuration + value: + - name: ubuntu + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-updates + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-security + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: mos + priority: 1050 + section: main restricted + suite: mos6.1 + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/ubuntu/x86_64 + - name: mos-updates + priority: 1050 + section: main restricted + suite: mos6.1-updates + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-security + priority: 1050 + section: main restricted + suite: mos6.1-security + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-holdback + priority: 1100 + section: main restricted + suite: mos6.1-holdback + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: Auxiliary + priority: 1150 + section: main restricted + suite: auxiliary + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/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: + label: Storage + 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) + restrictions: + - settings:storage.images_ceph.value == false + type: checkbox + value: false + 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: '2' + weight: 85 + 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 + 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: + label: Syslog + 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 + 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: + label: Workloads Collector User + restrictions: + - action: hide + condition: 'true' + weight: 10 + password: + type: password + value: pBkLbu1k + tenant: + type: text + value: services + user: + type: text + value: fuel_stats_user diff --git a/fuel/deploy/templates/hardware_environment/conf/ericsson_montreal_lab/dha.yaml b/fuel/deploy/templates/hardware_environment/conf/ericsson_montreal_lab/dha.yaml new file mode 100644 index 000000000..ca446f680 --- /dev/null +++ b/fuel/deploy/templates/hardware_environment/conf/ericsson_montreal_lab/dha.yaml @@ -0,0 +1,54 @@ +title: Deployment Hardware Adapter (DHA) +# DHA API version supported +version: +created: +comment: Config for Ericsson Montreal Lab + +# Adapter to use for this definition +adapter: hp + +# Node list. +# Mandatory property is id, all other properties are adapter specific. + +nodes: +- id: 1 + pxeMac: 14:58:D0:54:7A:D8 + ipmiIp: 10.118.32.198 + ipmiUser: <username> + ipmiPass: <password> +- id: 2 + pxeMac: 14:58:D0:55:E2:E0 + ipmiIp: 10.118.32.202 + ipmiUser: <username> + ipmiPass: <password> +- id: 3 + pxeMac: 9C:B6:54:8A:25:C0 + ipmiIp: 10.118.32.213 + ipmiUser: <username> + ipmiPass: <password> +- id: 4 + pxeMac: 14:58:D0:54:28:80 + ipmiIp: 10.118.32.201 + ipmiUser: <username> + ipmiPass: <password> +- id: 5 + pxeMac: 14:58:D0:54:E7:88 + ipmiIp: 10.118.32.203 + ipmiUser: <username> + ipmiPass: <password> +- id: 6 + pxeMac: 14:58:D0:54:7A:28 + ipmiIp: 10.118.32.205 + ipmiUser: <username> + ipmiPass: <password> +# Adding the Fuel node as node id 7 which may not be correct - please +# adjust as needed. +- id: 7 + libvirtName: fuel-opnfv + libvirtTemplate: templates/hardware_environment/vms/fuel.xml + isFuel: yes + username: root + password: r00tme + +disks: + fuel: 50G
\ No newline at end of file diff --git a/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod1/dea.yaml b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod1/dea.yaml new file mode 100644 index 000000000..db29fe977 --- /dev/null +++ b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod1/dea.yaml @@ -0,0 +1,841 @@ +title: Deployment Environment Adapter (DEA) +# DEA API version supported +version: +created: +comment: Config for LF POD1 - HA deployment with Ceph and Opendaylight +environment: + name: opnfv + mode: ha + net_segment_type: gre +wanted_release: Juno on Ubuntu 14.04.1 +nodes: +- id: 1 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 2 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 3 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 4 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +- id: 5 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +fuel: + ADMIN_NETWORK: + ipaddress: 10.20.0.2 + netmask: 255.255.0.0 + dhcp_pool_start: 10.20.0.3 + dhcp_pool_end: 10.20.0.254 + DNS_UPSTREAM: 8.8.8.8 + DNS_DOMAIN: domain.tld + DNS_SEARCH: domain.tld + FUEL_ACCESS: + user: admin + password: admin + HOSTNAME: opnfv + NTP1: 0.pool.ntp.org + NTP2: 1.pool.ntp.org + NTP3: 2.pool.ntp.org +interfaces_1: + eth0: + - public + eth1: + - fuelweb_admin + - 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: eth0 + - action: add-port + bridge: br-mgmt + name: eth1.300 + - action: add-port + bridge: br-storage + name: eth1.301 + - action: add-port + bridge: br-mesh + name: eth1.302 + - action: add-port + bridge: br-ex + name: eth0 +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: eth1.300 + - action: add-port + bridge: br-storage + name: eth1.301 + - action: add-port + bridge: br-mesh + name: eth1.302 +network: + management_vip: 192.168.0.2 + management_vrouter_vip: 192.168.0.3 + networking_parameters: + base_mac: fa:16:3e:00:00:00 + dns_nameservers: + - 8.8.4.4 + - 8.8.8.8 + floating_ranges: + - - 172.30.9.160 + - 172.30.9.254 + gre_id_range: + - 2 + - 65535 + internal_cidr: 192.168.111.0/24 + internal_gateway: 192.168.111.1 + net_l23_provider: ovs + segmentation_type: gre + vlan_range: + - 1000 + - 1030 + networks: + - cidr: 172.30.9.0/24 + gateway: 172.30.9.1 + ip_ranges: + - - 172.30.9.64 + - 172.30.9.159 + meta: + cidr: 172.16.0.0/24 + configurable: true + floating_range_var: floating_ranges + ip_range: + - 172.16.0.2 + - 172.16.0.126 + 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.2.0/24 + gateway: null + ip_ranges: + - - 192.168.2.2 + - 192.168.2.254 + meta: + assign_vip: 192.168.2.0/24 + configurable: true + map_priority: 2 + name: private + notation: cidr + render_addr_mask: private + render_type: cidr + seg_type: gre + use_gateway: false + vlan_start: 103 + name: private + vlan_start: 302 + - cidr: 192.168.0.0/24 + gateway: null + ip_ranges: + - - 192.168.0.2 + - 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: 300 + - cidr: 192.168.1.0/24 + gateway: null + ip_ranges: + - - 192.168.1.2 + - 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: 301 + - cidr: 10.20.0.0/16 + 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 + public_vip: 172.30.9.64 + public_vrouter_vip: 172.30.9.65 +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: + 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$)(?![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$)(?![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: 40 + heat: + description: '' + label: '' + type: hidden + value: true + weight: 30 + metadata: + 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: 40 + murano: + description: If selected, Murano component will be installed + label: Install Murano + restrictions: + - cluster:net_provider != 'neutron' + type: checkbox + value: false + weight: 20 + 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 + 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 + 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. + label: OpenStack debug logging + type: checkbox + value: false + weight: 20 + libvirt_type: + 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: 30 + nova_quota: + description: Quotas are used to limit CPU and memory usage for tenants. Enabling + quotas will increase load on the Nova database. + label: Nova quotas + type: checkbox + value: false + weight: 25 + puppet_debug: + description: Debug puppet logging mode provides more information, but requires + more disk space. + 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. + label: Resume guests state on host boot + type: checkbox + value: true + weight: 60 + 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. + label: Use qcow format for images + type: checkbox + value: true + weight: 50 + use_vcenter: + type: hidden + value: false + weight: 30 + corosync: + group: + description: '' + label: Group + type: text + value: 226.94.1.1 + weight: 10 + metadata: + 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.4.4, 8.8.8.8 + weight: 10 + metadata: + label: Host OS DNS Servers + weight: 90 + 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: + label: External MongoDB + restrictions: + - action: hide + condition: settings:additional_components.mongo.value == false + 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: + label: Host OS NTP Servers + weight: 100 + 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.pool.ntp.org, 1.pool.ntp.org + weight: 10 + kernel_params: + kernel: + description: Default kernel parameters + label: Initial parameters + type: text + value: console=ttyS0,9600 console=tty0 net.ifnames=0 biosdevname=0 rootdelay=90 + nomodeset + weight: 45 + metadata: + label: Kernel parameters + weight: 40 + murano_settings: + metadata: + label: Murano Settings + restrictions: + - action: hide + condition: settings:additional_components.murano.value == false + weight: 20 + murano_repo_url: + description: '' + label: Murano Repository URL + type: text + value: http://storage.apps.openstack.org/ + weight: 10 + neutron_mellanox: + metadata: + enabled: true + 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: + enabled: true + label: OpenDaylight plugin + plugin_id: 1 + restrictions: + - cluster:net_provider != 'neutron': Only neutron is supported by OpenDaylight + toggleable: true + weight: 70 + 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 + use_vxlan: + description: Configure neutron to use VXLAN tunneling + label: Use vxlan + restrictions: + - action: disable + condition: networking_parameters:segmentation_type == 'vlan' + message: Neutron with GRE segmentation required + type: checkbox + value: true + weight: 20 + vni_range_end: + description: VXLAN VNI IDs range end + label: VNI range end + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10000' + weight: 31 + vni_range_start: + description: VXLAN VNI IDs range start + label: VNI range start + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10' + weight: 30 + provision: + metadata: + label: Provision + weight: 80 + method: + description: Which provision method to use for this cluster. + label: Provision method + type: radio + value: image + values: + - data: image + description: Copying pre-built images on a disk. + label: Image + - data: cobbler + description: Install from scratch using anaconda or debian-installer. + label: (DEPRECATED) Classic (use anaconda or debian-installer) + 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: + label: Public network assignment + restrictions: + - action: hide + condition: cluster:net_provider != 'neutron' + weight: 50 + repo_setup: + metadata: + always_editable: true + 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-6.1/operations.html#external-ubuntu-ops). + + ' + extra_priority: null + type: custom_repo_configuration + value: + - name: ubuntu + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-updates + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-security + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: mos + priority: 1050 + section: main restricted + suite: mos6.1 + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/ubuntu/x86_64 + - name: mos-updates + priority: 1050 + section: main restricted + suite: mos6.1-updates + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-security + priority: 1050 + section: main restricted + suite: mos6.1-security + type: deb + uri: hhttp://10.20.0.2:8080/mos-ubuntu + - name: mos-holdback + priority: 1100 + section: main restricted + suite: mos6.1-holdback + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: Auxiliary + priority: 1150 + section: main restricted + suite: auxiliary + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/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: + label: Storage + 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) + restrictions: + - settings:storage.images_ceph.value == false + type: checkbox + value: false + 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: '2' + weight: 85 + 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 + 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: + label: Syslog + 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 + 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: + label: Workloads Collector User + restrictions: + - action: hide + condition: 'true' + weight: 10 + password: + type: password + value: pBkLbu1k + tenant: + type: text + value: services + user: + type: text + value: fuel_stats_user diff --git a/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod1/dha.yaml b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod1/dha.yaml new file mode 100644 index 000000000..724d6d833 --- /dev/null +++ b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod1/dha.yaml @@ -0,0 +1,49 @@ +title: Deployment Hardware Adapter (DHA) +# DHA API version supported +version: +created: +comment: Config for LF POD1 + +# Adapter to use for this definition +adapter: ipmi + +# Node list. +# Mandatory property is id, all other properties are adapter specific. + +nodes: +- id: 1 + pxeMac: 00:25:b5:b0:00:ef + ipmiIp: 172.30.8.69 + ipmiUser: admin + ipmiPass: octopus +- id: 2 + pxeMac: 00:25:b5:b0:00:cf + ipmiIp: 172.30.8.78 + ipmiUser: admin + ipmiPass: octopus +- id: 3 + pxeMac: 00:25:b5:b0:00:8f + ipmiIp: 172.30.8.68 + ipmiUser: admin + ipmiPass: octopus +- id: 4 + pxeMac: 00:25:b5:b0:00:6f + ipmiIp: 172.30.8.77 + ipmiUser: admin + ipmiPass: octopus +- id: 5 + pxeMac: 00:25:b5:b0:00:4f + ipmiIp: 172.30.8.67 + ipmiUser: admin + ipmiPass: octopus +# Adding the Fuel node as node id 6 which may not be correct - please +# adjust as needed. +- id: 6 + libvirtName: fuel-opnfv + libvirtTemplate: templates/hardware_environment/vms/fuel.xml + isFuel: yes + username: root + password: r00tme + +disks: + fuel: 50G
\ No newline at end of file diff --git a/fuel/deploy/libvirt/dea.yaml b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod2/dea.yaml index 802293f62..81cbcbf5f 100644 --- a/fuel/deploy/libvirt/dea.yaml +++ b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod2/dea.yaml @@ -1,40 +1,38 @@ title: Deployment Environment Adapter (DEA) # DEA API version supported -version: 1.1 -created: Sat Apr 25 16:26:22 UTC 2015 -comment: Small libvirt setup -environment_name: opnfv59-b -environment_mode: multinode -wanted_release: Juno on Ubuntu 12.04.4 +version: +created: +comment: Config for LF POD2 - HA deployment with Ceph and Opendaylight +environment: + name: opnfv + mode: ha + net_segment_type: gre +wanted_release: Juno on Ubuntu 14.04.1 nodes: - id: 1 - interfaces: interface1 - transformations: controller1 - role: controller + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller - id: 2 - interfaces: interface1 - transformations: controller1 - role: controller + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller - id: 3 - interfaces: interface1 - transformations: controller1 - role: controller + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller - id: 4 - interfaces: interface1 - transformations: compute1 - role: compute + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute - id: 5 - interfaces: interface1 - transformations: compute1 - role: compute -- id: 6 - interfaces: interface1 - transformations: compute1 - role: compute + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute fuel: ADMIN_NETWORK: ipaddress: 10.20.0.2 - netmask: 255.255.255.0 + netmask: 255.255.0.0 dhcp_pool_start: 10.20.0.3 dhcp_pool_end: 10.20.0.254 DNS_UPSTREAM: 8.8.8.8 @@ -43,178 +41,104 @@ fuel: FUEL_ACCESS: user: admin password: admin - HOSTNAME: opnfv59 + HOSTNAME: opnfv NTP1: 0.pool.ntp.org NTP2: 1.pool.ntp.org NTP3: 2.pool.ntp.org -interfaces: - interface1: - eth0: - - fuelweb_admin - - management - eth1: - - storage - eth2: - - private - eth3: - - public -transformations: - controller1: - - action: add-br - name: br-eth0 - - action: add-port - bridge: br-eth0 - name: eth0 - - action: add-br - name: br-eth1 - - action: add-port - bridge: br-eth1 - name: eth1 - - action: add-br - name: br-eth2 - - action: add-port - bridge: br-eth2 - name: eth2 - - action: add-br - name: br-eth3 - - action: add-port - bridge: br-eth3 - name: eth3 - - action: add-br - name: br-ex - - action: add-br - name: br-mgmt - - action: add-br - name: br-storage - - action: add-br - name: br-fw-admin - - action: add-patch - bridges: - - br-eth1 - - br-storage - tags: - - 102 - - 0 - vlan_ids: - - 102 - - 0 - - action: add-patch - bridges: - - br-eth0 - - br-mgmt - tags: - - 101 - - 0 - vlan_ids: - - 101 - - 0 - - action: add-patch - bridges: - - br-eth0 - - br-fw-admin - trunks: - - 0 - - action: add-patch - bridges: - - br-eth3 - - br-ex - trunks: - - 0 - - action: add-br - name: br-prv - - action: add-patch - bridges: - - br-eth2 - - br-prv - compute1: - - action: add-br - name: br-eth0 - - action: add-port - bridge: br-eth0 - name: eth0 - - action: add-br - name: br-eth1 - - action: add-port - bridge: br-eth1 - name: eth1 - - action: add-br - name: br-eth2 - - action: add-port - bridge: br-eth2 - name: eth2 - - action: add-br - name: br-eth3 - - action: add-port - bridge: br-eth3 - name: eth3 - - action: add-br - name: br-mgmt - - action: add-br - name: br-storage - - action: add-br - name: br-fw-admin - - action: add-patch - bridges: - - br-eth1 - - br-storage - tags: - - 102 - - 0 - vlan_ids: - - 102 - - 0 - - action: add-patch - bridges: - - br-eth0 - - br-mgmt - tags: - - 101 - - 0 - vlan_ids: - - 101 - - 0 - - action: add-patch - bridges: - - br-eth0 - - br-fw-admin - trunks: - - 0 - - action: add-br - name: br-prv - - action: add-patch - bridges: - - br-eth2 - - br-prv -opnfv: - compute: {} - controller: {} +interfaces_1: + eth0: + - fuelweb_admin + - management + - storage + - private + eth2: + - public +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: eth0 + - action: add-port + bridge: br-mgmt + name: eth0.300 + - action: add-port + bridge: br-storage + name: eth0.301 + - action: add-port + bridge: br-mesh + name: eth0.302 + - action: add-port + bridge: br-ex + name: eth2 +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: eth0.300 + - action: add-port + bridge: br-storage + name: eth0.301 + - action: add-port + bridge: br-mesh + name: eth0.302 network: + management_vip: 192.168.1.2 + management_vrouter_vip: 192.168.1.3 networking_parameters: base_mac: fa:16:3e:00:00:00 dns_nameservers: - 8.8.4.4 - 8.8.8.8 floating_ranges: - - - 172.16.0.130 - - 172.16.0.254 + - - 172.30.10.160 + - 172.30.10.254 gre_id_range: - 2 - 65535 internal_cidr: 192.168.111.0/24 internal_gateway: 192.168.111.1 net_l23_provider: ovs - segmentation_type: vlan + segmentation_type: gre vlan_range: - 1000 - 1030 networks: - - cidr: 172.16.0.0/24 - gateway: 172.16.0.1 + - cidr: 172.30.10.0/24 + gateway: 172.30.10.1 ip_ranges: - - - 172.16.0.2 - - 172.16.0.126 + - - 172.30.10.64 + - 172.30.10.159 meta: - assign_vip: true cidr: 172.16.0.0/24 configurable: true floating_range_var: floating_ranges @@ -227,16 +151,36 @@ network: render_addr_mask: public render_type: null use_gateway: true + vips: + - haproxy + - vrouter vlan_start: null name: public vlan_start: null - - cidr: 192.168.0.0/24 + - cidr: 192.168.2.0/24 gateway: null ip_ranges: - - - 192.168.0.1 - - 192.168.0.254 + - - 192.168.2.2 + - 192.168.2.254 + meta: + cidr: 192.168.2.0/24 + configurable: true + map_priority: 2 + name: private + notation: cidr + render_addr_mask: private + render_type: cidr + seg_type: gre + use_gateway: false + vlan_start: 103 + name: private + vlan_start: 302 + - cidr: 192.168.1.0/24 + gateway: null + ip_ranges: + - - 192.168.1.2 + - 192.168.1.254 meta: - assign_vip: true cidr: 192.168.0.0/24 configurable: true map_priority: 2 @@ -245,16 +189,18 @@ network: render_addr_mask: internal render_type: cidr use_gateway: false + vips: + - haproxy + - vrouter vlan_start: 101 name: management - vlan_start: 101 - - cidr: 192.168.1.0/24 + vlan_start: 300 + - cidr: 192.168.0.0/24 gateway: null ip_ranges: - - - 192.168.1.1 - - 192.168.1.254 + - - 192.168.0.2 + - 192.168.0.254 meta: - assign_vip: false cidr: 192.168.1.0/24 configurable: true map_priority: 2 @@ -265,31 +211,13 @@ network: use_gateway: false vlan_start: 102 name: storage - vlan_start: 102 - - cidr: null - gateway: null - ip_ranges: [] - meta: - assign_vip: false - configurable: false - map_priority: 2 - name: private - neutron_vlan_range: true - notation: null - render_addr_mask: null - render_type: null - seg_type: vlan - use_gateway: false - vlan_start: null - name: private - vlan_start: null - - cidr: 10.20.0.0/24 - gateway: null + vlan_start: 301 + - cidr: 10.20.0.0/16 + gateway: 10.20.0.2 ip_ranges: - - 10.20.0.3 - 10.20.0.254 meta: - assign_vip: false configurable: false map_priority: 0 notation: ip_ranges @@ -299,12 +227,17 @@ network: use_gateway: true name: fuelweb_admin vlan_start: null + public_vip: 172.30.10.64 + public_vrouter_vip: 172.30.10.65 settings: editable: access: email: description: Email address for Administrator - label: email + label: Email + regex: + error: Invalid email + source: ^\S+@\S+$ type: text value: admin@localhost weight: 40 @@ -313,25 +246,30 @@ settings: weight: 10 password: description: Password for Administrator - label: password + label: Password + regex: + error: Empty password + source: \S type: password value: admin weight: 20 tenant: description: Tenant (project) name for Administrator - label: tenant + label: Tenant regex: error: Invalid tenant name - source: ^(?!services$)(?!nova$)(?!glance$)(?!keystone$)(?!neutron$)(?!cinder$)(?!swift$)(?!ceph$)(?![Gg]uest$).* + source: ^(?!services$)(?!nova$)(?!glance$)(?!keystone$)(?!neutron$)(?!cinder$)(?!swift$)(?!ceph$)(?![Gg]uest$)(?!.* + +.*$).+ type: text value: admin weight: 30 user: description: Username for Administrator - label: username + label: Username regex: error: Invalid username - source: ^(?!services$)(?!nova$)(?!glance$)(?!keystone$)(?!neutron$)(?!cinder$)(?!swift$)(?!ceph$)(?![Gg]uest$).* + source: ^(?!services$)(?!nova$)(?!glance$)(?!keystone$)(?!neutron$)(?!cinder$)(?!swift$)(?!ceph$)(?![Gg]uest$)(?!.* + +.*$).+ type: text value: admin weight: 10 @@ -351,6 +289,14 @@ settings: metadata: 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: 40 murano: description: If selected, Murano component will be installed label: Install Murano @@ -369,7 +315,7 @@ settings: auth_key: description: Public key(s) to include in authorized_keys on deployed nodes label: Public Key - type: text + type: textarea value: '' weight: 70 auto_assign_floating_ip: @@ -377,24 +323,11 @@ settings: to a new instance label: Auto assign floating IP restrictions: - - cluster:net_provider == 'neutron' + - action: hide + condition: cluster:net_provider == 'neutron' type: checkbox value: false weight: 40 - compute_scheduler_driver: - label: Scheduler driver - type: radio - value: nova.scheduler.filter_scheduler.FilterScheduler - values: - - data: nova.scheduler.filter_scheduler.FilterScheduler - description: Currently the most advanced OpenStack scheduler. See the OpenStack - documentation for details. - label: Filter scheduler - - data: nova.scheduler.simple.SimpleScheduler - description: This is 'naive' scheduler which tries to find the least loaded - host - label: Simple scheduler - weight: 40 debug: description: Debug logging mode provides more information, but requires more disk space. @@ -402,17 +335,6 @@ settings: type: checkbox value: false weight: 20 - disable_offload: - description: If set, generic segmentation offload (gso) and generic receive - offload (gro) on physical nics will be disabled. See ethtool man. - label: Disable generic offload on physical nics - restrictions: - - action: hide - condition: cluster:net_provider == 'neutron' and networking_parameters:segmentation_type - == 'gre' - type: checkbox - value: true - weight: 80 libvirt_type: label: Hypervisor type type: radio @@ -421,21 +343,10 @@ settings: - data: kvm description: Choose this type of hypervisor if you run OpenStack on hardware label: KVM - restrictions: - - settings:common.libvirt_type.value == 'vcenter' - data: qemu description: Choose this type of hypervisor if you run OpenStack on virtual hosts. label: QEMU - restrictions: - - settings:common.libvirt_type.value == 'vcenter' - - data: vcenter - description: Choose this type of hypervisor if you run OpenStack in a vCenter - environment. - label: vCenter - restrictions: - - settings:common.libvirt_type.value != 'vcenter' or cluster:net_provider - == 'neutron' weight: 30 metadata: label: Common @@ -447,12 +358,19 @@ settings: type: checkbox value: false weight: 25 + puppet_debug: + description: Debug puppet logging mode provides more information, but requires + more disk space. + 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. + nova-compute starts. If the guest was not running previously, a restart will + not be attempted. label: Resume guests state on host boot type: checkbox value: true @@ -465,6 +383,10 @@ settings: type: checkbox value: true weight: 50 + use_vcenter: + type: hidden + value: false + weight: 30 corosync: group: description: '' @@ -494,19 +416,74 @@ settings: 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, 8.8.4.4 + value: 8.8.4.4, 8.8.8.8 weight: 10 metadata: - label: Upstream DNS + label: Host OS DNS Servers weight: 90 + 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: + label: External MongoDB + restrictions: + - action: hide + condition: settings:additional_components.mongo.value == false + 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: - label: Upstream NTP + label: Host OS NTP Servers weight: 100 ntp_list: description: List of upstream NTP servers, separated by comma - label: NTP servers list + 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.pool.ntp.org, 1.pool.ntp.org weight: 10 @@ -515,15 +492,32 @@ settings: description: Default kernel parameters label: Initial parameters type: text - value: console=ttyS0,9600 console=tty0 rootdelay=90 nomodeset + value: console=ttyS0,9600 console=tty0 net.ifnames=0 biosdevname=0 rootdelay=90 + nomodeset weight: 45 metadata: label: Kernel parameters weight: 40 + murano_settings: + metadata: + label: Murano Settings + restrictions: + - action: hide + condition: settings:additional_components.murano.value == false + weight: 20 + murano_repo_url: + description: '' + label: Murano Repository URL + type: text + value: http://storage.apps.openstack.org/ + weight: 10 neutron_mellanox: metadata: enabled: true label: Mellanox Neutron components + restrictions: + - action: hide + condition: not ('experimental' in version:feature_groups) toggleable: false weight: 50 plugin: @@ -538,9 +532,8 @@ settings: 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. + 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' @@ -561,117 +554,77 @@ settings: type: text value: '16' weight: 70 - nsx_plugin: - connector_type: - description: Default network transport type to use - label: NSX connector type - type: select - value: stt - values: - - data: gre - label: GRE - - data: ipsec_gre - label: GRE over IPSec - - data: stt - label: STT - - data: ipsec_stt - label: STT over IPSec - - data: bridge - label: Bridge - weight: 80 - l3_gw_service_uuid: - description: UUID for the default L3 gateway service to use with this cluster - label: L3 service UUID - regex: - error: Invalid L3 gateway service UUID - source: '[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}' - type: text - value: '' - weight: 50 + opendaylight: metadata: - enabled: false - label: VMware NSX + enabled: true + label: OpenDaylight plugin + plugin_id: 1 restrictions: - - action: hide - condition: cluster:net_provider != 'neutron' or networking_parameters:net_l23_provider - != 'nsx' - weight: 20 - nsx_controllers: - description: One or more IPv4[:port] addresses of NSX controller node, separated - by comma (e.g. 10.30.30.2,192.168.110.254:443) - label: NSX controller endpoint - regex: - error: Invalid controller endpoints, specify valid IPv4[:port] pair - source: ^(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])(:(6553[0-5]|655[0-2][\d]|65[0-4][\d]{2}|6[0-4][\d]{3}|5[\d]{4}|[\d][\d]{0,3}))?(,(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])(:(6553[0-5]|655[0-2][\d]|65[0-4][\d]{2}|6[0-4][\d]{3}|5[\d]{4}|[\d][\d]{0,3}))?)*$ - type: text - value: '' - weight: 60 - nsx_password: - description: Password for Administrator - label: NSX password - regex: - error: Empty password - source: \S - type: password - value: '' - weight: 30 - nsx_username: - description: NSX administrator's username - label: NSX username + - cluster:net_provider != 'neutron': Only neutron is supported by OpenDaylight + toggleable: true + weight: 70 + rest_api_port: + description: Port on which ODL REST API will be available. + label: Port number regex: - error: Empty username - source: \S + 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: admin + value: '8282' + weight: 40 + use_vxlan: + description: Configure neutron to use VXLAN tunneling + label: Use vxlan + restrictions: + - action: disable + condition: networking_parameters:segmentation_type == 'vlan' + message: Neutron with GRE segmentation required + type: checkbox + value: true weight: 20 - packages_url: - description: URL to NSX specific packages - label: URL to NSX bits + vni_range_end: + description: VXLAN VNI IDs range end + label: VNI range end regex: - error: Invalid URL, specify valid HTTP/HTTPS URL with IPv4 address (e.g. - http://10.20.0.2/nsx) - source: ^https?://(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])(:(6553[0-5]|655[0-2][\d]|65[0-4][\d]{2}|6[0-4][\d]{3}|5[\d]{4}|[\d][\d]{0,3}))?(/.*)?$ + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' type: text - value: '' - weight: 70 - replication_mode: - description: '' - label: NSX cluster has Service nodes - type: checkbox - value: true - weight: 90 - transport_zone_uuid: - description: UUID of the pre-existing default NSX Transport zone - label: Transport zone UUID + value: '10000' + weight: 31 + vni_range_start: + description: VXLAN VNI IDs range start + label: VNI range start regex: - error: Invalid transport zone UUID - source: '[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}' + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' type: text - value: '' - weight: 40 + value: '10' + weight: 30 provision: metadata: label: Provision - restrictions: - - action: hide - condition: not ('experimental' in version:feature_groups) weight: 80 method: description: Which provision method to use for this cluster. label: Provision method type: radio - value: cobbler + value: image values: - data: image description: Copying pre-built images on a disk. label: Image - data: cobbler description: Install from scratch using anaconda or debian-installer. - label: Classic (use anaconda or debian-installer) + label: (DEPRECATED) Classic (use anaconda or debian-installer) public_network_assignment: assign_to_all_nodes: - description: When disabled, public network will be assigned to controllers - and zabbix-server only + description: When disabled, public network will be assigned to controllers only label: Assign public network to all nodes type: checkbox value: false @@ -682,42 +635,118 @@ settings: - action: hide condition: cluster:net_provider != 'neutron' weight: 50 + repo_setup: + metadata: + always_editable: true + 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-6.1/operations.html#external-ubuntu-ops). + + ' + extra_priority: null + type: custom_repo_configuration + value: + - name: ubuntu + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-updates + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-security + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: mos + priority: 1050 + section: main restricted + suite: mos6.1 + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/ubuntu/x86_64 + - name: mos-updates + priority: 1050 + section: main restricted + suite: mos6.1-updates + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-security + priority: 1050 + section: main restricted + suite: mos6.1-security + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-holdback + priority: 1100 + section: main restricted + suite: mos6.1-holdback + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: Auxiliary + priority: 1150 + section: main restricted + suite: auxiliary + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/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). + 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) - restrictions: - - settings:common.libvirt_type.value == 'vcenter' type: checkbox - value: false + 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: false + 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: - - settings:common.libvirt_type.value != 'vcenter' + - 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.' + (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 @@ -735,123 +764,31 @@ settings: 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. + 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*$ - restrictions: - - settings:common.libvirt_type.value == 'vcenter' type: text value: '2' weight: 85 - vc_datacenter: - description: Inventory path to a datacenter. If you want to use ESXi host - as datastore, it should be "ha-datacenter". - label: Datacenter name - regex: - error: Empty datacenter - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 65 - vc_datastore: - description: Datastore associated with the datacenter. - label: Datastore name - regex: - error: Empty datastore - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 60 - vc_host: - description: IP Address of vCenter/ESXi - label: vCenter/ESXi IP - regex: - error: Specify valid IPv4 address - source: ^(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])$ - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 45 - vc_image_dir: - description: The name of the directory where the glance images will be stored - in the VMware datastore. - label: Datastore Images directory - regex: - error: Empty images directory - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: /openstack_glance - weight: 70 - vc_password: - description: vCenter/ESXi admin password - label: Password - regex: - error: Empty password - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: password - value: '' - weight: 55 - vc_user: - description: vCenter/ESXi admin username - label: Username - regex: - error: Empty username - source: \S - restrictions: - - action: hide - condition: settings:storage.images_vcenter.value == false or settings:common.libvirt_type.value - != 'vcenter' - type: text - value: '' - weight: 50 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:common.libvirt_type.value - == 'vcenter' + - settings:storage.volumes_lvm.value == true type: checkbox - value: false + value: true weight: 20 volumes_lvm: - description: Requires at least one Storage - Cinder LVM node. + 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: true - weight: 10 - volumes_vmdk: - description: Configures Cinder to store volumes via VMware vCenter. - label: VMware vCenter for volumes (Cinder) - restrictions: - - settings:common.libvirt_type.value != 'vcenter' or settings:storage.volumes_lvm.value - == true - type: checkbox value: false - weight: 15 + weight: 10 syslog: metadata: label: Syslog @@ -883,94 +820,22 @@ settings: description: '' label: TCP weight: 30 - vcenter: - cluster: - description: vCenter cluster name. If you have multiple clusters, use comma - to separate names - label: Cluster - regex: - error: Invalid cluster list - source: ^([^,\ ]+([\ ]*[^,\ ])*)(,[^,\ ]+([\ ]*[^,\ ])*)*$ - type: text - value: '' - weight: 40 - datastore_regex: - description: The Datastore regexp setting specifies the data stores to use - with Compute. For example, "nas.*". If you want to use all available datastores, - leave this field blank - label: Datastore regexp - regex: - error: Invalid datastore regexp - source: ^(\S.*\S|\S|)$ - type: text - value: '' - weight: 50 - host_ip: - description: IP Address of vCenter - label: vCenter IP - regex: - error: Specify valid IPv4 address - source: ^(([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])\.){3}([\d]|[1-9][\d]|1[\d]{2}|2[0-4][\d]|25[0-5])$ - type: text - value: '' - weight: 10 - metadata: - label: vCenter - restrictions: - - action: hide - condition: settings:common.libvirt_type.value != 'vcenter' - weight: 20 - use_vcenter: - description: '' - label: '' + workloads_collector: + enabled: type: hidden value: true - weight: 5 - vc_password: - description: vCenter admin password - label: Password - regex: - error: Empty password - source: \S - type: password - value: admin - weight: 30 - vc_user: - description: vCenter admin username - label: Username - regex: - error: Empty username - source: \S - type: text - value: admin - weight: 20 - vlan_interface: - description: Physical ESXi host ethernet adapter for VLAN networking (e.g. - vmnic1). If empty "vmnic0" is used by default - label: ESXi VLAN interface - restrictions: - - action: hide - condition: cluster:net_provider != 'nova_network' or networking_parameters:net_manager - != 'VlanManager' - type: text - value: '' - weight: 60 - zabbix: metadata: - label: Zabbix Access + label: Workloads Collector User restrictions: - action: hide - condition: not ('experimental' in version:feature_groups) - weight: 70 + condition: 'true' + weight: 10 password: - description: Password for Zabbix Administrator - label: password type: password - value: zabbix - weight: 20 - username: - description: Username for Zabbix Administrator - label: username + value: pBkLbu1k + tenant: type: text - value: admin - weight: 10 + value: services + user: + type: text + value: fuel_stats_user diff --git a/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod2/dha.yaml b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod2/dha.yaml new file mode 100644 index 000000000..cfc97094c --- /dev/null +++ b/fuel/deploy/templates/hardware_environment/conf/linux_foundation_lab/pod2/dha.yaml @@ -0,0 +1,49 @@ +title: Deployment Hardware Adapter (DHA) +# DHA API version supported +version: +created: +comment: Config for LF POD2 and Opendaylight + +# Adapter to use for this definition +adapter: ipmi + +# Node list. +# Mandatory property is id, all other properties are adapter specific. + +nodes: +- id: 1 + pxeMac: 00:25:b5:a0:00:2a + ipmiIp: 172.30.8.75 + ipmiUser: admin + ipmiPass: octopus +- id: 2 + pxeMac: 00:25:b5:a0:00:3a + ipmiIp: 172.30.8.65 + ipmiUser: admin + ipmiPass: octopus +- id: 3 + pxeMac: 00:25:b5:a0:00:4a + ipmiIp: 172.30.8.74 + ipmiUser: admin + ipmiPass: octopus +- id: 4 + pxeMac: 00:25:b5:a0:00:5a + ipmiIp: 172.30.8.73 + ipmiUser: admin + ipmiPass: octopus +- id: 5 + pxeMac: 00:25:b5:a0:00:6a + ipmiIp: 172.30.8.72 + ipmiUser: admin + ipmiPass: octopus +# Adding the Fuel node as node id 6 which may not be correct - please +# adjust as needed. +- id: 6 + libvirtName: fuel-opnfv + libvirtTemplate: templates/hardware_environment/vms/fuel.xml + isFuel: yes + username: root + password: r00tme + +disks: + fuel: 50G
\ No newline at end of file diff --git a/fuel/deploy/templates/hardware_environment/conf/opnfv_box/dea.yaml b/fuel/deploy/templates/hardware_environment/conf/opnfv_box/dea.yaml new file mode 100644 index 000000000..0895e4f1d --- /dev/null +++ b/fuel/deploy/templates/hardware_environment/conf/opnfv_box/dea.yaml @@ -0,0 +1,842 @@ +title: Deployment Environment Adapter (DEA) +# DEA API version supported +version: +created: +comment: Config for OPNFV BOX - HA deployment with Ceph +environment: + name: opnfv_virt + mode: ha + net_segment_type: gre +wanted_release: Juno on Ubuntu 14.04.1 +nodes: +- id: 1 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 2 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 3 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 4 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +- id: 5 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +opnfv: + hosts: + - name: + address: + fqdn: +fuel: + ADMIN_NETWORK: + ipaddress: 10.20.0.2 + netmask: 255.255.0.0 + dhcp_pool_start: 10.20.0.3 + dhcp_pool_end: 10.20.0.254 + DNS_UPSTREAM: 8.8.8.8 + DNS_DOMAIN: domain.tld + DNS_SEARCH: domain.tld + FUEL_ACCESS: + user: admin + password: admin + HOSTNAME: opnfv + NTP1: 0.pool.ntp.org + NTP2: 1.pool.ntp.org + NTP3: 2.pool.ntp.org +interfaces_1: + eth0: + - public + eth1: + - fuelweb_admin + - 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: eth0 + - action: add-port + bridge: br-mgmt + name: eth1.300 + - action: add-port + bridge: br-storage + name: eth1.301 + - action: add-port + bridge: br-mesh + name: eth1.302 + - action: add-port + bridge: br-ex + name: eth0 +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: eth1.300 + - action: add-port + bridge: br-storage + name: eth1.301 + - action: add-port + bridge: br-mesh + name: eth1.302 +network: + networking_parameters: + base_mac: fa:16:3e:00:00:00 + dns_nameservers: + - 8.8.4.4 + - 8.8.8.8 + floating_ranges: + - - 172.30.10.83 + - 172.30.10.92 + gre_id_range: + - 2 + - 65535 + internal_cidr: 192.168.111.0/24 + internal_gateway: 192.168.111.1 + net_l23_provider: ovs + segmentation_type: gre + vlan_range: + - 1000 + - 1030 + networks: + - cidr: 172.30.10.0/24 + gateway: 172.30.10.1 + ip_ranges: + - - 172.30.10.73 + - 172.30.10.82 + meta: + cidr: 172.30.10.0/24 + configurable: true + floating_range_var: floating_ranges + ip_range: + - 172.30.10.73 + - 172.30.10.82 + 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.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: 300 + name: management + vlan_start: 300 + - 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: 301 + name: storage + vlan_start: 301 + - cidr: 192.168.2.0/24 + gateway: null + ip_ranges: + - - 192.168.2.1 + - 192.168.2.254 + meta: + assign_vip: 192.168.2.0/24 + configurable: true + map_priority: 2 + name: private + notation: cidr + render_addr_mask: private + render_type: cidr + seg_type: gre + use_gateway: false + vlan_start: 302 + name: private + vlan_start: 302 + - cidr: 10.20.0.0/24 + gateway: 10.20.0.2 + ip_ranges: + - - 10.20.0.3 + - 10.20.255.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: + 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$)(?![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$)(?![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: 40 + heat: + description: '' + label: '' + type: hidden + value: true + weight: 30 + metadata: + 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: 40 + murano: + description: If selected, Murano component will be installed + label: Install Murano + restrictions: + - cluster:net_provider != 'neutron' + type: checkbox + value: false + weight: 20 + 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 + 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 + 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. + label: OpenStack debug logging + type: checkbox + value: false + weight: 20 + libvirt_type: + 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: 30 + nova_quota: + description: Quotas are used to limit CPU and memory usage for tenants. Enabling + quotas will increase load on the Nova database. + label: Nova quotas + type: checkbox + value: false + weight: 25 + puppet_debug: + description: Debug puppet logging mode provides more information, but requires + more disk space. + 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. + label: Resume guests state on host boot + type: checkbox + value: true + weight: 60 + 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. + label: Use qcow format for images + type: checkbox + value: true + weight: 50 + use_vcenter: + type: hidden + value: false + weight: 30 + corosync: + group: + description: '' + label: Group + type: text + value: 226.94.1.1 + weight: 10 + metadata: + 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.4.4, 8.8.8.8 + weight: 10 + metadata: + label: Host OS DNS Servers + weight: 90 + 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: + label: External MongoDB + restrictions: + - action: hide + condition: settings:additional_components.mongo.value == false + 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: + label: Host OS NTP Servers + weight: 100 + 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.pool.ntp.org, 1.pool.ntp.org + weight: 10 + kernel_params: + kernel: + description: Default kernel parameters + label: Initial parameters + type: text + value: console=ttyS0,9600 console=tty0 net.ifnames=0 biosdevname=0 rootdelay=90 + nomodeset + weight: 45 + metadata: + label: Kernel parameters + weight: 40 + murano_settings: + metadata: + label: Murano Settings + restrictions: + - action: hide + condition: settings:additional_components.murano.value == false + weight: 20 + murano_repo_url: + description: '' + label: Murano Repository URL + type: text + value: http://storage.apps.openstack.org/ + weight: 10 + neutron_mellanox: + metadata: + enabled: true + 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: + enabled: true + label: OpenDaylight plugin + plugin_id: 1 + restrictions: + - cluster:net_provider != 'neutron': Only neutron is supported by OpenDaylight + toggleable: true + weight: 70 + 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 + use_vxlan: + description: Configure neutron to use VXLAN tunneling + label: Use vxlan + restrictions: + - action: disable + condition: networking_parameters:segmentation_type == 'vlan' + message: Neutron with GRE segmentation required + type: checkbox + value: true + weight: 20 + vni_range_end: + description: VXLAN VNI IDs range end + label: VNI range end + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10000' + weight: 31 + vni_range_start: + description: VXLAN VNI IDs range start + label: VNI range start + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10' + weight: 30 + provision: + metadata: + label: Provision + weight: 80 + method: + description: Which provision method to use for this cluster. + label: Provision method + type: radio + value: image + values: + - data: image + description: Copying pre-built images on a disk. + label: Image + - data: cobbler + description: Install from scratch using anaconda or debian-installer. + label: (DEPRECATED) Classic (use anaconda or debian-installer) + 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: + label: Public network assignment + restrictions: + - action: hide + condition: cluster:net_provider != 'neutron' + weight: 50 + repo_setup: + metadata: + always_editable: true + 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-6.1/operations.html#external-ubuntu-ops). + + ' + extra_priority: null + type: custom_repo_configuration + value: + - name: ubuntu + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-updates + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-security + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: mos + priority: 1050 + section: main restricted + suite: mos6.1 + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/ubuntu/x86_64 + - name: mos-updates + priority: 1050 + section: main restricted + suite: mos6.1-updates + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-security + priority: 1050 + section: main restricted + suite: mos6.1-security + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-holdback + priority: 1100 + section: main restricted + suite: mos6.1-holdback + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: Auxiliary + priority: 1150 + section: main restricted + suite: auxiliary + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/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: + label: Storage + 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) + restrictions: + - settings:storage.images_ceph.value == false + type: checkbox + value: false + 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: '2' + weight: 85 + 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 + 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: + label: Syslog + 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 + 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: + label: Workloads Collector User + restrictions: + - action: hide + condition: 'true' + weight: 10 + password: + type: password + value: pBkLbu1k + tenant: + type: text + value: services + user: + type: text + value: fuel_stats_user diff --git a/fuel/deploy/templates/hardware_environment/conf/opnfv_box/dha.yaml b/fuel/deploy/templates/hardware_environment/conf/opnfv_box/dha.yaml new file mode 100644 index 000000000..c2624f2ba --- /dev/null +++ b/fuel/deploy/templates/hardware_environment/conf/opnfv_box/dha.yaml @@ -0,0 +1,49 @@ +title: Deployment Hardware Adapter (DHA) +# DHA API version supported +version: +created: +comment: Config for OPNFV BOX + +# Adapter to use for this definition +adapter: ipmi + +# Node list. +# Mandatory property is id, all other properties are adapter specific. + +nodes: +- id: 1 + pxeMac: b8:ae:ed:76:4d:a4 + ipmiIp: <ipmi_ip> + ipmiUser: <username> + ipmiPass: <password> +- id: 2 + pxeMac: b8:ae:ed:76:4d:94 + ipmiIp: <ipmi_ip> + ipmiUser: <username> + ipmiPass: <password> +- id: 3 + pxeMac: b8:ae:ed:76:4c:eb + ipmiIp: <ipmi_ip> + ipmiUser: <username> + ipmiPass: <password> +- id: 4 + pxeMac: b8:ae:ed:76:37:62 + ipmiIp: <ipmi_ip> + ipmiUser: <username> + ipmiPass: <password> +- id: 5 + pxeMac: b8:ae:ed:76:4d:95 + ipmiIp: <ipmi_ip> + ipmiUser: <username> + ipmiPass: <password> +# Adding the Fuel node as node id 6 which may not be correct - please +# adjust as needed. +- id: 6 + libvirtName: fuel-opnfv + libvirtTemplate: templates/hardware_environment/vms/fuel.xml + isFuel: yes + username: root + password: r00tme + +disks: + fuel: 50G
\ No newline at end of file diff --git a/fuel/deploy/baremetal/vm/vFuel b/fuel/deploy/templates/hardware_environment/vms/fuel.xml index 1b4f4eb47..e3e3f80bb 100644 --- a/fuel/deploy/baremetal/vm/vFuel +++ b/fuel/deploy/templates/hardware_environment/vms/fuel.xml @@ -1,15 +1,15 @@ -<domain type='kvm'> - <name>vFuel</name> +<domain type='kvm' id='62'> + <name>fuel</name> <memory unit='KiB'>8290304</memory> <currentMemory unit='KiB'>8290304</currentMemory> - <vcpu placement='static'>2</vcpu> + <vcpu placement='static'>4</vcpu> <resource> <partition>/machine</partition> </resource> <os> - <type arch='x86_64' machine='pc-i440fx-utopic'>hvm</type> - <boot dev='hd'/> + <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type> <boot dev='cdrom'/> + <boot dev='hd'/> <bootmenu enable='no'/> </os> <features> @@ -33,15 +33,14 @@ <suspend-to-disk enabled='no'/> </pm> <devices> - <emulator>/usr/bin/kvm</emulator> + <emulator>/usr/libexec/qemu-kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='raw'/> - <source file='/mnt/images/vFuel.raw'/> <target dev='vda' bus='virtio'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> - <target dev='hda' bus='ide'/> + <target dev='hdb' bus='ide'/> <readonly/> </disk> <controller type='usb' index='0' model='ich9-ehci1'> @@ -55,19 +54,21 @@ <controller type='usb' index='0' model='ich9-uhci3'> <master startport='4'/> </controller> - <controller type='pci' index='0' model='pci-root'/> - <controller type='virtio-serial' index='0'> + <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'> - <source bridge='vfuelnet'/> <model type='virtio'/> </interface> <serial type='pty'> + <source path='/dev/pts/0'/> <target port='0'/> </serial> - <console type='pty'> + <console type='pty' tty='/dev/pts/0'> + <source path='/dev/pts/0'/> <target type='serial' port='0'/> </console> <input type='mouse' bus='ps2'/> @@ -83,5 +84,8 @@ <memballoon model='virtio'> </memballoon> </devices> - <seclabel type='dynamic' model='apparmor' relabel='yes'/> -</domain> + <seclabel type='dynamic' model='selinux' relabel='yes'> + <label>system_u:system_r:svirt_t:s0:c52,c932</label> + <imagelabel>system_u:object_r:svirt_image_t:s0:c52,c932</imagelabel> + </seclabel> +</domain>
\ No newline at end of file diff --git a/fuel/deploy/templates/virtual_environment/conf/dea.yaml b/fuel/deploy/templates/virtual_environment/conf/dea.yaml new file mode 100644 index 000000000..bc9a1f931 --- /dev/null +++ b/fuel/deploy/templates/virtual_environment/conf/dea.yaml @@ -0,0 +1,838 @@ +title: Deployment Environment Adapter (DEA) +# DEA API version supported +version: +created: +comment: Config for Virtual Environment - HA deployment with Ceph and Opendaylight +environment: + name: opnfv_virt + mode: ha + net_segment_type: gre +wanted_release: Juno on Ubuntu 14.04.1 +nodes: +- id: 1 + interfaces: interfaces_1 + transformations: transformations_1 + role: ceph-osd,controller +- id: 2 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +- id: 3 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +- id: 4 + interfaces: interfaces_1 + transformations: transformations_2 + role: ceph-osd,compute +fuel: + ADMIN_NETWORK: + ipaddress: 10.20.0.2 + netmask: 255.255.0.0 + dhcp_pool_start: 10.20.0.3 + dhcp_pool_end: 10.20.0.254 + DNS_UPSTREAM: 10.118.32.193 + DNS_DOMAIN: opnfvericsson.ca + DNS_SEARCH: opnfvericsson.ca + FUEL_ACCESS: + user: admin + password: admin + HOSTNAME: opnfv_virt + NTP1: 10.118.34.219 + NTP2: + NTP3: +interfaces_1: + eth0: + - fuelweb_admin + - management + eth1: + - storage + eth2: + - private + eth3: + - public +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: eth0 + - action: add-port + bridge: br-mgmt + name: eth0.101 + - action: add-port + bridge: br-storage + name: eth1.102 + - action: add-port + bridge: br-mesh + name: eth2.103 + - action: add-port + bridge: br-ex + name: eth3 +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: eth0.101 + - action: add-port + bridge: br-storage + name: eth1.102 + - action: add-port + bridge: br-mesh + name: eth2.103 +network: + management_vip: 192.168.0.2 + management_vrouter_vip: 192.168.0.3 + networking_parameters: + base_mac: fa:16:3e:00:00:00 + dns_nameservers: + - 10.118.32.193 + floating_ranges: + - - 172.16.0.130 + - 172.16.0.254 + gre_id_range: + - 2 + - 65535 + internal_cidr: 192.168.111.0/24 + internal_gateway: 192.168.111.1 + net_l23_provider: ovs + segmentation_type: gre + vlan_range: + - 1000 + - 1030 + networks: + - cidr: 172.16.0.0/24 + gateway: 172.16.0.1 + ip_ranges: + - - 172.16.0.2 + - 172.16.0.126 + meta: + cidr: 172.16.0.0/24 + configurable: true + floating_range_var: floating_ranges + ip_range: + - 172.16.0.2 + - 172.16.0.126 + 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.0.0/24 + gateway: null + ip_ranges: + - - 192.168.0.2 + - 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.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.2.0/24 + gateway: null + ip_ranges: + - - 192.168.2.2 + - 192.168.2.254 + meta: + cidr: 192.168.2.0/24 + configurable: true + map_priority: 2 + name: private + notation: cidr + render_addr_mask: private + render_type: cidr + seg_type: gre + use_gateway: false + vlan_start: 103 + name: private + vlan_start: 103 + - cidr: 10.20.0.0/16 + 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 + public_vip: 172.16.0.2 + public_vrouter_vip: 172.16.0.3 +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: + 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$)(?![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$)(?![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: 40 + heat: + description: '' + label: '' + type: hidden + value: true + weight: 30 + metadata: + 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: 40 + murano: + description: If selected, Murano component will be installed + label: Install Murano + restrictions: + - cluster:net_provider != 'neutron' + type: checkbox + value: false + weight: 20 + 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 + 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 + 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. + label: OpenStack debug logging + type: checkbox + value: false + weight: 20 + libvirt_type: + label: Hypervisor type + type: radio + value: qemu + 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: 30 + nova_quota: + description: Quotas are used to limit CPU and memory usage for tenants. Enabling + quotas will increase load on the Nova database. + label: Nova quotas + type: checkbox + value: false + weight: 25 + puppet_debug: + description: Debug puppet logging mode provides more information, but requires + more disk space. + 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. + label: Resume guests state on host boot + type: checkbox + value: true + weight: 60 + 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. + label: Use qcow format for images + type: checkbox + value: true + weight: 50 + use_vcenter: + type: hidden + value: false + weight: 30 + corosync: + group: + description: '' + label: Group + type: text + value: 226.94.1.1 + weight: 10 + metadata: + 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: 10.118.32.193 + weight: 10 + metadata: + label: Host OS DNS Servers + weight: 90 + 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: + label: External MongoDB + restrictions: + - action: hide + condition: settings:additional_components.mongo.value == false + 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: + label: Host OS NTP Servers + weight: 100 + 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: 10.118.34.219 + weight: 10 + kernel_params: + kernel: + description: Default kernel parameters + label: Initial parameters + type: text + value: console=ttyS0,9600 console=tty0 net.ifnames=0 biosdevname=0 rootdelay=90 + nomodeset + weight: 45 + metadata: + label: Kernel parameters + weight: 40 + murano_settings: + metadata: + label: Murano Settings + restrictions: + - action: hide + condition: settings:additional_components.murano.value == false + weight: 20 + murano_repo_url: + description: '' + label: Murano Repository URL + type: text + value: http://storage.apps.openstack.org/ + weight: 10 + neutron_mellanox: + metadata: + enabled: true + 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: + enabled: true + label: OpenDaylight plugin + plugin_id: 1 + restrictions: + - cluster:net_provider != 'neutron': Only neutron is supported by OpenDaylight + toggleable: true + weight: 70 + 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 + use_vxlan: + description: Configure neutron to use VXLAN tunneling + label: Use vxlan + restrictions: + - action: disable + condition: networking_parameters:segmentation_type == 'vlan' + message: Neutron with GRE segmentation required + type: checkbox + value: true + weight: 20 + vni_range_end: + description: VXLAN VNI IDs range end + label: VNI range end + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10000' + weight: 31 + vni_range_start: + description: VXLAN VNI IDs range start + label: VNI range start + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10' + weight: 30 + provision: + metadata: + label: Provision + weight: 80 + method: + description: Which provision method to use for this cluster. + label: Provision method + type: radio + value: image + values: + - data: image + description: Copying pre-built images on a disk. + label: Image + - data: cobbler + description: Install from scratch using anaconda or debian-installer. + label: (DEPRECATED) Classic (use anaconda or debian-installer) + 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: + label: Public network assignment + restrictions: + - action: hide + condition: cluster:net_provider != 'neutron' + weight: 50 + repo_setup: + metadata: + always_editable: true + 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-6.1/operations.html#external-ubuntu-ops). + + ' + extra_priority: null + type: custom_repo_configuration + value: + - name: ubuntu + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-updates + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: ubuntu-security + priority: null + section: main + suite: trusty + type: deb + uri: http://10.20.0.2:8080/ubuntu-part + - name: mos + priority: 1050 + section: main restricted + suite: mos6.1 + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/ubuntu/x86_64 + - name: mos-updates + priority: 1050 + section: main restricted + suite: mos6.1-updates + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-security + priority: 1050 + section: main restricted + suite: mos6.1-security + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: mos-holdback + priority: 1100 + section: main restricted + suite: mos6.1-holdback + type: deb + uri: http://10.20.0.2:8080/mos-ubuntu + - name: Auxiliary + priority: 1150 + section: main restricted + suite: auxiliary + type: deb + uri: http://10.20.0.2:8080/2014.2.2-6.1/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: + label: Storage + 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) + restrictions: + - settings:storage.images_ceph.value == false + type: checkbox + value: false + 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: '2' + weight: 85 + 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 + 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: + label: Syslog + 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 + 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: + label: Workloads Collector User + restrictions: + - action: hide + condition: 'true' + weight: 10 + password: + type: password + value: pBkLbu1k + tenant: + type: text + value: services + user: + type: text + value: fuel_stats_user diff --git a/fuel/deploy/templates/virtual_environment/conf/dha.yaml b/fuel/deploy/templates/virtual_environment/conf/dha.yaml new file mode 100644 index 000000000..6d476b874 --- /dev/null +++ b/fuel/deploy/templates/virtual_environment/conf/dha.yaml @@ -0,0 +1,38 @@ +title: Deployment Hardware Adapter (DHA) +# DHA API version supported +version: +created: +comment: Config for Virtual Environment + +# Adapter to use for this definition +adapter: libvirt + +# Node list. +# Mandatory property is id, all other properties are adapter specific. + +nodes: +- id: 1 + libvirtName: controller1 + libvirtTemplate: templates/virtual_environment/vms/controller.xml +- id: 2 + libvirtName: compute1 + libvirtTemplate: templates/virtual_environment/vms/compute.xml +- id: 3 + libvirtName: compute2 + libvirtTemplate: templates/virtual_environment/vms/compute.xml +- id: 4 + libvirtName: compute3 + libvirtTemplate: templates/virtual_environment/vms/compute.xml +- id: 5 + libvirtName: fuel-master + libvirtTemplate: templates/virtual_environment/vms/fuel.xml + isFuel: yes + username: root + password: r00tme + +virtNetConfDir: templates/virtual_environment/networks + +disks: + fuel: 50G + controller: 50G + compute: 50G diff --git a/fuel/deploy/libvirt/networks/fuel1 b/fuel/deploy/templates/virtual_environment/networks/fuel1.xml index 7b2b15423..7b2b15423 100644 --- a/fuel/deploy/libvirt/networks/fuel1 +++ b/fuel/deploy/templates/virtual_environment/networks/fuel1.xml diff --git a/fuel/deploy/libvirt/networks/fuel2 b/fuel/deploy/templates/virtual_environment/networks/fuel2.xml index 615c92094..615c92094 100644 --- a/fuel/deploy/libvirt/networks/fuel2 +++ b/fuel/deploy/templates/virtual_environment/networks/fuel2.xml diff --git a/fuel/deploy/libvirt/networks/fuel3 b/fuel/deploy/templates/virtual_environment/networks/fuel3.xml index 2383e6c1f..2383e6c1f 100644 --- a/fuel/deploy/libvirt/networks/fuel3 +++ b/fuel/deploy/templates/virtual_environment/networks/fuel3.xml diff --git a/fuel/deploy/libvirt/networks/fuel4 b/fuel/deploy/templates/virtual_environment/networks/fuel4.xml index 5b69f912d..5b69f912d 100644 --- a/fuel/deploy/libvirt/networks/fuel4 +++ b/fuel/deploy/templates/virtual_environment/networks/fuel4.xml diff --git a/fuel/deploy/libvirt/vms/compute b/fuel/deploy/templates/virtual_environment/vms/compute.xml index 75915090c..fbef4bda7 100644 --- a/fuel/deploy/libvirt/vms/compute +++ b/fuel/deploy/templates/virtual_environment/vms/compute.xml @@ -1,5 +1,5 @@ <domain type='kvm'> - <name>compute4</name> + <name>compute</name> <memory unit='KiB'>8388608</memory> <currentMemory unit='KiB'>8388608</currentMemory> <vcpu placement='static'>2</vcpu> @@ -7,7 +7,7 @@ <type arch='x86_64' machine='pc-1.0'>hvm</type> <boot dev='network'/> <boot dev='hd'/> - <bootmenu enable='yes'/> + <bios rebootTimeout='30000'/> </os> <features> <acpi/> diff --git a/fuel/deploy/libvirt/vms/controller b/fuel/deploy/templates/virtual_environment/vms/controller.xml index a87126296..3ff28218d 100644 --- a/fuel/deploy/libvirt/vms/controller +++ b/fuel/deploy/templates/virtual_environment/vms/controller.xml @@ -1,12 +1,13 @@ <domain type='kvm'> - <name>controller1</name> - <memory unit='KiB'>2097152</memory> - <currentMemory unit='KiB'>2097152</currentMemory> + <name>controller</name> + <memory unit='KiB'>8388608</memory> + <currentMemory unit='KiB'>8388608</currentMemory> <vcpu placement='static'>2</vcpu> <os> <type arch='x86_64' machine='pc-1.0'>hvm</type> <boot dev='network'/> <boot dev='hd'/> + <bios rebootTimeout='30000'/> </os> <features> <acpi/> diff --git a/fuel/deploy/libvirt/vms/fuel-master b/fuel/deploy/templates/virtual_environment/vms/fuel.xml index f4e652bf2..1a3286001 100644 --- a/fuel/deploy/libvirt/vms/fuel-master +++ b/fuel/deploy/templates/virtual_environment/vms/fuel.xml @@ -1,5 +1,5 @@ <domain type='kvm'> - <name>fuel-master</name> + <name>fuel</name> <memory unit='KiB'>2097152</memory> <currentMemory unit='KiB'>2097152</currentMemory> <vcpu placement='static'>2</vcpu> diff --git a/fuel/deploy/transplant_fuel_settings.py b/fuel/deploy/transplant_fuel_settings.py index bb4f9b6d7..d2aece87a 100644 --- a/fuel/deploy/transplant_fuel_settings.py +++ b/fuel/deploy/transplant_fuel_settings.py @@ -1,3 +1,13 @@ +############################################################################### +# Copyright (c) 2015 Ericsson AB and others. +# 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 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################### + + import sys import common import io @@ -6,12 +16,16 @@ from dea import DeploymentEnvironmentAdapter check_file_exists = common.check_file_exists +ASTUTE_YAML = '/etc/fuel/astute.yaml' + + def usage(): print ''' Usage: python transplant_fuel_settings.py <deafile> ''' + def parse_arguments(): if len(sys.argv) != 2: usage() @@ -20,6 +34,7 @@ def parse_arguments(): check_file_exists(dea_file) return dea_file + def transplant(dea, astute): fuel_conf = dea.get_fuel_config() for key in fuel_conf.iterkeys(): @@ -30,17 +45,17 @@ def transplant(dea, astute): astute[key] = fuel_conf[key] return astute + def main(): dea_file = parse_arguments() - astute_yaml = '/etc/fuel/astute.yaml' - check_file_exists(astute_yaml) + check_file_exists(ASTUTE_YAML) dea = DeploymentEnvironmentAdapter(dea_file) - with io.open(astute_yaml) as stream: + with io.open(ASTUTE_YAML) as stream: astute = yaml.load(stream) transplant(dea, astute) - with io.open(astute_yaml, 'w') as stream: + with io.open(ASTUTE_YAML, 'w') as stream: yaml.dump(astute, stream, default_flow_style=False) if __name__ == '__main__': - main()
\ No newline at end of file + main() |