-
-
Save Oratorian/274bc106fec46787408cc1f4bd21bc74 to your computer and use it in GitHub Desktop.
This script will download a cloud image of many Linux distros and create a Proxmox 6 KVM template from it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -o errexit | |
clear | |
printf "\n*** This script will download a cloud image and create a Proxmox VM template from it. ***\n\n" | |
### HOW TO USE | |
### Pre-req: | |
### - run on a Proxmox 6 server | |
### - a dhcp server should be active on vmbr1 | |
### | |
### - fork the gist and adapt the defaults (especially SSHKEY) as needed | |
### - download latest version of the script: | |
### curl wget https://gist.githubusercontent.com/chriswayg/43fbea910e024cbe608d7dcb12cb8466/raw/create-cloud-template.sh > /usr/local/bin/create-cloud-template.sh && chmod -v +x /usr/local/bin/create-cloud-template.sh | |
### - (optionally) prepare a cloudinit user-config.yml in the working directory | |
### this could be copied and modified from the cloudinit user dump at the end of this script | |
### - run the script: | |
### $ create-cloud-template.sh | |
### - clone the finished template from the Proxmox GUI and test | |
### | |
### NOTES: | |
### - links to cloud images: | |
### Directory: https://docs.openstack.org/image-guide/obtain-images.html | |
### Debian http://cdimage.debian.org/cdimage/openstack/ | |
### Ubuntu http://cloud-images.ubuntu.com/ | |
### CentOS: http://cloud.centos.org/centos/7/images/ | |
### Fedora: https://alt.fedoraproject.org/cloud/ | |
### SUSE 15 SP1 JeOS: https://download.suse.com/Download?buildid=OE-3enq3uys~ | |
### CirrOS http://download.cirros-cloud.net/ | |
### CoreOS (EOL 05.2020): https://stable.release.core-os.net/amd64-usr/current/ | |
### Flatcar (CoreOS fork): https://stable.release.flatcar-linux.net/amd64-usr/current/ | |
### Gentoo: http://gentoo.osuosl.org/experimental/amd64/openstack | |
### Arch (also Gentoo): https://linuximages.de/openstack/arch/ | |
### Alpine: https://github.com/chriswayg/packer-qemu-cloud/ | |
### RancherOS: https://github.com/rancher/os/releases (also includes Proxmox iso version) | |
### | |
### - most links will download the latest current (stable) version of the OS | |
### - older cloud-init versions do not support hashed passwords | |
## TODO | |
## - verify authenticity of downloaded images using hash or GPG | |
printf "* Available templates to generate:\n 2) Debian 9\n 3) Debian 10\n 4) Ubuntu 18.04\n 5) Centos 7\n 6) CoreOS/Flatcar\n 7) Arch\n 8) Alpine 3.11\n 9) RancherOS 1.5.5\n\n" | |
read -p "* Enter number of distro to use: " OSNR | |
# defaults which are used for most templates | |
RESIZE=+30G | |
MEMORY=2048 | |
BRIDGE=vmbr1 | |
USERCONFIG_DEFAULT=none # cloud-init-config.yml | |
CITYPE=nocloud | |
SNIPPETSPATH=/var/lib/vz/snippets | |
SSHKEY=~/.ssh/2019_id_rsa.pub # ~/.ssh/id_rsa.pub | |
STORAGE= #define your storage here local/local-lvm or any other storage you created in Proxmox using its name | |
FORMAT= #the disk format of the disk, in case of local=qcow2 in case of local-lvm=raw | |
node=`cat /proc/sys/kernel/hostname` #This will enter the node automaticly since Proxmox uses hostnames as names for nodes | |
NOTE="" | |
case $OSNR in | |
2) | |
OSNAME=debian9 | |
VMID_DEFAULT=51100 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
VMIMAGE=debian-9-openstack-amd64.qcow2 | |
NOTE="\n## Default user is 'root'\n## NOTE: Setting a password via cloud-config does not work.\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://cdimage.debian.org/cdimage/openstack/current-9/$VMIMAGE | |
;; | |
3) | |
OSNAME=debian10 | |
VMID_DEFAULT=51200 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
VMIMAGE=debian-10-openstack-amd64.qcow2 | |
NOTE="\n## Default user is 'root'\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://cdimage.debian.org/cdimage/openstack/current-10/$VMIMAGE | |
;; | |
4) | |
printf "* Available Ubuntu templates to generate:\n 1)Ubuntu 18.04\n 2)Ubuntu 20.04\n\n" | |
read -p "* Enter number of ubuntu-distro to use: " OSNR2 | |
case $OSNR2 in | |
1) | |
OSNAME=ubuntu1804 | |
VMID_DEFAULT=52000 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
VMIMAGE=bionic-server-cloudimg-amd64.img | |
NOTE="\n## Default user is 'root'\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://cloud-images.ubuntu.com/bionic/current/$VMIMAGE | |
;; | |
2) | |
OSNAME=ubuntu2004 | |
VMID_DEFAULT=52001 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
VMIMAGE=focal-server-cloudimg-amd64.img | |
NOTE="\n## Default user is 'root'\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://cloud-images.ubuntu.com/focal/current/$VMIMAGE | |
;; | |
esac | |
;; | |
5) | |
OSNAME=centos7 | |
VMID_DEFAULT=53100 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
RESIZE=+24G | |
VMIMAGE=CentOS-7-x86_64-GenericCloud.qcow2 | |
NOTE="\n## Default user is 'root'\n## NOTE: CentOS ignores hostname config.\n# use 'hostnamectl set-hostname centos7-cloud' inside VM\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N http://cloud.centos.org/centos/7/images/$VMIMAGE | |
;; | |
6) | |
# - Proxmox creates a configdrive with the option: 'manage_etc_hosts: true' | |
# which causes an error in 'user-configdrive.service': | |
# 'Failed to apply cloud-config: Invalid option to manage_etc_hosts' | |
# There is no problem, when supplying a compatible 'user-config.yml'. | |
# - CoreOS needs 'configdrive2' | |
# - CoreOS is End of Life in 05.2020, use Flatcar instead | |
# https://github.com/coreos/coreos-cloudinit/blob/master/Documentation/config-drive.md | |
# | |
# OSNAME=coreos | |
# VMID_DEFAULT=54600 | |
# read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
# VMID=${VMID:-$VMID_DEFAULT} | |
# RESIZE=+24G | |
# VMIMAGE=coreos_production_qemu_image.img.bz2 | |
# CITYPE=configdrive2 | |
# NOTE="\n## Default user is 'core'\n## NOTE: In CoreOS, setting a password via cloud-config does not seem to work!\n" | |
# printf "$NOTE\n" | |
# wget -P /tmp -N https://stable.release.core-os.net/amd64-usr/current/$VMIMAGE | |
OSNAME=flatcar | |
VMID_DEFAULT=54600 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
RESIZE=+24G | |
VMIMAGE=flatcar_production_qemu_image.img.bz2 | |
CITYPE=configdrive2 | |
NOTE="\n## Default user is 'coreos'\n## NOTE: Setting a password via cloud-config does not work.\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://stable.release.flatcar-linux.net/amd64-usr/current/$VMIMAGE | |
;; | |
7) | |
OSNAME=arch | |
VMID_DEFAULT=54200 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
RESIZE=+29G | |
VMIMAGE=arch-openstack-LATEST-image-bootstrap.qcow2 | |
NOTE="\n## Default user is 'arch'\n## NOTE: Setting a password via cloud-config does not work.\n# Resizing does not happen automatically inside the VM\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://linuximages.de/openstack/arch/$VMIMAGE | |
;; | |
8) | |
OSNAME=alpine311 | |
VMID_DEFAULT=54000 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
VMIMAGE=alpine-311-cloudimg-amd64.qcow2 | |
NOTE="\n## Default user is 'alpine'\n## NOTE: Cloud-init on Alpine 3.11 is not able to apply network config.\n# Setting a password via cloud-config does not work.\n# CHANGE the default root passwword (root can only login via console).\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://github.com/chriswayg/packer-proxmox-templates/releases/download/v1.6/$VMIMAGE | |
#cp -v /root/$VMIMAGE /tmp/ # for local testing | |
;; | |
9) | |
OSNAME=rancheros | |
VMID_DEFAULT=54400 | |
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID | |
VMID=${VMID:-$VMID_DEFAULT} | |
VMIMAGE=rancheros-openstack.img | |
CITYPE=configdrive2 | |
NOTE="\n## Default user is 'rancher'\n## NOTE: Setting a password via cloud-config does not work.\n# RancherOS does autologin on console.\n" | |
printf "$NOTE\n" | |
wget -P /tmp -N https://github.com/rancher/os/releases/download/v1.5.5/$VMIMAGE | |
;; | |
*) | |
printf "\n** Unknown OS number. Please use one of the above!\n" | |
exit 0 | |
;; | |
esac | |
[[ $VMIMAGE == *".bz2" ]] \ | |
&& printf "\n** Uncompressing image (waiting to complete...)\n" \ | |
&& bzip2 -d --force /tmp/$VMIMAGE \ | |
&& VMIMAGE=$(echo "${VMIMAGE%.*}") # remove .bz2 file extension from file name | |
# TODO: could prompt for the VM name | |
printf "\n** Creating a VM with $MEMORY MB using network bridge $BRIDGE\n" | |
qm create $VMID --name $OSNAME-cloud --memory $MEMORY --net0 virtio,bridge=$BRIDGE | |
printf "\n** Importing the disk in qcow2 format (as 'Unused Disk 0')\n" | |
qm importdisk $VMID /tmp/$VMIMAGE local -format $FORMAT | |
printf "\n** Attaching the disk to the vm using VirtIO SCSI\n" | |
qm set $VMID --scsihw virtio-scsi-pci --scsi0 $STORAGE:vm-$VMID-disk-0 | |
printf "\n** Setting boot and display settings with serial console\n" | |
qm set $VMID --boot c --bootdisk scsi0 --serial0 socket --vga serial0 | |
printf "\n** Using a dhcp server on $BRIDGE (or change to static IP)\n" | |
qm set $VMID --ipconfig0 ip=dhcp | |
#This would work in a bridged setup, but a routed setup requires a route to be added in the guest | |
#qm set $VMID --ipconfig0 ip=10.10.10.222/24,gw=10.10.10.1 | |
printf "\n** Creating a cloudinit drive managed by Proxmox\n" | |
qm set $VMID --ide2 local:cloudinit | |
printf "\n** Specifying the cloud-init configuration format\n" | |
qm set $VMID --citype $CITYPE | |
printf "#** Made with create-cloud-template.sh - https://gist.github.com/chriswayg/43fbea910e024cbe608d7dcb12cb8466\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf | |
## TODO: Also ask for a network configuration. Or create a config with routing for a static IP | |
printf "\n*** The script can add a cloud-init configuration with users and SSH keys from a file in the current directory.\n" | |
read -p "Supply the name of the cloud-init-config.yml (this will be skipped, if file not found) [$USERCONFIG_DEFAULT]: " USERCONFIG | |
USERCONFIG=${USERCONFIG:-$USERCONFIG_DEFAULT} | |
if [ -f $PWD/$USERCONFIG ] | |
then | |
# The cloud-init user config file overrides the user settings done elsewhere | |
printf "\n** Adding user configuration\n" | |
cp -v $PWD/$USERCONFIG $SNIPPETSPATH/$VMID-$OSNAME-$USERCONFIG | |
qm set $VMID --cicustom "user=local:snippets/$VMID-$OSNAME-$USERCONFIG" | |
printf "#* cloud-config: $VMID-$OSNAME-$USERCONFIG\n" >> /etc/pve/nodes/$nod/qemu-server/$VMID.conf | |
else | |
# The SSH key should be supplied either in the cloud-init config file or here | |
printf "\n** Skipping config file, as none was found\n\n** Adding SSH key\n" | |
qm set $VMID --sshkey $SSHKEY | |
USER=root | |
qm set $VMID --ciuser root | |
printf "\n" | |
read -p "Supply an optional password for the default user (press Enter for none): " PASSWORD | |
[ ! -z "$PASSWORD" ] \ | |
&& printf "\n** Adding the password to the config\n" \ | |
&& qm set $VMID --cipassword $PASSWORD \ | |
&& printf "#* a password has been set for the default user\n" >> /etc/pve/nodes/$node/qemu-server/$VMID.conf | |
printf "#- cloud-config used: via Proxmox\n" >> /etc/pve/nodes/$node/qemu-server/$VMID.conf | |
fi | |
# The NOTE is added to the Summary section of the VM (TODO there seems to be no 'qm' command for this) | |
printf "#$NOTE\n" >> /etc/pve/nodes/$node/qemu-server/$VMID.conf | |
printf "\n** Increasing the disk size\n" | |
qm resize $VMID scsi0 $RESIZE | |
printf "\n*** The following cloud-init configuration will be used ***\n" | |
printf "\n------------- User ------------------\n" | |
qm cloudinit dump $VMID user | |
printf "\n------------- Network ---------------\n" | |
qm cloudinit dump $VMID network | |
# convert the vm into a template (TODO make this optional) | |
qm template $VMID | |
printf "\n** Removing previously downloaded image file\n\n" | |
rm -v /tmp/$VMIMAGE | |
printf "$NOTE\n\n" |
It works on Debian and Ubuntu nodes.
The storage is a setting value that can be specified in the script, see line 54. This can be set to whatever storage the user has. I just gave some examples based on standard proxmox setups.
The node value is always the systems hostname on initial setup. But can also be freely modified in line 56, just delete my example and set your static node here.
The VMID is set upon choosing which ostemplate you download starting line 59 to 191
The script prompts you to enter one or uses the default value.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi there. Did you test this version of the script? I think it 'almost' works. The insertion of $node has a few errors. See fx. lines 222 and 234. In my own version of this script I also added a NODENAME variable to set, as the node may not even be the one where the script is executed (if someone has several nodes).
You may also want to look at lines 203 and 217 to set the storage to non-local values. If for example the Proxmox node runs diskless, the 'local' import of the QCOW2 image will not work.
Line 206 needs $VMID before the disk image file too, to find the right path.