Adds VMWare Vagrant box build configuration

master
Eugene Zamriy 1 year ago
parent 882617e945
commit eef59510ca
Signed by untrusted user: ezamriy
GPG Key ID: 7EBF95C7DCFA496C

2
.gitignore vendored

@ -0,0 +1,2 @@
.vscode
*.box

@ -4,6 +4,74 @@
building MSVSphere images for various cloud platforms.
## Build environment configuration
Supported operating systems:
* MSVSphere 9 and other EL9-compatible distributions
* Fedora
Follow the Packer installation [instructions](https://developer.hashicorp.com/packer/downloads?product_intent=packer).
Alternatively, you can install a Packer binary from a Yandex
[mirror](https://hashicorp-releases.yandexcloud.net/packer/): just download a
latest version archive and unzip it somewhere in PATH (e.g. `~/.local/bin`).
Verify that Packer works:
```shell
$ packer version
Packer v1.9.1
```
Install required Packer plugins:
```shell
$ packer init -upgrade .
```
Dependently on your network configuration, you may also need to open the
8000-9000 TCP port range so that Packer can serve kickstart files to VMs:
```shell
$ firewall-cmd --zone=public --add-port=8000-9000/tcp --permanent
$ firewall-cmd --reload
```
## Building images
In order to build an image use the following command syntax:
```shell
$ packer build -only=${BUILDER}.${CONFIGURATION} .
```
where `${BUILDER}` is a Packer builder (e.g. `virtualbox-iso`) and
`${CONFIGURATION}` is an image configuration name (e.g.
`msvsphere-9-vagrant-x86_64`).
A graphical VM console is disabled by default, but you can enable it for
debugging purposes by setting the `headless` variable to `false`:
```shell
$ packer build -only=vmware-iso.msvsphere-9-vagrant-x86_64 \
-var headless=false .
```
See the [variables.pkr.hcl](variables.pkr.hcl) file for other supported
variables.
### Building Vagrant boxes
VMWare Vagrant box build command:
```shell
$ packer build -only=vmware-iso.msvsphere-9-vagrant-x86_64 .
```
## License
Licensed under the MIT license, see the [LICENSE](LICENSE) file for details.

@ -0,0 +1,3 @@
---
collections: []
roles: []

@ -0,0 +1,3 @@
# cleanup_vm
An Ansible role that cleans-up and deprovisions a virtual machine.

@ -0,0 +1,14 @@
galaxy_info:
role_name: cleanup_vm
author: Eugene Zamriy
description: Cleans-up and deprovisions a VM
license: MIT
min_ansible_version: '2.5'
platforms:
- name: EL
versions:
- '8'
- '9'
galaxy_tags: []
dependencies: []

@ -0,0 +1,148 @@
---
- name: Remove old kernels
ansible.builtin.shell: dnf remove -y $(dnf repoquery --installonly --latest-limit=-1 -q)
- name: Delete DNF cache
ansible.builtin.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 }}"
- name: Find temporary files
ansible.builtin.find:
file_type: any
paths:
- /tmp
- /var/tmp
patterns: '*'
register: tmp_files
- name: Remove temporary files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ tmp_files.files }}"
- name: Find SSH host keys
ansible.builtin.find:
paths: /etc/ssh
patterns: '*host*key*'
register: host_keys
- name: Remove SSH host keys
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ host_keys.files }}"
- name: Remove kickstart files
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /root/anaconda-ks.cfg
- /root/original-ks.cfg
- name: Truncate files
ansible.builtin.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.
ansible.builtin.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.
ansible.builtin.find:
paths:
- /var/log
- /var/log/sssd
patterns: '*log,*.old,*.log.gz,*.[0-9],*.gz,*-????????'
register: log_files
- name: Remove log files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ log_files.files }}"
- name: Remove random-seed
ansible.builtin.file:
path: /var/lib/systemd/random-seed
state: absent
- name: Disable root SSH login via password
ansible.builtin.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
ansible.builtin.shell: dd if=/dev/zero of=/zeroed_file bs=1M oflag=direct || rm -f /zeroed_file
- name: Detect swap partition
ansible.builtin.command: grep -oP '^/dev/[\w-]+' /proc/swaps
register: swaps
ignore_errors: true
- name: Wipe out swap data
block:
- name: Get swap partition UUID
ansible.builtin.command: "blkid {{ swaps.stdout }} -s UUID -o value"
register: swap_blkid
- name: Unmount swap partition
ansible.builtin.command: "swapoff {{ swaps.stdout }}"
- name: Fill swap partition with zeroes
ansible.builtin.shell: "dd if=/dev/zero of={{ swaps.stdout }} bs=1M oflag=direct || /bin/true"
- name: Format swap partition
ansible.builtin.command: "mkswap -U {{ swap_blkid.stdout }} -f {{ swaps.stdout }}"
- name: Mount swap partition
ansible.builtin.command: "swapon {{ swaps.stdout }}"
when: swaps.rc == 0
- name: Sync disc
ansible.builtin.command: sync
- name: Clear shell history
ansible.builtin.shell: history -c
- name: Check if WALinuxAgent is installed
ansible.builtin.stat:
path: /usr/sbin/waagent
register: cleanup_vm_waagent
- name: Deprovision WALinuxAgent
ansible.builtin.command: waagent -deprovision+user -force
when: cleanup_vm_waagent.stat.exists

@ -0,0 +1,3 @@
# nfs_client
An Ansible role that installs the `nfs-utils` package.

@ -0,0 +1,15 @@
galaxy_info:
role_name: nfs_client
author: Eugene Zamriy
description: Installs nfs-utils package
license: MIT
min_ansible_version: '2.5'
platforms:
- name: EL
versions:
- '8'
- '9'
galaxy_tags:
- nfs
dependencies: []

@ -0,0 +1,5 @@
---
- name: Install nfs-utils
ansible.builtin.dnf:
name: nfs-utils
state: present

@ -0,0 +1,4 @@
# vagrant_pubkey
An Ansible role that adds a Vagrant public SSH key to the `vagrant` user's
`~/.ssh/authorized_keys` file.

@ -0,0 +1,15 @@
galaxy_info:
role_name: vagrant_pubkey
author: Eugene Zamriy
description: Adds Vagrant public SSH key
license: MIT
min_ansible_version: '2.5'
platforms:
- name: EL
versions:
- '8'
- '9'
galaxy_tags:
- vagrant
dependencies: []

@ -0,0 +1,16 @@
---
- name: Create /home/vagrant/.ssh directory
ansible.builtin.file:
path: /home/vagrant/.ssh
state: directory
owner: vagrant
group: vagrant
mode: 0o700
- name: Download Vagrant public SSH key
ansible.builtin.get_url:
url: https://raw.githubusercontent.com/hashicorp/vagrant/main/keys/vagrant.pub
dest: /home/vagrant/.ssh/authorized_keys
owner: vagrant
group: vagrant
mode: 0o600

@ -0,0 +1,4 @@
# vmware_guest
An Ansible role that installs the `open-vm-tools` package on a virtual
machine.

@ -0,0 +1,17 @@
galaxy_info:
role_name: vmware_guest
author: Eugene Zamriy
description: Installs open-vm-tools
license: MIT
min_ansible_version: '2.5'
platforms:
- name: EL
versions:
- '8'
- '9'
galaxy_tags:
- guest
- system
- vmware
dependencies: []

@ -0,0 +1,5 @@
---
- name: Install open-vm-tools
ansible.builtin.dnf:
name: open-vm-tools
state: present

@ -0,0 +1,11 @@
---
- name: MSVSphere Vagrant box
hosts: default
become: true
roles:
- role: vmware_guest
when: packer_provider == 'vmware-iso'
- nfs_client
- vagrant_pubkey
- cleanup_vm

@ -0,0 +1,69 @@
# MSVSphere 9 Vagrant boxes 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 --disabled
services --enabled=sshd
selinux --enforcing
bootloader --location=mbr
zerombr
clearpart --all --initlabel
autopart --type=plain --nohome --noboot --noswap
rootpw vagrant
user --name=vagrant --plaintext --password vagrant
reboot --eject
%packages --inst-langs=en
@core
bzip2
dracut-config-generic
tar
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
# allow passwordless sudo for the vagrant user
echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant
# see Vagrant documentation (https://docs.vagrantup.com/v2/boxes/base.html)
# for details about the requiretty.
sed -i "s/^.*requiretty/# Defaults requiretty/" /etc/sudoers
yum clean all
# permit root login via SSH with password authentication
echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/01-permitrootlogin.conf
%end

@ -0,0 +1,58 @@
/**
* Packer template for building MSVSphere 9 Vagrant boxes.
*/
source "vmware-iso" "msvsphere-9-vagrant-x86_64" {
iso_url = var.iso_url_9_x86_64
iso_checksum = var.iso_checksum_9_x86_64
boot_command = var.vagrant_boot_cmd_9_x86_64_bios
boot_wait = var.boot_wait
cpus = var.cpus
memory = var.memory
disk_size = var.vagrant_disk_size
headless = var.headless
http_directory = var.http_directory
guest_os_type = "centos-64"
shutdown_command = var.vagrant_shutdown_command
ssh_username = var.vagrant_ssh_username
ssh_password = var.vagrant_ssh_password
ssh_timeout = var.ssh_timeout
vmx_data = {
"cpuid.coresPerSocket" : "1"
}
vmx_data_post = {
"memsize" : var.post_memory
"numvcpus" : var.post_cpus
}
vmx_remove_ethernet_interfaces = true
}
build {
sources = [
"sources.vmware-iso.msvsphere-9-vagrant-x86_64"
]
provisioner "ansible" {
playbook_file = "ansible/vagrant.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 = [
"--extra-vars",
"packer_provider=${source.type}"
]
}
post-processors {
post-processor "vagrant" {
compression_level = "9"
output = "MSVSphere-${var.os_version_9}-${formatdate("YYYYMMDD", timestamp())}.{{.Provider}}.x86_64.box"
}
}
}

@ -0,0 +1,107 @@
/**
* MSVSphere Packer template variables.
*/
variable "os_version_9" {
description = "The target MSVSphere 9 version"
type = string
default = "9.2"
}
// TODO: switch to the boot ISO on production
variable "iso_url_9_x86_64" {
description = "MSVSphere 9 x86_64 installation ISO URL"
type = string
default = "https://rsync.inferitos.ru/msvsphere/9.2/isos/x86_64/MSVSphere-9.2-alpha-x86_64-minimal.iso"
}
variable "iso_checksum_9_x86_64" {
description = "MSVSphere 9 x86_64 installation ISO checksum"
type = string
default = "file:https://rsync.inferitos.ru/msvsphere/9.2/isos/x86_64/CHECKSUM"
}
variable "headless" {
description = "Start the VM without a GUI console if true"
type = bool
default = true
}
variable "cpus" {
description = "The number of CPUs for a VM"
type = number
default = 2
}
variable "memory" {
description = "The amount of RAM in megabytes"
type = number
default = 2048
}
variable "boot_wait" {
description = "Time to wait before interacting with an OS bootloader menu"
type = string
default = "10s"
}
variable "ssh_timeout" {
description = "The SSH connection timeout"
type = string
default = "1800s"
}
variable "post_cpus" {
description = "The number of CPUs to set for the VM after build"
type = number
default = 1
}
variable "post_memory" {
description = "The amount of RAM to set for the VM after build"
type = number
default = 1024
}
variable "http_directory" {
description = "The kickstart files directory path"
type = string
default = "http"
}
/**
* Vagrant-specific settings.
*/
variable "vagrant_disk_size" {
description = "The VM disk size in megabytes"
type = number
default = 20000
}
variable "vagrant_boot_cmd_9_x86_64_bios" {
description = "The boot command for x86_64 VMs in a BIOS mode"
type = list(string)
default = [
"<tab> inst.text inst.gpt ",
"inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/msvsphere-9-vagrant.x86_64.ks",
"<enter><wait>"
]
}
variable "vagrant_ssh_username" {
description = "A login to use for SSH authentication"
type = string
default = "vagrant"
}
variable "vagrant_ssh_password" {
description = "A password to use for SSH authentication"
type = string
default = "vagrant"
}
variable "vagrant_shutdown_command" {
description = "The VM shutdown command"
type = string
default = "echo vagrant | sudo -S /sbin/shutdown -hP now"
}
Loading…
Cancel
Save