diff --git a/README.md b/README.md index c92ebf0..ab34e0e 100644 --- a/README.md +++ b/README.md @@ -113,3 +113,15 @@ VM 'ubuntuTest' removed successfully. ## TODO - FreeBSD support is still in progress +- Check if used commands are available +./vm_create.sh: línea 52: mkpasswd: orden no encontrada +./vm_create.sh: línea 259: virt-install: orden no encontrada +./vm_create.sh: línea 261: virsh: orden no encontrada +qemu-img wget curl mkpass arp +sudo apt install --no-install-recommends qemu-system libvirt-clients libvirt-daemon-system whois virtinst net-tools +sudo chmod 750 /home/victor +sudo usermod -a -G libvirt $(whoami) +sudo usermod --append --groups earl libvirt-qemu + +- Refactoring variables, functions and scripts calls for legibility and maintenance +- add script for create default files (network, variables etc) diff --git a/common.sh b/common.sh new file mode 100644 index 0000000..8fc0706 --- /dev/null +++ b/common.sh @@ -0,0 +1,9 @@ +#!/bin/env bash +OS_JSON_FILE="os_options.json" +#VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/.local/share/libvirt"} +#VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/var/lib/libvirt"} +VM_BASE_DIR="${HOME}/vms" +VM_BASE_IMAGES="base" +VM_USERNAME="user" +VM_IMAGE_PATH="${VM_BASE_DIR}/images/$1.img" +CI_IMAGE_PATH="${VM_BASE_DIR}/images/$1-cidata.iso" diff --git a/network.xml b/network.xml new file mode 100644 index 0000000..cd5e95a --- /dev/null +++ b/network.xml @@ -0,0 +1,14 @@ + + vmnetwork + + + + + + + + + + + + diff --git a/os_option_test.json b/os_option_test.json new file mode 100644 index 0000000..e51178a --- /dev/null +++ b/os_option_test.json @@ -0,0 +1,68 @@ +{ + "os_variants": [ + { + "id": 1, + "name": "Debian 12", + "variant": "$GUEST_OS_TYPE_DEBIAN", + "url": "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2", + "origin_image_name": "debian-12-generic-amd64.qcow2", + "md5sum": "https://cdimage.debian.org/images/cloud/bookworm/latest/SHA512SUMS", + "boot_type": "bios" + }, + { + "id": 2, + "name": "Ubuntu 20.04 server", + "variant": "ubuntu20.04", + "url": "https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img", + "origin_image_name": "focal-server-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/focal/current/SHA256SUMS", + "boot_type": "bios" + + }, + { + "id": 3, + "name": "Ubuntu 20.04 minimal", + "variant": "ubuntu20.04", + "url": "https://cloud-images.ubuntu.com/minimal/releases/focal/release/ubuntu-20.04-minimal-cloudimg-amd64.img", + "origin_image_name": "ubuntu-20.04-minimal-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/minimal/releases/focal/release/SHA256SUMS", + "boot_type": "bios" + }, + { + "id": 4, + "name": "Ubuntu 22.04 server", + "variant": "ubuntu22.04", + "url": "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img", + "origin_image_name": "jammy-server-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS", + "boot_type": "uefi" + }, + { + "id": 5, + "name": "Ubuntu 22.04 minimal", + "variant": "ubuntu22.04", + "url": "https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img", + "origin_image_name": "ubuntu-22.04-minimal-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS", + "boot_type": "uefi" + }, + { + "id": 6, + "name": "Ubuntu 24.04 server", + "variant": "ubuntu22.04", + "url": "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img", + "origin_image_name": "noble-server-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/noble/current/SHA256SUMS", + "boot_type": "uefi" + }, + { + "id": 7, + "name": "Ubuntu 24.04 minimal", + "variant": "ubuntu22.04", + "url": "https://cloud-images.ubuntu.com/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img", + "origin_image_name": "ubuntu-24.04-minimal-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/minimal/releases/noble/release/SHA256SUMS", + "boot_type": "uefi" + } + ] +} diff --git a/os_options.json b/os_options.json new file mode 100644 index 0000000..e00b0fc --- /dev/null +++ b/os_options.json @@ -0,0 +1,41 @@ +{ + "os_variants": [ + { + "id": 1, + "name": "Debian 12", + "variant": "$GUEST_OS_TYPE_DEBIAN", + "url": "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2", + "origin_image_name": "debian-12-generic-amd64.qcow2", + "md5sum": "https://cdimage.debian.org/images/cloud/bookworm/latest/SHA512SUMS", + "boot_type": "bios" + }, + { + "id": 2, + "name": "Ubuntu 20.04 server", + "variant": "ubuntu20.04", + "url": "https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img", + "origin_image_name": "focal-server-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/focal/current/SHA256SUMS", + "boot_type": "bios" + + }, + { + "id": 3, + "name": "Ubuntu 22.04 server", + "variant": "ubuntu22.04", + "url": "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img", + "origin_image_name": "jammy-server-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS", + "boot_type": "uefi" + }, + + "id": 4, + "name": "Ubuntu 24.04 server", + "variant": "ubuntu22.04", + "url": "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img", + "origin_image_name": "noble-server-cloudimg-amd64.img", + "md5sum": "https://cloud-images.ubuntu.com/noble/current/SHA256SUMS", + "boot_type": "uefi" + } + ] +} diff --git a/vm_create.sh b/vm_create.sh index 2b06b8e..b6f002a 100755 --- a/vm_create.sh +++ b/vm_create.sh @@ -1,17 +1,21 @@ #!/bin/env bash +source common.sh VM_HOSTNAME= -VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"} VM_DISK_SIZE=20 VM_DISK_FORMAT=qcow2 VM_MEM_SIZE=2048 VM_VCPUS=2 VM_BASE_IMAGE= VM_OS_VARIANT= -VM_USERNAME="user" VM_BRIDGE_INT= -VM_NET_USED="PU-internalTests" -LIBVIRT_NET_OPTION="network=$VM_NET_USED,model=e1000" -HAT_STREAM="stable" +VM_BASE_IMAGE_LOCATION= +VM_NET_USED="default" +#LIBVIRT_NET_OPTION="network=$VM_NET_USED,model=e1000" +LIBVIRT_NET_MODEL="virtio" +LIBVIRT_NET_OPTION="network=$VM_NET_USED,model=$LIBVIRT_NET_MODEL" + +#LIBVIRT_NET_OPTION="model=e1000" + # Functions usage() { @@ -32,48 +36,27 @@ EOF } HOST_OS=$(cat /etc/os-release | grep -v VERSION_ID |grep "ID=" | awk -F'=' '{print $2}') -if [ "$HOST_OS" == "debian" ]; then +if [ $HOST_OS == "debian" ]; then source env_scripts/older_os.sh else source env_scripts/newer_os.sh fi +#create_network() +#{ +#virsh net-define mynet.xml +#virsh net-autostart mynet +#virsh net-start mynet +#} download_base_image() { -if ! test -f "${VM_BASE_DIR}/base/$VM_OS_VARIANT.qcow2"; then - if [[ "$VM_OS_VARIANT" == "freebsd14.2" ]]; then - VM_DISK_FORMAT="qcow2.xz" - cd ${VM_BASE_DIR}/base/ - wget -v -O "${VM_BASE_DIR}/base/$VM_OS_VARIANT.${VM_DISK_FORMAT}" ${VM_BASE_IMAGE} - xz -d $VM_OS_VARIANT.${VM_DISK_FORMAT} - mv $VM_OS_VARIANT.${VM_DISK_FORMAT} $VM_OS_VARIANT.img - cd - - elif [[ "$VM_OS_VARIANT" == "fedora-coreos-stable" ]]; then - podman run --pull=always --rm \ - -v /dev:/dev -v /run/udev:/run/udev \ - -v $VM_BASE_DIR/base:/data -w /data \ - quay.io/coreos/coreos-installer:release \ - download -s ${HAT_STREAM} -p qemu -f qcow2.xz --decompress -C . - mv $VM_BASE_DIR/base/fedora-coreos-*.qcow2 $VM_BASE_DIR/base/"$VM_OS_VARIANT".qcow2 - else - wget -v -O "${VM_BASE_DIR}/base/$VM_OS_VARIANT.${VM_DISK_FORMAT}" ${VM_BASE_IMAGE} - fi +VM_BASE_IMAGE_NAME=$(basename "${VM_BASE_IMAGE_NAME}" .img) +VM_BASE_IMAGE_LOCATION="${VM_BASE_DIR}/${VM_BASE_IMAGES}/$VM_BASE_IMAGE_NAME.${VM_DISK_FORMAT}" +if ! test -f "${VM_BASE_IMAGE_LOCATION}"; then + wget -O "${VM_BASE_IMAGE_LOCATION}" ${VM_BASE_IMAGE} fi } -gen_coreos_data() -{ -cat < "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data.bu" -variant: fcos -version: 1.6.0 -passwd: - users: - - name: core - ssh_authorized_keys: - - ${SSH_PUB_KEY} -EOF -} - gen_linux_user_data() { VM_USER_PASS=$(tr -dc A-Za-z0-9 ID_MAX )); then + echo "Invalid option. Please enter a number between 1 and ${ID_MAX}." + exit 1 fi +selected=$(jq -r ".os_variants[] | select(.id == $answer)" "$OS_JSON_FILE") -echo "Creating a qcow2 image file ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img that uses the cloud image file ${VM_BASE_DIR}/base/$VM_OS_VARIANT.${VM_DISK_FORMAT} as its base" +if [ -z "$selected" ]; then + echo "Invalid option." + exit 1 +fi + +# Asignar variables +VM_OS_VARIANT=$(echo "$selected" | jq -r .variant) +VM_BASE_IMAGE=$(echo "$selected" | jq -r .url) +VM_BASE_IMAGE_NAME=$(echo "$selected" | jq -r .origin_image_name) +VM_BOOT_TYPE=$(echo "$selected" | jq -r .boot_type) +VM_CHECKSUMS_URL=$(echo "$selected" | jq -r .md5sum) +CHECKSUM_TMP_FOLDER=$(mktemp) +curl -s -o "${CHECKSUM_TMP_FOLDER}" "${VM_CHECKSUMS_URL}" +VM_BASE_IMAGE_CHECKSUM=$(grep "${VM_BASE_IMAGE_NAME}" "${CHECKSUM_TMP_FOLDER}" | awk '{print $1}') + +# Download base image +download_base_image +check_hash + +echo "Creating a qcow2 image file ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img that uses the cloud image file ${VM_BASE_IMAGE_LOCATION} as its base" if ! test -f "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img"; then - qemu-img create -b "${VM_BASE_DIR}/base/${VM_OS_VARIANT}.qcow2" -f qcow2 -F qcow2 "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img" "${VM_DISK_SIZE}G" + #qemu-img create -b "${VM_BASE_DIR}/${VM_BASE_IMAGES}/${VM_OS_VARIANT}.qcow2" -f qcow2 -F qcow2 "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img" "${VM_DISK_SIZE}G" + qemu-img convert \ + -O qcow2 \ + "${VM_BASE_IMAGE_LOCATION}" \ + "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img" + qemu-img resize \ + "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img" \ + "${VM_DISK_SIZE}G" + sudo chown -R $USER:libvirt-qemu "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img" else - echo "El fichero ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img ya existe" + echo "El fichero ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img ya existe. Elimina la VM con vm_delete.sh" exit 1 fi @@ -223,7 +242,7 @@ instance-id: ${VM_HOSTNAME} local-hostname: ${VM_HOSTNAME} EOF #cloud-init VM user-data -if [[ "$VM_OS_VARIANT" == "freebsd14.2" ]]; then +if [[ "$VM_OS_VARIANT" == "freebsd14.0" ]]; then gen_freebsd_user_data # genisoimage \ # -output ${VM_BASE_DIR}/images/${VM_HOSTNAME}-cidata.iso \ @@ -240,50 +259,23 @@ if [[ "$VM_OS_VARIANT" == "freebsd14.2" ]]; then # --autostart \ # --import --noautoconsole \ # --cloud-init root-password-generate=on,user-data=${VM_BASE_DIR}/init/${VM_HOSTNAME}-user-data -elif [[ "$VM_OS_VARIANT" == "fedora-coreos-stable" ]]; then - gen_coreos_data else gen_linux_user_data fi -if [[ "$VM_OS_VARIANT" == "fedora-coreos-stable" ]]; then - IGNITION_CONFIG="${VM_BASE_DIR}/init/${VM_HOSTNAME}.ign" - BUTANE_CONFIG="$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data.bu" - IGNITION_DEVICE_ARG=(--qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=${IGNITION_CONFIG}") - #Generate ignition config - podman run --interactive --rm quay.io/coreos/butane:release \ - --pretty --strict < ${BUTANE_CONFIG} > ${IGNITION_CONFIG} - chown ${USERNAME}:libvirt-qemu /home/victor/vms/init/* - #Install - virt-install \ - --connect="qemu:///system" \ - --name ${VM_HOSTNAME} \ - --memory ${VM_MEM_SIZE} \ - --vcpus="${VM_VCPUS}" \ - --os-variant=${VM_OS_VARIANT} \ - --disk ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img,device=disk,bus=virtio \ - --autostart \ - --import --noautoconsole \ - --network ${LIBVIRT_NET_OPTION} "${IGNITION_DEVICE_ARG[@]}" - #https://unix.stackexchange.com/questions/578086/virt-install-error-cant-load-ignit -else - virt-install \ - --name ${VM_HOSTNAME} \ - --memory ${VM_MEM_SIZE} \ - --vcpus="${VM_VCPUS}" \ - --os-variant=${VM_OS_VARIANT} \ - --disk ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img,device=disk,bus=virtio \ - --network ${LIBVIRT_NET_OPTION} \ - --autostart \ - --import --noautoconsole \ - --cloud-init root-password-generate=on,user-data=${VM_BASE_DIR}/init/${VM_HOSTNAME}-user-data -# cloud-localds \ -# ${VM_BASE_DIR}/images/${VM_HOSTNAME}.iso \ -# ${VM_BASE_DIR}/init/${VM_HOSTNAME}-user-data -fi -virsh dumpxml "${VM_HOSTNAME}" > "${VM_BASE_DIR}/xml/${VM_HOSTNAME}.xml" -if [ -n $VERBOSE ]; then - set +xv +VM_INSTALL_OPTS="" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --name ${VM_HOSTNAME}" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --memory ${VM_MEM_SIZE}" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --vcpus ${VM_VCPUS}" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --os-variant=${VM_OS_VARIANT}" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --disk ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img,device=disk,bus=virtio" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --network ${LIBVIRT_NET_OPTION}" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --autostart" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --import --noautoconsole" +VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --cloud-init root-password-generate=on,user-data=${VM_BASE_DIR}/init/${VM_HOSTNAME}-user-data" +if [ "$VM_BOOT_TYPE" = "UEFI" ]; then + VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --boot uefi" fi -# Show running VMs -virsh list +eval virt-install $VM_INSTALL_OPTS + +virsh dumpxml "${VM_HOSTNAME}" > "${VM_BASE_DIR}/xml/${VM_HOSTNAME}.xml"