diff --git a/.ansible-lint-ignore b/.ansible-lint-ignore index 57b65c5f0..03b849a44 100644 --- a/.ansible-lint-ignore +++ b/.ansible-lint-ignore @@ -39,6 +39,7 @@ roles/idrac_reset/defaults/main.yml var-naming[no-role-prefix] roles/idrac_os_deployment/defaults/main/rhel.yml var-naming[no-role-prefix] roles/idrac_os_deployment/defaults/main/esxi.yml var-naming[no-role-prefix] roles/idrac_os_deployment/defaults/main/main.yml var-naming[no-role-prefix] +roles/idrac_os_deployment/defaults/main/ubuntu.yml var-naming[no-role-prefix] roles/idrac_job_queue/defaults/main.yml var-naming[no-role-prefix] roles/idrac_job_queue/molecule/delete_job/converge.yml var-naming[no-role-prefix] diff --git a/roles/idrac_os_deployment/README.md b/roles/idrac_os_deployment/README.md index a86526f03..5a68ff783 100644 --- a/roles/idrac_os_deployment/README.md +++ b/roles/idrac_os_deployment/README.md @@ -5,17 +5,17 @@ Role to deploy operating system and version on the servers.
The role perform the following operations: 1. Downloads or copies the source ISO as a local copy in the ansible controller machine tmp folder. -1. Create a kickstart file using jinja template based on the os name and version . -1. Extract the ISO using the `xorriso` library. -1. Enable the extracted ISO to use kickstart file by modifying the boot configurations for bios and uefi. -1. Compile the iso to generate a custom iso by embedding the kickstart file in an iso using the `mkisofs`, `isohybrid` and `implantisomd5` commands. -1. Copy the custom ISO generated to destination share location as specfied to the role input. Based on the input a following method is used to copy the destination to a shared repository. +2. Create a kickstart file using jinja template based on the os name and version . +3. Extract the ISO using the `xorriso` library, in case of ubuntu we use `7z`. +4. Enable the extracted ISO to use kickstart file by modifying the boot configurations for bios and uefi. +5. Compile the iso to generate a custom iso by embedding the kickstart file in an iso using the `mkisofs`, `isohybrid` and `implantisomd5` commands. +6. Copy the custom ISO generated to destination share location as specfied to the role input. Based on the input a following method is used to copy the destination to a shared repository. - CIFS/NFS uses the local file mount to copy the ISO to a location. - HTTP/HTTPS uses the SSH to copy/transfer the ISO to a location where the web server content is served. -1. Using an iDRAC `idrac_virtual_media` module mount the custom ISO as virtual media (virtual CD) in an iDRAC. -1. Using an iDRAC `idrac_boot` module set the boot target to CD and enable a reboot to CD once. -1. Track for the OS deployment for the specified amount of user input time. -1. Eject the virtual media after the specfied time is finished. +7. Using an iDRAC `idrac_virtual_media` module mount the custom ISO as virtual media (virtual CD) in an iDRAC. +8. Using an iDRAC `idrac_boot` module set the boot target to CD and enable a reboot to CD once. +9. Track for the OS deployment for the specified amount of user input time. +10. Eject the virtual media after the specfied time is finished. Requirements ------------ @@ -32,6 +32,7 @@ xorriso syslinux isomd5sum wget +7z ``` ### Production Requirements to use the role. @@ -42,6 +43,7 @@ xorriso syslinux isomd5sum wget +7z ``` ### Ansible collections @@ -423,7 +425,7 @@ Role Variables idrac_os_deployment_supported_os - { RHEL: ["8", "9"], ESXI: ["8"] } + { RHEL: ["8", "9"], ESXI: ["8"], UBUNTU: ["jammy"] } Hold the map data of supported os name and version @@ -456,7 +458,7 @@ Example Playbook destination: protocol: https hostname: 198.192.0.1 - mountpath: /user/www/myrepo + mountpoint: /user/www/myrepo os_type: linux iso_path: /to/iso ``` @@ -480,7 +482,7 @@ Example Playbook destination: protocol: https hostname: 198.192.0.1 - mountpath: /user/www/myrepo + mountpoint: /user/www/myrepo os_type: linux iso_path: /to/iso ``` @@ -501,6 +503,30 @@ Example Playbook iso_name: custom-rhel.iso is_custom_iso: true ``` +``` +- name: Generate custom iso using a kickstart file and install UBUNTU OS + ansible.builtin.import_role: + name: idrac_os_deployment + vars: + hostname: 192.168.0.1 + username: root + password: password + ca_path: path/to/ca + os_name: UBUNTU + os_version: jammy + source: + protocol: https + hostname: 198.192.0.1 + ks_path: /to/iso/ks_ubuntu.cfg + path: /to/iso + iso_name: ubuntu.iso + destination: + protocol: https + hostname: 198.192.0.1 + mountpoint: /user/www/myrepo + os_type: linux + iso_path: /to/iso +``` Author Information ------------------ Dell Technologies
diff --git a/roles/idrac_os_deployment/defaults/main/ubuntu.yml b/roles/idrac_os_deployment/defaults/main/ubuntu.yml new file mode 100644 index 000000000..a2d29759e --- /dev/null +++ b/roles/idrac_os_deployment/defaults/main/ubuntu.yml @@ -0,0 +1,23 @@ +ubuntu_update_installer: true +ubuntu_preserve_sources_list: false +ubuntu_primary_mirror: "http://archive.ubuntu.com/ubuntu" +ubuntu_primary_arches: [i386, amd64] +ubuntu_secondary_mirror: "http://ports.ubuntu.com/ubuntu-ports" +ubuntu_secondary_arches: [s390x, arm64, armhf, powerpc, ppc64el, riscv64] +ubuntu_fallback_strategy: "abort" +ubuntu_geoip: true +ubuntu_git_ppa: "ppa:git-core/ppa" +ubuntu_hostname: "ubuntu" +# Initial user password "ubuntu" (hashed using SHA-512) +ubuntu_user_password: "$6$xlpCfETR.9nMepDn$0GDk0yuTOOMXrxFQacjQdbTNwCys.wMlo.EDzfKJGvLhy61R8IxaSCNveo247McGthyg7vBUgDlmTS3wF.64k1" +ubuntu_realname: "ubuntu" +ubuntu_username: "ubuntu" +ubuntu_keyboard: "us" +ubuntu_keyboard_toggle: "" +ubuntu_keyboard_variant: "" +ubuntu_locale: "en_US" +ubuntu_allow_pw: true +ubuntu_authorized_keys: [] # Add public keys here as a YAML list +ubuntu_install_ssh: true +ubuntu_storage_layout: "lvm" +ubuntu_match_size: "largest" diff --git a/roles/idrac_os_deployment/meta/argument_specs.yml b/roles/idrac_os_deployment/meta/argument_specs.yml index e1b4935aa..1bf13c620 100644 --- a/roles/idrac_os_deployment/meta/argument_specs.yml +++ b/roles/idrac_os_deployment/meta/argument_specs.yml @@ -37,14 +37,14 @@ argument_specs: type: str description: - The operating system name to match the jinja template of the kickstart file. - - Supported os name is versions for RHEL and ESXI. + - Supported os name is versions for RHEL and ESXI and UBUNTU. - Jinja template file should exists in the format _.j2 - This is required when I(is_custom_iso) is C(false). os_version: type: str description: - The operating system version to match the jinja template of the kickstart file. - - Supported versions for RHEL are 9.x and 8.x and for ESXi is 8.x. + - Supported versions for RHEL are 9.x and 8.x and for ESXi is 8.x and for UBUNTU is jammy. - Jinja template file should exists in the format _.j2 - This is required when I(is_custom_iso) is C(false) source: diff --git a/roles/idrac_os_deployment/tasks/iso/extract_iso.yml b/roles/idrac_os_deployment/tasks/iso/extract_iso.yml index 54e66a46e..3b2802f0a 100644 --- a/roles/idrac_os_deployment/tasks/iso/extract_iso.yml +++ b/roles/idrac_os_deployment/tasks/iso/extract_iso.yml @@ -5,6 +5,15 @@ changed_when: idrac_os_deployment_extract_cmd_out.rc == 0 failed_when: idrac_os_deployment_extract_cmd_out.rc != 0 ansible.builtin.command: "{{ idrac_os_deployment_xorriso_cmd | format(idrac_os_deployment_iso_file, idrac_os_deployment_iso_extract_dir) }}" + when: os_name.lower() in ['rhel', 'esxi'] + +- name: Extract the ISO on to extract folder (Ubuntu) + delegate_to: "{{ idrac_os_deployment_delegate }}" + register: idrac_os_deployment_extract_cmd_out + changed_when: idrac_os_deployment_extract_cmd_out.rc == 0 + failed_when: idrac_os_deployment_extract_cmd_out.rc != 0 + ansible.builtin.command: "{{ idrac_os_deployment_7z_cmd | format(idrac_os_deployment_iso_file, idrac_os_deployment_iso_extract_dir) }}" + when: os_name.lower() == "ubuntu" - name: Update file permissions delegate_to: "{{ idrac_os_deployment_delegate }}" diff --git a/roles/idrac_os_deployment/tasks/ubuntu/compile_iso.yml b/roles/idrac_os_deployment/tasks/ubuntu/compile_iso.yml new file mode 100644 index 000000000..d8f7209b8 --- /dev/null +++ b/roles/idrac_os_deployment/tasks/ubuntu/compile_iso.yml @@ -0,0 +1,52 @@ +--- +- name: Create 'server' folder inside the extract directory + delegate_to: "{{ idrac_os_deployment_delegate }}" + ansible.builtin.file: + path: "{{ idrac_os_deployment_iso_extract_dir }}/server" + state: directory + mode: "{{ idrac_os_deployment_copy_mode }}" + +- name: Create an empty 'meta-data' file inside the server folder + delegate_to: "{{ idrac_os_deployment_delegate }}" + ansible.builtin.copy: + content: "" + dest: "{{ idrac_os_deployment_iso_extract_dir }}/server/meta-data" + mode: "{{ idrac_os_deployment_copy_mode }}" + +- name: Copy KS user-data to extracted + delegate_to: "{{ idrac_os_deployment_delegate }}" + ansible.builtin.copy: + src: "{{ idrac_os_deployment_kickstart_file }}" + dest: "{{ idrac_os_deployment_iso_extract_dir }}/server/{{ idrac_os_deployment_ubuntu_ks_filename }}" + mode: "{{ idrac_os_deployment_copy_mode }}" + +- name: Append autoinstall menu entry to grub.cfg + delegate_to: "{{ idrac_os_deployment_delegate }}" + ansible.builtin.lineinfile: + path: "{{ idrac_os_deployment_iso_extract_dir }}/boot/grub/grub.cfg" + insertafter: "^set menu_color_highlight=black/light-gray" + line: | + menuentry 'Install Ubuntu with Kickstart' { + set gfxpayload=keep + linux /casper/vmlinuz quiet autoinstall ds=nocloud\;s={{ idrac_os_deployment_ubuntu_ks_location }}server/ --- + initrd /casper/initrd + } + +- name: Get iso LABEL + delegate_to: "{{ idrac_os_deployment_delegate }}" + ansible.builtin.command: "blkid -s LABEL -o value {{ idrac_os_deployment_iso_file }}" + register: idrac_os_deployment_blkid_output + changed_when: idrac_os_deployment_blkid_output.rc != 0 + +- name: Set iso LABEL + ansible.builtin.set_fact: + idrac_os_deployment_iso_label: "{{ idrac_os_deployment_blkid_output.stdout | trim }}" + +- name: Compile custom ISO + delegate_to: "{{ idrac_os_deployment_delegate }}" + ansible.builtin.command: + chdir: "{{ idrac_os_deployment_iso_extract_dir }}" + cmd: "{{ idrac_os_deployment_ubuntu_mkiso_cmd | format(idrac_os_deployment_custom_iso_file, idrac_os_deployment_iso_label) }}" + register: idrac_os_deployment_mkisofs_output + changed_when: idrac_os_deployment_mkisofs_output.rc == 0 + failed_when: idrac_os_deployment_mkisofs_output.rc != 0 diff --git a/roles/idrac_os_deployment/templates/UBUNTU_jammy.j2 b/roles/idrac_os_deployment/templates/UBUNTU_jammy.j2 new file mode 100644 index 000000000..2ccb417e1 --- /dev/null +++ b/roles/idrac_os_deployment/templates/UBUNTU_jammy.j2 @@ -0,0 +1,43 @@ +#cloud-config +# vim: ft=yaml: +autoinstall: + version: 1 + early-commands: + - ["cat", "/autoinstall.yaml"] + refresh-installer: + update: {{ ubuntu_update_installer }} + apt: + preserve_sources_list: {{ ubuntu_preserve_sources_list }} + mirror-selection: + primary: + - country-mirror + - uri: "{{ ubuntu_primary_mirror }}" + arches: {{ ubuntu_primary_arches }} + - uri: "{{ ubuntu_secondary_mirror }}" + arches: {{ ubuntu_secondary_arches }} + fallback: {{ ubuntu_fallback_strategy }} + geoip: {{ ubuntu_geoip }} + sources: + git-ppa: + source: {{ ubuntu_git_ppa }} + identity: + hostname: "{{ ubuntu_hostname }}" + password: "{{ ubuntu_user_password }}" + realname: "{{ ubuntu_realname }}" + username: "{{ ubuntu_username }}" + keyboard: + layout: "{{ ubuntu_keyboard }}" + toggle: "{{ ubuntu_keyboard_toggle }}" + variant: "{{ ubuntu_keyboard_variant }}" + locale: "{{ ubuntu_locale }}" + ssh: + allow-pw: {{ ubuntu_allow_pw }} + authorized-keys: {{ ubuntu_authorized_keys }} + install-server: {{ ubuntu_install_ssh }} + storage: + layout: + name: "{{ ubuntu_storage_layout }}" + match: + size: "{{ ubuntu_match_size }}" + late-commands: + - 'echo ''APT::Install-Recommends "false";'' >/target/etc/apt/apt.conf.d/02InstallRecommends' diff --git a/roles/idrac_os_deployment/vars/main.yml b/roles/idrac_os_deployment/vars/main.yml index 46220659d..2d376fd2f 100644 --- a/roles/idrac_os_deployment/vars/main.yml +++ b/roles/idrac_os_deployment/vars/main.yml @@ -5,6 +5,7 @@ idrac_os_deployment_delegate: "{{ lookup('ansible.builtin.env', 'RUNON', default idrac_os_deployment_supported_os: RHEL: ["8", "9"] ESXI: ["8"] + UBUNTU: ["jammy"] # Validation Error messages idrac_os_deployment_err_msg_os_required: "The parameters `os_name` and `os_version` is required." @@ -56,6 +57,7 @@ idrac_os_deployment_custom_iso_file: "" idrac_os_deployment_hybrid_cmd: isohybrid --uefi %s idrac_os_deployment_checksum_cmd: implantisomd5 %s idrac_os_deployment_xorriso_cmd: "xorriso -osirrox on -indev %s -extract / %s" +idrac_os_deployment_7z_cmd: "7z -y x %s -o%s" # Attributes required to compile esxi iso idrac_os_deployment_esxi_ks_filename: "KS.CFG" @@ -75,6 +77,27 @@ idrac_os_deployment_rhel_mkiso_cmd: -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -graft-points -joliet-long -V %s ." +# Attributes required to compile ubuntu iso +idrac_os_deployment_ubuntu_ks_filename: "user-data" +idrac_os_deployment_ubuntu_ks_dest_prefix: "/cdrom/" +idrac_os_deployment_ubuntu_ks_location: "{{ idrac_os_deployment_ubuntu_ks_dest_prefix }}" +idrac_os_deployment_ubuntu_mkiso_cmd: + "xorriso -as mkisofs -r \ + -o %s \ + -V '%s' \ + --grub2-mbr './[BOOT]/1-Boot-NoEmul.img' \ + -partition_offset 16 \ + --mbr-force-bootable \ + -append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b './[BOOT]/2-Boot-NoEmul.img' \ + -appended_part_as_gpt \ + -iso_mbr_part_type a2a0d0ebe5b9334487c068b6b72699c7 \ + -c '/boot.catalog' \ + -b '/boot/grub/i386-pc/eltorito.img' \ + -no-emul-boot -boot-load-size 4 -boot-info-table --grub2-boot-info \ + -eltorito-alt-boot \ + -e '--interval:appended_partition_2:::' \ + -no-emul-boot ." + # Extra params idrac_os_deployment_set_no_log: false idrac_os_deployment_validate_kickstart_file_ext: true