diff --git a/metal/group_vars/all.yml b/metal/group_vars/all.yml index 5292cca7..273c3bdf 100644 --- a/metal/group_vars/all.yml +++ b/metal/group_vars/all.yml @@ -1,5 +1,6 @@ iso_url: "https://mirrors.nhanhoa.com/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-dvd1.iso" disk: "sda" +dns_server: "8.8.8.8" network_interface: "eno1" ssh_public_key: "{{lookup('file', '~/.ssh/id_rsa.pub') }}" diff --git a/metal/playbook.yml b/metal/playbook.yml index 262adaeb..e929367b 100644 --- a/metal/playbook.yml +++ b/metal/playbook.yml @@ -1,5 +1,6 @@ - name: Install OS on empty nodes - hosts: controller + hosts: all + gather_facts: no vars_prompt: - name: username prompt: Enter username for metal nodes diff --git a/metal/roles/pxe-boot/tasks/main.yml b/metal/roles/pxe-boot/tasks/main.yml index f6e8b651..f8154dee 100644 --- a/metal/roles/pxe-boot/tasks/main.yml +++ b/metal/roles/pxe-boot/tasks/main.yml @@ -1,72 +1,12 @@ -- name: Create build directory - file: - path: "{{ item }}" - state: directory - loop: - - "{{ role_path }}/build" - - "{{ role_path }}/build/images" - - "{{ role_path }}/build/mnt" +- name: Render configs and start PXE server + include_tasks: + file: server.yml + run_once: yes + when: + - "'controller' in group_names" -# - name: Download ISO -# get_url: -# url: "{{ iso_url }}" -# dest: "{{ role_path }}/build/images/centos8.iso" - -- name: Mount the ISO - mount: - src: "{{ role_path }}/build/images/centos8.iso" - path: "{{ role_path }}/build/mnt" - fstype: iso9660 - opts: loop,ro - state: mounted - become: yes - -- name: Copy configs - copy: - src: "{{ role_path }}/templates/" - dest: "{{ role_path }}/build" - -- name: Render DHCP config - template: - src: dhcp/dhcpd.conf.j2 - dest: "{{ role_path }}/build/dhcp/dhcpd.conf" - -- name: Render GRUB config - template: - src: tftp/tftpboot/grub.cfg.j2 - dest: "{{ role_path }}/build/tftp/tftpboot/grub.cfg" - -- name: Render shared kickstart config - template: - src: http/kickstart/centos8.ks.j2 - dest: "{{ role_path }}/build/http/kickstart/centos8.ks" - -- name: Render seperate network kickstart config for each node - template: - src: http/kickstart/network/network.ks.j2 - dest: "{{ role_path }}/build/http/kickstart/network/{{ hostvars[item]['mac'] }}.ks" - loop: "{{ groups['metal'] }}" - -- name: Start PXE server - docker_compose: - project_src: "{{ role_path }}/build" - build: yes - delegate_to: localhost - -- name: Unconditionally shut down the machine with all defaults - community.general.shutdown: - delay: 0 - -- name: Wait for the machine to shutdown - wait_for: - timeout: 30 - delegate_to: localhost - -- name: Send magic Wake-on-LAN packet - community.general.wakeonlan: - mac: "{{ hostvars[inventory_hostname]['mac'] }}" - delegate_to: localhost - -- name: Wait for the servers to comes up - wait_for_connection: - timeout: 600 +- name: Wakes the nodes up and install OS on them + include_tasks: + file: wake.yml + when: + - "'metal' in group_names" diff --git a/metal/roles/pxe-boot/tasks/server.yml b/metal/roles/pxe-boot/tasks/server.yml new file mode 100644 index 00000000..3ad2b0f2 --- /dev/null +++ b/metal/roles/pxe-boot/tasks/server.yml @@ -0,0 +1,62 @@ +- name: Gather network facts + ansible.builtin.setup: + gather_subset: + - network + +- name: Create build directory + file: + path: "{{ item }}" + state: directory + loop: + - "{{ role_path }}/build" + - "{{ role_path }}/build/images" + - "{{ role_path }}/build/mnt" + +# - name: Download ISO +# get_url: +# url: "{{ iso_url }}" +# dest: "{{ role_path }}/build/images/centos8.iso" +# delegate_to: localhost + +- name: Mount the ISO + mount: + src: "{{ role_path }}/build/images/centos8.iso" + path: "{{ role_path }}/build/mnt" + fstype: iso9660 + opts: loop,ro + state: mounted + become: yes + +- name: Copy configs + copy: + src: "{{ role_path }}/templates/" + dest: "{{ role_path }}/build" + +- name: Render DHCP config + template: + src: dhcp/dhcpd.conf.j2 + dest: "{{ role_path }}/build/dhcp/dhcpd.conf" + +- name: Render GRUB config + template: + src: tftp/tftpboot/grub.cfg.j2 + dest: "{{ role_path }}/build/tftp/tftpboot/grub.cfg" + +- name: Render shared kickstart config + template: + src: http/kickstart/centos8.ks.j2 + dest: "{{ role_path }}/build/http/kickstart/centos8.ks" + +- name: Render seperate network kickstart config for each node + template: + src: http/kickstart/network/network.ks.j2 + dest: "{{ role_path }}/build/http/kickstart/network/{{ hostvars[item]['mac'] }}.ks" + loop: "{{ groups['metal'] }}" + +- name: Start PXE server + docker_compose: + project_src: "{{ role_path }}/build" + state: present + restarted: yes + build: yes + recreate: always diff --git a/metal/roles/pxe-boot/tasks/wake.yml b/metal/roles/pxe-boot/tasks/wake.yml new file mode 100644 index 00000000..54a3ccf3 --- /dev/null +++ b/metal/roles/pxe-boot/tasks/wake.yml @@ -0,0 +1,18 @@ +- name: Unconditionally shut down the machine with all defaults + community.general.shutdown: + delay: 0 + ignore_unreachable: yes + +- name: Wait for the machine to shutdown + wait_for: + timeout: 30 + delegate_to: localhost + +- name: Send magic Wake-on-LAN packet + community.general.wakeonlan: + mac: "{{ hostvars[inventory_hostname]['mac'] }}" + delegate_to: localhost + +- name: Wait for the servers to comes up + wait_for_connection: + timeout: 600 diff --git a/metal/roles/pxe-boot/templates/dhcp/dhcpd.conf.j2 b/metal/roles/pxe-boot/templates/dhcp/dhcpd.conf.j2 index 49c7facf..483d7b1d 100644 --- a/metal/roles/pxe-boot/templates/dhcp/dhcpd.conf.j2 +++ b/metal/roles/pxe-boot/templates/dhcp/dhcpd.conf.j2 @@ -5,13 +5,13 @@ option pxelinux.pathprefix code 210 = text; option pxelinux.reboottime code 211 = unsigned integer 32; option architecture-type code 93 = unsigned integer 16; -subnet {{ subnet }} netmask {{ netmask }} { -option routers {{ gateway }}; -range {{ range_start }} {{ range_end }}; +subnet {{ ansible_default_ipv4.network }} netmask {{ ansible_default_ipv4.netmask }} { + option routers {{ ansible_default_ipv4.gateway }}; + range {{ ansible_default_ipv4.gateway | ansible.netcommon.ipmath(1) }} {{ ansible_default_ipv4.broadcast | ansible.netcommon.ipmath(-1) }}; class "pxeclients" { match if substring (option vendor-class-identifier, 0, 9) = "PXEClient"; - next-server {{ pxe_server }}; + next-server {{ ansible_default_ipv4.address }}; if option architecture-type = 00:07 { filename "grubx64.efi"; diff --git a/metal/roles/pxe-boot/templates/http/kickstart/centos8.ks.j2 b/metal/roles/pxe-boot/templates/http/kickstart/centos8.ks.j2 index 63cc9173..b9806887 100644 --- a/metal/roles/pxe-boot/templates/http/kickstart/centos8.ks.j2 +++ b/metal/roles/pxe-boot/templates/http/kickstart/centos8.ks.j2 @@ -1,6 +1,6 @@ %pre --interpreter=/bin/sh mac=$(ip --brief link show dev {{ network_interface }} | tr -s ' ' | cut -d ' ' -f 3 | sed 's/:/-/g') -curl "http://{{ pxe_server }}/kickstart/network/$mac.ks" > /tmp/network.ks +curl "http://{{ ansible_default_ipv4.address }}/kickstart/network/$mac.ks" > /tmp/network.ks %end #version=RHEL8 @@ -17,9 +17,9 @@ lang en_US.UTF-8 # Network information %include /tmp/network.ks -repo --name="AppStream" --baseurl=http://{{ pxe_server }}/CentOS/AppStream +repo --name="AppStream" --baseurl=http://{{ ansible_default_ipv4.address }}/CentOS/AppStream # Use network installation -url --url="http://{{ pxe_server }}/CentOS/" +url --url="http://{{ ansible_default_ipv4.address }}/CentOS/" # Disable Setup Agent on first boot firstboot --disable # Do not configure the X Window System diff --git a/metal/roles/pxe-boot/templates/http/kickstart/network/network.ks.j2 b/metal/roles/pxe-boot/templates/http/kickstart/network/network.ks.j2 index c8bb54d5..e2051145 100644 --- a/metal/roles/pxe-boot/templates/http/kickstart/network/network.ks.j2 +++ b/metal/roles/pxe-boot/templates/http/kickstart/network/network.ks.j2 @@ -1,2 +1,2 @@ -network --bootproto=static --device={{ network_interface }} --ip={{ hostvars[item]['ansible_host'] }} --gateway={{ gateway }} --nameserver={{ dns }} --netmask={{ netmask }} --ipv6=auto --activate -network --hostname={{ hostvars[item]['inventory_hostname'] }} +network --bootproto=static --device={{ network_interface }} --ip={{ hostvars[item]['ansible_host'] }} --gateway={{ ansible_default_ipv4.gateway }} --nameserver={{ dns_server }} --netmask={{ ansible_default_ipv4.netmask }} --ipv6=auto --activate +network --hostname={{ hostvars[item]['inventory_hostname'] }} diff --git a/metal/roles/pxe-boot/templates/tftp/tftpboot/grub.cfg.j2 b/metal/roles/pxe-boot/templates/tftp/tftpboot/grub.cfg.j2 index 885714c8..f7e2f8b6 100644 --- a/metal/roles/pxe-boot/templates/tftp/tftpboot/grub.cfg.j2 +++ b/metal/roles/pxe-boot/templates/tftp/tftpboot/grub.cfg.j2 @@ -1,5 +1,5 @@ set timeout=5 menuentry 'CentOS' { -linuxefi vmlinuz ip=dhcp inst.repo=http://{{ pxe_server }}/CentOS ks=http://{{ pxe_server }}/kickstart/centos8.ks +linuxefi vmlinuz ip=dhcp inst.repo=http://{{ ansible_default_ipv4.address }}/CentOS ks=http://{{ ansible_default_ipv4.address }}/kickstart/centos8.ks initrdefi initrd.img }