From 14c4e59137b57b0d35107ab31139a040aebc144b Mon Sep 17 00:00:00 2001 From: Teodoro Cook Date: Tue, 10 Oct 2023 08:26:01 -0600 Subject: [PATCH] Add debian test scenario (#7) --- .github/workflows/molecule.yml | 26 ++- .github/workflows/release.yml | 3 +- .talismanrc | 4 +- Makefile | 4 +- molecule/common/create.yml | 24 ++- molecule/common/prepare.yml | 196 +++++++++++++--------- molecule/common/verify.yml | 6 +- molecule/debian/molecule.yml | 139 +++++++++++++++ molecule/default | 1 + molecule/{default => ubuntu}/molecule.yml | 3 +- 10 files changed, 312 insertions(+), 94 deletions(-) create mode 100644 molecule/debian/molecule.yml create mode 120000 molecule/default rename molecule/{default => ubuntu}/molecule.yml (96%) diff --git a/.github/workflows/molecule.yml b/.github/workflows/molecule.yml index 54f02fc..20de7ee 100644 --- a/.github/workflows/molecule.yml +++ b/.github/workflows/molecule.yml @@ -14,14 +14,31 @@ defaults: jobs: + mirror: + name: mirror + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'nephelaiio.growfs' + + - name: Test debian mirror access (http) + run: curl -sD- http://debian-archive.trafficmanager.net/debian/ + + - name: Test debian security mirror access (http) + run: curl -sD- http://debian-archive.trafficmanager.net/debian-security/ + molecule: name: molecule runs-on: libvirt strategy: matrix: include: - - scenario: default - net: '192.168.255.0/24' + - scenario: ubuntu + release: jammy + - scenario: debian + release: bullseye steps: - name: Check out the codebase. @@ -43,6 +60,9 @@ jobs: - name: Install dependencies run: make install + - name: Disable firewall + run: sudo ufw disable + - name: Debug test environment run: make debug @@ -52,7 +72,7 @@ jobs: PY_COLORS: '1' ANSIBLE_FORCE_COLOR: '1' MOLECULE_SCENARIO: ${{ matrix.scenario }} - MOLECULE_NET: ${{ matrix.net }} + MOLECULE_DISTRO: "${{ matrix.release }}" MOLECULE_OUTPUT_DIR: "/tmp/logs" - name: Upload install logs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f8fe9ce..03f6a1f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,7 @@ # See: https://github.com/ansible/galaxy/issues/46 name: Release + on: push: tags: @@ -18,7 +19,7 @@ defaults: jobs: release: - name: Release + name: release runs-on: ubuntu-latest steps: - name: Check out the codebase. diff --git a/.talismanrc b/.talismanrc index 6432a16..8446c83 100644 --- a/.talismanrc +++ b/.talismanrc @@ -3,7 +3,9 @@ fileignoreconfig: ignore_detectors: [filecontent] - filename: tasks/lvm.yml ignore_detectors: [filecontent] -- filename: molecule/default/molecule.yml +- filename: molecule/ubuntu/molecule.yml + ignore_detectors: [filecontent] +- filename: molecule/debian/molecule.yml ignore_detectors: [filecontent] - filename: molecule/common/create.yml ignore_detectors: [filecontent] diff --git a/Makefile b/Makefile index 35529ba..0227d5d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ .PHONY: all ${MAKECMDGOALS} -MOLECULE_SCENARIO ?= default -MOLECULE_DOCKER_IMAGE ?= ubuntu2004 +MOLECULE_SCENARIO ?= ubuntu GALAXY_API_KEY ?= GITHUB_REPOSITORY ?= $$(git config --get remote.origin.url | cut -d: -f 2 | cut -d. -f 1) GITHUB_ORG = $$(echo ${GITHUB_REPOSITORY} | cut -d/ -f 1) @@ -42,4 +41,5 @@ version: @poetry run molecule --version debug: version + sudo ufw status @poetry export --dev --without-hashes diff --git a/molecule/common/create.yml b/molecule/common/create.yml index a16759f..f5972b1 100644 --- a/molecule/common/create.yml +++ b/molecule/common/create.yml @@ -35,7 +35,7 @@ url: "{{ iso_installer.url }}" dest: "{{ iso_installer.dest | urlsplit('path') }}" - - name: Build guest installer isos + - name: Build ubuntu installer isos ansible.builtin.include_role: name: nephelaiio.ubuntu_installer vars: @@ -53,6 +53,28 @@ loop_var: guest label: "{{ guest.installer_hostname }}" loop: "{{ guest_info }}" + when: molecule_scenario == "ubuntu" + + - name: Build debian installer isos + ansible.builtin.include_role: + name: nephelaiio.debian_installer + vars: + debian_installer_interface_name: enp1s0 + debian_installer_target_dir: "{{ cache_dir }}" + debian_installer_image_url: "{{ iso_installer.dest }}" + debian_installer_hostname: "{{ guest.installer_hostname }}" + debian_installer_username: molecule + debian_installer_password: "{{ 'molecule' | password_hash('sha512') }}" + debian_installer_sshkey: + - "{{ lookup('file', kvm_keypair + '.pub') }}" + debian_installer_interface: "{{ guest.installer_interface }}" + debian_installer_partman_method: "{{ guest.installer_partitioning_method }}" + debian_installer_preseed_include: "{{ guest.installer_preseed_include | default('') }}" + loop_control: + loop_var: guest + label: "{{ guest.installer_hostname }}" + loop: "{{ guest_info }}" + when: molecule_scenario == "debian" - name: Create KVM guest disks ansible.builtin.command: "qemu-img create {{ guest_disk }} {{ guest_disk_size }}" diff --git a/molecule/common/prepare.yml b/molecule/common/prepare.yml index 2bcc231..18fd212 100644 --- a/molecule/common/prepare.yml +++ b/molecule/common/prepare.yml @@ -9,103 +9,135 @@ become: true pre_tasks: - - name: Query KVM guest info - community.libvirt.virt: - command: info - register: libvirt_info - delegate_to: localhost - run_once: true - - - name: Shut down guest - when: - - inventory_hostname in libvirt_info - - libvirt_info[inventory_hostname].state == "running" + - name: Recofigure guest storage block: - - name: Wait for connection - ansible.builtin.wait_for_connection: - timeout: 1200 + - name: Query KVM guest info + community.libvirt.virt: + command: info + register: libvirt_info + delegate_to: localhost + run_once: true - name: Shut down guest - community.general.shutdown: + when: + - inventory_hostname in libvirt_info + - libvirt_info[inventory_hostname].state == "running" + block: - - name: Wait for shutdown to complete - ansible.builtin.pause: - seconds: 30 + - name: Wait for connection + ansible.builtin.wait_for_connection: + timeout: 1200 - - name: Force kvm guest poweroff - ansible.builtin.shell: "virsh destroy {{ inventory_hostname }} >/dev/null 2>&1" - ignore_errors: true - failed_when: false - changed_when: false - delegate_to: localhost + - name: Shut down guest + community.general.shutdown: - - name: Wait for poweroff to complete - ansible.builtin.pause: - seconds: 30 + - name: Wait for shutdown to complete + ansible.builtin.pause: + seconds: 30 - - name: Reconfigure guest disks - delegate_to: localhost - block: + - name: Force kvm guest poweroff + ansible.builtin.shell: "virsh destroy {{ inventory_hostname }} >/dev/null 2>&1" + ignore_errors: true + failed_when: false + changed_when: false + delegate_to: localhost - - name: Stat kvm base disk - ansible.builtin.stat: - path: "{{ cache_dir }}/{{ inventory_hostname }}.img" - register: guest_disk_query + - name: Wait for poweroff to complete + ansible.builtin.pause: + seconds: 30 - - name: Debug base disk info - ansible.builtin.debug: - msg: "{{ guest_disk_query.stat }}" + - name: Reconfigure guest disks + delegate_to: localhost + block: + + - name: Stat kvm base disk + ansible.builtin.stat: + path: "{{ cache_dir }}/{{ inventory_hostname }}.img" + register: guest_disk_query + + - name: Debug base disk info + ansible.builtin.debug: + msg: "{{ guest_disk_query.stat }}" + + - name: Resize kvm base disks + ansible.builtin.command: "qemu-img resize -f raw {{ guest_disk }} {{ guest_disk_size }}" + vars: + guest_disk: "{{ cache_dir }}/{{ inventory_hostname }}.img" + guest_disk_size: "{{ 2 * (disk_size | int) }}" + when: (guest_disk_size | int) > (guest_disk_query.stat.size | int) + + - name: Stat additional kvm disk + ansible.builtin.stat: + path: "{{ cache_dir }}/{{ inventory_hostname }}.add.img" + register: guest_addisk_query + + - name: Create additional kvm disk for lvm instances + ansible.builtin.command: "qemu-img create -f raw {{ guest_disk }} {{ guest_disk_size }}" + args: + creates: "{{ guest_disk }}" + vars: + guest_disk: "{{ cache_dir }}/{{ inventory_hostname }}.add.img" + guest_disk_size: "{{ 2 * (disk_size | int) }}" + when: + - not guest_addisk_query.stat.exists + - partitioning_method == 'lvm' + notify: attach kvm guest disk + + - name: Manage permissions for extra kvm guest disk + ansible.builtin.file: + path: "{{ guest_disk }}" + owner: libvirt-qemu + group: kvm + mode: 0660 + vars: + guest_disk: "{{ cache_dir }}/{{ inventory_hostname }}.add.img" + when: partitioning_method == 'lvm' + + - name: Flush handlers + ansible.builtin.meta: flush_handlers + + - name: Start kvm guest + community.libvirt.virt: + name: "{{ inventory_hostname }}" + state: running - - name: Resize kvm base disks - ansible.builtin.command: "qemu-img resize -f raw {{ guest_disk }} {{ guest_disk_size }}" - vars: - guest_disk: "{{ cache_dir }}/{{ inventory_hostname }}.img" - guest_disk_size: "{{ 2 * (disk_size | int) }}" - when: (guest_disk_size | int) > (guest_disk_query.stat.size | int) - - - name: Stat additional kvm disk - ansible.builtin.stat: - path: "{{ cache_dir }}/{{ inventory_hostname }}.add.img" - register: guest_addisk_query - - - name: Create additional kvm disk for lvm instances - ansible.builtin.command: "qemu-img create -f raw {{ guest_disk }} {{ guest_disk_size }}" - args: - creates: "{{ guest_disk }}" + - name: Wait for connection + ansible.builtin.wait_for_connection: + timeout: 120 + + - name: Gather facts + ansible.builtin.setup: + tags: always + + always: + + - name: Set debug facts + ansible.builtin.set_fact: + debug_disk: "{{ disk_location }}.debug" + debug_hostdir: "{{ _hostdir }}" + debug_logfile: "{{ _logfile }}" + debug_crashdir: "{{ _crashdir }}" + debug_output_dir: "{{ output_dir }}" + debug_output_curtin: "{{ output_dir }}/{{ inventory_hostname }}.curtin.log" + debug_output_screenshot: "{{ output_dir }}/{{ inventory_hostname }}.png" vars: - guest_disk: "{{ cache_dir }}/{{ inventory_hostname }}.add.img" - guest_disk_size: "{{ 2 * (disk_size | int) }}" - when: - - not guest_addisk_query.stat.exists - - partitioning_method == 'lvm' - notify: attach kvm guest disk + _hostdir: "{{ cache_dir }}/{{ inventory_hostname }}" + _logfile: "{{ _hostdir }}/var/log/installer/curtin-install.log" + _crashdir: "{{ _hostdir }}/var/crash/" - - name: Manage permissions for extra kvm guest disk + - name: Create output directory ansible.builtin.file: - path: "{{ guest_disk }}" - owner: libvirt-qemu - group: kvm - mode: 0660 - vars: - guest_disk: "{{ cache_dir }}/{{ inventory_hostname }}.add.img" - when: partitioning_method == 'lvm' - - - name: Flush handlers - ansible.builtin.meta: flush_handlers - - - name: Start kvm guest - community.libvirt.virt: - name: "{{ inventory_hostname }}" - state: running - - - name: Wait for connection - ansible.builtin.wait_for_connection: - timeout: 120 + state: directory + path: "{{ debug_output_dir }}" + delegate_to: localhost + run_once: true - - name: Gather facts - ansible.builtin.setup: - tags: always + - name: Take guest screenshot + ansible.builtin.command: "virsh screenshot {{ inventory_hostname }} {{ debug_output_screenshot }}" + delegate_to: localhost + when: molecule_debug + become: true handlers: diff --git a/molecule/common/verify.yml b/molecule/common/verify.yml index 7255ac8..6d1d41f 100644 --- a/molecule/common/verify.yml +++ b/molecule/common/verify.yml @@ -61,8 +61,8 @@ installer_disk_size: "{{ installer_disk_device.size_total }}" installer_disk_threshold: "{{ (1.5 * (disk_size | int)) | int }}" when: - - (installer_disk_size | int) < (installer_disk_threshold | int) - partitioning_method != 'lvm' + - (installer_disk_size | int) < (installer_disk_threshold | int) - name: Check lvm root device size ansible.builtin.fail: @@ -70,10 +70,10 @@ vars: installer_disk_device: "{{ ansible_mounts | selectattr('mount', 'equalto', '/') | list | first }}" installer_disk_size: "{{ installer_disk_device.size_total }}" - installer_disk_threshold: "{{ (3.5 * (disk_size | int)) | int }}" + installer_disk_threshold: "{{ (2.5 * (disk_size | int)) | int }}" when: - - (installer_disk_size | int) < (installer_disk_threshold | int) - partitioning_method == 'lvm' + - (installer_disk_size | int) < (installer_disk_threshold | int) - growfs_lvs_mount is undefined - name: Check lvs root device size diff --git a/molecule/debian/molecule.yml b/molecule/debian/molecule.yml new file mode 100644 index 0000000..b842199 --- /dev/null +++ b/molecule/debian/molecule.yml @@ -0,0 +1,139 @@ +--- +dependency: + name: galaxy + options: + role-file: requirements.yml + requirements-file: requirements.yml +driver: + name: default + options: + managed: false + ansible_connection_options: + ansible_connection: local +platforms: + - name: installer +provisioner: + name: ansible + log: true + env: + ANSIBLE_VERBOSITY: ${MOLECULE_VERBOSITY:-0} + config_options: + defaults: + interpreter_python: auto_silent + callbacks_enabled: ansible.posix.profile_tasks + callback_whitelist: profile_tasks, timer, yaml + playbooks: + prepare: ../common/prepare.yml + create: ../common/create.yml + converge: ../common/converge.yml + verify: ../common/verify.yml + cleanup: ../common/cleanup.yml + side_effect: ../common/reboot.yml + inventory: + hosts: + all: + vars: + growfs_device_filter: "vd.*" + molecule_scenario: "${MOLECULE_SCENARIO_NAME}" + molecule_distro: "{{ lookup('env', 'MOLECULE_DISTRO', default='bullseye') }}" + molecule_iso: "{{ lookup('env', 'MOLECULE_ISO', default='https://cdimage.debian.org/mirror/cdimage/archive/11.8.0/amd64/iso-dvd/debian-11.8.0-amd64-DVD-1.iso') }}" + molecule_debug: "{{ lookup('env', 'GITHUB_ACTIONS', default='false') | bool }}" + cache_dir: "/tmp/{{ molecule_distro }}" + output_dir: "{{ lookup('env', 'MOLECULE_OUTPUT_DIR', default='/tmp/logs') }}" + + molecule_net: "{{ lookup('env', 'MOLECULE_NET', default='192.168.254.0/24') }}" + bridge_net: "{{ molecule_net | ansible.utils.ipv4('network/prefix') }}" + bridge_host: "{{ bridge_net | ansible.utils.nthhost(1) }}" + bridge_prefix: "{{ bridge_net | ansible.utils.ipaddr('prefix') }}" + bridge_name: "{{ molecule_distro }}br1" + bridge_iface: "{{ molecule_distro }}0" + + kvm_keypair: "{{ cache_dir }}/kvm_key" + ansible_ssh_common_args: '-o StrictHostKeyChecking=no' + + iso_installer: + dest: "file://{{ cache_dir }}/{{ molecule_distro }}.iso" + url: "{{ molecule_iso }}" + + guests: + - installer_hostname: "{{ molecule_distro }}-lvm-10g" + installer_disk_size: "{{ 10*(1024**3) }}" + installer_interface: + static: true + ipaddress: "{{ bridge_net | ansible.utils.nthhost(2) }}" + network: "{{ bridge_net | ansible.utils.ipaddr('network') }}" + netmask: "{{ bridge_net | ansible.utils.ipaddr('netmask') }}" + gateway: "{{ bridge_host }}" + nameservers: + - 1.1.1.1 + - 8.8.8.8 + installer_partitioning_method: lvm + installer_preseed_include: | + d-i partman-auto/expert_recipe string \ + boot-root :: \ + 512 10 512 ext3 \ + $$primary{ } $$bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext3 } \ + mountpoint{ /boot } \ + . \ + 4000 20 4000 linux-swap \ + $$primary{ } \ + method{ swap } format{ } \ + . \ + 1000 50 1000000000 lvm \ + $$primary{ } \ + method{ lvm } \ + . \ + 1000 50 1000000000 ext4 \ + $$lvmok{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . + d-i partman-basicfilesystems/no_swap boolean false + + - installer_hostname: "{{ molecule_distro }}-static-10g" + installer_disk_size: "{{ 10*(1024**3) }}" + installer_interface: + static: true + ipaddress: "{{ bridge_net | ansible.utils.nthhost(3) }}" + network: "{{ bridge_net | ansible.utils.ipaddr('network') }}" + netmask: "{{ bridge_net | ansible.utils.ipaddr('netmask') }}" + gateway: "{{ bridge_host }}" + nameservers: + - 1.1.1.1 + - 8.8.8.8 + installer_partitioning_method: regular + installer_preseed_include: | + d-i partman-auto/expert_recipe string \ + boot-root :: \ + 512 10 512 ext3 \ + $$primary{ } $$bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 4000 20 4000 linux-swap \ + $$primary{ } \ + method{ swap } format{ } \ + . \ + 1000 50 1000000000 ext4 \ + $$primary{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . + d-i partman-basicfilesystems/no_swap boolean false + +verifier: + name: ansible +scenario: + test_sequence: + - dependency + - create + - prepare + - converge + - side_effect + - verify + - cleanup diff --git a/molecule/default b/molecule/default new file mode 120000 index 0000000..7d13753 --- /dev/null +++ b/molecule/default @@ -0,0 +1 @@ +ubuntu \ No newline at end of file diff --git a/molecule/default/molecule.yml b/molecule/ubuntu/molecule.yml similarity index 96% rename from molecule/default/molecule.yml rename to molecule/ubuntu/molecule.yml index 07823a7..1dfc347 100644 --- a/molecule/default/molecule.yml +++ b/molecule/ubuntu/molecule.yml @@ -34,6 +34,7 @@ provisioner: all: vars: growfs_device_filter: "vd.*" + molecule_scenario: "${MOLECULE_SCENARIO_NAME}" molecule_distro: "{{ lookup('env', 'MOLECULE_DISTRO', default='jammy') }}" molecule_iso: "{{ lookup('env', 'MOLECULE_ISO', default='https://releases.ubuntu.com/jammy/ubuntu-22.04.3-live-server-amd64.iso') }}" molecule_debug: "{{ lookup('env', 'GITHUB_ACTIONS', default='false') | bool }}" @@ -51,7 +52,7 @@ provisioner: ansible_ssh_common_args: '-o StrictHostKeyChecking=no' iso_installer: - dest: "file://{{ cache_dir }}/server-live.iso" + dest: "file://{{ cache_dir }}/{{ molecule_distro }}.iso" url: "{{ molecule_iso }}" guests: