Add initial config to support deployments on VMs 21/72621/10
authorRihab Banday <rihab.banday@ericsson.com>
Mon, 31 May 2021 18:23:21 +0000 (20:23 +0200)
committerRihab Banday <rihab.banday@ericsson.com>
Wed, 1 Sep 2021 15:03:29 +0000 (15:03 +0000)
* Add initial version of PDF and IDF that
will be consumed by the hardware provisioner used in
Kuberef to bring up libvirt VMs (for now 2 VMs for dev purposes).
* Add deploy_on_vms.sh script to deploy Kuberef on VMs
* Add new functions referenced by the deploy_on_vms.sh
script - these can be merged with existing functions
* Modify some of te BMRA templates to accomodate new changes.

This has been tested on Ubuntu 18.04 baremetal server.

Change-Id: I95a5e85cdab95befd24a1cae9f367b32ce26621e
Signed-off-by: Rihab Banday <rihab.banday@ericsson.com>
Reviewed-on: https://gerrit.opnfv.org/gerrit/c/kuberef/+/72621
Tested-by: jenkins-ci <jenkins-opnfv-ci@opnfv.org>
Reviewed-by: Michael Pedersen <michaelx.pedersen@intel.com>
Reviewed-by: Georg Kunz <georg.kunz@ericsson.com>
12 files changed:
deploy.env
deploy.sh
dev/deploy_on_vms.sh [new file with mode: 0755]
functions.sh
hw_config/libvirt-vms/idf.yaml [new file with mode: 0644]
hw_config/libvirt-vms/pdf.yaml [new file with mode: 0644]
inventory/group_vars/all/global.yaml
playbooks/configure-vms.yaml [new file with mode: 0644]
playbooks/roles/bmra-config/templates/inventory.j2
playbooks/roles/configure-vms/tasks/main.yaml [new file with mode: 0644]
playbooks/roles/configure-vms/templates/Debian.interface.j2 [new file with mode: 0644]
requirements.txt

index e317a5f..59a5f71 100644 (file)
@@ -4,8 +4,14 @@
 
 # Define environment variables
 
+# Vendor name - some examples are listed under kuberef/hw_config
 export VENDOR=${VENDOR:-intel}
+
+# OS to be installed on target hosts
+# Currently centos7 and ubuntu1804 are supported
 export DISTRO=${DISTRO:-centos7}
+
+# k8s provisioiner details
 export INSTALLER=bmra
 export BMRA_PROFILE=$(yq r $CURRENTPATH/hw_config/$VENDOR/idf.yaml bmra.profile)
 
index f0bca92..b2426b3 100755 (executable)
--- a/deploy.sh
+++ b/deploy.sh
@@ -57,14 +57,14 @@ copy_files_jump
 # Setup networking (Adapt according to your network setup)
 # ---------------------------------------------------------------------
 if [[ "$DEPLOYMENT" == "full" ]]; then
-    provision_hosts
+    provision_hosts_baremetal
     setup_network
 fi
 
 # ---------------------------------------------------------------------
 # Provision k8s cluster (currently BMRA)
 # ---------------------------------------------------------------------
-provision_k8s
+provision_k8s_baremetal
 
 # ---------------------------------------------------------------------
 # Copy kubeconfig to desired location
diff --git a/dev/deploy_on_vms.sh b/dev/deploy_on_vms.sh
new file mode 100755 (executable)
index 0000000..2a8ad56
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/bash
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) Ericsson AB and others
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+# Script for end to end RI-2 deployment using Infra engine and BMRA on VMS
+# TODO Update README
+
+set -o errexit
+set -o nounset
+if [ "${DEBUG:-false}" == "true" ]; then
+    set -o xtrace
+fi
+
+# Get path information
+CURRENTPATH=$(git rev-parse --show-toplevel)
+export CURRENTPATH
+
+# shellcheck source=./functions.sh
+source "$CURRENTPATH/functions.sh"
+# shellcheck source=./deploy.env
+source "$CURRENTPATH/deploy.env"
+
+# ---------------------------------------------------------------------
+# check installation and runtime prerequisites
+# ---------------------------------------------------------------------
+check_prerequisites
+
+# ---------------------------------------------------------------------
+# creates a virtual environment for installation of dependencies
+# ---------------------------------------------------------------------
+creates_virtualenv
+
+# ---------------------------------------------------------------------
+# bootstrap install prerequisites
+# ---------------------------------------------------------------------
+run_playbook bootstrap
+
+# ---------------------------------------------------------------------
+# Create BMRA config based on IDF and PDF
+# ---------------------------------------------------------------------
+run_playbook bmra-config
+
+# ---------------------------------------------------------------------
+# Provision VMs
+# ---------------------------------------------------------------------
+provision_hosts_vms
+
+# ---------------------------------------------------------------------
+# Configure Networking on the VMs
+# ---------------------------------------------------------------------
+ansible-playbook -i "$CURRENTPATH"/engine/engine/inventory/inventory.ini "$CURRENTPATH"/playbooks/configure-vms.yaml
+
+# ---------------------------------------------------------------------
+# Provision k8s cluster (currently BMRA)
+# ---------------------------------------------------------------------
+provision_k8s_vms
index 4265dca..f10f2e5 100755 (executable)
@@ -63,23 +63,9 @@ check_prerequisites() {
     sudo sed -i "s/^Defaults.*env_reset/#&/" /etc/sudoers
 
     #-------------------------------------------------------------------------------
-    # Check if Python Virtual Environment is installed
+    # Check if necessary tools are installed
     #-------------------------------------------------------------------------------
-    if ! command -v virtualenv &> /dev/null; then
-        error "VirtualEnv not found. Please install."
-    fi
-
-    #-------------------------------------------------------------------------------
-    # Check if PIP Installs Packages is installed
-    #-------------------------------------------------------------------------------
-    if ! command -v pip &> /dev/null; then
-        error "PIP not found. Please install."
-    fi
-
-    #-------------------------------------------------------------------------------
-    # Check is libvirt is installed
-    #-------------------------------------------------------------------------------
-    for tool in ansible yq virsh jq; do
+    for tool in ansible yq virsh jq docker virtualenv pip; do
         if ! command -v "$tool" &> /dev/null; then
             error "$tool not found. Please install."
         fi
@@ -173,23 +159,37 @@ copy_files_jump() {
 }
 
 # Host Provisioning
-provision_hosts() {
+provision_hosts_baremetal() {
     # shellcheck disable=SC2087
     ssh -o StrictHostKeyChecking=no -tT "$USERNAME"@"$(get_vm_ip)" << EOF
 # Install and run cloud-infra
-if [ ! -d "${PROJECT_ROOT}/engine" ]; then
-    ssh-keygen -t rsa -N "" -f ${PROJECT_ROOT}/.ssh/id_rsa
+if [ ! -d "${PROJECT_ROOT}"/engine" ]; then
+    ssh-keygen -t rsa -N "" -f "${PROJECT_ROOT}"/.ssh/id_rsa
     git clone https://gerrit.nordix.org/infra/engine.git
-    cd ${PROJECT_ROOT}/engine/engine && git checkout ${ENGINE_COMMIT_ID}
-    cp ${PROJECT_ROOT}/${VENDOR}/{pdf.yaml,idf.yaml} \
-    ${PROJECT_ROOT}/engine/engine
+    cp "${PROJECT_ROOT}"/"${VENDOR}"/{pdf.yaml,idf.yaml} \
+    "${PROJECT_ROOT}"/engine/engine
 fi
-${PROJECT_ROOT}/engine/engine/deploy.sh -s ironic -d ${DISTRO} \
--p file:///${PROJECT_ROOT}/engine/engine/pdf.yaml \
--i file:///${PROJECT_ROOT}/engine/engine/idf.yaml
+cd "${PROJECT_ROOT}"/engine/engine || return
+./deploy.sh -s ironic -d "${DISTRO}" \
+-p file:///"${PROJECT_ROOT}"/engine/engine/pdf.yaml \
+-i file:///"${PROJECT_ROOT}"/engine/engine/idf.yaml
 EOF
 }
 
+provision_hosts_vms() {
+    # shellcheck disable=SC2087
+# Install and run cloud-infra
+if [ ! -d "$CURRENTPATH/engine" ]; then
+    git clone https://gerrit.nordix.org/infra/engine.git "${CURRENTPATH}"/engine
+    cp "$CURRENTPATH"/hw_config/"$VENDOR"/{pdf.yaml,idf.yaml} \
+    "${CURRENTPATH}"/engine/engine
+fi
+cd "$CURRENTPATH"/engine/engine || return
+./deploy.sh -s ironic \
+-p file:///"${CURRENTPATH}"/engine/engine/pdf.yaml \
+-i file:///"${CURRENTPATH}"/engine/engine/idf.yaml
+}
+
 # Setup networking on provisioned hosts (Adapt setup_network.sh according to your network setup)
 setup_network() {
     # Set Upper limit of number nodes in RI2 cluster (starting from 0)
@@ -200,14 +200,14 @@ setup_network() {
         # SSH to jumphost
         # shellcheck disable=SC2087
         ssh -o StrictHostKeyChecking=no -tT "$USERNAME"@"$(get_vm_ip)" << EOF
-ssh -o StrictHostKeyChecking=no root@${NODE_IP} \
-    'bash -s' <  ${PROJECT_ROOT}/${VENDOR}/setup_network.sh
+ssh -o StrictHostKeyChecking=no root@"${NODE_IP}" \
+    'bash -s' <  "${PROJECT_ROOT}"/"${VENDOR}"/setup_network.sh
 EOF
     done
 }
 
 # k8s Provisioning (currently BMRA)
-provision_k8s() {
+provision_k8s_baremetal() {
     ansible_cmd="/bin/bash -c '"
     if [[ "$DEPLOYMENT" == "k8s" ]]; then
         ansible-playbook -i "$CURRENTPATH"/sw_config/bmra/inventory.ini "$CURRENTPATH"/playbooks/pre-install.yaml
@@ -226,49 +226,81 @@ if ! command -v docker; then
         sleep 2
     done
 fi
-if [ ! -d "${PROJECT_ROOT}/container-experience-kits" ]; then
-    git clone --recurse-submodules --depth 1 https://github.com/intel/container-experience-kits.git -b v21.03 ${PROJECT_ROOT}/container-experience-kits/
-    cp -r ${PROJECT_ROOT}/container-experience-kits/examples/${BMRA_PROFILE}/group_vars ${PROJECT_ROOT}/container-experience-kits/
+if [ ! -d "${PROJECT_ROOT}"/container-experience-kits" ]; then
+    git clone --recurse-submodules --depth 1 https://github.com/intel/container-experience-kits.git -b v21.03 "${PROJECT_ROOT}"/container-experience-kits/
+    cp -r "${PROJECT_ROOT}"/container-experience-kits/examples/"${BMRA_PROFILE}"/group_vars "${PROJECT_ROOT}"/container-experience-kits/
 fi
 if [ -f "${PROJECT_ROOT}/docker_config" ]; then
-    cp ${PROJECT_ROOT}/docker_config \
-        ${PROJECT_ROOT}/${INSTALLER}/dockerhub_credentials/vars/main.yml
-    cp -r ${PROJECT_ROOT}/${INSTALLER}/dockerhub_credentials \
-        ${PROJECT_ROOT}/container-experience-kits/roles/
-    cp ${PROJECT_ROOT}/${INSTALLER}/patched_k8s.yml \
-        ${PROJECT_ROOT}/container-experience-kits/playbooks/k8s/k8s.yml
+    cp "${PROJECT_ROOT}"/docker_config \
+        "${PROJECT_ROOT}"/"${INSTALLER}"/dockerhub_credentials/vars/main.yml
+    cp -r "${PROJECT_ROOT}"/"${INSTALLER}"/dockerhub_credentials \
+        "${PROJECT_ROOT}"/container-experience-kits/roles/
+    cp "${PROJECT_ROOT}"/"${INSTALLER}"/patched_k8s.yml \
+        "${PROJECT_ROOT}"/container-experience-kits/playbooks/k8s/k8s.yml
 fi
-cp ${PROJECT_ROOT}/${INSTALLER}/{inventory.ini,ansible.cfg} \
-    ${PROJECT_ROOT}/container-experience-kits/
-cp ${PROJECT_ROOT}/${INSTALLER}/{all.yml,kube-node.yml} \
-    ${PROJECT_ROOT}/container-experience-kits/group_vars/
-cp ${PROJECT_ROOT}/${INSTALLER}/patched_cmk_build.yml \
-    ${PROJECT_ROOT}/container-experience-kits/roles/cmk_install/tasks/main.yml
-cp ${PROJECT_ROOT}/${INSTALLER}/patched_vfio.yml \
-    ${PROJECT_ROOT}/container-experience-kits/roles/sriov_nic_init/tasks/bind_vf_driver.yml
-cp ${PROJECT_ROOT}/${INSTALLER}/patched_rhel_packages.yml \
-    ${PROJECT_ROOT}/container-experience-kits/roles/bootstrap/install_packages/tasks/rhel.yml
-cp ${PROJECT_ROOT}/${INSTALLER}/patched_packages.yml \
-    ${PROJECT_ROOT}/container-experience-kits/roles/bootstrap/install_packages/tasks/main.yml
-cp ${PROJECT_ROOT}/${INSTALLER}/patched_kubespray_requirements.txt \
-    ${PROJECT_ROOT}/container-experience-kits/playbooks/k8s/kubespray/requirements.txt
+cp "${PROJECT_ROOT}"/"${INSTALLER}"/{inventory.ini,ansible.cfg} \
+    "${PROJECT_ROOT}"/container-experience-kits/
+cp "${PROJECT_ROOT}"/"${INSTALLER}"/{all.yml,kube-node.yml} \
+    "${PROJECT_ROOT}"/container-experience-kits/group_vars/
+cp "${PROJECT_ROOT}"/"${INSTALLER}"/patched_cmk_build.yml \
+    "${PROJECT_ROOT}"/container-experience-kits/roles/cmk_install/tasks/main.yml
+cp "${PROJECT_ROOT}"/"${INSTALLER}"/patched_vfio.yml \
+    "${PROJECT_ROOT}"/container-experience-kits/roles/sriov_nic_init/tasks/bind_vf_driver.yml
+cp "${PROJECT_ROOT}"/"${INSTALLER}"/patched_rhel_packages.yml \
+    "${PROJECT_ROOT}"/container-experience-kits/roles/bootstrap/install_packages/tasks/rhel.yml
+cp "${PROJECT_ROOT}"/"${INSTALLER}"/patched_packages.yml \
+    "${PROJECT_ROOT}"/container-experience-kits/roles/bootstrap/install_packages/tasks/main.yml
+cp "${PROJECT_ROOT}"/"${INSTALLER}"/patched_kubespray_requirements.txt \
+    "${PROJECT_ROOT}"/container-experience-kits/playbooks/k8s/kubespray/requirements.txt
 
 sudo docker run --rm \
 -e ANSIBLE_CONFIG=/bmra/ansible.cfg \
--e PROFILE=${BMRA_PROFILE} \
--v ${PROJECT_ROOT}/container-experience-kits:/bmra \
+-e PROFILE="${BMRA_PROFILE}" \
+-v "${PROJECT_ROOT}"/container-experience-kits:/bmra \
 -v ~/.ssh/:/root/.ssh/ rihabbanday/bmra21.03-install:centos \
-${ansible_cmd}
+"${ansible_cmd}"
 EOF
 }
 
+provision_k8s_vms() {
+    # shellcheck disable=SC2087
+# Install BMRA
+if [ ! -d "${CURRENTPATH}/container-experience-kits" ]; then
+    git clone --recurse-submodules --depth 1 https://github.com/intel/container-experience-kits.git -b v21.03 "${CURRENTPATH}"/container-experience-kits/
+    cp -r "${CURRENTPATH}"/container-experience-kits/examples/"${BMRA_PROFILE}"/group_vars "${CURRENTPATH}"/container-experience-kits/
+fi
+cp "${CURRENTPATH}"/sw_config/bmra/{inventory.ini,ansible.cfg} \
+    "${CURRENTPATH}"/container-experience-kits/
+cp "${CURRENTPATH}"/sw_config/bmra/{all.yml,kube-node.yml} \
+    "${CURRENTPATH}"/container-experience-kits/group_vars/
+cp "${CURRENTPATH}"/sw_config/bmra/patched_cmk_build.yml \
+    "${CURRENTPATH}"/container-experience-kits/roles/cmk_install/tasks/main.yml
+cp "${CURRENTPATH}"/sw_config/bmra/patched_vfio.yml \
+   "${CURRENTPATH}"/container-experience-kits/roles/sriov_nic_init/tasks/bind_vf_driver.yml
+cp "${CURRENTPATH}"/sw_config/bmra/patched_rhel_packages.yml \
+    "${CURRENTPATH}"/container-experience-kits/roles/bootstrap/install_packages/tasks/rhel.yml
+cp "${CURRENTPATH}"/sw_config/bmra/patched_packages.yml \
+    "${CURRENTPATH}"/container-experience-kits/roles/bootstrap/install_packages/tasks/main.yml
+cp "${CURRENTPATH}"/sw_config/"${INSTALLER}"/patched_kubespray_requirements.txt \
+    "${CURRENTPATH}"/container-experience-kits/playbooks/k8s/kubespray/requirements.txt
+
+ansible-playbook -i "$CURRENTPATH"/sw_config/bmra/inventory.ini "$CURRENTPATH"/playbooks/pre-install.yaml
+
+sudo docker run --rm \
+-e ANSIBLE_CONFIG=/bmra/ansible.cfg \
+-e PROFILE="${BMRA_PROFILE}" \
+-v "${CURRENTPATH}"/container-experience-kits:/bmra \
+-v ~/.ssh/:/root/.ssh/ rihabbanday/bmra21.03-install:centos \
+ansible-playbook -i /bmra/inventory.ini /bmra/playbooks/"${BMRA_PROFILE}".yml
+}
+
 # Copy kubeconfig to the appropriate location needed by functest containers
 copy_k8s_config() {
 # TODO Use Kubespray variables in BMRA to simplify this
     MASTER_IP=$(get_host_pxe_ip "nodes[0]")
     # shellcheck disable=SC2087
     ssh -o StrictHostKeyChecking=no -tT "$USERNAME"@"$(get_vm_ip)" << EOF
-scp -o StrictHostKeyChecking=no -q root@$MASTER_IP:/root/.kube/config ${PROJECT_ROOT}/kubeconfig
+scp -o StrictHostKeyChecking=no -q root@"$MASTER_IP":/root/.kube/config "${PROJECT_ROOT}"/kubeconfig
 EOF
 
 # Copy kubeconfig from Jump VM to appropriate location in Jump Host
diff --git a/hw_config/libvirt-vms/idf.yaml b/hw_config/libvirt-vms/idf.yaml
new file mode 100644 (file)
index 0000000..1616f9f
--- /dev/null
@@ -0,0 +1,114 @@
+---
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2020
+# 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
+##############################################################################
+### Installer descriptor file ###
+idf:
+  version: 0.1
+  net_config: &net_config
+    admin:
+      interface: 0
+      network: 10.1.0.0
+      mask: 24
+    public:
+      interface: 1
+      network: 10.2.0.0
+      mask: 24
+      gateway: 10.2.0.1
+      dns:
+        - 8.8.8.8
+        - 8.8.4.4
+  kubespray: &idf_kubespray
+    nodes_roles:
+      node1: [k8s-cluster, kube-master, etcd, vault]
+      node2: [k8s-cluster, kube-node]
+    groups:
+      k8s-cluster:
+        - kube-node
+        - kube-master
+    hostnames:
+      node1: master1
+      node2: worker1
+    network:
+      # network mapping
+      network_mapping:
+        # Admin network
+        net_admin: admin
+        # Public network
+        net_public: public
+        # Management network used by installer components to communicate
+        net_mgmt: admin
+
+engine:
+  pod_name: jumphost
+  net_config: *net_config
+
+  # net_config network to be used by the PXE
+  pxe_network: admin
+
+  # net_config network to be used for the internet access
+  public_network: public
+
+  # interface to be used by the PXE
+  pxe_interface: br_admin
+
+  installers:
+    kubespray: *idf_kubespray
+
+bmra:
+  profile: full_nfv
+  network_roles:
+    sriov:
+      - name: ens2
+        pci: "00:02.0"
+        pf_driver: virtio_net
+        vf_driver: virtio_net
+    sriov_dpdk:
+      - name: ens3
+        pci: "00:03.0"
+        pf_driver: virtio_net
+        vf_driver: virtio_net
+  device_roles:
+#    qat:
+#      - name: crypto01
+#        pci: "0000:ab:00.0"
+#        mod_type: qat_c62x
+#        pci_type: c6xx
+#        vfs: 4
+  features:
+    sriov:
+      enable: false
+      sriov_vfs_per_port: 2
+      sriov_dpdk_vfs_per_port: 4
+    sriov_cni: true
+    sriov_net_dp: true
+    hugepages:
+      enable: true
+      default: 2M
+      hugepages_1G: 0
+      hugepages_2M: 5120
+    isolcpus:
+      enable: false
+      autogenerate: false
+      cpus: "4-19,24-39,44-59,64-79" # Not used when autogenerate is true
+    nfd: true
+    cmk:
+      enable: true
+      num_shared_cores: 1
+      num_exclusive_cores: 2
+    topology_manager:
+      enable: true
+      policy: "best-effort"
+    tas:
+      enable: true
+      demo_policy: false
+    bond_cni: true
+    psp: true
+    qat:
+      enable: false
+      update_drivers: false
diff --git a/hw_config/libvirt-vms/pdf.yaml b/hw_config/libvirt-vms/pdf.yaml
new file mode 100644 (file)
index 0000000..6686e02
--- /dev/null
@@ -0,0 +1,128 @@
+---
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2020
+# 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
+##############################################################################
+### POD descriptor file ###
+details:
+  type: virtual
+  link: http://wiki.nordix.org/
+jumphost:
+  name: jumphost
+  node:
+    type: virtual
+    vendor: libvirt
+    model: pc
+    arch: x86_64
+    cpus: 12
+    cpu_cflags: host-passthrough
+    cores: 12
+    memory: 16G
+  disks:
+    - name: disk1
+      disk_capacity: 300G
+      disk_type: hdd
+      disk_interface: sata
+      disk_rotation:
+  os: ubuntu1804
+  interfaces:
+      # NOTE (fdegir): The IPs listed below actually belong to the libvirt bridges
+      # we create & configure since this is virtual POD and its real IP has nothing
+      # to do with the deployment itself.
+      # interface connected to admin/pxe network
+      - address: 10.1.0.1
+      # interface connected to public network
+      - address: 10.2.0.1
+##############################################################################
+nodes:
+  - name: node1
+    node:
+      type: virtual
+      vendor: libvirt
+      model: pc
+      arch: x86_64
+      cpus: 4
+      cpu_cflags: host-passthrough
+      cores: 4
+      memory: 16G
+    disks: &disks
+      - name: disk1
+        disk_capacity: 30G
+        disk_type: hdd
+        disk_interface: sata
+        disk_rotation:
+      - name: disk2
+        disk_capacity: 20G
+        disk_type: hdd
+        disk_interface: sata
+        disk_rotation:
+    remote_params: &remote_params
+      type:
+        - ipmi
+      user: admin
+      pass: password
+      privilege_level: OPERATOR
+    remote_management:
+      <<: *remote_params
+      port: 623
+      address: 10.1.0.1
+      mac_address: "52:54:00:72:bf:cf"
+    interface_common_nic1: &interface_common_nic1
+      name: nic1
+      speed:
+      features:
+      vlan: native
+    interface_common_nic2: &interface_common_nic2
+      name: nic2
+      speed:
+      features:
+      vlan: native
+    interface_common_nic3: &interface_common_nic3
+      name: nic3
+      speed:
+      features:
+      vlan: native
+    interface_common_nic4: &interface_common_nic4
+      name: nic4
+      speed:
+      features:
+      vlan: native
+    interfaces:
+      # interface connected to admin/pxe network
+      - mac_address: "52:54:00:72:bf:cf"
+        address: 10.1.0.3
+        <<: *interface_common_nic1
+      # interface connected to public network
+      - mac_address: "52:54:00:21:4f:fb"
+        address: 10.2.0.3
+        <<: *interface_common_nic2
+  ##############################################################################
+  - name: node2
+    node:
+      type: virtual
+      vendor: libvirt
+      model: pc
+      arch: x86_64
+      cpus: 6
+      cpu_cflags: host-passthrough
+      cores: 6
+      memory: 32G
+    disks: *disks
+    remote_management:
+      <<: *remote_params
+      port: 624
+      address: 10.1.0.1
+      mac_address: "52:54:00:b9:d4:87"
+    interfaces:
+      # interface connected to admin/pxe network
+      - mac_address: "52:54:00:b9:d4:87"
+        address: 10.1.0.4
+        <<: *interface_common_nic1
+      # interface connected to public network
+      - mac_address: "52:54:00:b7:9f:50"
+        address: 10.2.0.4
+        <<: *interface_common_nic2
index c032226..1474d03 100644 (file)
@@ -24,3 +24,6 @@ deployment_type: "{{ lookup('env', 'DEPLOYMENT') }}"
 
 # OS distro from DISTRO from environment variables
 os_distro: "{{ lookup('env', 'DISTRO') }}"
+
+# Vendor name from hw_config folder (used for VM specific changes)
+vendor: "{{ lookup('env', 'VENDOR') }}"
diff --git a/playbooks/configure-vms.yaml b/playbooks/configure-vms.yaml
new file mode 100644 (file)
index 0000000..0434fed
--- /dev/null
@@ -0,0 +1,17 @@
+---
+# SPDX-license-identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2020 Samsung Electronics
+# 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
+##############################################################################
+
+- name: Install requirements on nodes
+  hosts: baremetal
+  gather_facts: true
+  roles:
+    - role: configure-vms
+
+# vim: set ts=2 sw=2 expandtab:
index 9b91c5f..f22aa56 100644 (file)
@@ -6,7 +6,7 @@ SPDX-License-Identifier: Apache-2.0
 
 [all]
 {% for node in nodes %}
-{{ idf.kubespray.hostnames[node.name] }}   ansible_host={{ node.interfaces[idf.net_config[engine.pxe_network].interface].address }} ip={{ node.interfaces[idf.net_config[engine.pxe_network].interface].address }}
+{{ idf.kubespray.hostnames[node.name] }}   ansible_host={{ node.interfaces[idf.net_config[engine.pxe_network].interface].address }} ip={{ node.interfaces[idf.net_config[engine.pxe_network].interface].address }} {% if vendor|lower == 'libvirt-vms' %} ansible_user=root {% endif %}{{''}}
 {% endfor %}
 localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python2
 
diff --git a/playbooks/roles/configure-vms/tasks/main.yaml b/playbooks/roles/configure-vms/tasks/main.yaml
new file mode 100644 (file)
index 0000000..ee90782
--- /dev/null
@@ -0,0 +1,91 @@
+---
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2019 The Nordix Foundation. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+- name: Get node names from IDF
+  set_fact:
+    node_name: "{{ item.key }}"
+  with_dict: "{{ idf.kubespray.hostnames }}"
+  when: item.value == inventory_hostname
+
+- name: Set facts for the nodes
+  set_fact:
+    node: "{{ nodes | selectattr('name', 'equalto', node_name) | first }}"
+
+- name: Configure modules
+  lineinfile:
+    dest: /etc/modules
+    state: present
+    create: true
+    line: "8021q"
+
+- name: Add modules
+  modprobe:
+    name: 8021q
+    state: present
+
+- name: Ensure interfaces.d folder is empty
+  file:
+    state: "{{ item }}"
+    path: "/etc/network/interfaces.d"
+  with_items:
+    - absent
+    - directory
+
+- name: Ensure /etc/interfaces can source additional files
+  copy:
+    content: |
+      auto lo
+      iface lo inet loopback
+      source /etc/network/interfaces.d/*.cfg
+    dest: "/etc/network/interfaces"
+
+- name: Compute mapping dict from mac address to device name
+  set_fact:
+    device_mac_dict: "{{ (device_mac_dict | default({})) | combine({item.macaddress: item.device}) }}"
+  loop: |-
+      {{ ansible_interfaces | map('regex_replace', '-', '_') | map('regex_replace', '^', 'ansible_') |
+      map('extract', hostvars[inventory_hostname]) |  selectattr('macaddress','defined') | list }}
+  when: "'.' not in item.device"
+
+- name: Filter to include only configured ethernet interfaces
+  set_fact:
+    if_mac_dict: "{{ ( if_mac_dict | default({}) ) | combine({item.mac_address: device_mac_dict[item.mac_address]}) }}"
+  loop: "{{ node.interfaces }}"
+
+- name: Configure networking for host
+  template:
+    src: "Debian.interface.j2"
+    dest: "/etc/network/interfaces.d/{{ item.value }}.cfg"
+  loop: "{{ if_mac_dict | dict2items }}"
+
+- name: Reboot the machine
+  shell: "sleep 5 && reboot"
+  async: 1
+  poll: 0
+  changed_when: false
+
+- name: Wait for host to come back to life
+  wait_for_connection:
+    connect_timeout: 10
+    sleep: 5
+    delay: 120
+    timeout: 300
+  register: result
+  until: result is succeeded
+  retries: 3
diff --git a/playbooks/roles/configure-vms/templates/Debian.interface.j2 b/playbooks/roles/configure-vms/templates/Debian.interface.j2
new file mode 100644 (file)
index 0000000..ef1a9fd
--- /dev/null
@@ -0,0 +1,33 @@
+{%- set macaddress = item.key -%}
+{%- set device = item.value -%}
+{%- for selected_net_name, selected_net in idf.net_config.items() if node.interfaces[selected_net.interface].mac_address == macaddress -%}
+{%- set selected_inf = node.interfaces[selected_net.interface] -%}
+{%- set ifname = device if selected_inf.vlan == 'native' else device + '.' + selected_inf.vlan -%}
+{%- set proto = "inet6" if selected_net.network | ipv6 else "inet" -%}
+{%- set method = selected_inf.address if selected_inf.address in ["dhcp", "manual"] else "static" -%}
+
+auto {{ ifname }}
+iface {{ ifname }} {{ proto }} {{ method }}
+{% if selected_net.gateway is defined %}
+up route add default gateway {{ selected_net.gateway | ipaddr('address') }}
+{% endif %}
+{% if method != "manual" %}
+address {{ selected_inf.address | ipaddr('address') }}
+{% endif %}
+{% if selected_inf.address | ipv6 %}
+netmask {{ selected_net.mask }}
+{% endif %}
+{% if selected_inf.address | ipv4 %}
+netmask {{ (selected_net.network + "/" + (selected_net.mask | string)) | ipaddr('netmask') }}
+{% endif %}
+{% if selected_net.gateway is defined %}
+gateway {{ selected_net.gateway | ipaddr('address') }}
+{% endif %}
+{% if selected_net.routes is defined %}
+{% for route in selected_net.routes %}
+up route add -net {{ route.network }}/{{ route.mask }} gw {{ route.gateway }}
+{% endfor %}
+{% endif %}
+
+{%- endfor -%}
+
index 95bdbf4..178004a 100644 (file)
@@ -4,3 +4,4 @@
 
 ansible
 libvirt-python
+netaddr