Merge pull request #91 from stackhpc/libvirt-galaxy
Move libvirt-host and libvirt-vm to Ansible Galaxy roles
This commit is contained in:
commit
d820d09e62
@ -1,61 +0,0 @@
|
||||
Libvirt Host
|
||||
============
|
||||
|
||||
This role configures a host as a Libvirt/KVM hypervisor. It can also configure
|
||||
storage pools and networks on the host.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The host should have Virtualization Technology (VT) enabled.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
`libvirt_host_networks` is a list of pools to define and start. Each item
|
||||
should be a dict containing the following items:
|
||||
- `name` The name of the pool.
|
||||
- `type` The type of the pool, currently only `dir` is supported.
|
||||
- `capacity` The capacity, in bytes, of the pool.
|
||||
- `path` The absolute path to the pool's backing directory.
|
||||
- `mode` The access mode of the pool.
|
||||
- `owner` The owner of the pool.
|
||||
- `group` The group of the pool.
|
||||
|
||||
`libvirt_host_networks` is a list of networks to define and start. Each item
|
||||
should be a dict containing the following items:
|
||||
- `name` The name of the network.
|
||||
- `mode` The forwarding mode of the network, currently only `bridge` is
|
||||
supported.
|
||||
- bridge` The name of the bridge interface for this network.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
None
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
---
|
||||
- name: Ensure that Libvirt is configured
|
||||
hosts: all
|
||||
roles:
|
||||
- role: libvirt-host
|
||||
libvirt_host_pools:
|
||||
- name: my-pool
|
||||
type: dir
|
||||
capacity: 1024
|
||||
path: /path/to/pool
|
||||
mode: 0755
|
||||
owner: my-user
|
||||
group: my-group
|
||||
libvirt_host_networks:
|
||||
- name: br-example
|
||||
mode: bridge
|
||||
bridge: br-example
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
- Mark Goddard (<mark@stackhpc.com>)
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
# List of pools to define and start.
|
||||
# Each item should be a dict containing the following items:
|
||||
# name: The name of the pool.
|
||||
# type: The type of the pool, currently only 'dir' is supported.
|
||||
# capacity: The capacity, in bytes, of the pool.
|
||||
# path: The absolute path to the pool's backing directory.
|
||||
# mode: The access mode of the pool.
|
||||
# owner: The owner of the pool.
|
||||
# group: The group of the pool.
|
||||
libvirt_host_pools: []
|
||||
|
||||
# List of networks to define and start.
|
||||
# Each item should be a dict containing the following items:
|
||||
# name: The name of the network.
|
||||
# mode: The forwarding mode of the network, currently only 'bridge' is
|
||||
# supported.
|
||||
# bridge: The name of the bridge interface for this network.
|
||||
libvirt_host_networks: []
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: Mark Goddard
|
||||
description: >
|
||||
Role to install and configure a host as a Libvirt/KVM hypervisor
|
||||
company: StackHPC Ltd
|
||||
license: Apache2
|
||||
min_ansible_version: 2.0
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 7
|
||||
galaxy_tags:
|
||||
- cloud
|
||||
- kvm
|
||||
- libvirt
|
||||
- vm
|
||||
|
||||
dependencies: []
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
- name: Ensure the libvirt package is installed
|
||||
yum:
|
||||
name: "{{ item }}"
|
||||
state: installed
|
||||
with_items:
|
||||
- libvirt
|
||||
- libvirt-daemon-kvm
|
||||
- libvirt-python
|
||||
- python-lxml
|
||||
- qemu-kvm
|
||||
become: True
|
||||
|
||||
- name: Ensure the libvirt daemon is started and enabled
|
||||
service:
|
||||
name: libvirtd
|
||||
state: running
|
||||
enabled: yes
|
||||
become: True
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
- include: validate.yml
|
||||
- include: install.yml
|
||||
- include: pools.yml
|
||||
- include: networks.yml
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
- name: Ensure libvirt networks are defined
|
||||
virt_net:
|
||||
name: "{{ item.name }}"
|
||||
command: define
|
||||
xml: "{{ item.xml | default(lookup('template', 'network.xml.j2')) }}"
|
||||
with_items: "{{ libvirt_host_networks }}"
|
||||
become: True
|
||||
|
||||
- name: Ensure libvirt networks are active
|
||||
virt_net:
|
||||
name: "{{ item.name }}"
|
||||
state: active
|
||||
with_items: "{{ libvirt_host_networks }}"
|
||||
become: True
|
||||
|
||||
- name: Ensure libvirt networks are started on boot
|
||||
virt_net:
|
||||
name: "{{ item.name }}"
|
||||
autostart: yes
|
||||
with_items: "{{ libvirt_host_networks }}"
|
||||
become: True
|
@ -1,32 +0,0 @@
|
||||
---
|
||||
- name: Ensure libvirt storage pool directories exist
|
||||
file:
|
||||
path: "{{ item.path }}"
|
||||
owner: "{{ item.owner }}"
|
||||
group: "{{ item.group }}"
|
||||
mode: "{{ item.mode|int(base=8) }}"
|
||||
state: directory
|
||||
with_items: "{{ libvirt_host_pools }}"
|
||||
become: True
|
||||
|
||||
- name: Ensure libvirt storage pools are defined
|
||||
virt_pool:
|
||||
name: "{{ item.name }}"
|
||||
command: define
|
||||
xml: "{{ item.xml | default(lookup('template', 'pool.xml.j2')) }}"
|
||||
with_items: "{{ libvirt_host_pools }}"
|
||||
become: True
|
||||
|
||||
- name: Ensure libvirt storage pools are active
|
||||
virt_pool:
|
||||
name: "{{ item.name }}"
|
||||
state: active
|
||||
with_items: "{{ libvirt_host_pools }}"
|
||||
become: True
|
||||
|
||||
- name: Ensure libvirt storage pools are started on boot
|
||||
virt_pool:
|
||||
name: "{{ item.name }}"
|
||||
autostart: yes
|
||||
with_items: "{{ libvirt_host_pools }}"
|
||||
become: True
|
@ -1,13 +0,0 @@
|
||||
---
|
||||
- name: Verify that Virtualization Technology (VT) is enabled
|
||||
command: grep -c -E 'svm|vmx' /proc/cpuinfo
|
||||
changed_when: False
|
||||
failed_when: False
|
||||
register: result
|
||||
|
||||
- name: Fail if Virtualization Technology (VT) is disabled
|
||||
fail:
|
||||
msg: >
|
||||
Virtualization Technology (VT) is currently disabled. Please enable VT
|
||||
before running this role again.
|
||||
when: result.rc != 0
|
@ -1,5 +0,0 @@
|
||||
<network connections='1'>
|
||||
<name>{{ item.name }}</name>
|
||||
<forward mode='{{ item.mode }}'/>
|
||||
<bridge name='{{ item.bridge }}'/>
|
||||
</network>
|
@ -1,7 +0,0 @@
|
||||
<pool type='{{ item.type }}'>
|
||||
<name>{{ item.name }}</name>
|
||||
<capacity unit='bytes'>{{ item.capacity }}</capacity>
|
||||
<target>
|
||||
<path>{{ item.path }}</path>
|
||||
</target>
|
||||
</pool>
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
# State of the VM. May be 'present' or 'absent'.
|
||||
libvirt_vm_state: present
|
||||
|
||||
# Name of the VM.
|
||||
libvirt_vm_name:
|
||||
|
||||
# Memory in MB.
|
||||
libvirt_vm_memory_mb:
|
||||
|
||||
# Number of vCPUs.
|
||||
libvirt_vm_vcpus:
|
||||
|
||||
# List of volumes.
|
||||
libvirt_vm_volumes: []
|
||||
|
||||
# List of network interfaces.
|
||||
libvirt_vm_interfaces: []
|
||||
|
||||
# Path to cache downloaded images.
|
||||
libvirt_vm_image_cache_path:
|
||||
|
||||
# List of authorized SSH public keys.
|
||||
#libvirt_vm_public_keys: []
|
@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2017 StackHPC Ltd.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Ensure that a libvirt volume does not exists.
|
||||
# On success, output a JSON object with a 'changed' item.
|
||||
|
||||
if [[ $# -ne 2 ]]; then
|
||||
echo "Usage: $0 <name> <pool>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NAME=$1
|
||||
POOL=$2
|
||||
|
||||
# Check whether a volume with this name exists.
|
||||
output=$(virsh vol-info --pool $POOL --vol $NAME 2>&1)
|
||||
result=$?
|
||||
if [[ $result -ne 0 ]]; then
|
||||
if echo "$output" | grep 'Storage volume not found' >/dev/null 2>&1; then
|
||||
echo '{"changed": false}'
|
||||
exit 0
|
||||
else
|
||||
echo "Unexpected error while getting volume info"
|
||||
echo "$output"
|
||||
exit $result
|
||||
fi
|
||||
fi
|
||||
|
||||
# Delete the volume.
|
||||
output=$(virsh vol-delete --pool $POOL --vol $NAME 2>&1)
|
||||
result=$?
|
||||
if [[ $result -ne 0 ]]; then
|
||||
echo "Failed to delete volume"
|
||||
echo "$output"
|
||||
exit $result
|
||||
fi
|
||||
|
||||
echo '{"changed": true}'
|
||||
exit 0
|
@ -1,96 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2017 StackHPC Ltd.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Ensure that a libvirt volume exists, optionally uploading an image.
|
||||
# On success, output a JSON object with a 'changed' item.
|
||||
|
||||
if [[ $# -ne 4 ]] && [[ $# -ne 5 ]]; then
|
||||
echo "Usage: $0 <name> <pool> <capacity> <format> [<image>]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NAME=$1
|
||||
POOL=$2
|
||||
CAPACITY=$3
|
||||
FORMAT=$4
|
||||
IMAGE=$5
|
||||
|
||||
# Check whether a volume with this name exists.
|
||||
output=$(virsh vol-info --pool $POOL --vol $NAME 2>&1)
|
||||
result=$?
|
||||
if [[ $result -eq 0 ]]; then
|
||||
echo '{"changed": false}'
|
||||
exit 0
|
||||
elif ! echo "$output" | grep 'Storage volume not found' >/dev/null 2>&1; then
|
||||
echo "Unexpected error while getting volume info"
|
||||
echo "$output"
|
||||
exit $result
|
||||
fi
|
||||
|
||||
# Create the volume.
|
||||
output=$(virsh vol-create-as --pool $POOL --name $NAME --capacity $CAPACITY --format $FORMAT 2>&1)
|
||||
result=$?
|
||||
if [[ $result -ne 0 ]]; then
|
||||
echo "Failed to create volume"
|
||||
echo "$output"
|
||||
exit $result
|
||||
fi
|
||||
|
||||
# Determine the path to the volume file.
|
||||
output=$(virsh vol-key --pool $POOL --vol $NAME 2>&1)
|
||||
result=$?
|
||||
if [[ $result -ne 0 ]]; then
|
||||
echo "Failed to get volume file path"
|
||||
echo "$output"
|
||||
virsh vol-delete --pool $POOL --vol $NAME
|
||||
exit $result
|
||||
fi
|
||||
|
||||
# Change the ownership of the volume to qemu. Without doing this libvirt cannot
|
||||
# access the volume.
|
||||
output=$(chown qemu:qemu $output 2>1)
|
||||
result=$?
|
||||
if [[ $result -ne 0 ]]; then
|
||||
echo "Failed to change ownership of the volume to qemu"
|
||||
echo "$output"
|
||||
virsh vol-delete --pool $POOL --vol $NAME
|
||||
exit $result
|
||||
fi
|
||||
|
||||
if [[ -n $IMAGE ]]; then
|
||||
# Upload an image to the volume.
|
||||
output=$(virsh vol-upload --pool $POOL --vol $NAME --file $IMAGE 2>&1)
|
||||
result=$?
|
||||
if [[ $result -ne 0 ]]; then
|
||||
echo "Failed to upload image $IMAGE to volume $NAME"
|
||||
echo "$output"
|
||||
virsh vol-delete --pool $POOL --vol $NAME
|
||||
exit $result
|
||||
fi
|
||||
|
||||
# Resize the volume to the requested capacity.
|
||||
output=$(virsh vol-resize --pool $POOL --vol $NAME --capacity $CAPACITY 2>&1)
|
||||
result=$?
|
||||
if [[ $result -ne 0 ]]; then
|
||||
echo "Failed to resize volume $VOLUME to $CAPACITY"
|
||||
echo "$output"
|
||||
virsh vol-delete --pool $POOL --vol $NAME
|
||||
exit $result
|
||||
fi
|
||||
fi
|
||||
|
||||
echo '{"changed": true}'
|
||||
exit 0
|
@ -1,20 +0,0 @@
|
||||
---
|
||||
# The destroyed state does not seem to be idempotent, so check whether the VM
|
||||
# exists before destroying it.
|
||||
- name: Check the VM's status
|
||||
virt:
|
||||
name: "{{ libvirt_vm_name }}"
|
||||
command: list_vms
|
||||
register: result
|
||||
|
||||
- block:
|
||||
- name: Ensure the VM is absent
|
||||
virt:
|
||||
name: "{{ libvirt_vm_name }}"
|
||||
state: destroyed
|
||||
|
||||
- name: Ensure the VM is undefined
|
||||
virt:
|
||||
name: "{{ libvirt_vm_name }}"
|
||||
command: undefine
|
||||
when: libvirt_vm_name in result.list_vms
|
@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Ensure the VM volumes do not exist
|
||||
script: >
|
||||
destroy_virt_volume.sh
|
||||
{{ item.name }}
|
||||
{{ item.pool }}
|
||||
with_items: "{{ libvirt_vm_volumes }}"
|
||||
register: volume_result
|
||||
changed_when:
|
||||
- volume_result | success
|
||||
- (volume_result.stdout | from_json).changed | default(True)
|
@ -1,10 +0,0 @@
|
||||
---
|
||||
- block:
|
||||
- include: volumes.yml
|
||||
- include: vm.yml
|
||||
when: libvirt_vm_state == 'present'
|
||||
|
||||
- block:
|
||||
- include: destroy-volumes.yml
|
||||
- include: destroy-vm.yml
|
||||
when: libvirt_vm_state == 'absent'
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
- name: Ensure the VM is defined
|
||||
virt:
|
||||
name: "{{ libvirt_vm_name }}"
|
||||
command: define
|
||||
xml: "{{ lookup('template', 'vm.xml.j2') }}"
|
||||
|
||||
- name: Ensure the VM is running
|
||||
virt:
|
||||
name: "{{ libvirt_vm_name }}"
|
||||
state: running
|
||||
|
||||
- name: Ensure the VM is started at boot
|
||||
virt:
|
||||
name: "{{ libvirt_vm_name }}"
|
||||
command: autostart
|
@ -1,30 +0,0 @@
|
||||
---
|
||||
- name: Ensure remote images are downloaded
|
||||
get_url:
|
||||
url: "{{ item }}"
|
||||
dest: "{{ libvirt_vm_image_cache_path }}/{{ item | basename }}"
|
||||
with_items: "{{ libvirt_vm_volumes | selectattr('image', 'defined') | map(attribute='image') | list }}"
|
||||
when: "'http' in item"
|
||||
|
||||
- name: Ensure local images are copied
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ libvirt_vm_image_cache_path }}/{{ item | basename }}"
|
||||
with_items: "{{ libvirt_vm_volumes | selectattr('image', 'defined') | map(attribute='image') | list }}"
|
||||
when: "'http' not in item"
|
||||
|
||||
- name: Ensure the VM volumes exist
|
||||
script: >
|
||||
virt_volume.sh
|
||||
{{ item.name }}
|
||||
{{ item.pool }}
|
||||
{{ item.capacity }}
|
||||
{{ item.format | default('qcow2') }}
|
||||
{% if item.image is defined %}
|
||||
{{ libvirt_vm_image_cache_path }}/{{ item.image | basename }}
|
||||
{% endif %}
|
||||
with_items: "{{ libvirt_vm_volumes }}"
|
||||
register: volume_result
|
||||
changed_when:
|
||||
- volume_result | success
|
||||
- (volume_result.stdout | from_json).changed | default(True)
|
@ -1,30 +0,0 @@
|
||||
<domain type='kvm'>
|
||||
<name>{{ libvirt_vm_name }}</name>
|
||||
<memory>{{ libvirt_vm_memory_mb | int * 1024 }}</memory>
|
||||
<vcpu>{{ libvirt_vm_vcpus }}</vcpu>
|
||||
<clock sync="localtime"/>
|
||||
<os>
|
||||
<type arch='x86_64'>hvm</type>
|
||||
</os>
|
||||
<devices>
|
||||
{% for volume in libvirt_vm_volumes %}
|
||||
<disk type='volume' device='{{ volume.device | default('disk') }}'>
|
||||
<driver name='qemu' type='{{ volume.format }}'/>
|
||||
<source pool='{{ volume.pool }}' volume='{{ volume.name }}'/>
|
||||
<target dev='vd{{ 'abcdefghijklmnopqrstuvwxyz'[loop.index] }}'/>
|
||||
</disk>
|
||||
{% endfor %}
|
||||
{% for interface in libvirt_vm_interfaces %}
|
||||
<interface type='network'>
|
||||
<source network='{{ interface.network }}'/>
|
||||
<model type='virtio'/>
|
||||
</interface>
|
||||
{% endfor %}
|
||||
<serial type='pty'>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target type='serial' port='0'/>
|
||||
</console>
|
||||
</devices>
|
||||
</domain>
|
@ -4,6 +4,6 @@
|
||||
tags:
|
||||
- libvirt-host
|
||||
roles:
|
||||
- role: libvirt-host
|
||||
- role: stackhpc.libvirt-host
|
||||
libvirt_host_pools: "{{ seed_hypervisor_libvirt_pools }}"
|
||||
libvirt_host_networks: "{{ seed_hypervisor_libvirt_networks }}"
|
||||
|
@ -5,7 +5,7 @@
|
||||
seed_host: "{{ groups['seed'][0] }}"
|
||||
seed_hostvars: "{{ hostvars[seed_host] }}"
|
||||
roles:
|
||||
- role: libvirt-vm
|
||||
- role: stackhpc.libvirt-vm
|
||||
seed_vm_configdrive_volume:
|
||||
name: "{{ seed_hostvars.seed_vm_name }}-configdrive"
|
||||
pool: "{{ seed_hostvars.seed_vm_pool }}"
|
||||
|
@ -92,7 +92,7 @@
|
||||
register: stat_result
|
||||
|
||||
roles:
|
||||
- role: libvirt-vm
|
||||
- role: stackhpc.libvirt-vm
|
||||
seed_vm_configdrive_volume:
|
||||
name: "{{ seed_hostvars.seed_vm_name }}-configdrive"
|
||||
pool: "{{ seed_hostvars.seed_vm_pool }}"
|
||||
|
@ -10,6 +10,8 @@
|
||||
name: singleplatform-eng.users
|
||||
- src: stackhpc.drac
|
||||
- src: stackhpc.drac-facts
|
||||
- src: stackhpc.libvirt-host
|
||||
- src: stackhpc.libvirt-vm
|
||||
- src: stackhpc.os-flavors
|
||||
- src: stackhpc.os-images
|
||||
- src: stackhpc.os-ironic-state
|
||||
|
Loading…
Reference in New Issue
Block a user