Skip to content

Support for network filesystems. #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 33 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ Role Variables
- `libvirt_volume_default_images_path`: Directory in which instance images are
stored. Default is '/var/lib/libvirt/images'.

- `libvirt_volume_default_type`: What type of backing volume does the instance use? Default is `volume`.
- `libvirt_volume_default_type`: What type of backing volume does the instance
use? Default is `volume`. Options include `file`, `network` and `volume`.

- `libvirt_volume_default_format`: Format for volumes created by the role, Default is `qcow2`.

- `libvirt_volume_default_device`: Control how device appears in guest OS. Defaults to `disk`.
- `libvirt_volume_default_format`: Format for volumes created by the role.
Default is `qcow2`. Options include `raw`, `qcow2`, `vmdk`. See `man virsh`
for the full range.

- `libvirt_volume_default_device`: Control how device appears in guest OS.
Defaults to `disk`. Options include `cdrom` and `disk`.

- `libvirt_vm_engine`: virtualisation engine. If not set, the role will attempt
to auto-detect the optimal engine to use.
Expand Down Expand Up @@ -75,14 +78,22 @@ Role Variables

- `volumes`: a list of volumes to attach to the VM. Each volume is
defined with the following dict:
- `type`: What type of backing volume does the instance use? All
options for `libvirt_volume_default_type` are valid here. Default
is `libvirt_volume_default_type`.
- `pool`: Name or UUID of the storage pool from which the volume should be
allocated.
allocated. Required when `type` is `volume`.
- `name`: Name to associate with the volume being created; For `file` type volumes include extension if you would like volumes created with one.
- `file_path`: Where the image of `file` type volumes should be placed; defaults to `libvirt_volume_default_images_path`
- `device`: `disk` or `cdrom`
- `capacity`: volume capacity (can be suffixed with M,G,T or MB,GB,TB, etc) (required when type is `disk`)
- `format`: options include `raw`, `qcow2`, `vmdk`. See `man virsh` for the
full range. Default is `qcow2`.
- `device`: `Control how device appears in guest OS. All options for
`libvirt_volume_default_device` are valid here. Default is
`libvirt_volume_default_type`.
- `capacity`: volume capacity, can be suffixed with k, M, G, T, P or E when type is `network` or MB,GB,TB, etc when type is `disk` (required when type is `disk` or `network`)
- `auth`: Authentication details should they be required. If auth is required, `name`, `type`, `token` will need to be supplied.
- `source`: Where the remote volume comes from when type is `network`. `protocol`, `name`, `hostname` and `port` should be supplied.
- `format`: Format of the volume. All options for
`libvirt_volume_default_format` are valid here. Default is
`libvirt_volume_default_format`.
- `image`: (optional) a URL to an image with which the volume is initalised (full copy).
- `backing_image`: (optional) name of the backing volume which is assumed to already be the same pool (copy-on-write).
- `image` and `backing_image` are mutually exclusive options.
Expand Down Expand Up @@ -167,6 +178,19 @@ Example Playbook
device: 'cdrom'
format: 'raw'
target: 'hda' # first device on ide bus
- name: 'networkfs'
type: 'network'
format: 'raw'
capacity: '50G'
auth:
name: 'admin'
type: 'ceph'
token: ''
source:
protocol: 'rbd'
name: 'rbd/bigstore'
hostname: 'ceph.example.org'
port: '6789'
interfaces:
- network: 'br-datacentre'

Expand Down
17 changes: 15 additions & 2 deletions tasks/volumes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
with_items: "{{ volumes | selectattr('image', 'defined') | map(attribute='image') | list }}"
when: "'http' not in item"

- name: Ensure the VM volumes exist
- name: Ensure the VM disk volumes exist
script: >
virt_volume.sh
-n {{ item.name }}
Expand All @@ -27,11 +27,24 @@
{% endif %}
-a {{ ansible_check_mode }}
with_items: "{{ volumes }}"
when: item.type | default(libvirt_volume_default_type) == 'volume'
when: item.type | default(libvirt_volume_default_type) in ['volume', 'network']
environment: "{{ libvirt_vm_script_env }}"
register: volume_result
changed_when:
- volume_result is success
- (volume_result.stdout | from_json).changed | default(True)
check_mode: False
become: true

- name: Ensure the VM network volumes exist
command: qemu-img create -f {{ item.source.protocol }} {{ item.source.protocol }}:{{ item.source.name }} {{ item.capacity }}
with_items: "{{ volumes }}"
when: item.type | default(libvirt_volume_default_type) == 'network'
register: volume_result_network
# 0 is OK, 1 is an existing image
failed_when: volume_result_network.rc >= 2
changed_when:
- volume_result_network is success
- volume_result_network.rc == 1
check_mode: False
become: true
13 changes: 12 additions & 1 deletion templates/vm.xml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,18 @@
<driver name='qemu' type='{{ volume.format | default(libvirt_volume_default_format) }}'/>
{% if volume.type | default(libvirt_volume_default_type) == 'file' %}
<source file='{{ volume.file_path |default(libvirt_volume_default_images_path) }}/{{ volume.name}}'/>
{% else %}
{% elif volume.type is defined and volume.type == 'network' %}
{% if volume.auth.name is defined %}
<auth username='{{ volume.auth.name }}'>
<secret type='{{ volume.auth.type }}' uuid='{{ volume.auth.token }}'/>
</auth>
{% endif %} {# End volume.auth.name check #}
{% if volume.source.name is defined %}
<source protocol='{{ volume.source.protocol }}' name='{{ volume.source.name }}'>
<host name='{{ volume.source.hostname }}' port='{{ volume.source.port }}'/>
</source>
{% endif %} {# End volume.source.name check #}
{% else %} {# End elif volume.type is defined #}
<source pool='{{ volume.pool }}' volume='{{ volume.name }}'/>
{% endif %}
{% if volume.target is undefined %}
Expand Down