52-coreos-installer.yml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. ---
  2. # Perform the tasks involved with installing SNO using coreos-installer.
  3. - name: Prepare the files required for a SNO installation using coreos-installer.
  4. hosts: workstation.lab.example.com
  5. become: no
  6. gather_subset: min
  7. tasks:
  8. - name: Check the dependency status.
  9. ansible.builtin.stat:
  10. path: "{{ ansible_facts['user_dir'] }}/{{ item }}"
  11. get_attributes: no
  12. get_checksum: no
  13. get_mime: no
  14. register: dependencies
  15. loop:
  16. - install-pull-secret
  17. - .ssh/openshift.pub
  18. - ca/ca-cert.pem
  19. - mirror/working-dir/cluster-resources/idms-oc-mirror.yaml
  20. - Downloads/rhcos-418.94.202501221327-0-live.x86_64.iso
  21. - ansible.builtin.assert:
  22. that:
  23. - dependencies.results[0].stat.exists
  24. - dependencies.results[1].stat.exists
  25. - dependencies.results[2].stat.exists
  26. - dependencies.results[3].stat.exists
  27. - dependencies.results[4].stat.exists
  28. fail_msg: |
  29. ERROR: Either pull secret, SSH keypair, CA certificate, RHCOS ISO, or mirror artifacts are missing.
  30. Ensure all the relevant preceding tasks have been completed:
  31. - Quay prerequisites,
  32. - Quay deployment,
  33. - oc-mirror prerequisites,
  34. - oc-mirror execution,
  35. - OpenShift installation prerequisites
  36. Exiting.
  37. success_msg: "OK, dependencies exist."
  38. - name: Check whether someone fiddled with installation before.
  39. ansible.builtin.stat:
  40. path: "{{ ansible_facts['user_dir'] }}/sno-iso/.openshift_install.log"
  41. register: install_log
  42. - name: Warn if installation log was found.
  43. ansible.builtin.pause:
  44. prompt: |
  45. WARNING: Found .openshift_install.log in the cluster working directory. This usually
  46. means there were previous attempts of creating installation artifacts.
  47. If you want to recreate the cluster working directory from scratch, run this
  48. playbook with the variable "recreate_cluster_dir" set to any value like this:
  49. ansible-playbook -e recreate_cluster_dir=yes ./52-coreos-installer.yml
  50. Continuing in 5 seconds unless you interrupt execution.
  51. seconds: 5
  52. when:
  53. - install_log.stat.exists
  54. - recreate_cluster_dir is not defined
  55. - name: Load the dependencies as facts.
  56. ansible.builtin.set_fact:
  57. pull_secret: "{{ lookup('ansible.builtin.file', ansible_facts['user_dir'] + '/install-pull-secret') }}"
  58. public_key: "{{ lookup('ansible.builtin.file', ansible_facts['user_dir'] + '/.ssh/openshift.pub') }}"
  59. lab_ca_cert: "{{ lookup('ansible.builtin.file', ansible_facts['user_dir'] + '/ca/ca-cert.pem') }}"
  60. content_sources: "{{ lookup('ansible.builtin.file', ansible_facts['user_dir'] + '/mirror/working-dir/cluster-resources/idms-oc-mirror.yaml')
  61. | ansible.builtin.from_yaml_all }}"
  62. - name: Set the fact determining installation type (required for templating).
  63. ansible.builtin.set_fact:
  64. install_type: iso
  65. - name: Ensure install-config is there.
  66. ansible.builtin.template:
  67. src: templates/install-config-template.yaml.j2
  68. dest: "{{ ansible_facts['user_dir'] }}/install-config-sno-iso.yaml"
  69. mode: 0644
  70. owner: student
  71. group: student
  72. register: updated_install_config
  73. - name: Remove the installation directory if so required.
  74. ansible.builtin.file:
  75. path: "{{ ansible_facts['user_dir'] }}/sno-iso"
  76. state: absent
  77. when:
  78. - recreate_cluster_dir is defined
  79. - recreate_cluster_dir
  80. - name: Ensure the presence of installation directory.
  81. ansible.builtin.file:
  82. path: "{{ ansible_facts['user_dir'] }}/sno-iso"
  83. state: directory
  84. mode: 0755
  85. - name: Also, ensure that the right install-config.yaml file is in there.
  86. ansible.builtin.copy:
  87. src: "{{ ansible_facts['user_dir'] }}/install-config-sno-iso.yaml"
  88. remote_src: yes
  89. dest: "{{ ansible_facts['user_dir'] }}/sno-iso/install-config.yaml"
  90. mode: 0644
  91. register: published_install_config
  92. when:
  93. - (not install_log.stat.exists) or (recreate_cluster_dir is defined) or updated_install_config.changed
  94. - name: Create installation manifests if install config was published.
  95. ansible.builtin.command:
  96. cmd: openshift-install-fips create manifests
  97. chdir: "{{ ansible_facts['user_dir'] }}/sno-iso"
  98. when: published_install_config.changed
  99. - name: Render chrony customizations in home directory.
  100. ansible.builtin.template:
  101. src: templates/chrony-customization.bu.j2
  102. dest: "{{ ansible_facts['user_dir'] }}/chrony-{{ item }}.bu"
  103. mode: 0644
  104. owner: student
  105. group: student
  106. loop:
  107. - master
  108. - worker
  109. - name: Publish chrony customizations in manifests directory.
  110. ansible.builtin.command:
  111. cmd: butane ./chrony-{{ item }}.bu -o ./sno-iso/openshift/99_chrony_{{ item }}.yaml
  112. chdir: "{{ ansible_facts['user_dir'] }}"
  113. creates: sno-iso/openshift/99_chrony_{{ item }}.yaml
  114. loop:
  115. - master
  116. - worker
  117. when: published_install_config.changed
  118. - name: Everything should be set by now, so create SNO install config.
  119. ansible.builtin.command:
  120. cmd: openshift-install-fips create single-node-ignition-config
  121. chdir: "{{ ansible_facts['user_dir'] }}/sno-iso"
  122. when: published_install_config.changed
  123. register: recreated_sno_cfg
  124. - name: Ensure custom ISO is gone if anything was changed.
  125. ansible.builtin.file:
  126. path: "{{ ansible_facts['user_dir'] }}/sno-coreos-installer.iso"
  127. state: absent
  128. when:
  129. - recreated_sno_cfg is defined
  130. - recreated_sno_cfg.changed
  131. - name: Check if custom ISO is there.
  132. ansible.builtin.stat:
  133. path: "{{ ansible_facts['user_dir'] }}/sno-coreos-installer.iso"
  134. get_attributes: no
  135. get_checksum: no
  136. get_mime: no
  137. register: custom_iso
  138. - name: Embed install config in the ISO.
  139. ansible.builtin.command:
  140. cmd: coreos-installer iso ignition embed -fi ./sno-iso/bootstrap-in-place-for-live-iso.ign -o sno-coreos-installer.iso {{ ansible_facts['user_dir'] }}/Downloads/rhcos-418.94.202501221327-0-live.x86_64.iso
  141. chdir: "{{ ansible_facts['user_dir'] }}"
  142. when: not custom_iso.stat.exists
  143. - name: Ensure utility is configured in terms of DNS and DHCP.
  144. hosts: utility.lab.example.com
  145. gather_subset: min
  146. become: yes
  147. tasks:
  148. - name: Ensure the old master01 host config is gone (it is a single line).
  149. ansible.builtin.lineinfile:
  150. path: /etc/dhcp/dhcpd.conf
  151. regexp: '\s*host master01\.ocp4\.example\.com { .* }\s*$'
  152. state: absent
  153. notify:
  154. - restart dhcpd
  155. - name: Ensure the new master01 host config is present (it is a block).
  156. ansible.builtin.blockinfile:
  157. path: /etc/dhcp/dhcpd.conf
  158. marker: '# {mark} DHCP config for master01'
  159. marker_begin: "Start"
  160. marker_end: "End"
  161. block: |
  162. host master01.ocp4.example.com {
  163. hardware ethernet 52:54:00:00:32:0A;
  164. fixed-address 192.168.50.10;
  165. option host-name "master01";
  166. option domain-name "iso.ocp4.example.com";
  167. option routers 127.0.0.1;
  168. }
  169. insertbefore: "host master02"
  170. state: present
  171. notify:
  172. - restart dhcpd
  173. - name: Ensure forward DNS records are there.
  174. ansible.builtin.lineinfile:
  175. path: /var/named/ocp4.example.com.db
  176. regexp: "{{ item.regex }}"
  177. line: "{{ item.line }}"
  178. insertafter: "{{ item.after }}"
  179. loop:
  180. - regex: '^master01\.iso '
  181. line: "master01.iso IN A 192.168.50.10"
  182. after: '^master01 '
  183. - regex: '^api\.iso '
  184. line: "api.iso IN CNAME master01.iso"
  185. after: '^master01\.iso '
  186. - regex: '^api-int\.iso '
  187. line: "api-int.iso IN CNAME master01.iso"
  188. after: '^api\.iso '
  189. - regex: '^\*\.apps\.iso '
  190. line: "*.apps.iso IN A 192.168.50.10"
  191. after: '^api-int\.iso '
  192. register: dnsfw_fix
  193. notify:
  194. - reload dns
  195. - name: Increase the serial number of the forward zone if changed.
  196. block:
  197. - name: Load the zone file.
  198. ansible.builtin.slurp:
  199. src: /var/named/ocp4.example.com.db
  200. register: zonefile_fw
  201. - name: Read the serial number from the zone file and increase it by one.
  202. ansible.builtin.set_fact:
  203. new_fw_serial: "{{ (zonefile_fw.content | ansible.builtin.b64decode() | ansible.builtin.regex_search('^.*; serial', ignorecase=True, multiline=True) | ansible.builtin.regex_replace('; serial.*$', '') | trim | int) + 1 }}"
  204. - name: Insert the new serial number instead of the old one.
  205. ansible.builtin.lineinfile:
  206. path: /var/named/ocp4.example.com.db
  207. regexp: "; serial"
  208. line: " {{ new_fw_serial }} ; serial"
  209. when: dnsfw_fix.changed
  210. - name: Ensure reverse DNS record is there.
  211. ansible.builtin.lineinfile:
  212. path: /var/named/ocp4.example.com.reverse.db
  213. regexp: '^10\s+IN\s+PTR'
  214. line: "10 IN PTR master01.iso.ocp4.example.com."
  215. insertbefore: "master02"
  216. register: dnsre_fix
  217. notify:
  218. - reload dns
  219. - name: Increase the serial number of the reverse zone if changed.
  220. block:
  221. - name: Load the zone file.
  222. ansible.builtin.slurp:
  223. src: /var/named/ocp4.example.com.reverse.db
  224. register: zonefile_re
  225. - name: Read the serial number from the zone file and increase it by one.
  226. ansible.builtin.set_fact:
  227. new_re_serial: "{{ (zonefile_re.content | ansible.builtin.b64decode() | ansible.builtin.regex_search('^.*; serial', ignorecase=True, multiline=True) | ansible.builtin.regex_replace('; serial.*$', '') | trim | int) + 1 }}"
  228. - name: Insert the new serial number instead of the old one.
  229. ansible.builtin.lineinfile:
  230. path: /var/named/ocp4.example.com.reverse.db
  231. regexp: "; serial"
  232. line: " {{ new_re_serial }} ; serial"
  233. when: dnsre_fix.changed
  234. handlers:
  235. - name: restart dhcpd
  236. ansible.builtin.systemd_service:
  237. name: dhcpd
  238. state: restarted
  239. - name: reload dns
  240. ansible.builtin.systemd_service:
  241. name: named
  242. state: reloaded
  243. - name: Copy the ISO file to target machine and write it to /dev/sdb
  244. hosts: master01.ocp4.example.com
  245. gather_subset: min
  246. become: yes
  247. tasks:
  248. - name: Copy the ISO file to master01.
  249. ansible.builtin.copy:
  250. src: /home/student/sno-coreos-installer.iso
  251. dest: /root/sno-coreos-installer.iso
  252. mode: 0644
  253. register: copied_iso
  254. - name: Write the ISO to /dev/sdb if it was changed.
  255. ansible.builtin.command:
  256. cmd: dd if=/root/sno-coreos-installer.iso of=/dev/sdb conv=sync bs=4k
  257. when: copied_iso.changed
  258. register: wrote_iso
  259. - name: Wipe the filesystem of /dev/sda if ISO was written to /dev/sdb.
  260. ansible.builtin.command:
  261. cmd: wipefs -af /dev/sda
  262. when: wrote_iso.changed
  263. register: wiped_fs
  264. - name: Reboot the machine if filesystem was wiped.
  265. ansible.builtin.command:
  266. cmd: reboot
  267. ignore_errors: yes
  268. when: wiped_fs.changed
  269. ...