Add create-cloudpanel-template.sh
This commit is contained in:
parent
04b4e7a6e8
commit
746fd4b1c2
1 changed files with 208 additions and 0 deletions
208
create-cloudpanel-template.sh
Normal file
208
create-cloudpanel-template.sh
Normal file
|
@ -0,0 +1,208 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status.
|
||||
set -e
|
||||
|
||||
# Function to check for required utilities
|
||||
function check_utilities() {
|
||||
local utilities=("qm" "wget" "xz" "sha256sum" "ssh-keygen")
|
||||
for util in "${utilities[@]}"; do
|
||||
command -v "$util" >/dev/null 2>&1 || { echo "$util not found. Please install it."; exit 1; }
|
||||
done
|
||||
}
|
||||
|
||||
# Function to set up SSH keys
|
||||
function setup_ssh_keys() {
|
||||
local default_ssh_key_dir="${HOME}/ssh-keys"
|
||||
local ssh_key_dir="$default_ssh_key_dir"
|
||||
|
||||
while true; do
|
||||
# Ensure the SSH key directory exists
|
||||
if [[ ! -d "${ssh_key_dir}" ]]; then
|
||||
echo "SSH key directory not found at ${ssh_key_dir}. Creating directory..."
|
||||
mkdir -p "${ssh_key_dir}"
|
||||
chmod 700 "${ssh_key_dir}"
|
||||
fi
|
||||
|
||||
# Determine the SSH public key file
|
||||
ssh_keyfile=$(ls "${ssh_key_dir}"/*.pub 2>/dev/null | head -n 1)
|
||||
|
||||
if [[ -z "${ssh_keyfile}" ]]; then
|
||||
echo "No SSH public key found in ${ssh_key_dir}."
|
||||
read -p "Do you want to generate a new SSH key pair in this directory? (yes/no): " generate_key
|
||||
if [[ "${generate_key}" == "yes" ]]; then
|
||||
ssh-keygen -t rsa -b 4096 -f "${ssh_key_dir}/id_rsa" -N ""
|
||||
ssh_keyfile="${ssh_key_dir}/id_rsa.pub"
|
||||
chmod 600 "${ssh_key_dir}/id_rsa"
|
||||
chmod 644 "${ssh_key_dir}/id_rsa.pub"
|
||||
echo "SSH key pair generated at ${ssh_key_dir}/id_rsa and ${ssh_keyfile}."
|
||||
break
|
||||
else
|
||||
read -p "Do you want to specify a different directory for your SSH keys? (yes/no): " change_dir
|
||||
if [[ "${change_dir}" == "yes" ]]; then
|
||||
read -p "Please enter the full path to your SSH key directory: " ssh_key_dir
|
||||
else
|
||||
echo "Cannot proceed without an SSH public key. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Using existing SSH public key: ${ssh_keyfile}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
chmod 700 "${ssh_key_dir}"
|
||||
chmod 600 "${ssh_key_dir}"/id_* 2>/dev/null || true
|
||||
chmod 644 "${ssh_key_dir}"/*.pub 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Function to generate cloud-init user data with CloudPanel installation
|
||||
function generate_cloud_init_config() {
|
||||
local vm_id="$1"
|
||||
cat > "vm-${vm_id}-cloud-init.yaml" << 'EOF'
|
||||
#cloud-config
|
||||
package_update: true
|
||||
package_upgrade: true
|
||||
packages:
|
||||
- curl
|
||||
- wget
|
||||
- sudo
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
|
||||
runcmd:
|
||||
- curl -sS https://installer.cloudpanel.io/ce/v2/install.sh -o /root/install.sh
|
||||
- echo "a3ba69a8102345127b4ae0e28cfe89daca675cbc63cd39225133cdd2fa02ad36 /root/install.sh" | sha256sum -c
|
||||
- DB_ENGINE=MARIADB_11.4 bash /root/install.sh
|
||||
|
||||
power_state:
|
||||
mode: reboot
|
||||
timeout: 1800
|
||||
condition: True
|
||||
EOF
|
||||
|
||||
# Import the cloud-init config
|
||||
qm set "${vm_id}" --cicustom "user=local:snippets/vm-${vm_id}-cloud-init.yaml"
|
||||
}
|
||||
|
||||
# Function to create or update a template
|
||||
function create_template() {
|
||||
local vm_id="$1"
|
||||
local vm_name="$2"
|
||||
local image_file="$3"
|
||||
|
||||
echo "Processing template ${vm_name} (${vm_id})"
|
||||
|
||||
# Compute the checksum of the image file
|
||||
local image_checksum
|
||||
image_checksum=$(sha256sum "${image_file}" | awk '{print $1}')
|
||||
local checksum_file="checksums/${vm_id}.sha256"
|
||||
|
||||
# Check if template exists and handle accordingly
|
||||
if qm status "${vm_id}" &>/dev/null; then
|
||||
echo "Template with VM ID ${vm_id} already exists. Removing..."
|
||||
qm destroy "${vm_id}" --destroy-unreferenced-disks yes
|
||||
fi
|
||||
|
||||
echo "Creating template ${vm_name} (${vm_id})"
|
||||
|
||||
# Create new VM
|
||||
qm create "${vm_id}" --name "${vm_name}" --ostype l26
|
||||
|
||||
# Set networking to default bridge
|
||||
qm set "${vm_id}" --net0 virtio,bridge=vmbr0
|
||||
|
||||
# Set display to serial
|
||||
qm set "${vm_id}" --serial0 socket --vga serial0
|
||||
|
||||
# Set memory and CPU (increased for CloudPanel requirements)
|
||||
qm set "${vm_id}" --memory 2048 --cores 2 --cpu host
|
||||
|
||||
# Import the disk
|
||||
qm set "${vm_id}" --scsi0 "${storage}:0,import-from=${PWD}/${image_file},discard=on"
|
||||
|
||||
# Set SCSI hardware as default boot disk
|
||||
qm set "${vm_id}" --boot order=scsi0 --scsihw virtio-scsi-single
|
||||
|
||||
# Enable QEMU guest agent
|
||||
qm set "${vm_id}" --agent enabled=1,fstrim_cloned_disks=1
|
||||
|
||||
# Add cloud-init device
|
||||
qm set "${vm_id}" --ide2 "${storage}:cloudinit"
|
||||
|
||||
# Set cloud-init network configuration
|
||||
qm set "${vm_id}" --ipconfig0 "ip=dhcp,ip6=auto"
|
||||
|
||||
# Import the SSH keyfile
|
||||
if [[ -f "${ssh_keyfile}" ]]; then
|
||||
qm set "${vm_id}" --sshkeys "${ssh_keyfile}"
|
||||
else
|
||||
echo "SSH key file not found at ${ssh_keyfile}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add the user
|
||||
qm set "${vm_id}" --ciuser "${username}"
|
||||
|
||||
# Generate and apply cloud-init config with CloudPanel installation
|
||||
generate_cloud_init_config "${vm_id}"
|
||||
|
||||
# Resize the disk to 25G for CloudPanel requirements
|
||||
qm disk resize "${vm_id}" scsi0 25G
|
||||
|
||||
# Convert the VM into a template
|
||||
qm template "${vm_id}"
|
||||
|
||||
# Save the checksum
|
||||
mkdir -p checksums
|
||||
echo "${image_checksum}" > "${checksum_file}"
|
||||
|
||||
# Remove the image file when done
|
||||
rm -f "${image_file}"
|
||||
}
|
||||
|
||||
# Check for required utilities
|
||||
check_utilities
|
||||
|
||||
# User-configurable variables
|
||||
export username="hackiri" # Replace with your desired username
|
||||
export storage="ceph_local" # Replace with your Proxmox storage name
|
||||
|
||||
# Validate variables
|
||||
if [[ -z "${username}" || "${username}" == "your_username_here" ]]; then
|
||||
echo "Please set a valid username in the script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! pvesm status | grep -q "^${storage}\s"; then
|
||||
echo "Storage '${storage}' not found. Please check your Proxmox storage configuration."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set up SSH keys
|
||||
setup_ssh_keys
|
||||
|
||||
# CloudPanel works best with Ubuntu 24.04 (Lunar Lobster)
|
||||
declare -a images=(
|
||||
# Ubuntu 22.04 LTS (Jammy Jellyfish) with CloudPanel
|
||||
"912|ubuntu-24.04-template|https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
|
||||
)
|
||||
|
||||
# Loop through the images array
|
||||
for entry in "${images[@]}"; do
|
||||
IFS='|' read -r vm_id vm_name image_url <<< "${entry}"
|
||||
|
||||
# Extract the filename from the URL
|
||||
image_file="${image_url##*/}"
|
||||
|
||||
# Download the image with timestamping
|
||||
echo "Downloading ${image_file}..."
|
||||
if ! wget -N "${image_url}"; then
|
||||
echo "Failed to download ${image_url}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create or update the template
|
||||
create_template "${vm_id}" "${vm_name}" "${image_file}"
|
||||
done
|
Loading…
Reference in a new issue