diff --git a/alma/alma-9.pkr.hcl b/alma/alma-9.pkr.hcl new file mode 100644 index 0000000..8599113 --- /dev/null +++ b/alma/alma-9.pkr.hcl @@ -0,0 +1,61 @@ +packer { + required_plugins { + ansible = { + source = "github.com/hashicorp/ansible" + version = "~> 1" + } + qemu = { + source = "github.com/hashicorp/qemu" + version = "~> 1" + } + } +} + +variable "SSH_PRIVATE_KEY_FILE" { + type = string + default = "" +} + +variable "SSH_PUB_KEY" { + type = string + default = "" +} + +source "qemu" "alma_9" { + boot_command = [ + "", + "linux inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/alma-9.cfg.tpl", + " PACKER_USER=root PACKER_AUTHORIZED_KEY={{ `${var.SSH_PUB_KEY}` | urlquery }}", + "" + ] + boot_wait = "3s" + disk_size = 8000 + format = "qcow2" + headless = true + http_directory = "httpdir" + http_port_max = 8550 + http_port_min = 8500 + iso_checksum = "sha256:1e5d7da3d84d5d9a5a1177858a5df21b868390bfccf7f0f419b1e59acc293160" + iso_url = "https://repo.almalinux.org/almalinux/9/isos/x86_64/AlmaLinux-9-latest-x86_64-boot.iso" + memory = 1024 + qemuargs = [["-cpu", "host"]] + shutdown_command = "shutdown -h now" + ssh_private_key_file = "${var.SSH_PRIVATE_KEY_FILE}" + ssh_timeout = "90m" + ssh_username = "root" + vm_name = "alma.9-2024.08.29" +} + +build { + sources = ["source.qemu.alma_9"] + + provisioner "ansible" { + playbook_file = "provisioners/config.yml" + use_proxy = false + } + + provisioner "shell" { + script = "provisioners/cleanup.sh" + } + +} diff --git a/alma/appdb/alma-9.yaml b/alma/appdb/alma-9.yaml new file mode 100644 index 0000000..e65df3a --- /dev/null +++ b/alma/appdb/alma-9.yaml @@ -0,0 +1,16 @@ +--- +appdb: + version: 2024.08.29 + expireson: 6 + notes: First release of Alma 9 + url: https://api.cloud.ifca.es:8080/swift/v1/egi_endorsed_vas/alma.9-2024.08.29.qcow2 + sha512: "4c92810eeaf85568b4e1adeeb22e069ed35dea1ba252b0878dabe7751d388ba9cc83c96728ffaf072a9f43adefcf6be9a73c3d45aebf631d7c8a534ab8345583" + arch: x86_64 + os: + family: Linux + name: Alma + version: '9' + ram: + minimum: 1GB + format: qcow2 + hypervisor: KVM diff --git a/alma/httpdir/alma-9.cfg.tpl b/alma/httpdir/alma-9.cfg.tpl new file mode 100644 index 0000000..8aae03a --- /dev/null +++ b/alma/httpdir/alma-9.cfg.tpl @@ -0,0 +1,56 @@ + + +lang en_US.UTF-8 +keyboard --vckeymap=us --xlayouts='us' +network --bootproto=dhcp --device=link --activate +# network installation +url --url https://repo.almalinux.org/almalinux/9/BaseOS/x86_64/kickstart/ +repo --name=BaseOS --baseurl=https://repo.almalinux.org/almalinux/9/BaseOS/x86_64/os/ +repo --name=AppStream --baseurl=https://repo.almalinux.org/almalinux/9/AppStream/x86_64/os/ +rootpw --plaintext rootpassword + +firewall --enabled --service=ssh +selinux --disabled +timezone UTC +bootloader --location=mbr +text +skipx + +zerombr +clearpart --all --initlabel +part / --size=1 --grow --fstype ext4 +firstboot --disabled +reboot + +%packages +@^minimal-environment +openssh-clients +openssh-server +sudo +kexec-tools +%end + +%post --erroronfail + +# based on: +# https://developer.hashicorp.com/packer/integrations/hashicorp/qemu/latest/components/builder/qemu#ssh-key-pair-automation + +for x in $(cat /proc/cmdline) +do + case $x in + PACKER_AUTHORIZED_KEY=*) + # URL decode $encoded into $PACKER_AUTHORIZED_KEY + encoded=$(echo "${x#*=}" | tr '+' ' ') + printf -v PACKER_AUTHORIZED_KEY '%b' "${encoded//%/\\x}" + ;; + esac +done + +echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/01-permitrootlogin.conf +mkdir -p /root/.ssh +echo $PACKER_AUTHORIZED_KEY >> /root/.ssh/authorized_keys +chmod 400 /root/.ssh/authorized_keys +%end + +%addon com_redhat_kdump --enable --reserve-mb='auto' +%end diff --git a/alma/provisioners/README.md b/alma/provisioners/README.md new file mode 100644 index 0000000..e62da22 --- /dev/null +++ b/alma/provisioners/README.md @@ -0,0 +1,5 @@ +# README + +This config is based on: +* [AlmaLinux OS Cloud Images](https://github.com/AlmaLinux/cloud-images/) +* [Previous EGI configuration for CentOS](https://github.com/EGI-Federation/fedcloud-vmi-templates/blob/7f6fe98eef5140922ba635e7222ccf23a6eda7b6/centos/) diff --git a/alma/provisioners/cleanup.sh b/alma/provisioners/cleanup.sh new file mode 100644 index 0000000..7fefa22 --- /dev/null +++ b/alma/provisioners/cleanup.sh @@ -0,0 +1,6 @@ +#!/bin/bash -x + +# Clean up leftover build files +sudo rm -fr /home/*/{.ssh,.ansible,.cache} +sudo rm -fr /root/{.ssh,.ansible,.cache} +sudo rm -fr /root/'~'* diff --git a/alma/provisioners/config.yml b/alma/provisioners/config.yml new file mode 100644 index 0000000..b3798ca --- /dev/null +++ b/alma/provisioners/config.yml @@ -0,0 +1,11 @@ +# An Ansible playbook that configures a Generic Cloud (OpenStack) image +--- +- name: AlmaLinux Generic Cloud + hosts: default + become: true + + roles: + - cloud_init + - qemu_guest + - config_vm + - cleanup_vm diff --git a/alma/provisioners/roles/cleanup_vm/defaults/main.yml b/alma/provisioners/roles/cleanup_vm/defaults/main.yml new file mode 100644 index 0000000..4a0ea17 --- /dev/null +++ b/alma/provisioners/roles/cleanup_vm/defaults/main.yml @@ -0,0 +1,2 @@ +--- +cleanup_ssh_host_keys: true diff --git a/alma/provisioners/roles/cleanup_vm/tasks/main.yml b/alma/provisioners/roles/cleanup_vm/tasks/main.yml new file mode 100644 index 0000000..2a12fad --- /dev/null +++ b/alma/provisioners/roles/cleanup_vm/tasks/main.yml @@ -0,0 +1,159 @@ +--- +- name: Remove old kernels + shell: dnf remove -y $(dnf repoquery --installonly --latest-limit=-1 -q) + +- name: Delete DNF cache + command: dnf clean all + +- name: Find DNF history files + ansible.builtin.find: + paths: /var/lib/dnf + patterns: "history*" + register: dnf_history + +- name: Reset DNF history + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + loop: "{{ dnf_history.files }}" + loop_control: + label: "{{ item.path }}" + +- name: Find temporary files + find: + file_type: any + paths: + - /tmp + - /var/tmp + patterns: '*' + register: tmp_files + +- name: Remove temporary files + file: + path: "{{ item.path }}" + state: absent + loop: "{{ tmp_files.files }}" + loop_control: + label: "{{ item.path }}" + +- name: Remove SSH host keys + block: + - name: Find SSH host keys + find: + paths: /etc/ssh + patterns: '*host*key*' + register: host_keys + + - name: Remove SSH host keys + file: + path: "{{ item.path }}" + state: absent + loop: "{{ host_keys.files }}" + loop_control: + label: "{{ item.path }}" + when: cleanup_ssh_host_keys | bool + +- name: Remove kickstart files + file: + path: "{{ item }}" + state: absent + loop: + - /root/anaconda-ks.cfg + - /root/original-ks.cfg + +- name: Truncate files + command: "truncate -s 0 {{ item }}" + loop: + - /etc/machine-id + - /etc/resolv.conf + - /var/log/audit/audit.log + - /var/log/wtmp + - /var/log/lastlog + - /var/log/btmp + - /var/log/cron + - /var/log/maillog + - /var/log/messages + - /var/log/secure + - /var/log/spooler + +- name: Remove log folders. + file: + path: "{{ item }}" + state: absent + loop: + - /var/log/anaconda + - /var/log/qemu-ga + - /var/log/tuned + - /var/lib/cloud + - /etc/hostname + - /etc/machine-info + - /var/lib/systemd/credential.secret + +- name: Find log files. + find: + paths: + - /var/log + - /var/log/sssd + patterns: '*log,*.old,*.log.gz,*.[0-9],*.gz,*-????????' + register: log_files + +- name: Remove log files + file: + path: "{{ item.path }}" + state: absent + loop: "{{ log_files.files }}" + loop_control: + label: "{{ item.path }}" + +- name: Remove random-seed + file: + path: /var/lib/systemd/random-seed + state: absent + +- name: Disable root SSH login via password + file: + path: /etc/ssh/sshd_config.d/01-permitrootlogin.conf + state: absent + when: ansible_facts['distribution_major_version'] == '9' + +- name: Fill free space with zeroes + shell: dd if=/dev/zero of=/zeroed_file bs=1M oflag=direct || rm -f /zeroed_file + +- name: Detect swap partition + command: grep -oP '^/dev/[\w-]+' /proc/swaps + register: swaps + ignore_errors: true + +- name: Wipe out swap data + block: + - name: Get swap partition UUID + command: "blkid {{ swaps.stdout }} -s UUID -o value" + register: swap_blkid + + - name: Unmount swap partition + command: "swapoff {{ swaps.stdout }}" + + - name: Fill swap partition with zeroes + shell: "dd if=/dev/zero of={{ swaps.stdout }} bs=1M oflag=direct || /bin/true" + + - name: Format swap partition + command: "mkswap -U {{ swap_blkid.stdout }} -f {{ swaps.stdout }}" + + - name: Mount swap partition + command: "swapon {{ swaps.stdout }}" + when: swaps.rc == 0 + +- name: Sync disc + command: sync + +- name: Clear shell history + shell: history -c + +- name: Check if WALinuxAgent is installed + stat: + path: /usr/sbin/waagent + register: cleanup_vm_waagent + +- name: Deprovision WALinuxAgent + command: waagent -deprovision+user -force + when: cleanup_vm_waagent.stat.exists diff --git a/alma/provisioners/roles/cloud_init/tasks/main.yml b/alma/provisioners/roles/cloud_init/tasks/main.yml new file mode 100644 index 0000000..5cdf80b --- /dev/null +++ b/alma/provisioners/roles/cloud_init/tasks/main.yml @@ -0,0 +1,28 @@ +- name: Install cloud-init + dnf: + name: + - cloud-init + - cloud-utils-growpart + - dracut-config-generic + +- name: Enable cloud-init services + service: + name: "{{ item }}" + enabled: true + with_items: + - cloud-config + - cloud-init + - cloud-init-local + - cloud-final + +- name: Create fedcloud config + copy: + content: | + # EGI FedCloud configuration + + # Make sure to disable ssh password authentication + ssh_pwauth: 0 + # Regenerate keys + ssh_deletekeys: True + ssh_genkeytypes: ['rsa', 'dsa'] + dest: /etc/cloud/cloud.cfg.d/01_fedcloud.cfg diff --git a/alma/provisioners/roles/config_vm/tasks/main.yml b/alma/provisioners/roles/config_vm/tasks/main.yml new file mode 100644 index 0000000..bafff2b --- /dev/null +++ b/alma/provisioners/roles/config_vm/tasks/main.yml @@ -0,0 +1,32 @@ +--- +- name: Configure /etc/sysconfig/network + lineinfile: + path: /etc/sysconfig/network + line: "{{ item }}" + with_items: + - NETWORKING=yes + - NOZEROCONF=yes + +# https://bugzilla.redhat.com/show_bug.cgi?id=1849082#c7 +- name: Enable Xen support + block: + - name: Enable xen drivers in dracut + lineinfile: + path: /etc/dracut.conf.d/xen.conf + line: 'add_drivers+=" xen-netfront xen-blkfront "' + create: true + owner: root + group: root + mode: 0644 + + - name: Upgrade initramfs + command: dracut -f --regenerate-all + when: ansible_facts['architecture'] == 'x86_64' + +- name: Regenerate the initramfs + command: dracut -f --regenerate-all + +- name: Disable root login + user: + name: root + password: '!!' diff --git a/alma/provisioners/roles/qemu_guest/tasks/main.yml b/alma/provisioners/roles/qemu_guest/tasks/main.yml new file mode 100644 index 0000000..6152f39 --- /dev/null +++ b/alma/provisioners/roles/qemu_guest/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- name: Install qemu-guest-agent and rsync + dnf: + name: + - qemu-guest-agent + - rsync + state: latest