From 695d757ac3d56bca2e72b85ae70b20c49073d7c3 Mon Sep 17 00:00:00 2001 From: Will Miller Date: Wed, 22 Aug 2018 16:59:55 +0000 Subject: [PATCH] WIP: Libvirt VM creation --- ansible/create_libvirt_vms.yml | 10 ++++----- ansible/deploy.yml | 26 ++++++++++++++++++------ ansible/group_vars/controllers | 1 + ansible/group_vars/hypervisors | 20 ++++++++++++------ ansible/host_setup.yml | 2 +- ansible/physical_network.yml | 37 +++++++++------------------------- ansible/vm_networking.yml | 30 +++++++++++++++++++++++++++ 7 files changed, 80 insertions(+), 46 deletions(-) create mode 100644 ansible/vm_networking.yml diff --git a/ansible/create_libvirt_vms.yml b/ansible/create_libvirt_vms.yml index 654fe16..6766035 100644 --- a/ansible/create_libvirt_vms.yml +++ b/ansible/create_libvirt_vms.yml @@ -4,9 +4,7 @@ name: stackhpc.libvirt-vm vars: libvirt_vm_default_console_log_dir: "{{ console_log_directory }}" - libvirt_vms: - - state: present - name: - run_once: true - # FIXME(w-miller): Schedule to different hypervisors. - delegate_to: "{{ groups['libvirt'][0] }}" + # Configure VM definitions for the Libvirt provider. + libvirt_vms: > + {{ vms | map('set_libvirt_interfaces') + | map('set_libvirt_volume_pool') }} diff --git a/ansible/deploy.yml b/ansible/deploy.yml index 2d9c7f6..35c40b7 100644 --- a/ansible/deploy.yml +++ b/ansible/deploy.yml @@ -6,12 +6,25 @@ - hosts: controllers tasks: - include_tasks: schedule.yml + + - name: Load allocations from file + include_vars: + file: "{{ allocations_file_path }}" + name: allocations + +- hosts: hypervisors + tasks: + - include_tasks: vm_networking.yml vars: + vm: "{{ item }}" + # Allocations are stored in the controller node's vars. + loop: > + {{ hostvars[groups.controllers.0].allocations.result[ + inventory_hostname] | default([]) }} - hosts: libvirt tasks: - - name: Configure host as a Libvirt/QEMU/KVM hypervisor - include_role: + - include_role: name: stackhpc.libvirt-host vars: libvirt_host_pools: @@ -24,8 +37,9 @@ group: "{{ libvirt_pool_group }}" libvirt_host_require_vt: "{{ libvirt_require_vt }}" - - name: Create Libvirt VMs - include_tasks: create_libvirt_vms.yml + - include_tasks: create_libvirt_vms.yml vars: - flavour: flav0 - name: "{{ item }}" + # Allocations are stored in the controller node's vars. + vms: > + {{ hostvars[groups.controllers.0].allocations.result[ + inventory_hostname] | default([]) }} diff --git a/ansible/group_vars/controllers b/ansible/group_vars/controllers index fe97a2d..dd29727 100644 --- a/ansible/group_vars/controllers +++ b/ansible/group_vars/controllers @@ -1,6 +1,7 @@ --- # FIXME(w-miller): set this more cleverly? base_path: "~/tenks/" +allocations_file_path: "{{ base_path + '/allocations.yml' }}" flavours: flav0: diff --git a/ansible/group_vars/hypervisors b/ansible/group_vars/hypervisors index 03140d9..3f1d03b 100644 --- a/ansible/group_vars/hypervisors +++ b/ansible/group_vars/hypervisors @@ -20,11 +20,19 @@ python_requirements: # {{ 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" + +# Prefix for all veth links. +veth_prefix: 'p-' + +# Suffix for veth links attached to a Tenks OVS bridge. +veth_bridge_ovs_suffix: '-ovs' +# Suffix for veth links attached to a source Linux bridge. +veth_bridge_source_suffix: '-phy' + +# Suffix for veth links attached to a Tenks OVS bridge. +veth_vm_ovs_suffix: '-ovs' +# Suffix for veth links attached to a VM. VMs aren't physical so '-phy' doesn't +# seem right. +veth_vm_source_suffix: '-tap' console_log_directory: /var/log/tenks/console_logs/ diff --git a/ansible/host_setup.yml b/ansible/host_setup.yml index 24f3de4..34a8bd9 100644 --- a/ansible/host_setup.yml +++ b/ansible/host_setup.yml @@ -33,7 +33,7 @@ # to a containerised version of OVS. when: ovs_vsctl_check.rc == 127 -- name: Configure physical network +- name: Configure physical networks include_tasks: physical_network.yml vars: network_name: "{{ item.0 }}" diff --git a/ansible/physical_network.yml b/ansible/physical_network.yml index aaa94c1..4915cf6 100644 --- a/ansible/physical_network.yml +++ b/ansible/physical_network.yml @@ -43,33 +43,16 @@ - 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 + include_role: + name: veth-pair + vars: + veth_pair_ovs_bridge: "{{ tenks_bridge }}" + veth_pair_ovs_link_name: > + {{ veth_prefix + tenks_bridge + veth_bridge_ovs_suffix }} + veth_pair_source_bridge: "{{ source_interface }}" + veth_pair_source_link_name: > + {{ veth_prefix + tenks_bridge + veth_bridge_source_suffix }} + plug_into_source: true - name: Connect to existing Open vSwitch bridge when: source_type == 'ovs_bridge' diff --git a/ansible/vm_networking.yml b/ansible/vm_networking.yml new file mode 100644 index 0000000..fffaf0e --- /dev/null +++ b/ansible/vm_networking.yml @@ -0,0 +1,30 @@ +--- +- block: + - set_fact: + # The index of the physical network within this hypervisor's physical + # networks. + idx: > + {{ (physnet_mappings | dictsort | list).index( + (item, physnet_mappings.item)) }} + # Veth pairs are unique for any VM-physnet combination. However, device + # names cannot be longer than 15 characters, so use physical networks' + # indices instead. + veth_base_name: "{{ veth_prefix + vm.name + '-' + idx }}" + + - name: Set VM veth device names + set_fact: + veths: > + {{ (interfaces | default([])).append(veth_base_name + + veth_vm_source_suffix) }} + + - name: Set up veth pairs for the VM + include_role: + name: veth-pair + vars: + veth_pair_ovs_bridge: > + {{ bridge_prefix ~ idx }} + veth_pair_ovs_link_name: "{{ veth_base_name + veth_vm_ovs_suffix }}" + veth_pair_source_link_name: > + {{ veth_base_name + veth_vm_source_suffix }} + + loop: "{{ vm.physical_networks }}"