Skip to content

Commit

Permalink
vmware_guest_disk: add sharing (multi-writer) capability (ansible-col…
Browse files Browse the repository at this point in the history
…lections#212) (ansible-collections#214)

vmware_guest_disk: add sharing (multi-writer) capability

Reviewed-by: https://github.com/apps/ansible-zuul
  • Loading branch information
cspeidel authored and C1299593 Phillipe Smith Carvalho Chaves committed Jul 6, 2020
1 parent 4900bf4 commit 2a4f6a1
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 9 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/214-add-disk-sharing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- vmware_guest_disk - add support for setting the sharing/multi-writer mode of virtual disks (https://github.com/ansible-collections/vmware/issues/212)
39 changes: 36 additions & 3 deletions plugins/modules/vmware_guest_disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
- ' - C(persistent) Changes are immediately and permanently written to the virtual disk. This is default.'
- ' - C(independent_persistent) Same as persistent, but not affected by snapshots.'
- ' - C(independent_nonpersistent) Changes to virtual disk are made to a redo log and discarded at power off, but not affected by snapshots.'
- ' - C(sharing) (bool): The sharing mode of the virtual disk. The default value is no sharing.'
- ' Setting C(sharing) means that multiple virtual machines can write to the virtual disk.'
- ' Sharing can only be set if C(type) is C(eagerzeroedthick).'
- ' - C(datastore) (string): Name of datastore or datastore cluster to be used for the disk.'
- ' - C(autoselect_datastore) (bool): Select the less used datastore. Specify only if C(datastore) is not specified.'
- ' - C(scsi_controller) (integer): SCSI controller number. Valid value range from 0 to 3.'
Expand Down Expand Up @@ -344,13 +347,14 @@ def create_scsi_controller(self, scsi_type, scsi_bus_number):
return scsi_ctl

@staticmethod
def create_scsi_disk(scsi_ctl_key, disk_index, disk_mode, disk_filename):
def create_scsi_disk(scsi_ctl_key, disk_index, disk_mode, disk_filename, sharing):
"""
Create Virtual Device Spec for virtual disk
Args:
scsi_ctl_key: Unique SCSI Controller Key
disk_index: Disk unit number at which disk needs to be attached
disk_mode: Disk mode
sharing: Disk sharing mode
disk_filename: Path to the disk file on the datastore
Returns: Virtual Device Spec for virtual disk
Expand All @@ -361,6 +365,7 @@ def create_scsi_disk(scsi_ctl_key, disk_index, disk_mode, disk_filename):
disk_spec.device = vim.vm.device.VirtualDisk()
disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
disk_spec.device.backing.diskMode = disk_mode
disk_spec.device.backing.sharing = sharing
disk_spec.device.controllerKey = scsi_ctl_key
disk_spec.device.unitNumber = disk_index

Expand Down Expand Up @@ -416,6 +421,28 @@ def get_ioandshares_diskconfig(self, disk_spec, disk):
disk_spec.device.storageIOAllocation = io_disk_spec
return disk_spec

def get_sharing(self, disk, disk_type, disk_index):
"""
Get the sharing mode of the virtual disk
Args:
disk: Virtual disk data object
disk_type: Disk type of the virtual disk
disk_index: Disk unit number at which disk needs to be attached
Returns:
sharing_mode: The sharing mode of the virtual disk
"""
sharing = disk.get('sharing')
if sharing and disk_type != 'eagerzeroedthick':
self.module.fail_json(msg="Invalid 'sharing' mode specified for disk index [%s]. 'disk_mode'"
" must be 'eagerzeroedthick' when 'sharing'." % disk_index)
if sharing:
sharing_mode = 'sharingMultiWriter'
else:
sharing_mode = 'sharingNone'
return sharing_mode

def ensure_disks(self, vm_obj=None):
"""
Manage internal state of virtual machine disks
Expand Down Expand Up @@ -466,7 +493,7 @@ def ensure_disks(self, vm_obj=None):
scsi_controller = disk['scsi_controller'] + 1000 # VMware auto assign 1000 + SCSI Controller
if disk['disk_unit_number'] not in current_scsi_info[scsi_controller]['disks'] and disk['state'] == 'present':
# Add new disk
disk_spec = self.create_scsi_disk(scsi_controller, disk['disk_unit_number'], disk['disk_mode'], disk['filename'])
disk_spec = self.create_scsi_disk(scsi_controller, disk['disk_unit_number'], disk['disk_mode'], disk['filename'], disk['sharing'])
if disk['filename'] is None:
disk_spec.device.capacityInKB = disk['size']
if disk['disk_type'] == 'thin':
Expand All @@ -480,6 +507,7 @@ def ensure_disks(self, vm_obj=None):
if disk['filename'] is not None:
disk_spec.device.backing.fileName = disk['filename']
disk_spec.device.backing.datastore = disk['datastore']
disk_spec.device.backing.sharing = disk['sharing']
disk_spec = self.get_ioandshares_diskconfig(disk_spec, disk)
self.config_spec.deviceChange.append(disk_spec)
disk_change = True
Expand Down Expand Up @@ -552,7 +580,8 @@ def sanitize_disk_inputs(self):
autoselect_datastore=True,
disk_unit_number=0,
scsi_controller=0,
disk_mode='persistent')
disk_mode='persistent',
sharing=False)
# Check state
if 'state' in disk:
if disk['state'] not in ['absent', 'present']:
Expand Down Expand Up @@ -718,6 +747,9 @@ def sanitize_disk_inputs(self):
" 'disk_mode' value from ['persistent', 'independent_persistent', 'independent_nonpersistent']." % disk_index)
current_disk['disk_mode'] = temp_disk_mode

# Sharing mode of disk
current_disk['sharing'] = self.get_sharing(disk, disk_type, disk_index)

# SCSI Controller Type
scsi_contrl_type = disk.get('scsi_type', 'paravirtual').lower()
if scsi_contrl_type not in self.scsi_device_type.keys():
Expand Down Expand Up @@ -807,6 +839,7 @@ def gather_disk_facts(vm_obj):
backing_filename=disk.backing.fileName,
backing_datastore=disk.backing.datastore.name,
backing_disk_mode=disk.backing.diskMode,
backing_sharing=disk.backing.sharing,
backing_writethrough=disk.backing.writeThrough,
backing_thinprovisioned=disk.backing.thinProvisioned,
backing_eagerlyscrub=bool(disk.backing.eagerlyScrub),
Expand Down
69 changes: 63 additions & 6 deletions tests/integration/targets/vmware_guest_disk/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
datacenter: "{{ dc1 }}"
validate_certs: no
name: "{{ virtual_machines[0].name }}"
disk:
disk:
- size_gb: 1
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
Expand All @@ -106,7 +106,7 @@
assert:
that:
- test_custom_shares is changed

- name: create new disk with custom IO limits and shares in IO Limits
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
Expand All @@ -115,7 +115,7 @@
datacenter: "{{ dc1 }}"
validate_certs: no
name: "{{ virtual_machines[0].name }}"
disk:
disk:
- size_gb: 1
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
Expand Down Expand Up @@ -146,7 +146,7 @@
datacenter: "{{ dc1 }}"
validate_certs: no
name: "{{ virtual_machines[0].name }}"
disk:
disk:
- size_gb: 2
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
Expand Down Expand Up @@ -177,7 +177,7 @@
datacenter: "{{ dc1 }}"
validate_certs: no
name: "{{ virtual_machines[0].name }}"
disk:
disk:
- size_gb: 3
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
Expand Down Expand Up @@ -208,7 +208,7 @@
datacenter: "{{ dc1 }}"
validate_certs: no
name: "{{ virtual_machines[0].name }}"
disk:
disk:
- size_gb: 4
type: eagerzeroedthick
datastore: "{{ rw_datastore }}"
Expand Down Expand Up @@ -280,3 +280,60 @@
assert:
that:
- test_recreate_disk is changed

- name: create new disk with sharing (multi-writer) mode
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ dc1 }}"
validate_certs: no
name: "{{ virtual_machines[0].name }}"
disk:
- datastore: "{{ rw_datastore }}"
disk_mode: "independent_persistent"
scsi_controller: 0
scsi_type: 'paravirtual'
size_gb: 1
state: present
type: eagerzeroedthick
sharing: True
unit_number: 6
register: test_create_disk_sharing

- debug:
msg: "{{ test_create_disk_sharing }}"

- name: assert that changes were made
assert:
that:
- test_create_disk_sharing is changed

- name: create new disk with invalid disk type for sharing (multi-writer) mode
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ dc1 }}"
validate_certs: no
name: "{{ virtual_machines[0].name }}"
disk:
- datastore: "{{ rw_datastore }}"
disk_mode: "independent_persistent"
scsi_controller: 0
scsi_type: 'paravirtual'
size_gb: 1
state: present
type: thin
unit_number: 5
sharing: True
register: test_create_disk_sharing_invalid
ignore_errors: True

- debug:
msg: "{{ test_create_disk_sharing_invalid }}"

- name: assert that changes were not made
assert:
that:
- not(test_create_disk_sharing_invalid is changed)

0 comments on commit 2a4f6a1

Please sign in to comment.