From c021fd8e8452d410080435ca6acbe1df99a4d040 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Mon, 11 Jun 2018 08:07:30 +0530 Subject: [PATCH] VMware: Allow user to select disk_mode (#38951) * VMware: Allow user to select disk_mode This fix allows user to select disk modes for given disk configuration in the given VM. Fixes: #37749 Signed-off-by: Abhijeet Kasurde * Review comments Signed-off-by: Abhijeet Kasurde --- .../modules/cloud/vmware/vmware_guest.py | 19 ++- .../vmware_guest/tasks/disk_mode_d1_c1_f0.yml | 120 ++++++++++++++++++ .../targets/vmware_guest/tasks/main.yml | 3 +- 3 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 test/integration/targets/vmware_guest/tasks/disk_mode_d1_c1_f0.yml diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest.py b/lib/ansible/modules/cloud/vmware/vmware_guest.py index c12269c5a9..fd2f8342b5 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_guest.py +++ b/lib/ansible/modules/cloud/vmware/vmware_guest.py @@ -172,6 +172,11 @@ options: - ' Default: C(None) thick disk, no eagerzero.' - ' - C(datastore) (string): Datastore to use for the disk. If C(autoselect_datastore) is enabled, filter datastore selection.' - ' - C(autoselect_datastore) (bool): select the less used datastore. Specify only if C(datastore) is not specified.' + - ' - C(disk_mode) (string): Type of disk mode. Added in version 2.6' + - ' - Available options are :' + - ' - 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.' cdrom: description: - A CD-ROM configuration for the virtual machine. @@ -588,7 +593,6 @@ class PyVmomiDeviceHelper(object): diskspec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.create diskspec.device = vim.vm.device.VirtualDisk() diskspec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo() - diskspec.device.backing.diskMode = 'persistent' diskspec.device.controllerKey = scsi_ctl.device.key if self.next_disk_unit_number == 7: @@ -1571,6 +1575,19 @@ class PyVmomiHelper(PyVmomi): diskspec = self.device_helper.create_scsi_disk(scsi_ctl, disk_index) disk_modified = True + if 'disk_mode' in expected_disk_spec: + disk_mode = expected_disk_spec.get('disk_mode', 'persistent').lower() + valid_disk_mode = ['persistent', 'independent_persistent', 'independent_nonpersistent'] + if disk_mode not in valid_disk_mode: + self.module.fail_json(msg="disk_mode specified is not valid." + " Should be one of ['%s']" % "', '".join(valid_disk_mode)) + + if (vm_obj and diskspec.device.backing.diskMode != disk_mode) or (vm_obj is None): + diskspec.device.backing.diskMode = disk_mode + disk_modified = True + else: + diskspec.device.backing.diskMode = "persistent" + # is it thin? if 'type' in expected_disk_spec: disk_type = expected_disk_spec.get('type', '').lower() diff --git a/test/integration/targets/vmware_guest/tasks/disk_mode_d1_c1_f0.yml b/test/integration/targets/vmware_guest/tasks/disk_mode_d1_c1_f0.yml new file mode 100644 index 0000000000..1d3afda1f0 --- /dev/null +++ b/test/integration/targets/vmware_guest/tasks/disk_mode_d1_c1_f0.yml @@ -0,0 +1,120 @@ +# Test code for the vmware_guest module. +# Copyright: (c) 2018, Abhijeet Kasurde +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Wait for Flask controller to come up online + wait_for: + host: "{{ vcsim }}" + port: 5000 + state: started + +- name: kill vcsim + uri: + url: http://{{ vcsim }}:5000/killall +- name: start vcsim with no folders + uri: + url: http://{{ vcsim }}:5000/spawn?datacenter=1&cluster=1&folder=0 + register: vcsim_instance + +- name: Wait for Flask controller to come up online + wait_for: + host: "{{ vcsim }}" + port: 443 + state: started + +- name: get a list of VMS from vcsim + uri: + url: http://{{ vcsim }}:5000/govc_find?filter=VM + register: vmlist + +- debug: var=vcsim_instance +- debug: var=vmlist + +- name: create new VMs with invalid disk mode + vmware_guest: + validate_certs: False + hostname: "{{ vcsim }}" + username: "{{ vcsim_instance['json']['username'] }}" + password: "{{ vcsim_instance['json']['password'] }}" + name: "{{ 'newvm_' + item|basename }}" + guest_id: centos64Guest + datacenter: "{{ (item|basename).split('_')[0] }}" + hardware: + num_cpus: 1 + memory_mb: 512 + disk: + - size: 1gb + type: eagerzeroedthick + autoselect_datastore: True + disk_mode: 'invalid_disk_mode' + state: poweredoff + folder: "{{ item|dirname }}" + with_items: "{{ vmlist['json'] }}" + register: disk_mode_d1_c1_f0 + ignore_errors: True + +- debug: var=disk_mode_d1_c1_f0 + +- name: assert that changes were not made + assert: + that: + - "disk_mode_d1_c1_f0.results|map(attribute='changed')|unique|list == [false]" + +- name: create new VMs with valid disk mode + vmware_guest: + validate_certs: False + hostname: "{{ vcsim }}" + username: "{{ vcsim_instance['json']['username'] }}" + password: "{{ vcsim_instance['json']['password'] }}" + name: "{{ 'newvm_' + item|basename }}" + guest_id: centos64Guest + datacenter: "{{ (item|basename).split('_')[0] }}" + hardware: + num_cpus: 1 + memory_mb: 512 + disk: + - size: 1gb + type: eagerzeroedthick + autoselect_datastore: True + disk_mode: 'independent_persistent' + state: poweredoff + folder: "{{ item|dirname }}" + with_items: "{{ vmlist['json'] }}" + register: disk_mode_d1_c1_f0_2 + +- debug: var=disk_mode_d1_c1_f0_2 + +- name: assert that changes were made + assert: + that: + - "disk_mode_d1_c1_f0_2.results|map(attribute='changed')|unique|list == [true]" + +# TODO: vcsim does not support reconfiguration of disk mode, fails with types.InvalidDeviceSpec +#- name: create new VMs with valid disk mode again +# vmware_guest: +# validate_certs: False +# hostname: "{{ vcsim }}" +# username: "{{ vcsim_instance['json']['username'] }}" +# password: "{{ vcsim_instance['json']['password'] }}" +# name: "{{ 'newvm_' + item|basename }}" +# guest_id: centos64Guest +# datacenter: "{{ (item|basename).split('_')[0] }}" +# hardware: +# num_cpus: 1 +# memory_mb: 512 +# disk: +# - size: 1gb +# type: eagerzeroedthick +# autoselect_datastore: True +# disk_mode: 'independent_persistent' +# state: poweredoff +# folder: "{{ item|dirname }}" +# with_items: "{{ vmlist['json'] }}" +# register: disk_mode_d1_c1_f0_2 + +#- debug: var=disk_mode_d1_c1_f0_2 + +#- name: assert that changes were not made +# assert: +# that: +# - "disk_mode_d1_c1_f0_2.results|map(attribute='changed')|unique|list == [false]" diff --git a/test/integration/targets/vmware_guest/tasks/main.yml b/test/integration/targets/vmware_guest/tasks/main.yml index f76248c3ec..0dff2383bf 100644 --- a/test/integration/targets/vmware_guest/tasks/main.yml +++ b/test/integration/targets/vmware_guest/tasks/main.yml @@ -28,4 +28,5 @@ #- include: template_d1_c1_f0.yml - include: vapp_d1_c1_f0.yml - include: disk_size_d1_c1_f0.yml -- include: network_with_device.yml \ No newline at end of file +- include: network_with_device.yml +- include: disk_mode_d1_c1_f0.yml