From fe6c8344d1cdf23add574a461af280d4033b8428 Mon Sep 17 00:00:00 2001 From: Kevin Carter Date: Thu, 16 Aug 2018 12:18:48 -0500 Subject: [PATCH] Convert test network setup to use the networkd role The test network setup was using the legacy interface configs and providing an inconsistent experience. These changes will pull it in plce with the intergrated repo for all of our distros giving us a very consistent experience. Change-Id: I637b048b8c8a3fb44f91e4227a02787eacd32b57 Signed-off-by: Kevin Carter --- .../debian_interface_default.cfg.j2 | 27 -- .../redhat_interface_alias.cfg.j2 | 5 - .../redhat_interface_default.cfg.j2 | 12 - .../rpm_interface_ifdown-post.cfg.j2 | 29 -- .../rpm_interface_ifup-post.cfg.j2 | 36 --- .../suse_interface_default.cfg.j2 | 9 - test-prepare-host.yml | 259 ++++++++---------- tests/host_vars/localhost.yml | 5 + 8 files changed, 125 insertions(+), 257 deletions(-) delete mode 100644 network_interfaces/debian_interface_default.cfg.j2 delete mode 100644 network_interfaces/redhat_interface_alias.cfg.j2 delete mode 100644 network_interfaces/redhat_interface_default.cfg.j2 delete mode 100644 network_interfaces/rpm_interface_ifdown-post.cfg.j2 delete mode 100644 network_interfaces/rpm_interface_ifup-post.cfg.j2 delete mode 100644 network_interfaces/suse_interface_default.cfg.j2 diff --git a/network_interfaces/debian_interface_default.cfg.j2 b/network_interfaces/debian_interface_default.cfg.j2 deleted file mode 100644 index ce134466..00000000 --- a/network_interfaces/debian_interface_default.cfg.j2 +++ /dev/null @@ -1,27 +0,0 @@ -auto {{ item.name | default('br-mgmt') }} -iface {{ item.name | default('br-mgmt') }} inet static - bridge_stp off - bridge_waitport 0 - bridge_fd 0 - # Notice the bridge port is the vlan tagged interface - address {{ item.ip_addr | default('10.1.0.1') }} - netmask {{ item.netmask | default('255.255.255.0') }} - offload-sg off -{% if item.veth_peer is defined %} - # Create veth pair, don't bomb if already exists - pre-up ip link add {{ item.name | default('br-mgmt') }}-veth type veth peer name {{ item.veth_peer | default('eth1') }} || true - # Set both ends UP - pre-up ip link set {{ item.name | default('br-mgmt') }}-veth up - pre-up ip link set {{ item.veth_peer | default('eth1') }} up - # Delete veth pair on DOWN - post-down ip link del {{ item.name | default('br-mgmt') }}-veth || true - bridge_ports {{ item.name | default('br-mgmt') }}-veth -{% else %} - bridge_ports none -{% endif %} - -{% if item.alias is defined %} -iface {{ item.name | default('br-mgmt') }} inet static - address {{ item.alias }} - netmask {{ item.netmask | default('255.255.255.0') }} -{% endif %} diff --git a/network_interfaces/redhat_interface_alias.cfg.j2 b/network_interfaces/redhat_interface_alias.cfg.j2 deleted file mode 100644 index 79a04a85..00000000 --- a/network_interfaces/redhat_interface_alias.cfg.j2 +++ /dev/null @@ -1,5 +0,0 @@ -# This interface is an alias -DEVICE={{ item.name | default('br-mgmt') }}:0 -IPADDR={{ item.alias | default('10.1.0.1') }} -NETMASK={{ item.netmask | default('255.255.255.0') }} -ONBOOT=yes diff --git a/network_interfaces/redhat_interface_default.cfg.j2 b/network_interfaces/redhat_interface_default.cfg.j2 deleted file mode 100644 index 25c2dfac..00000000 --- a/network_interfaces/redhat_interface_default.cfg.j2 +++ /dev/null @@ -1,12 +0,0 @@ -{% if item.veth_peer is defined %} -# This interface has a veth peer -{% endif %} -DEVICE={{ item.name | default('br-mgmt') }} -TYPE=Bridge -IPADDR={{ item.ip_addr | default('10.1.0.1') }} -NETMASK={{ item.netmask | default('255.255.255.0') }} -ONBOOT=yes -BOOTPROTO=none -NM_CONTROLLED=no -DELAY=0 -ETHTOOL_OPTS="-K ${DEVICE} sg off" diff --git a/network_interfaces/rpm_interface_ifdown-post.cfg.j2 b/network_interfaces/rpm_interface_ifdown-post.cfg.j2 deleted file mode 100644 index e35945df..00000000 --- a/network_interfaces/rpm_interface_ifdown-post.cfg.j2 +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2014, Rackspace US, Inc. -# -# 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. - -source /etc/os-release || source /usr/lib/os-release - -case "${ID}" in - *suse*) INTERFACE="${1}"; ;; - centos|rhel|fedora) INTERFACE="${DEVICE}"; ;; - *) echo "Unsupported distribution ${ID}"; exit 1; -esac - -_ip=$(which ip 2>/dev/null || { echo "Failed to find ip executable"; exit 1; }) - -if [ "${INTERFACE}" == "{{ item[1].name | default('br-mgmt') }}" ]; then - eval $_ip link set {{ item[1].name | default('br-mgmt') }}-veth nomaster || true - eval $_ip link del {{ item[1].name | default('br-mgmt') }}-veth || true -fi diff --git a/network_interfaces/rpm_interface_ifup-post.cfg.j2 b/network_interfaces/rpm_interface_ifup-post.cfg.j2 deleted file mode 100644 index 29c3f66d..00000000 --- a/network_interfaces/rpm_interface_ifup-post.cfg.j2 +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2014, Rackspace US, Inc. -# Copyright 2017, SUSE LINUX GmbH. -# -# 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. - -source /etc/os-release || source /usr/lib/os-release - -case "${ID}" in - *suse*) INTERFACE="${1}"; ;; - centos|rhel|fedora) INTERFACE="${DEVICE}"; ;; - *) echo "Unsupported distribution ${ID}"; exit 1; -esac - -_ip=$(which ip 2>/dev/null || { echo "Failed to find ip executable"; exit 1; }) - -if [ "${INTERFACE}" == "{{ item[1].name | default('br-mgmt') }}" ]; then - # Create veth pair, don't bomb if already exists - echo "Creating veth" - eval $_ip link add {{ item[1].name | default('br-mgmt') }}-veth type veth peer name {{ item[1].veth_peer | default('eth0') }} || true - # Set both ends UP - eval $_ip link set {{ item[1].name | default('br-mgmt') }}-veth up || true - eval $_ip link set {{ item[1].veth_peer | default('eth0') }} up || true - # add eth12 to the bridge - eval $_ip link set {{ item[1].name | default('br-mgmt') }}-veth master {{ item[1].name | default('br-mgmt') }} || true -fi diff --git a/network_interfaces/suse_interface_default.cfg.j2 b/network_interfaces/suse_interface_default.cfg.j2 deleted file mode 100644 index f0cc3770..00000000 --- a/network_interfaces/suse_interface_default.cfg.j2 +++ /dev/null @@ -1,9 +0,0 @@ -{% if item.veth_peer is defined %} -# This interface has a veth peer -{% endif %} -BRIDGE='yes' -IPADDR={{ item.ip_addr | default('10.1.0.1') }} -NETMASK={{ item.netmask | default('255.255.255.0') }} -STARTMODE='auto' -BOOTPROTO='static' -ETHTOOL_OPTIONS_sg='-K iface sg off' diff --git a/test-prepare-host.yml b/test-prepare-host.yml index af7b9bdc..daea3459 100644 --- a/test-prepare-host.yml +++ b/test-prepare-host.yml @@ -98,150 +98,131 @@ - test-vars.yml roles: - role: "lxc_hosts" - post_tasks: - - name: Ensure that /etc/network/interfaces.d/ exists (Debian) - file: - path: /etc/network/interfaces.d/ - state: directory - tags: - - networking-dir-create - when: - - ansible_pkg_mgr == 'apt' - - - name: Copy network configuration (Debian) - template: - src: "network_interfaces/debian_interface_{{ item.type | default('default') }}.cfg.j2" - dest: "/etc/network/interfaces.d/{{ item.name | default('br-mgmt') }}.cfg" - with_items: "{{ bridges }}" - register: network_interfaces_deb - when: - - ansible_pkg_mgr == 'apt' - - - name: Copy network configuration (RedHat) - template: - src: "network_interfaces/redhat_interface_{{ item.type | default('default') }}.cfg.j2" - dest: "/etc/sysconfig/network-scripts/ifcfg-{{ item.name | default('br-mgmt') }}" - with_items: "{{ bridges }}" - register: network_interfaces_rhel - when: - - ansible_pkg_mgr in ['yum', 'dnf'] - - - name: Copy network configuration (SUSE) - template: - src: "network_interfaces/suse_interface_{{ item.type | default('default') }}.cfg.j2" - dest: "/etc/sysconfig/network/ifcfg-{{ item.name | default('br-mgmt') }}" - with_items: "{{ bridges }}" - register: network_interfaces_suse - when: - - ansible_pkg_mgr == 'zypper' - - - name: Create alias file when required - template: - src: "network_interfaces/redhat_interface_alias.cfg.j2" - dest: "/etc/sysconfig/network-scripts/ifcfg-{{ item.name | default('br-mgmt')}}:0" - with_items: "{{ bridges }}" - when: - - ansible_pkg_mgr in ['yum', 'dnf'] - - item.alias is defined - - - name: Put down post-up script for veth-peer interfaces (RedHat) - template: - src: "network_interfaces/rpm_interface_{{ item[0] }}.cfg.j2" - dest: "/etc/sysconfig/network-scripts/{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}" - mode: "0755" - with_nested: - - [ "ifup-post", "ifdown-post" ] - - "{{ bridges }}" - when: - - item[1].veth_peer is defined - - ansible_pkg_mgr in ['yum', 'dnf'] - - # NOTE(hworang): Nested loops do not work on blocks. See - # https://github.com/ansible/ansible/issues/13262 - # As such we need to do that on a per-task basis. - - block: - - name: Put down post-up script for veth-peer interfaces (SUSE) - template: - src: "network_interfaces/rpm_interface_{{ item[0] }}.cfg.j2" - dest: "/etc/sysconfig/network/scripts/{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}" - mode: "0755" - with_nested: - - [ "ifup-post", "ifdown-post" ] - - "{{ bridges }}" - - name: Configure ifcfg files to use the post-up script (SUSE) - lineinfile: - dest: "/etc/sysconfig/network/ifcfg-{{ item[1].name | default('br-mgmt') }}" - line: "POST_UP_SCRIPT=\"compat:suse:{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}\"" - with_nested: - - ['ifup-post'] - - "{{ bridges }}" - - name: Configure ifcfg files to use the post-down script (SUSE) - lineinfile: - dest: "/etc/sysconfig/network/ifcfg-{{ item[1].name | default('br-mgmt') }}" - line: "POST_DOWN_SCRIPT=\"compat:suse:{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}\"" - with_nested: - - ['ifdown-post'] - - "{{ bridges }}" - when: - - item[1].veth_peer is defined - - ansible_pkg_mgr == 'zypper' - - - name: Ensure our interfaces.d configuration files are loaded automatically - lineinfile: - dest: /etc/network/interfaces - line: "source /etc/network/interfaces.d/*.cfg" - when: - - ansible_pkg_mgr == 'apt' + +- name: Playbook for configuring test host networking + hosts: localhost + # This set of tasks runs against localhost + # and requires root access, but tests run as + # the user running the playbook (zuul). As + # such, we use a local connection and become. + connection: local + become: yes + vars_files: + - test-vars.yml + + tasks: + - name: Run the systemd-networkd role + include_role: + name: systemd_networkd + private: true + vars: + systemd_interface_cleanup: true + systemd_run_networkd: true + systemd_netdevs: |- + {% set systemd_network_devices = [] %} + {% for interface in (bridges | default([])) %} + {% if interface is string %} + {% set _ = systemd_network_devices.append({'NetDev': {'Name': 'dummy-' + interface, 'Kind': 'dummy'}}) %} + {% set _ = systemd_network_devices.append({'NetDev': {'Name': interface, 'Kind': 'bridge'}}) %} + {% else %} + {% set interface_name = (interface.name | default('br-mgmt')) %} + {% set _ = systemd_network_devices.append({'NetDev': {'Name': 'dummy-' + interface_name, 'Kind': 'dummy'}}) %} + {% set _ = systemd_network_devices.append({'NetDev': {'Name': interface_name, 'Kind': 'bridge'}}) %} + {% if interface.veth_peer is defined %} + {% set _ = systemd_network_devices.append({'NetDev': {'Name': interface_name + '-veth', 'Kind': 'veth'}, 'Peer': {'Name': interface.veth_peer}}) %} + {% endif %} + {% endif %} + {% endfor %} + {{ systemd_network_devices }} + systemd_networks: |- + {# If the interface is a string or no ip address is defined and the default address "10.1.0.1/24" will be used #} + {% set systemd_network_networks = [] %} + {% for interface in (bridges | default([])) %} + {% if interface is string %} + {% set _ = systemd_network_networks.append({'interface': 'dummy-' + interface, 'bridge': interface}) %} + {% set _ = systemd_network_networks.append({'interface': interface, 'address': '10.1.0.1', 'netmask': '255.255.255.0'}) %} + {% else %} + {% set interface_name = (interface.name | default('br-mgmt')) %} + {% if interface.alias is defined %} + {% set _ = systemd_network_networks.append({'interface': 'dummy-' + interface_name, 'bridge': interface_name}) %} + {% set _ = systemd_network_networks.append({'interface': interface_name, 'netmask': (interface.netmask | default('255.255.255.0')), 'config_overrides': {'Network': {'Address': {(interface.ip_addr | default('10.1.0.1')): null, (interface.alias | string): null}}}}) %} + {% else %} + {% set _ = systemd_network_networks.append({'interface': 'dummy-' + interface_name, 'bridge': interface_name}) %} + {% set _ = systemd_network_networks.append({'interface': interface_name, 'address': (interface.ip_addr | default('10.1.0.1')), 'netmask': (interface.netmask | default('255.255.255.0'))}) %} + {% endif %} + {% if interface.veth_peer is defined %} + {% set _ = systemd_network_networks.append({'interface': interface.veth_peer + '-veth', 'bridge': interface_name}) %} + {% endif %} + {% endif %} + {% endfor %} + {{ systemd_network_networks }} + + - name: Run the systemd service role + include_role: + name: systemd_service + private: true + vars: + systemd_services: + - service_name: "networking-post-up" + config_overrides: + Unit: + Description: networking-post-up + After: network-online.target + Wants: network-online.target + Service: + RemainAfterExit: yes + service_type: oneshot + execstarts: |- + {% set veths = ['-/sbin/ethtool -K ' + (bootstrap_host_public_interface | default(ansible_default_ipv4['alias'])) + ' gso off sg off tso off tx off'] %} + {% for interface in (bridges | default([])) %} + {% if interface is string %} + {% set _ = veths.append('-/usr/sbin/ip link set ' + interface + ' up') %} + {% set _ = veths.append('-/sbin/ethtool -K ' + interface + ' gso off sg off tso off tx off') %} + {% else %} + {% set interface_name = (interface.name | default('br-mgmt')) %} + {% set _ = veths.append('-/usr/sbin/ip link set ' + interface_name + ' up') %} + {% set _ = veths.append('-/sbin/ethtool -K ' + interface_name + ' gso off sg off tso off tx off') %} + {% if interface.veth_peer is defined %} + {% set _ = veths.append('-/usr/sbin/ip link set ' + interface_name + '-veth up') %} + {% set _ = veths.append('-/usr/sbin/ip link set ' + interface.veth_peer + ' up') %} + {% set _ = veths.append('-/sbin/ethtool -K ' + interface.veth_peer + ' gso off sg off tso off tx off') %} + {% endif %} + {% endif %} + {% endfor %} + {{ veths }} + enabled: yes + state: started + systemd_tempd_prefix: openstack tags: - - networking-interfaces-load + - network-config - - name: Ensure the postup/postdown scripts are loaded (RedHat) - lineinfile: - dest: "/etc/sysconfig/network-scripts/{{ item[0] }}" - line: ". /etc/sysconfig/network-scripts/{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}" - insertbefore: "^exit 0" - with_nested: - - [ "ifup-post", "ifdown-post" ] - - "{{ bridges }}" - when: - - item[1].veth_peer is defined - - ansible_pkg_mgr in ['yum', 'dnf'] - - - name: Shut down the network interfaces - command: "ifdown {{ item.name | default('br-mgmt') }}" - when: - - (network_interfaces_rhel | changed) or (network_interfaces_deb | changed) or - (network_interfaces_suse | changed) - with_items: "{{ bridges }}" - - - name: Shut down the alias interface (RedHat) - command: "ifdown {{ item.name | default('br-mgmt') }}:0" - when: - - ansible_pkg_mgr in ['yum', 'dnf'] - - network_interfaces_rhel is changed - - item.alias is defined - with_items: "{{ bridges }}" - - - name: Start the network interfaces - command: "ifup {{ item.name | default('br-mgmt') }}" - when: - - (network_interfaces_rhel | changed) or (network_interfaces_deb | changed) or - (network_interfaces_suse | changed) - with_items: "{{ bridges }}" - - - name: Start the alias interface (RedHat) - command: "ifup {{ item.name | default('br-mgmt') }}:0" - when: - - ansible_pkg_mgr in ['yum', 'dnf'] - - network_interfaces_rhel is changed - - item.alias is defined - with_items: "{{ bridges }}" + post_tasks: + - name: (RE)Gather facts post setup + setup: + gather_subset: "network,hardware,virtual" - name: Trigger dnsmasq restart command: /bin/true changed_when: - - lxc_net_manage_iptables | bool - - iptables_clear is defined - - iptables_clear is changed + - (lxc_net_manage_iptables is defined) and (lxc_net_manage_iptables | bool) + - (iptables_clear is defined) and (iptables_clear is changed) notify: - Restart dnsmasq + + - name: Set interfaces fact + set_fact: + active_interfaces: |- + {% set interfaces = [] %} + {% for interface in (bridges | default([])) %} + {% if interface is string %} + {% set interface_name = interface %} + {% else %} + {% set interface_name = (interface.name | default('br-mgmt')) %} + {% endif %} + {% set _ = interfaces.append(hostvars[inventory_hostname][('ansible_' + (interface_name | replace('-', '_')))]['active'] == true) %} + {% endfor %} + {{ interfaces }} + + - name: Check that new network interfaces are up + assert: + that: "{{ active_interfaces }}" diff --git a/tests/host_vars/localhost.yml b/tests/host_vars/localhost.yml index 65ddeaa0..501b20a6 100644 --- a/tests/host_vars/localhost.yml +++ b/tests/host_vars/localhost.yml @@ -15,5 +15,10 @@ bridges: - "br-mgmt" + - name: "br-test1" + ip_addr: "10.1.1.1" + - name: "br-test2" + ip_addr: "10.1.2.1" + veth_peer: "veth-test" ansible_python_interpreter: "/usr/bin/python2"