initial commit
This commit is contained in:
parent
b916d56285
commit
51a028e634
6 changed files with 182 additions and 1 deletions
45
README.md
45
README.md
|
|
@ -1,2 +1,45 @@
|
||||||
# template-config
|
# EL7 VM Templatization for Proxmox
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
These are some handy tools to turn a VM into a template, so that creating a new VM is as simple as (full) clone and boot. There are several assumptions made that may not necessarily match with anyone else's environment:
|
||||||
|
- CentOS 7 minimal install (will probably work on any flavor of EL7)
|
||||||
|
- DHCP server available
|
||||||
|
- rootfs (/) is on the last partition of the primary disk, and is a primary partition
|
||||||
|
- a `centos` user exists on the VM (this is not a hard requirement, nothing bad will happen if it's not true)
|
||||||
|
|
||||||
|
Right now, the main things it will do is on the first time a new VM boots it will:
|
||||||
|
- generate a new hostname (configurable, defaults to using UUIDs)
|
||||||
|
- grow the rootfs
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Create a new VM (with a very small disk, like <=8GB) and install CentOS 7 minimal
|
||||||
|
1. Customize new install with whatever software/users/ssh keys you will want on *every* VM by default
|
||||||
|
1. Copy each of the four files to the location specified in the comment at the top:
|
||||||
|
- `cp ./vm-{seal,firstrun}.sh /usr/local/sbin/`
|
||||||
|
- `cp ./vm-firstrun.example-config /etc/sysconfig/vm-firstrun`
|
||||||
|
- `cp ./vm-firstrun.service /etc/systemd/system/vm-firstrun.service`
|
||||||
|
1. Make the two .sh scripts executable: `chmod +x /usr/local/sbin/vm-{seal,firstrun}.sh`
|
||||||
|
1. Let systemd see the new unit file: `systemctl daemon-reload`
|
||||||
|
1. Once all your customizations are done and you're ready to turn it into a template, run: `/usr/local/sbin/vm-seal.sh`
|
||||||
|
1. The VM should shutdown, then in Proxmox you can just right-click and convert to template
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
After doing the setup, to create a new VM:
|
||||||
|
1. do a full clone of the template
|
||||||
|
1. grow the size of the disk if needed
|
||||||
|
1. start the VM
|
||||||
|
|
||||||
|
If you ever need to make changes to your template:
|
||||||
|
1. follow the above steps to create a new VM from the template
|
||||||
|
1. make your changes on the new VM that will become the new template
|
||||||
|
1. when done making changes, run `/usr/local/sbin/vm-seal.sh`
|
||||||
|
1. after the new VM stops, convert it to a template and delete the old template
|
||||||
|
|
||||||
|
Note that because it touches `/.autorelabel`, the first boot can take a few minutes while the SELinux contexts are re-applied or whatever, if SELinux is disabled in your environment this may not matter.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
It's very simple, `vm-seal.sh` basically de-configures the parts of the system that should be unique, then removes any log files or anything that shouldn't really be on a newly-installed system. Then it enables `vm-firstrun.service` in systemd and does a shutdown. At the next boot, systemd starts the `vm-firstrun.service` which just runs `vm-firstrun.sh`, which generates a new hostname and grows the rootfs. Then it disables the `vm-firstrun.service` so that it won't run again next time the VM is rebooted.
|
||||||
BIN
vm-firstrun
Normal file
BIN
vm-firstrun
Normal file
Binary file not shown.
10
vm-firstrun.example-config
Normal file
10
vm-firstrun.example-config
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# /etc/sysconfig/vm-firstrun
|
||||||
|
# CFG_HOSTNAME_SCRIPT="uuidgen"
|
||||||
|
# CFG_HOSTNAME_PREFIX=""
|
||||||
|
# CFG_HOSTNAME_POSTFIX=""
|
||||||
|
# CFG_DOMAIN="localdomain"
|
||||||
|
# CFG_ROOTFS_DISK="/dev/sda"
|
||||||
|
# CFG_ROOTFS_PARTITION="3"
|
||||||
|
# CFG_ROOTFS_TYPE="xfs"
|
||||||
|
# CFG_SERVICE_NAME="vm-firstrun"
|
||||||
|
|
||||||
11
vm-firstrun.service
Normal file
11
vm-firstrun.service
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
# /etc/systemd/system/vm-firstrun.service
|
||||||
|
[Unit]
|
||||||
|
Description=Initialize this template-created VM
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/sbin/vm-firstrun.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
73
vm-firstrun.sh
Normal file
73
vm-firstrun.sh
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# /usr/local/sbin/vm-firstrun.sh
|
||||||
|
|
||||||
|
# This script depends on having these packages installed:
|
||||||
|
# - cloud-utils-growpart
|
||||||
|
# - parted
|
||||||
|
|
||||||
|
# This should be a simple bash file that sets the CFG_* variables
|
||||||
|
[ -f /etc/sysconfig/vm-firstrun ] && . /etc/sysconfig/vm-firstrun
|
||||||
|
|
||||||
|
## Set default values for anything that wasn't already set
|
||||||
|
# This will be run at firstboot to generate the hostname
|
||||||
|
CFG_HOSTNAME_SCRIPT="${CFG_HOSTNAME_SCRIPT:=uuidgen}"
|
||||||
|
# These can be set in config, there's just no reason for a default besides (blank)
|
||||||
|
# CFG_HOSTNAME_PREFIX="${CFG_HOSTNAME_PREFIX:=}"
|
||||||
|
# CFG_HOSTNAME_POSTFIX="${CFG_HOSTNAME_POSTFIX:=}"
|
||||||
|
CFG_DOMAIN="${CFG_DOMAIN:=localdomain}"
|
||||||
|
CFG_ROOTFS_DISK="${CFG_ROOTFS_DISK:=/dev/sda}"
|
||||||
|
CFG_ROOTFS_PARTITION="${CFG_ROOTFS_PARTITION:=3}"
|
||||||
|
CFG_ROOTFS_TYPE="${CFG_ROOTFS_TYPE:=xfs}"
|
||||||
|
CFG_SERVICE_NAME="${CFG_SERVICE_NAME:=vm-firstrun}"
|
||||||
|
|
||||||
|
## Helper Functions
|
||||||
|
function log() {
|
||||||
|
echo "$@" | logger --stderr -t vm-firstrun
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## Do the things
|
||||||
|
old_hostname="$(hostname -f)"
|
||||||
|
new_hostname="${CFG_HOSTNAME_PREFIX}$(${CFG_HOSTNAME_SCRIPT})${CFG_HOSTNAME_POSTFIX}"
|
||||||
|
if ! [ -z "${CFG_DOMAIN}" ]; then
|
||||||
|
new_hostname="${new_hostname}.${CFG_DOMAIN}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Setting hostname from '${old_hostname}' to '${new_hostname}'"
|
||||||
|
hostnamectl set-hostname "${new_hostname}"
|
||||||
|
|
||||||
|
if [ -b "${CFG_ROOTFS_DISK}" ]; then
|
||||||
|
if [ -b "${CFG_ROOTFS_DISK}${CFG_ROOTFS_PARTITION}" ]; then
|
||||||
|
# expand the partition
|
||||||
|
log "Expanding rootfs partition"
|
||||||
|
growpart "${CFG_ROOTFS_DISK}" "${CFG_ROOTFS_PARTITION}"
|
||||||
|
# reload partition table
|
||||||
|
log "Reloading partition table"
|
||||||
|
partprobe "${CFG_ROOTFS_DISK}"
|
||||||
|
|
||||||
|
# grow the rootfs
|
||||||
|
case "${CFG_ROOTFS_TYPE}" in
|
||||||
|
xfs)
|
||||||
|
log "Growing rootfs of type: ${CFG_ROOTFS_TYPE}"
|
||||||
|
xfs_growfs /
|
||||||
|
;;
|
||||||
|
ext*)
|
||||||
|
log "Growing ${CFG_ROOTFS_TYPE} rootfs on device: ${CFG_ROOTFS_DISK}${CFG_ROOTFS_PARTITION}"
|
||||||
|
resize2fs "${CFG_ROOTFS_DISK}${CFG_ROOTFS_PARTITION}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log "Unsupported rootfs type: ${CFG_ROOTFS_TYPE}"
|
||||||
|
log "Doing nothing, please grow the fs manually"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
log "rootfs partition not found, unable to expand: ${CFG_ROOTFS_DISK}${CFG_ROOTFS_PARTITION}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "rootfs disk not found, unable to expand: ${CFG_ROOTFS_DISK}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "initial config done, disabling myself"
|
||||||
|
systemctl disable "${CFG_SERVICE_NAME}"
|
||||||
|
|
||||||
44
vm-seal.sh
Normal file
44
vm-seal.sh
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# /usr/local/sbin/vm-seal.sh
|
||||||
|
|
||||||
|
unset HISTFILE
|
||||||
|
|
||||||
|
yum update -y
|
||||||
|
yum clean all -y
|
||||||
|
|
||||||
|
: > /etc/machine-id
|
||||||
|
hostnamectl set-hostname localhost.localdomain
|
||||||
|
systemctl enable vm-firstrun
|
||||||
|
|
||||||
|
rm -f /etc/ssh/ssh_host_*
|
||||||
|
|
||||||
|
rm -rf /root/.ssh/
|
||||||
|
rm -f /root/anaconda-ks.cfg
|
||||||
|
rm -f /root/.bash_history
|
||||||
|
|
||||||
|
rm -f /home/centos/.bash_history
|
||||||
|
rm -f /home/centos/.ssh/known_hosts
|
||||||
|
|
||||||
|
rm -f /var/log/boot.log
|
||||||
|
rm -f /var/log/cron
|
||||||
|
rm -f /var/log/dmesg
|
||||||
|
rm -f /var/log/grubby
|
||||||
|
rm -f /var/log/lastlog
|
||||||
|
rm -f /var/log/maillog
|
||||||
|
rm -f /var/log/messages
|
||||||
|
rm -f /var/log/secure
|
||||||
|
rm -f /var/log/spooler
|
||||||
|
rm -f /var/log/tallylog
|
||||||
|
rm -f /var/log/wpa_supplicant.log
|
||||||
|
rm -f /var/log/wtmp
|
||||||
|
rm -f /var/log/yum.log
|
||||||
|
rm -f /var/log/audit/audit.log
|
||||||
|
rm -f /var/log/tuned/tuned.log
|
||||||
|
|
||||||
|
updatedb
|
||||||
|
|
||||||
|
touch /.autorelabel
|
||||||
|
|
||||||
|
sys-unconfig
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue