Adds Generic Cloud image build configuration

master
Eugene Zamriy 1 year ago
parent ec903e2a0e
commit c75cc2f669
Signed by untrusted user: ezamriy
GPG Key ID: 7EBF95C7DCFA496C

@ -24,7 +24,8 @@ $ packer version
Packer v1.9.1
```
Install required Packer plugins:
In order to install required Packer plugins run the following command in the
project root:
```shell
$ packer init -upgrade .
@ -38,6 +39,19 @@ $ firewall-cmd --zone=public --add-port=8000-9000/tcp --permanent
$ firewall-cmd --reload
```
You will also need to install either QEMU/KVM or VirtualBox or
VMWare Workstation, depending on what types of images you are going to build.
For VirtualBox and VMWare Workstation just follow the official site
instructions.
The QEMU/KVM installation instructions are provided below:
```shell
$ dnf install @virtualization
$ dnf install edk2-ovmf
```
## Building images
@ -63,6 +77,15 @@ See the [variables.pkr.hcl](variables.pkr.hcl) file for other supported
variables.
### Building Generic Cloud images
Generic Cloud image build command:
```shell
$ packer build -only=qemu.msvsphere-9-gencloud-x86_64 .
```
### Building Vagrant boxes
VirtualBox Vagrant box build command:

@ -0,0 +1,8 @@
---
- name: MSVSphere Generic Cloud image
hosts: default
become: true
roles:
- gencloud_guest
- cleanup_vm

@ -1,4 +1,5 @@
---
collections: []
collections:
- community.general
roles:
- name: ezamriy.vbox_guest

@ -0,0 +1,3 @@
# disable_firstboot
An Ansible role that disables the `firstboot` program run.

@ -0,0 +1,10 @@
---
- name: Disable firstboot
ansible.builtin.lineinfile:
path: /etc/sysconfig/firstboot
regexp: '^RUN_FIRSTBOOT='
line: 'RUN_FIRSTBOOT=NO'
create: true
owner: root
group: root
mode: 0o644

@ -0,0 +1,3 @@
# gencoud_guest
An Ansible role that configures an MSVSphere Generic Cloud image system.

@ -0,0 +1,9 @@
TYPE=Ethernet
DEVICE=eth0
BOOTPROTO=dhcp
PERSISTENT_DHCLIENT=1
IPV6INIT=yes
IPV6_FAILURE_FATAL=no
PEERDNS=yes
USERCTL=yes
ONBOOT=yes

@ -0,0 +1,7 @@
---
dependencies:
- role: disable_firstboot
- role: setup_cloud_init
cloud_init_user: 'msvsphere'
- role: pvgrub_config
- role: qemu_guest_agent

@ -0,0 +1,124 @@
---
- name: Remove firewalld and linux-firmware
ansible.builtin.dnf:
name:
- firewalld
- firewalld-filesystem
- ipset
- ipset-libs
- iptables
- python3-firewall
- python3-slip
- libnftnl
- libnfnetlink
- linux-firmware
state: absent
- name: Install additional software
ansible.builtin.dnf:
name:
- cockpit-system
- cockpit-ws
- dnf-utils
- gdisk
- nfs-utils
- rsync
- tar
- tuned
- tcpdump
state: present
- name: Find persistent-net.rules
ansible.builtin.find:
paths: /etc/udev/rules.d
patterns: 70*
register: net_rules
- name: Delete persistent-net.rules
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
with_items: "{{ net_rules.files }}"
- name: Configure /etc/sysconfig/network
ansible.builtin.lineinfile:
path: /etc/sysconfig/network
line: "{{ item }}"
with_items:
- NETWORKING=yes
- NOZEROCONF=yes
- name: Configure /etc/sysconfig/network-scripts/ifcfg-eth0
ansible.builtin.copy:
src: ifcfg-eth0
dest: /etc/sysconfig/network-scripts/ifcfg-eth0
owner: root
group: root
mode: 0644
- name: Disable consistent network device naming
ansible.builtin.file:
src: /dev/null
dest: /etc/udev/rules.d/80-net-name-slot.rules
owner: root
group: root
state: link
- name: Disable virtual terminals allocation by logind
ansible.builtin.replace:
path: '/etc/systemd/logind.conf'
regexp: '^#?NAutoVTs=\d+'
replace: 'NAutoVTs=0'
- name: Configure NetworkManager default DHCP timeout
community.general.ini_file:
path: /etc/NetworkManager/conf.d/dhcp.conf
section: connection
option: ipv4.dhcp-timeout
value: 300
owner: root
group: root
mode: 0644
seuser: system_u
- name: Set default kernel package type to kernel
ansible.builtin.replace:
path: /etc/sysconfig/kernel
regexp: '^(DEFAULTKERNEL=).*$'
replace: '\1kernel'
# https://bugzilla.redhat.com/show_bug.cgi?id=1849082#c7
- name: Enable Xen support
block:
- name: Enable xen drivers in dracut
ansible.builtin.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
ansible.builtin.command: dracut -f --regenerate-all
when: ansible_facts['architecture'] == 'x86_64'
- name: Add msvsphere user to /etc/sudoers
ansible.builtin.lineinfile:
path: /etc/sudoers
line: "msvsphere\tALL=(ALL)\tNOPASSWD: ALL"
state: present
- name: Set virtual-guest as default profile for tuned
ansible.builtin.lineinfile:
path: /etc/tuned/active_profile
line: virtual-guest
create: yes
- name: Regenerate the initramfs
ansible.builtin.command: dracut -f --regenerate-all
- name: Disable root login
ansible.builtin.user:
name: root
password: '!!'

@ -0,0 +1,3 @@
# pvgrub_config
An Ansible role that generates pvgrub bootloader configuration.

@ -0,0 +1,52 @@
---
- name: Get root partition UUID
ansible.builtin.command: findmnt / -o UUID -n
changed_when: false
register: root_uuid
- name: Get default boot record title
ansible.builtin.command: grubby --default-title
changed_when: false
register: grub_rec_title
- name: Get default kernel path
ansible.builtin.command: grubby --default-kernel
changed_when: false
register: grub_kernel_path
- name: Get default initrd path
ansible.builtin.shell: grubby --info=DEFAULT | grep initrd | grep -oP 'initrd="\K\S+?.img'
changed_when: false
register: grub_initrd_path
- name: Create /boot/grub directory
ansible.builtin.file:
path: /boot/grub
state: directory
owner: root
group: root
mode: 0755
- name: Render /boot/grub/grub.conf
ansible.builtin.template:
src: grub.conf.j2
dest: /boot/grub/grub.conf
owner: root
group: root
mode: 0644
- name: Create /boot/grub/menu.lst symlink
ansible.builtin.file:
src: grub.conf
dest: /boot/grub/menu.lst
owner: root
group: root
state: link
- name: Create /etc/grub.conf symlink
ansible.builtin.file:
src: /boot/grub/grub.conf
dest: /etc/grub.conf
owner: root
group: root
state: link

@ -0,0 +1,7 @@
default=0
timeout=0
title {{ grub_rec_title.stdout }}
root (hd0)
kernel {{ grub_kernel_path.stdout }} ro root=UUID={{ root_uuid.stdout }} console=hvc0 LANG=en_US.UTF-8
initrd {{ grub_initrd_path.stdout }}

@ -0,0 +1,3 @@
# qemu_guest_agent
An Ansible role that installs `qemu-guest-agent` on a virtual machine.

@ -0,0 +1,16 @@
galaxy_info:
role_name: qemu_guest_agent
author: Eugene Zamriy
description: Installs qemu-guest-agent
license: MIT
min_ansible_version: '2.5'
platforms:
- name: EL
versions:
- '8'
- '9'
galaxy_tags:
- qemu
- qemu-guest-agent
dependencies: []

@ -0,0 +1,5 @@
---
- name: Install qemu-guest-agent
ansible.builtin.dnf:
name: qemu-guest-agent
state: present

@ -0,0 +1,10 @@
# setup_cloud_init
An Ansible role that installs and configures [cloud-init](https://cloud-init.io/).
## Role Variables
The role variables and their default values are listed below:
* `cloud_init_user: ''` - a name of a user managed by cloud-init.

@ -0,0 +1,24 @@
- name: Install cloud-init
ansible.builtin.dnf:
name:
- cloud-init
- cloud-utils-growpart
- dracut-config-generic
state: present
- name: Enable cloud-init services
ansible.builtin.service:
name: "{{ item }}"
enabled: true
with_items:
- cloud-config
- cloud-init
- cloud-init-local
- cloud-final
- name: Configure cloud-init user name
ansible.builtin.replace:
dest: /etc/cloud/cloud.cfg
regexp: '^(\s+name:).*$'
replace: "\\1 {{ cloud_init_user }}"
when: cloud_init_user | length > 0

@ -0,0 +1,73 @@
# MSVSphere 9 Generic Cloud image kickstart file
# TODO: change url to the kickstart one when we have it
url --url https://rsync.inferitos.ru/msvsphere/9.2/BaseOS/x86_64/os/
repo --name=BaseOS --baseurl=https://rsync.inferitos.ru/msvsphere/9.2/BaseOS/x86_64/os/
repo --name=AppStream --baseurl=https://rsync.inferitos.ru/msvsphere/9.2/AppStream/x86_64/os/
text
skipx
eula --agreed
firstboot --disabled
lang C.UTF-8
keyboard us
timezone UTC --utc
network --bootproto=dhcp
firewall --enabled --service=ssh
services --disabled="kdump" --enabled="chronyd,rsyslog,sshd"
selinux --enforcing
bootloader --timeout=1 --location=mbr --append="console=tty0 console=ttyS0,115200n8 no_timer_check crashkernel=auto net.ifnames=0"
%pre --erroronfail
parted -s -a optimal /dev/sda -- mklabel gpt
parted -s -a optimal /dev/sda -- mkpart biosboot 1MiB 2MiB set 1 bios_grub on
parted -s -a optimal /dev/sda -- mkpart '"EFI System Partition"' fat32 2MiB 202MiB set 2 esp on
parted -s -a optimal /dev/sda -- mkpart boot xfs 202MiB 714MiB
parted -s -a optimal /dev/sda -- mkpart root xfs 714MiB 100%
%end
part biosboot --fstype=biosboot --onpart=sda1
part /boot/efi --fstype=efi --onpart=sda2
part /boot --fstype=xfs --onpart=sda3
part / --fstype=xfs --onpart=sda4
rootpw --plaintext msvsphere
reboot --eject
%packages --inst-langs=en
@core
dracut-config-generic
grub2-pc
usermode
-biosdevname
-dnf-plugin-spacewalk
-dracut-config-rescue
-iprutils
-iwl*-firmware
-langpacks-*
-mdadm
-open-vm-tools
-plymouth
-rhn*
%end
# disable kdump service
%addon com_redhat_kdump --disable
%end
%post --erroronfail
grub2-install --target=i386-pc /dev/sda
# permit root login via SSH with password authetication
echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/01-permitrootlogin.conf
%end

@ -0,0 +1,56 @@
/**
* Packer template for building MSVSphere 9 Generic Cloud images.
*/
source "qemu" "msvsphere-9-gencloud-x86_64" {
iso_url = var.iso_url_9_x86_64
iso_checksum = var.iso_checksum_9_x86_64
boot_command = var.gencloud_boot_cmd_9_x86_64_uefi
boot_wait = var.boot_wait
cpus = var.cpus
memory = var.memory
disk_size = var.gencloud_disk_size
headless = var.headless
http_directory = var.http_directory
shutdown_command = var.root_shutdown_command
ssh_username = var.gencloud_ssh_username
ssh_password = var.gencloud_ssh_password
ssh_timeout = var.ssh_timeout
vnc_bind_address = var.vnc_bind_address
accelerator = "kvm"
efi_firmware_code = var.uefi_ovmf_code
efi_firmware_vars = var.uefi_ovmf_vars
disk_interface = "virtio-scsi"
disk_cache = "unsafe"
disk_discard = "unmap"
disk_detect_zeroes = "unmap"
disk_compression = true
format = "qcow2"
machine_type = "q35"
net_device = "virtio-net"
qemu_binary = var.qemu_binary
vm_name = "MSVSphere-${var.os_version_9}-${formatdate("YYYYMMDD", timestamp())}.gencloud.x86_64.qcow2"
qemuargs = [
["-cpu", "host"]
]
}
build {
sources = [
"qemu.msvsphere-9-gencloud-x86_64"
]
provisioner "ansible" {
playbook_file = "ansible/gencloud.yml"
galaxy_file = "ansible/requirements.yml"
roles_path = "ansible/roles"
collections_path = "ansible/collections"
ansible_env_vars = [
"ANSIBLE_PIPELINING=True",
"ANSIBLE_REMOTE_TEMP=/tmp",
"ANSIBLE_SSH_ARGS='-o ControlMaster=no -o ControlPersist=180s -o ServerAliveInterval=120s -o TCPKeepAlive=yes -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa'"
]
extra_arguments = ["--scp-extra-args", "'-O'"]
}
}

@ -45,6 +45,12 @@ variable "boot_wait" {
default = "10s"
}
variable "root_shutdown_command" {
description = "The VM shutdown command"
type = string
default = "/sbin/shutdown -hP now"
}
variable "ssh_timeout" {
description = "The SSH connection timeout"
type = string
@ -69,6 +75,24 @@ variable "http_directory" {
default = "http"
}
variable "uefi_ovmf_code" {
description = "QEMU/KVM UEFI firmware path"
type = string
default = "/usr/share/OVMF/OVMF_CODE.fd"
}
variable "uefi_ovmf_vars" {
description = "QEMU/KVM UEFI firmware variables path"
type = string
default = "/usr/share/OVMF/OVMF_VARS.fd"
}
variable "qemu_binary" {
description = "QEMU binary path"
type = string
default = null
}
/**
* Vagrant-specific settings.
*/
@ -105,3 +129,47 @@ variable "vagrant_shutdown_command" {
type = string
default = "echo vagrant | sudo -S /sbin/shutdown -hP now"
}
variable "vnc_bind_address" {
description = "The Packer VNC server bind address"
type = string
default = "127.0.0.1"
}
/**
* Generic Cloud-specific settings.
*/
variable "gencloud_disk_size" {
description = "The VM disk size"
type = string
default = "10G"
}
variable "gencloud_boot_cmd_9_x86_64_uefi" {
description = "The boot command for x86_64 VMs in UEFI mode"
type = list(string)
default = [
"c<wait>",
"linuxefi",
" /images/pxeboot/vmlinuz",
" inst.stage2=hd:LABEL=MSVSphere-9-2-Minimal-x86_64 ro",
" inst.text biosdevname=0 net.ifnames=0",
" inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/msvsphere-9-gencloud.x86_64.ks",
"<enter>",
"initrdefi /images/pxeboot/initrd.img",
"<enter>",
"boot<enter><wait>"
]
}
variable "gencloud_ssh_username" {
description = "A login to use for SSH authentication"
type = string
default = "root"
}
variable "gencloud_ssh_password" {
description = "A password to use for SSH authentication"
type = string
default = "msvsphere"
}

Loading…
Cancel
Save