Add initial host setup
Set up the basic Ansible directory structure, and add the logic to connect up the physical networks.
This commit is contained in:
parent
80ff2d9c88
commit
72a17aabd1
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,8 @@
|
||||
# All dot-files
|
||||
.*
|
||||
# Ansible retry files
|
||||
*.retry
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
41
ansible/group_vars/all
Normal file
41
ansible/group_vars/all
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
# Map physical network names to their source device. This can be either an
|
||||
# existing interface or an existing bridge.
|
||||
physnet_mappings: {}
|
||||
|
||||
virtualisation_provider: libvirt
|
||||
|
||||
system_requirements:
|
||||
- python-pip
|
||||
- python-virtualenv
|
||||
|
||||
# Path to virtualenv used to install Python requirements. If a virtualenv does
|
||||
# not exist at this location, one will be created.
|
||||
virtualenv_path: ~/tenks-venv
|
||||
|
||||
python_requirements:
|
||||
- virtualbmc
|
||||
|
||||
# Naming scheme for bridges created by tenks for physical networks is
|
||||
# {{ bridge_prefix + i }}, where `i` is the index of the physical network in
|
||||
# physnet_mappings (sorted alphabetically by key).
|
||||
bridge_prefix: brtenks
|
||||
# Naming scheme for veth pairs connected to the Tenks OVS bridge.
|
||||
veth_prefix: p-
|
||||
# Used for the port on the Tenks OVS bridge.
|
||||
veth_tenks_suffix: "-ovs"
|
||||
# Used for the port on the existing bridge.
|
||||
veth_source_suffix: "-phy"
|
||||
|
||||
libvirt_pool_name: tenks
|
||||
libvirt_pool_path: /var/lib/libvirt/tenks_pool/
|
||||
libvirt_pool_type: dir
|
||||
# Capacity is irrelevant for directory-based pools.
|
||||
libvirt_pool_capacity:
|
||||
libvirt_pool_mode: 755
|
||||
libvirt_pool_owner: "{ remote_user }}"
|
||||
libvirt_pool_group: "{ remote_user }}"
|
||||
|
||||
# By default, allow QEMU without hardware virtualisation since this is a
|
||||
# development tool.
|
||||
libvirt_require_vt: false
|
13
ansible/group_vars/libvirt
Normal file
13
ansible/group_vars/libvirt
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
libvirt_pool_name: tenks
|
||||
libvirt_pool_path: /var/lib/libvirt/tenks_pool/
|
||||
libvirt_pool_type: dir
|
||||
# Capacity is irrelevant for directory-based pools.
|
||||
libvirt_pool_capacity:
|
||||
libvirt_pool_mode: 755
|
||||
libvirt_pool_owner: "{{ ansible_user_id }}"
|
||||
libvirt_pool_group: "{{ ansible_user_id }}"
|
||||
|
||||
# By default, allow QEMU without hardware virtualisation since this is a
|
||||
# development tool.
|
||||
libvirt_require_vt: false
|
44
ansible/host_setup.yml
Normal file
44
ansible/host_setup.yml
Normal file
@ -0,0 +1,44 @@
|
||||
---
|
||||
- name: Ensure general system requirements are installed
|
||||
yum:
|
||||
name: "{{ system_requirements }}"
|
||||
become: true
|
||||
|
||||
- name: Check if ovs-vsctl command is present
|
||||
shell: ovs-vsctl --version
|
||||
register: ovs_vsctl_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- block:
|
||||
- name: Ensure Open vSwitch package is installed
|
||||
yum:
|
||||
name: openvswitch
|
||||
become: true
|
||||
|
||||
- name: Ensure Open vSwitch is started and enabled
|
||||
service:
|
||||
name: openvswitch
|
||||
state: running
|
||||
enabled: true
|
||||
become: true
|
||||
# Return code 127 means the command does not exist. Do this check to avoid
|
||||
# installing Open vSwitch system-wide if the command already exists as a link
|
||||
# to a containerised version of OVS.
|
||||
when: ovs_vsctl_check.rc == 127
|
||||
|
||||
- name: Configure physical network
|
||||
include_tasks: physical_network.yml
|
||||
vars:
|
||||
network_name: "{{ item.0 }}"
|
||||
tenks_bridge: "{{ bridge_prefix ~ idx }}"
|
||||
source_interface: "{{ item.1 }}"
|
||||
# Sort to ensure we always enumerate in the same order.
|
||||
loop: "{{ physnet_mappings | dictsort }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
|
||||
- name: Ensure Python requirements are installed
|
||||
pip:
|
||||
name: "{{ python_requirements }}"
|
||||
virtualenv: "{{ virtualenv_path }}"
|
20
ansible/main.yml
Normal file
20
ansible/main.yml
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
- hosts: all
|
||||
tasks:
|
||||
- include_tasks: host_setup.yml
|
||||
|
||||
- hosts: libvirt
|
||||
tasks:
|
||||
- name: Configure host as a Libvirt/QEMU/KVM hypervisor
|
||||
include_role:
|
||||
name: stackhpc.libvirt-host
|
||||
vars:
|
||||
libvirt_host_pools:
|
||||
- name: "{{ libvirt_pool_name }}"
|
||||
type: "{{ libvirt_pool_type }}"
|
||||
capacity: "{{ libvirt_pool_capacity }}"
|
||||
path: "{{ libvirt_pool_path }}"
|
||||
mode: "{{ libvirt_pool_mode }}"
|
||||
owner: "{{ libvirt_pool_owner }}"
|
||||
group: "{{ libvirt_pool_group }}"
|
||||
libvirt_host_require_vt: "{{ libvirt_require_vt }}"
|
103
ansible/physical_network.yml
Normal file
103
ansible/physical_network.yml
Normal file
@ -0,0 +1,103 @@
|
||||
---
|
||||
- name: Fail if source interface does not exist
|
||||
fail:
|
||||
msg: >
|
||||
The interface {{ source_interface }} specified for the physical network
|
||||
{{ network_name }} does not exist.
|
||||
when: source_interface not in ansible_interfaces
|
||||
|
||||
### Firstly, some fact gathering.
|
||||
# Start off by assuming the source interface is direct, unless proven
|
||||
# otherwise.
|
||||
- set_fact:
|
||||
source_type: 'direct'
|
||||
|
||||
- name: Get source interface details
|
||||
command: ip -details link show {{ source_interface }}
|
||||
register: if_details
|
||||
changed_when: false
|
||||
|
||||
- name: Register source interface as a Linux bridge
|
||||
set_fact:
|
||||
source_type: linux_bridge
|
||||
when: if_details.stdout_lines[-1].split()[0] == 'bridge'
|
||||
|
||||
- block:
|
||||
- name: Get list of OVS bridges
|
||||
command: ovs-vsctl list-br
|
||||
register: ovs_bridges
|
||||
changed_when: false
|
||||
|
||||
- name: Register source interface as an Open vSwitch bridge
|
||||
set_fact:
|
||||
source_type: ovs_bridge
|
||||
when: source_interface in ovs_bridges.stdout_lines
|
||||
|
||||
when: if_details.stdout_lines[-1].split()[0] == 'openvswitch'
|
||||
|
||||
|
||||
### Actual configuration starts here.
|
||||
- name: Ensure Open vSwitch bridge exists
|
||||
openvswitch_bridge:
|
||||
bridge: "{{ tenks_bridge }}"
|
||||
|
||||
- name: Connect to existing Linux bridge
|
||||
when: source_type == 'linux_bridge'
|
||||
block:
|
||||
- name: Create veth pair
|
||||
command: >
|
||||
ip link add dev {{ veth_prefix + tenks_bridge + veth_tenks_suffix }}
|
||||
type veth
|
||||
peer name {{ veth_prefix + tenks_bridge + veth_source_suffix }}
|
||||
register: res
|
||||
changed_when: res.rc == 0
|
||||
# Return code 2 means the veth pair already exists
|
||||
failed_when: res.rc not in [0, 2]
|
||||
become: true
|
||||
|
||||
- name: Plug veth into Tenks bridge
|
||||
openvswitch_port:
|
||||
bridge: "{{ tenks_bridge }}"
|
||||
port: "{{ veth_prefix + tenks_bridge + veth_tenks_suffix }}"
|
||||
|
||||
- name: Plug veth into source interface
|
||||
command: >
|
||||
brctl addif {{ source_interface }}
|
||||
{{ veth_prefix + tenks_bridge + veth_source_suffix }}
|
||||
register: res
|
||||
failed_when:
|
||||
- res.rc != 0
|
||||
- "'already a member of a bridge' not in res.stderr"
|
||||
changed_when: "'already a member of a bridge' not in res.stderr"
|
||||
become: true
|
||||
|
||||
- name: Connect to existing Open vSwitch bridge
|
||||
when: source_type == 'ovs_bridge'
|
||||
block:
|
||||
- name: Create patch port on Tenks bridge
|
||||
openvswitch_port:
|
||||
bridge: "{{ tenks_bridge }}"
|
||||
port: "{{ veth_prefix + tenks_bridge + veth_tenks_suffix }}"
|
||||
# Despite the module documentation, `set` will happily take multiple
|
||||
# properties.
|
||||
set: >
|
||||
Interface {{ veth_prefix + tenks_bridge + veth_tenks_suffix }}
|
||||
type=patch
|
||||
options:peer={{ veth_prefix + tenks_bridge + veth_source_suffix }}
|
||||
|
||||
- name: Create patch port on source bridge
|
||||
openvswitch_port:
|
||||
bridge: "{{ source_interface }}"
|
||||
port: "{{ veth_prefix + tenks_bridge + veth_source_suffix }}"
|
||||
set: >
|
||||
Interface {{ veth_prefix + tenks_bridge + veth_source_suffix }}
|
||||
type=patch
|
||||
options:peer={{ veth_prefix + tenks_bridge + veth_tenks_suffix }}
|
||||
|
||||
when: if_details.stdout_lines[-1].split()[0] == 'openvswitch'
|
||||
|
||||
- name: Plug source interface into Tenks bridge
|
||||
when: source_type == 'direct'
|
||||
openvswitch_port:
|
||||
bridge: "{{ tenks_bridge }}"
|
||||
port: "{{ source_interface }}"
|
3
requirements.yml
Normal file
3
requirements.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
src: stackhpc.libvirt-host
|
||||
src: stackhpc.libvirt-vm
|
Loading…
x
Reference in New Issue
Block a user