Skip to content

Commit

Permalink
Refactor cluster configuration with member fqdns (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
teddyphreak authored Jan 12, 2024
1 parent f3bf79d commit d046687
Show file tree
Hide file tree
Showing 32 changed files with 1,312 additions and 1,209 deletions.
41 changes: 21 additions & 20 deletions .github/workflows/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,29 @@ on:
jobs:
molecule:
name: molecule
runs-on: ubuntu-latest
runs-on: libvirt
strategy:
matrix:
scenario:
- name: install
- name: offline
- name: online
- name: stop
- name: start
- name: restart
- name: update
- name: upgrade
- install
- offline
- online
- stop
- start
- restart
- update
- upgrade
image:
- name: ubuntu2204
command: /lib/systemd/systemd
- name: ubuntu2004
command: /lib/systemd/systemd
- name: debian11
command: /lib/systemd/systemd
- name: rockylinux9
command: /usr/lib/systemd/systemd
- https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
include:
- scenario: install
image: https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
- scenario: install
image: https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2
- scenario: install
image: https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
- scenario: update
image: https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
steps:
- name: Check out the codebase
uses: actions/checkout@v4
Expand Down Expand Up @@ -61,6 +63,5 @@ jobs:
env:
PY_COLORS: '1'
ANSIBLE_FORCE_COLOR: '1'
MOLECULE_DOCKER_IMAGE: ${{ matrix.image.name }}
MOLECULE_DOCKER_COMMAND: ${{ matrix.image.command }}
MOLECULE_SCENARIO: ${{ matrix.scenario.name }}
MOLECULE_KVM_IMAGE: ${{ matrix.image }}
MOLECULE_SCENARIO: ${{ matrix.scenario }}
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.PHONY: all ${MAKECMDGOALS}

MOLECULE_SCENARIO ?= install
MOLECULE_DOCKER_IMAGE ?= ubuntu2004
MOLECULE_KVM_IMAGE ?= https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
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)
Expand All @@ -21,6 +21,7 @@ test: lint
install:
@type poetry >/dev/null || pip3 install poetry
@type yq || sudo apt-get install -y yq
@sudo apt-get install -y libvirt-dev
@poetry install --no-root

lint: install
Expand All @@ -41,7 +42,7 @@ build: requirements
@poetry run ansible-galaxy collection build --force

dependency create prepare converge idempotence side-effect verify destroy login reset list:
MOLECULE_DOCKER_IMAGE=${MOLECULE_DOCKER_IMAGE} poetry run molecule $@ -s ${MOLECULE_SCENARIO}
MOLECULE_KVM_IMAGE=${MOLECULE_KVM_IMAGE} poetry run molecule $@ -s ${MOLECULE_SCENARIO}

ignore:
@poetry run ansible-lint --generate-ignore
Expand Down
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
namespace: nephelaiio
name: mongodb
version: 0.1.4
version: 0.2.0
readme: README.md
authors:
- Ted Cook <[email protected]>
Expand Down
22 changes: 22 additions & 0 deletions molecule/common/cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- name: Destroy libvirt storage
hosts: localhost
become: true
vars_files:
- vars.yml
tasks:
- name: Delete cached images
ansible.builtin.file:
dest: "{{ _path }}"
state: absent
vars:
_basename: "{{ item | urlsplit('path') | basename }}"
_path: "{{ _libvirt_path }}/{{ _basename }}"
loop_control:
label: "{{ _path }}"
loop: "{{ molecule_yml.platforms | map(attribute='image') | unique }}"

- name: Destroy libvirt pool
community.libvirt.virt_pool:
state: deleted
name: "{{ _libvirt_pool }}"
272 changes: 272 additions & 0 deletions molecule/common/create.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
---
- name: Configure KVM host
hosts: localhost
become: true
vars_files:
- vars.yml
tasks:
- name: Install package requirements
ansible.builtin.package:
name:
- qemu-kvm
- qemu-efi
- libvirt-clients
- libvirt-daemon-system
- libvirt-daemon-system-systemd
- python3-libvirt
become: true

- name: Query libvirt pools
community.libvirt.virt_pool:
command: list_pools
register: _pools

- name: Create libvirt path
ansible.builtin.file:
path: "{{ _libvirt_path }}"
state: directory
owner: root
group: root
mode: 0755
become: true

- name: Define libvirt pool
community.libvirt.virt_pool:
command: define
name: "{{ _libvirt_pool }}"
xml: "{{ lookup('ansible.builtin.template', 'pool.j2.xml') }}"
vars:
_pool: "{{ _libvirt_pool }}"
_path: "{{ _libvirt_path }}"

- name: Activate libvirt pool
community.libvirt.virt_pool:
state: active
name: "{{ _libvirt_pool }}"

- name: Add libvirt network
community.libvirt.virt_net:
command: define
name: "{{ _libvirt_network }}"
xml: "{{ lookup('ansible.builtin.template', 'network.j2.xml') }}"
vars:
_network: "{{ _libvirt_network }}"
_address: "{{ _libvirt_address }}"
_dhcp: "{{ _libvirt_dhcp }}"
_net_address: "{{ _address | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}"
_net_mask: "{{ _address | ansible.utils.ipaddr('netmask') }}"
_net_dhcp_start: "{{ _dhcp | ansible.utils.ipaddr('2') | ansible.utils.ipaddr('address') }}"
_net_dhcp_end: "{{ _dhcp | ansible.utils.ipaddr('-2') | ansible.utils.ipaddr('address') }}"
when: _libvirt_network != "default"

- name: Start libvirt network
community.libvirt.virt_net:
command: create
name: "{{ _libvirt_network }}"
when: _libvirt_network != "default"

- name: List cached images
ansible.builtin.find:
paths: "{{ _libvirt_pool }}"
recurse: false
register: _cache_query

- name: Inspect cached images
ansible.builtin.set_fact:
_uncached_images: "{{ (_uncached_images | default([])) + [item] }}"
vars:
_cached_images: "{{ _cache_query.files | map(attribute='path') }}"
_basename: "{{ item | urlsplit('path') | basename }}"
_path: "{{ _libvirt_pool }}/{{ _basename }}"
loop: "{{ molecule_yml.platforms | map(attribute='image') | unique }}"
when: _path not in _cached_images

- name: Cache platform images
ansible.builtin.get_url:
url: "{{ item }}"
dest: "{{ _path }}"
owner: root
group: root
mode: 0600
vars:
_basename: "{{ item | urlsplit('path') | basename }}"
_path: "{{ _libvirt_path }}/{{ _basename }}"
loop: "{{ _uncached_images | default([]) }}"


- name: Create KVM guests
hosts: all
gather_facts: false
become: true
vars_files:
- vars.yml
tasks:
- name: Create KVM guest
delegate_to: localhost
block:
- name: Create SSH key
community.crypto.openssh_keypair:
path: "{{ lookup('ansible.builtin.env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/id_rsa"
run_once: true
register: _pubkey
become: false

- name: Query active KVM guests
ansible.builtin.command: virsh list --name
run_once: true
register: guest_query

- name: Manage KVM guests
when: inventory_hostname not in guest_query.stdout_lines
block:

- name: Create KVM guest disks
ansible.builtin.copy:
remote_src: true
src: "{{ _libvirt_path }}/{{ _platform.image | urlsplit('path') | basename }}"
dest: "{{ _disk }}"
owner: libvirt-qemu
group: kvm
mode: 0666
force: true
vars:
_platforms: "{{ molecule_yml.platforms }}"
_platform: "{{ _platforms | selectattr('name', 'equalto', inventory_hostname) | first }}"
_disk: "{{ _libvirt_path }}/{{ _platform.name }}.img"

- name: Resize KVM guest disks
ansible.builtin.command:
cmd: qemu-img resize {{ _disk }} {{ _platform.size | default('20G') }}
vars:
_platforms: "{{ molecule_yml.platforms }}"
_platform: "{{ _platforms | selectattr('name', 'equalto', inventory_hostname) | first }}"
_disk: "{{ _libvirt_path }}/{{ _platform.name }}.img"

- name: Create cloud-init tempdir
ansible.builtin.tempfile:
state: directory
prefix: libvirt
register: libvirt_tmpdir
run_once: true

- name: Create KVM guest
block:
- name: Create instance tempdir
ansible.builtin.file:
dest: "{{ libvirt_tmpdir.path }}/{{ inventory_hostname }}"
state: directory

- name: Create cloud-init meta data
ansible.builtin.template:
src: "meta-data.yml.j2"
dest: "{{ libvirt_tmpdir.path }}/{{ inventory_hostname }}/meta-data"

- name: Create cloud-init user data
ansible.builtin.template:
src: "user-data.yml.j2"
dest: "{{ libvirt_tmpdir.path }}/{{ inventory_hostname }}/user-data"
vars:
guest_user: "{{ _libvirt_user }}"
guest_key: "{{ _pubkey.public_key }}"

- name: Create cloud-init iso
ansible.builtin.command:
cmd: |
xorriso -as mkisofs
-volid cidata -joliet -rock
-o {{ _libvirt_path }}/{{ inventory_hostname }}.iso .
chdir: "{{ libvirt_tmpdir.path }}/{{ inventory_hostname }}"

- name: Create KVM guest
community.libvirt.virt:
xml: "{{ lookup('ansible.builtin.template', 'vm.j2.xml') }}"
command: define
vars:
guest_hostname: "{{ inventory_hostname }}"
guest_disk_format: qcow2
guest_disk_path: "{{ _libvirt_path }}/{{ inventory_hostname }}.img"
guest_iso_path: "{{ _libvirt_path }}/{{ inventory_hostname }}.iso"
guest_network: "{{ _libvirt_network }}"
guest_mac: "{{ '52:54:00' | random_mac(seed=guest_hostname) }}"
loop_control:
label: "{{ inventory_hostname }} - {{ _libvirt_path }}/{{ inventory_hostname }}.img"

always:
- name: Destroy cloud-init tempdir
ansible.builtin.file:
dest: "{{ libvirt_tmpdir.path }}"
state: absent
run_once: true

- name: Start KVM guest
community.libvirt.virt:
name: "{{ inventory_hostname }}"
state: running


- name: Build instance config file
hosts: localhost
vars_files:
- vars.yml
tasks:
- name: Create SSH key
community.crypto.openssh_keypair:
path: "{{ lookup('ansible.builtin.env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/id_rsa"
run_once: true
register: _pubkey

- name: Retrieve platform ip information
become: true
block:
- name: Wait for DHCP lease assignment
ansible.builtin.shell:
cmd: "virsh net-dhcp-leases --network {{ _libvirt_network }} | grep {{ item }}"
executable: /bin/bash
loop: "{{ molecule_yml.platforms | map(attribute='name') }}"
register: dhcp_query
retries: 6
delay: 30
until: dhcp_query is succeeded

- name: Query DHCP leases
ansible.builtin.shell: >
virsh net-dhcp-leases --network {{ _libvirt_network }} | grep {{ item }} | awk '{print $5}'
loop: "{{ molecule_yml.platforms | map(attribute='name') }}"
register: dhcp_query

- name: Populate instance config dict
ansible.builtin.set_fact:
instance_conf_dict: {
'instance': "{{ item }}",
'address': "{{ _libvirt_address | ansible.utils.ipaddr('address') }}",
'user': "{{ _libvirt_user }}",
'port': "22",
'identity_file': "{{ _pubkey.filename }}"
}
vars:
_libvirt_addresses: "{{ dhcp_query.results | nephelaiio.plugins.list_to_dict('item') }}"
_libvirt_address: "{{ _libvirt_addresses[item].stdout }}"
loop: "{{ molecule_yml.platforms | map(attribute='name') }}"
register: instance_config_dict

- name: Convert instance config dict to a list
ansible.builtin.set_fact:
_instance_conf: "{{ _instance_results | map(attribute='ansible_facts.instance_conf_dict') | list }}"
vars:
_instance_results: "{{ instance_config_dict.results }}"

- name: Dump instance config
ansible.builtin.copy:
content: "{{ _instance_conf | ansible.builtin.to_nice_yaml(indent=2) }}"
dest: "{{ molecule_instance_config }}"
mode: 0640

- name: Configure host file entries
ansible.builtin.lineinfile:
path: /etc/hosts
regexp: ".*{{ item.instance }}.*"
line: "{{ item.address }} {{ item.instance }}"
loop_control:
label: "{{ item.instance }}"
loop: "{{ _instance_conf }}"
become: true
Loading

0 comments on commit d046687

Please sign in to comment.