From d83eec5fb15a527ae0468c446236300c1b329ac0 Mon Sep 17 00:00:00 2001 From: Justin Cinkelj Date: Sat, 4 Jan 2025 22:53:06 +0100 Subject: [PATCH 1/4] Fix documentation vm_disk, param iso_name Param is "iso_name", not "name" Signed-off-by: Justin Cinkelj --- plugins/modules/vm_disk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/vm_disk.py b/plugins/modules/vm_disk.py index 18ddb097..da4d764c 100644 --- a/plugins/modules/vm_disk.py +++ b/plugins/modules/vm_disk.py @@ -180,7 +180,7 @@ scale_computing.hypercore.vm_disk: vm_name: demo-vm items: - - name: CentOS-Stream-9-latest-x86_64-dvd1.iso + - iso_name: CentOS-Stream-9-latest-x86_64-dvd1.iso disk_slot: 0 type: ide_cdrom state: present @@ -189,7 +189,7 @@ scale_computing.hypercore.vm_disk: vm_name: demo-vm items: - - name: CentOS-Stream-9-latest-x86_64-dvd1.iso + - iso_name: CentOS-Stream-9-latest-x86_64-dvd1.iso disk_slot: 0 type: ide_cdrom state: absent From 8226c0b7d4d0d03040ace4aa54ea84a18cd3c7cd Mon Sep 17 00:00:00 2001 From: Justin Cinkelj Date: Sat, 4 Jan 2025 22:54:31 +0100 Subject: [PATCH 2/4] Test ISO eject Reproduce #345 Signed-off-by: Justin Cinkelj --- .../targets/vm__iso_eject/tasks/main.yml | 251 ++++++++++++++++++ .../targets/vm_disk__iso_eject/tasks/main.yml | 223 ++++++++++++++++ 2 files changed, 474 insertions(+) create mode 100644 tests/integration/targets/vm__iso_eject/tasks/main.yml create mode 100644 tests/integration/targets/vm_disk__iso_eject/tasks/main.yml diff --git a/tests/integration/targets/vm__iso_eject/tasks/main.yml b/tests/integration/targets/vm__iso_eject/tasks/main.yml new file mode 100644 index 00000000..00afb359 --- /dev/null +++ b/tests/integration/targets/vm__iso_eject/tasks/main.yml @@ -0,0 +1,251 @@ +--- +- environment: + SC_HOST: "{{ sc_host }}" + SC_USERNAME: "{{ sc_config[sc_host].sc_username }}" + SC_PASSWORD: "{{ sc_config[sc_host].sc_password }}" + SC_TIMEOUT: "{{ sc_timeout }}" + vars: + vm_name: vm-integration--vm--iso-eject + + block: + # ------------------------------------------------------ + - &delete_vm + name: Delete the test VM - "{{ vm_name }}" + scale_computing.hypercore.vm: &vm-delete + vm_name: "{{ vm_name }}" + state: absent + memory: 536870912 + vcpu: 2 + register: result + + # ------------------------------------------------------ + # The file should be already created by prepare_iso.yml + - name: Get integration-test.iso info + scale_computing.hypercore.iso_info: + name: "integration-test.iso" + register: uploaded_iso_info + - ansible.builtin.assert: + that: + - uploaded_iso_info.records | length == 1 + - uploaded_iso_info.records.0.size == 356352 + + # ------------------------------------------------------ + - name: vm-fragment + when: false + scale_computing.hypercore.vm: &vm_fragment + vm_name: "{{ vm_name }}" + description: Demo VM + tags: + - "Integration test" + memory: 536870912 + vcpu: 2 + power_state: shutdown + state: present + # disks: + nics: [ ] + machine_type: BIOS + + + - name: Create the test VM - "{{ vm_name }}" + scale_computing.hypercore.vm: + <<: *vm_fragment + disks: + - disk_slot: 0 + type: virtio_disk + size: "{{ '2 GB' | human_to_bytes }}" + - disk_slot: 0 + type: ide_disk + size: "{{ '3 GB' | human_to_bytes }}" + register: result + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + - ansible.builtin.assert: + that: + - result.record.0.disks | length == 2 + - result.record.0.disks.0.type == "virtio_disk" + - result.record.0.disks.0.disk_slot == 0 + - result.record.0.disks.0.size == 2147483648 + - result.record.0.disks.1.type == "ide_disk" + - result.record.0.disks.1.disk_slot == 0 + - result.record.0.disks.1.size == 3221225472 + + # ------------------------------------------------------ + - &attach_iso + name: Attach ISO onto the new CD-ROM device + scale_computing.hypercore.vm: + <<: *vm_fragment + disks: + - disk_slot: 0 + type: virtio_disk + size: "{{ '2 GB' | human_to_bytes }}" + - disk_slot: 0 + type: ide_disk + size: "{{ '3 GB' | human_to_bytes }}" + - disk_slot: 1 + type: ide_cdrom + iso_name: "integration-test.iso" + state: present + register: result + - &vm_info + name: Get VM info + scale_computing.hypercore.vm_info: + vm_name: "{{ vm_name }}" + register: vm + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + - &assert__vm_disk__iso_attached + ansible.builtin.assert: + that: + - result.record.0.disks | length == 3 + - result.record.0.disks.0.type == "virtio_disk" + - result.record.0.disks.0.disk_slot == 0 + - result.record.0.disks.0.size == 2147483648 + - result.record.0.disks.1.type == "ide_disk" + - result.record.0.disks.1.disk_slot == 0 + - result.record.0.disks.1.size == 3221225472 + - result.record.0.disks.2.type == "ide_cdrom" + - result.record.0.disks.2.disk_slot == 1 + - result.record.0.disks.2.iso_name == "integration-test.iso" + - &assert__vm__iso_attached + ansible.builtin.assert: + that: + - vm is succeeded + - vm is not changed + - vm.records.0.disks | length == 3 + - vm.records.0.disks.0.type == "virtio_disk" + - vm.records.0.disks.0.disk_slot == 0 + - vm.records.0.disks.0.size == 2147483648 + - vm.records.0.disks.1.type == "ide_disk" + - vm.records.0.disks.1.disk_slot == 0 + - vm.records.0.disks.1.size == 3221225472 + - vm.records.0.disks.2.type == "ide_cdrom" + - vm.records.0.disks.2.disk_slot == 1 + - vm.records.0.disks.2.iso_name == "integration-test.iso" + + # idempotency + - *attach_iso + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is not changed + - *assert__vm_disk__iso_attached + - *assert__vm__iso_attached + + # ------------------------------------------------------ + - &eject_iso + name: Eject ISO, leave empty CD-ROM device + scale_computing.hypercore.vm: + <<: *vm_fragment + disks: + - disk_slot: 0 + type: virtio_disk + size: "{{ '2 GB' | human_to_bytes }}" + - disk_slot: 0 + type: ide_disk + size: "{{ '3 GB' | human_to_bytes }}" + - disk_slot: 1 + type: ide_cdrom + iso_name: "" + register: result + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + - &assert__vm_disk__iso_eject + ansible.builtin.assert: + that: + - result.record.0.disks | length == 3 + - result.record.0.disks.0.type == "virtio_disk" + - result.record.0.disks.0.disk_slot == 0 + - result.record.0.disks.0.size == 2147483648 + - result.record.0.disks.1.type == "ide_disk" + - result.record.0.disks.1.disk_slot == 0 + - result.record.0.disks.1.size == 3221225472 + - result.record.0.disks.2.type == "ide_cdrom" + - result.record.0.disks.2.disk_slot == 1 + - result.record.0.disks.2.iso_name == "" + - &assert__vm__iso_eject + ansible.builtin.assert: + that: + - vm is succeeded + - vm is not changed + - vm.records.0.disks | length == 3 + - vm.records.0.disks.0.type == "virtio_disk" + - vm.records.0.disks.0.disk_slot == 0 + - vm.records.0.disks.0.size == 2147483648 + - vm.records.0.disks.1.type == "ide_disk" + - vm.records.0.disks.1.disk_slot == 0 + - vm.records.0.disks.1.size == 3221225472 + - vm.records.0.disks.2.type == "ide_cdrom" + - vm.records.0.disks.2.disk_slot == 1 + - vm.records.0.disks.2.iso_name == "" + + # idempotency + - *eject_iso + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is not changed + - *assert__vm_disk__iso_eject + - *assert__vm__iso_eject + + # ------------------------------------------------------ + - &remove_iso + name: Remove CD-ROM device + scale_computing.hypercore.vm: + <<: *vm_fragment + disks: + - disk_slot: 0 + type: virtio_disk + size: "{{ '2 GB' | human_to_bytes }}" + - disk_slot: 0 + type: ide_disk + size: "{{ '3 GB' | human_to_bytes }}" + register: result + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + - &assert__vm_disk__iso_remove + ansible.builtin.assert: + that: + - result.record.0.disks | length == 2 + - result.record.0.disks.0.type == "virtio_disk" + - result.record.0.disks.0.disk_slot == 0 + - result.record.0.disks.0.size == 2147483648 + - result.record.0.disks.1.type == "ide_disk" + - result.record.0.disks.1.disk_slot == 0 + - result.record.0.disks.1.size == 3221225472 + - &assert__vm__iso_remove + ansible.builtin.assert: + that: + - vm is succeeded + - vm is not changed + - vm.records.0.disks | length == 2 + - vm.records.0.disks.0.type == "virtio_disk" + - vm.records.0.disks.0.disk_slot == 0 + - vm.records.0.disks.0.size == 2147483648 + - vm.records.0.disks.1.type == "ide_disk" + - vm.records.0.disks.1.disk_slot == 0 + - vm.records.0.disks.1.size == 3221225472 + + # idempotency + - *remove_iso + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is not changed + - *assert__vm_disk__iso_remove + - *assert__vm__iso_remove + + # ------------------------------------------------------ + - *delete_vm diff --git a/tests/integration/targets/vm_disk__iso_eject/tasks/main.yml b/tests/integration/targets/vm_disk__iso_eject/tasks/main.yml new file mode 100644 index 00000000..a127005a --- /dev/null +++ b/tests/integration/targets/vm_disk__iso_eject/tasks/main.yml @@ -0,0 +1,223 @@ +--- +- environment: + SC_HOST: "{{ sc_host }}" + SC_USERNAME: "{{ sc_config[sc_host].sc_username }}" + SC_PASSWORD: "{{ sc_config[sc_host].sc_password }}" + SC_TIMEOUT: "{{ sc_timeout }}" + vars: + vm_name: vm-integration--vm_disk--iso-eject + + block: + # ------------------------------------------------------ + - &delete_vm + name: Delete the test VM - "{{ vm_name }}" + scale_computing.hypercore.vm: &vm-delete + vm_name: "{{ vm_name }}" + state: absent + memory: 536870912 + vcpu: 2 + register: result + + # ------------------------------------------------------ + # The file should be already created by prepare_iso.yml + - name: Get integration-test.iso info + scale_computing.hypercore.iso_info: + name: "integration-test.iso" + register: uploaded_iso_info + - ansible.builtin.assert: + that: + - uploaded_iso_info.records | length == 1 + - uploaded_iso_info.records.0.size == 356352 + + # ------------------------------------------------------ + - name: Create the test VM - "{{ vm_name }}" + scale_computing.hypercore.vm: + vm_name: "{{ vm_name }}" + description: Demo VM + tags: + - "Integration test" + memory: 536870912 + vcpu: 2 + power_state: shutdown + state: present + disks: + - disk_slot: 0 + type: virtio_disk + size: "{{ '2 GB' | human_to_bytes }}" + - disk_slot: 0 + type: ide_disk + size: "{{ '3 GB' | human_to_bytes }}" + nics: [ ] + machine_type: BIOS + register: result + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + + # ------------------------------------------------------ + - &attach_iso + name: Attach ISO onto the new CD-ROM device + scale_computing.hypercore.vm_disk: + vm_name: "{{ vm_name }}" + items: + - disk_slot: 1 + type: ide_cdrom + iso_name: "integration-test.iso" + state: present + register: result + - &vm_info + name: Get VM info + scale_computing.hypercore.vm_info: + vm_name: "{{ vm_name }}" + register: vm + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + - &assert__vm_disk__iso_attached + ansible.builtin.assert: + that: + - result.record | length == 3 + - result.record.0.type == "virtio_disk" + - result.record.0.disk_slot == 0 + - result.record.0.size == 2147483648 + - result.record.1.type == "ide_disk" + - result.record.1.disk_slot == 0 + - result.record.1.size == 3221225472 + - result.record.2.type == "ide_cdrom" + - result.record.2.disk_slot == 1 + - result.record.2.iso_name == "integration-test.iso" + - &assert__vm__iso_attached + ansible.builtin.assert: + that: + - vm is succeeded + - vm is not changed + - vm.records.0.disks | length == 3 + - vm.records.0.disks.0 + - vm.records.0.disks.0.type == "virtio_disk" + - vm.records.0.disks.0.disk_slot == 0 + - vm.records.0.disks.0.size == 2147483648 + - vm.records.0.disks.1.type == "ide_disk" + - vm.records.0.disks.1.disk_slot == 0 + - vm.records.0.disks.1.size == 3221225472 + - vm.records.0.disks.2.type == "ide_cdrom" + - vm.records.0.disks.2.disk_slot == 1 + - vm.records.0.disks.2.iso_name == "integration-test.iso" + + # idempotency + - *attach_iso + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is not changed + - *assert__vm_disk__iso_attached + - *assert__vm__iso_attached + + # ------------------------------------------------------ + - &eject_iso + name: Eject ISO, leave empty CD-ROM device + scale_computing.hypercore.vm_disk: + vm_name: "{{ vm_name }}" + items: + - disk_slot: 1 + type: ide_cdrom + iso_name: "" + state: present + register: result + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + - &assert__vm_disk__iso_eject + ansible.builtin.assert: + that: + - result.record | length == 3 + - result.record.0.type == "virtio_disk" + - result.record.0.disk_slot == 0 + - result.record.0.size == 2147483648 + - result.record.1.type == "ide_disk" + - result.record.1.disk_slot == 0 + - result.record.1.size == 3221225472 + - result.record.2.type == "ide_cdrom" + - result.record.2.disk_slot == 1 + - result.record.2.iso_name == "" + - &assert__vm__iso_eject + ansible.builtin.assert: + that: + - vm is succeeded + - vm is not changed + - vm.records.0.disks | length == 3 + - vm.records.0.disks.0.type == "virtio_disk" + - vm.records.0.disks.0.disk_slot == 0 + - vm.records.0.disks.0.size == 2147483648 + - vm.records.0.disks.1.type == "ide_disk" + - vm.records.0.disks.1.disk_slot == 0 + - vm.records.0.disks.1.size == 3221225472 + - vm.records.0.disks.2.type == "ide_cdrom" + - vm.records.0.disks.2.disk_slot == 1 + - vm.records.0.disks.2.iso_name == "" + + # idempotency + - *eject_iso + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is not changed + - *assert__vm_disk__iso_eject + - *assert__vm__iso_eject + + # ------------------------------------------------------ + - &remove_iso + name: Remove CD-ROM device + scale_computing.hypercore.vm_disk: + vm_name: "{{ vm_name }}" + items: + - disk_slot: 1 + type: ide_cdrom + # iso_name: "" + state: absent + register: result + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is changed + - &assert__vm_disk__iso_remove + ansible.builtin.assert: + that: + - result.record | length == 2 + - result.record.0.type == "virtio_disk" + - result.record.0.disk_slot == 0 + - result.record.0.size == 2147483648 + - result.record.1.type == "ide_disk" + - result.record.1.disk_slot == 0 + - result.record.1.size == 3221225472 + - &assert__vm__iso_remove + ansible.builtin.assert: + that: + - vm is succeeded + - vm is not changed + - vm.records.0.disks | length == 2 + - vm.records.0.disks.0.type == "virtio_disk" + - vm.records.0.disks.0.disk_slot == 0 + - vm.records.0.disks.0.size == 2147483648 + - vm.records.0.disks.1.type == "ide_disk" + - vm.records.0.disks.1.disk_slot == 0 + - vm.records.0.disks.1.size == 3221225472 + + # idempotency + - *remove_iso + - *vm_info + - ansible.builtin.assert: + that: + - result is succeeded + - result is not changed + - *assert__vm_disk__iso_remove + - *assert__vm__iso_remove + + # ------------------------------------------------------ + - *delete_vm From 215cb9930364b959479f9c654048ea77c092e5ac Mon Sep 17 00:00:00 2001 From: Justin Cinkelj Date: Mon, 6 Jan 2025 10:25:30 +0100 Subject: [PATCH 3/4] Fix ISO eject Fixes #345 Signed-off-by: Justin Cinkelj --- plugins/module_utils/vm.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/module_utils/vm.py b/plugins/module_utils/vm.py index 421bed7f..cd65be22 100644 --- a/plugins/module_utils/vm.py +++ b/plugins/module_utils/vm.py @@ -1569,6 +1569,18 @@ def ensure_present_or_set(cls, module, rest_client, module_path, vm_before: VM): module, rest_client, iso, uuid, attach=True ) changed = True + else: + # Empty CD-ROM is requested. Detach ISO if needed. + if ansible_existing_disk: + name = ansible_existing_disk["iso_name"] # + existing_iso = ISO.get_by_name( + dict(name=name), rest_client, must_exist=False + ) + if existing_iso: + cls.iso_image_management( + module, rest_client, existing_iso, uuid, attach=False + ) + changed = True else: if ansible_existing_disk: existing_disk = Disk.from_ansible(ansible_existing_disk) From 0fb258852c134eda359b8b806313a6eb41726787 Mon Sep 17 00:00:00 2001 From: Justin Cinkelj Date: Mon, 6 Jan 2025 10:33:00 +0100 Subject: [PATCH 4/4] Add example for ISO eject Signed-off-by: Justin Cinkelj --- examples/iso_eject.yml | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 examples/iso_eject.yml diff --git a/examples/iso_eject.yml b/examples/iso_eject.yml new file mode 100644 index 00000000..21f8d74d --- /dev/null +++ b/examples/iso_eject.yml @@ -0,0 +1,66 @@ +--- +- name: Eject ISO image from VM + hosts: localhost + connection: local + gather_facts: false + vars: + vm_name: demo-vm + iso_url: http://tinycorelinux.net/13.x/x86/release/TinyCore-current.iso + iso_filename: "{{ iso_url | split('/') | last }}" + + tasks: + # ------------------------------------------------------ + - name: Prepare ISO + block: + - name: Download ISO from URL - {{ iso_filename }} + ansible.builtin.get_url: + url: "{{ iso_url }}" + dest: /tmp/{{ iso_filename }} + mode: "0644" + + - name: Upload ISO to HyperCore - {{ iso_filename }} + scale_computing.hypercore.iso: + name: "{{ iso_filename }}" + source: /tmp/{{ iso_filename }} + state: present + + # ------------------------------------------------------ + - name: Create VM {{ vm_name }} + scale_computing.hypercore.vm: + vm_name: "{{ vm_name }}" + memory: "{{ '1 GB' | human_to_bytes }}" + vcpu: 2 + disks: + # - type: virtio_disk + # disk_slot: 0 + # size: "{{ '10 GB' | human_to_bytes }}" + - type: ide_cdrom + disk_slot: 0 + iso_name: "{{ iso_filename }}" + nics: [] + state: present + power_state: shutdown + operating_system: os_other + + - &vm_info + name: VM info + block: + - name: Get VM state + scale_computing.hypercore.vm_info: + vm_name: "{{ vm_name }}" + register: vm_info + + - name: Show VM disks + ansible.builtin.debug: + var: vm_info.records.0.disks + + - name: Detach ISO from VM, leave empty CD-ROM, {{ vm_name }} + scale_computing.hypercore.vm_disk: + vm_name: "{{ vm_name }}" + items: + - disk_slot: 0 + type: ide_cdrom + iso_name: "" + state: present + + - *vm_info