serveral changes to improve legibility
This commit is contained in:
22
README.md
22
README.md
@ -5,11 +5,33 @@ Use cloud images on baremetal using libvirt/kvm
|
|||||||
- openssh
|
- openssh
|
||||||
- mkpass (whois)
|
- mkpass (whois)
|
||||||
- arp
|
- arp
|
||||||
|
|
||||||
## Links
|
## Links
|
||||||
- [https://blog.programster.org/create-debian-12-kvm-guest-from-cloud-image](https://blog.programster.org/create-debian-12-kvm-guest-from-cloud-image)
|
- [https://blog.programster.org/create-debian-12-kvm-guest-from-cloud-image](https://blog.programster.org/create-debian-12-kvm-guest-from-cloud-image)
|
||||||
- [https://earlruby.org/2023/02/quickly-create-guest-vms-using-virsh-cloud-image-files-and-cloud-init/](https://earlruby.org/2023/02/quickly-create-guest-vms-using-virsh-cloud-image-files-and-cloud-init/)
|
- [https://earlruby.org/2023/02/quickly-create-guest-vms-using-virsh-cloud-image-files-and-cloud-init/](https://earlruby.org/2023/02/quickly-create-guest-vms-using-virsh-cloud-image-files-and-cloud-init/)
|
||||||
- [https://sumit-ghosh.com/posts/create-vm-using-libvirt-cloud-images-cloud-init/)](https://sumit-ghosh.com/posts/create-vm-using-libvirt-cloud-images-cloud-init/)
|
- [https://sumit-ghosh.com/posts/create-vm-using-libvirt-cloud-images-cloud-init/)](https://sumit-ghosh.com/posts/create-vm-using-libvirt-cloud-images-cloud-init/)
|
||||||
|
|
||||||
|
## Preparing host
|
||||||
|
|
||||||
|
### Create bridge network
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo virsh --connect qemu:///session net-define /dev/stdin << EOF
|
||||||
|
<network>
|
||||||
|
<name>bridged-network</name>
|
||||||
|
<forward mode='bridge'/>
|
||||||
|
<bridge name='brbackend' />
|
||||||
|
</network>
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
#### AppArmor exception
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/
|
||||||
|
apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd
|
||||||
|
```
|
||||||
|
|
||||||
## Creating VMs
|
## Creating VMs
|
||||||
### Usage
|
### Usage
|
||||||
```shell
|
```shell
|
||||||
|
|||||||
112
base_scripts/vim_functions.sh
Normal file
112
base_scripts/vim_functions.sh
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#!/bin/env bash
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
VM_USER="user"
|
||||||
|
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
||||||
|
VM_IMAGE_PATH="${VM_BASE_DIR}/images/$1.img"
|
||||||
|
CI_IMAGE_PATH="${VM_BASE_DIR}/images/$1-cidata.iso"
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
## List Installed VMS
|
||||||
|
vm_list()
|
||||||
|
{
|
||||||
|
virsh list
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_net_get_mac()
|
||||||
|
{
|
||||||
|
local VM=$1
|
||||||
|
MAC_VM=$(virsh domiflist "$VM" | awk '{ print $5 }' | tail -2 | head -1)
|
||||||
|
echo $MAC_VM
|
||||||
|
}
|
||||||
|
## Get VM ip (only on NAT)
|
||||||
|
vm_net_get_ip()
|
||||||
|
{
|
||||||
|
local VM="$1"
|
||||||
|
# Obtener la dirección MAC de la interfaz de red
|
||||||
|
MAC_VM=$(vm_net_get_mac $VM)
|
||||||
|
if [[ -z "$MAC_VM" ]]; then
|
||||||
|
echo "Error: No se pudo encontrar la dirección MAC para '$VM'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
# Obtener la dirección IP a partir de la dirección MAC
|
||||||
|
VM_IP_ADDRESS=$(arp -a | grep "$MAC_VM" | awk '{ print $2 }' | sed 's/[()]//g')
|
||||||
|
if [[ -z "$VM_IP_ADDRESS" ]]; then
|
||||||
|
echo "Error: No se pudo encontrar la dirección IP para la dirección MAC '$MAC_VM'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "$VM_IP_ADDRESS"
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_net_create_netplan()
|
||||||
|
{
|
||||||
|
local VM=$1
|
||||||
|
local MAV_VM=$2
|
||||||
|
cat <<EOF > "$VM_BASE_DIR/init/${VM}-netplan"
|
||||||
|
# This file is generated from information provided by the datasource. Changes
|
||||||
|
# to it will not persist across an instance reboot. To disable cloud-init's
|
||||||
|
# network configuration capabilities, write a file
|
||||||
|
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
|
||||||
|
# network: {config: disabled}
|
||||||
|
network:
|
||||||
|
ethernets:
|
||||||
|
enp1s0:
|
||||||
|
addresses:
|
||||||
|
- ${IP}/24
|
||||||
|
nameservers:
|
||||||
|
addresses:
|
||||||
|
- 208.67.222.222
|
||||||
|
- 208.67.220.220
|
||||||
|
match:
|
||||||
|
macaddress: ${MAC_VM}
|
||||||
|
set-name: enp1s0
|
||||||
|
version: 2
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_net_bridge_set_ip()
|
||||||
|
{
|
||||||
|
local VM="$1"
|
||||||
|
local IP="$2"
|
||||||
|
MAC_VM=$(vm_net_get_mac "$VM")
|
||||||
|
CURRENT_IP=$(vm_net_get_ip "$VM")
|
||||||
|
define_netplan
|
||||||
|
# Obtener la dirección IP de la máquina virtual
|
||||||
|
scp -i ${VM_BASE_DIR}/ssh/${VM} \
|
||||||
|
-r $VM_BASE_DIR/init/${VM}-netplan \
|
||||||
|
${VM_USER}@${CURRENT_IP}:50-cloud-init.yaml
|
||||||
|
ssh -i ${VM_BASE_DIR}/ssh/${VM} -l${VM_USER} ${CURRENT_IP} "bash -s" -- < ../vm_example_scripts/apply_netplan.sh
|
||||||
|
}
|
||||||
|
## Connect to an existent VM using ssh
|
||||||
|
vm_connect()
|
||||||
|
{
|
||||||
|
local VM=$1
|
||||||
|
local VM_IP=$(get_vm_ip_address "$VM")
|
||||||
|
ssh -i ${VM_BASE_DIR}/ssh/${VM} -l${VM_USER} ${VM_IP}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Delete VM
|
||||||
|
vm_delete ()
|
||||||
|
{
|
||||||
|
local VM=$1
|
||||||
|
if [[ -f "$VM_IMAGE_PATH" ]]; then
|
||||||
|
# Safely remove the VM with confirmation
|
||||||
|
read -p "Are you sure you want to remove the VM '$VM' (y/N)? " confirm
|
||||||
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
||||||
|
# Attempt to stop the VM before deleting
|
||||||
|
virsh destroy "$VM" 2>/dev/null || true
|
||||||
|
# Delete VM definition and associated images
|
||||||
|
virsh undefine "$VM" 2>/dev/null || true
|
||||||
|
rm -fv "$VM_IMAGE_PATH" "$CI_IMAGE_PATH"
|
||||||
|
rm ${VM_BASE_DIR}/xml/$1.xml
|
||||||
|
rm ${VM_BASE_DIR}/ssh/$1*
|
||||||
|
rm ${VM_BASE_DIR}/init/$1-user-data
|
||||||
|
rm ${VM_BASE_DIR}/init/$1-meta-data
|
||||||
|
else
|
||||||
|
echo "VM removal cancelled."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Handle case where VM image is not found
|
||||||
|
echo "Cannot find VM image file '$VM_IMAGE_PATH'. No action taken."
|
||||||
|
fi
|
||||||
|
}
|
||||||
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
virsh list
|
|
||||||
2
env_scripts/newer_os.sh
Normal file
2
env_scripts/newer_os.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/env bash
|
||||||
|
GUEST_OS_TYPE_DEBIAN="debian12"
|
||||||
2
env_scripts/older_os.sh
Normal file
2
env_scripts/older_os.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/env bash
|
||||||
|
GUEST_OS_TYPE_DEBIAN="debian11"
|
||||||
0
kvm_cloudimage.sh
Normal file
0
kvm_cloudimage.sh
Normal file
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/env bash
|
||||||
#Variables
|
#Variables
|
||||||
VM="$1"
|
VM="$1"
|
||||||
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
||||||
@ -1,6 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/env bash
|
||||||
|
|
||||||
# Variables
|
|
||||||
VM_HOSTNAME=
|
VM_HOSTNAME=
|
||||||
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
||||||
VM_DISK_SIZE=20
|
VM_DISK_SIZE=20
|
||||||
@ -11,7 +9,8 @@ VM_BASE_IMAGE=
|
|||||||
VM_OS_VARIANT=
|
VM_OS_VARIANT=
|
||||||
VM_USERNAME="user"
|
VM_USERNAME="user"
|
||||||
VM_BRIDGE_INT=
|
VM_BRIDGE_INT=
|
||||||
LIBVIRT_NET_OPTION="network=default,model=e1000"
|
VM_NET_USED="default"
|
||||||
|
LIBVIRT_NET_OPTION="network=$VM_NET_USED,model=e1000"
|
||||||
# Functions
|
# Functions
|
||||||
usage()
|
usage()
|
||||||
{
|
{
|
||||||
@ -31,17 +30,43 @@ OPTIONS:
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HOST_OS=$(cat /etc/os-release | grep -v VERSION_ID |grep "ID=" | awk -F'=' '{print $2}')
|
||||||
|
if [ $HOST_OS == "debian" ]; then
|
||||||
|
source < env_scripts/older_os.sh
|
||||||
|
else
|
||||||
|
source > env_scripts/newer_os.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $answer in
|
||||||
|
[1]* ) VM_OS_VARIANT=${GUEST_OS_TYPE_DEBIAN}
|
||||||
|
VM_BASE_IMAGE='https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2'
|
||||||
|
break;;
|
||||||
|
[2]* ) VM_OS_VARIANT='ubuntu20.04'
|
||||||
|
VM_BASE_IMAGE='https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img'
|
||||||
|
break;;
|
||||||
|
[3]* ) VM_OS_VARIANT='ubuntu22.04'
|
||||||
|
VM_BASE_IMAGE='https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img'
|
||||||
|
break;;
|
||||||
|
[4]* ) VM_OS_VARIANT='ubuntu24.04'
|
||||||
|
VM_BASE_IMAGE='https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img'
|
||||||
|
break;;
|
||||||
|
[5]* ) VM_OS_VARIANT='freebsd14.0'
|
||||||
|
VM_BASE_IMAGE='https://download.freebsd.org/releases/VM-IMAGES/14.0-RELEASE/amd64/Latest/FreeBSD-14.0-RELEASE-amd64.qcow2.xz'
|
||||||
|
break;;
|
||||||
|
* ) echo "Please answer 1,2,3,4,5.";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
download_base_image()
|
download_base_image()
|
||||||
{
|
{
|
||||||
if ! test -f "$HOME/vms/base/$VM_OS_VARIANT.qcow2"; then
|
if ! test -f "${VM_BASE_DIR}/base/$VM_OS_VARIANT.qcow2"; then
|
||||||
if [[ "$VM_OS_VARIANT" == "freebsd14.0" ]]; then
|
if [[ "$VM_OS_VARIANT" == "freebsd14.0" ]]; then
|
||||||
VM_DISK_FORMAT=".qcow2.xz"
|
VM_DISK_FORMAT=".qcow2.xz"
|
||||||
wget -v -O "$HOME/vms/base/$VM_OS_VARIANT.${VM_DISK_FORMAT}" ${VM_BASE_IMAGE}
|
wget -v -O "${VM_BASE_DIR}/base/$VM_OS_VARIANT.${VM_DISK_FORMAT}" ${VM_BASE_IMAGE}
|
||||||
cd $HOME/vms/base/
|
cd ${VM_BASE_DIR}/base/
|
||||||
xz -d $VM_OS_VARIANT.${VM_DISK_FORMAT}
|
xz -d $VM_OS_VARIANT.${VM_DISK_FORMAT}
|
||||||
cd -
|
cd -
|
||||||
else
|
else
|
||||||
wget -v -O "$HOME/vms/base/$VM_OS_VARIANT.${VM_DISK_FORMAT}" ${VM_BASE_IMAGE}
|
wget -v -O "${VM_BASE_DIR}/base/$VM_OS_VARIANT.${VM_DISK_FORMAT}" ${VM_BASE_IMAGE}
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -163,9 +188,9 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "Creating a qcow2 image file ${VM_BASE_DIR}/images/${VM_HOSTNAME}.img that uses the cloud image file $HOME/vms/base/$VM_OS_VARIANT.${VM_DISK_FORMAT} as its base"
|
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 ! test -f "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img"; then
|
if ! test -f "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img"; then
|
||||||
qemu-img create -b "$HOME/vms/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}/base/${VM_OS_VARIANT}.qcow2" -f qcow2 -F qcow2 "${VM_BASE_DIR}/images/${VM_HOSTNAME}.img" "${VM_DISK_SIZE}G"
|
||||||
else
|
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"
|
||||||
exit 1
|
exit 1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/env bash
|
||||||
|
|
||||||
# Function for usage message
|
# Function for usage message
|
||||||
usage() {
|
usage() {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/env bash
|
||||||
usage() {
|
usage() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
USO: $0 VM
|
USO: $0 VM
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/env bash
|
||||||
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
||||||
VM_USER="user"
|
VM_USER="user"
|
||||||
VM=$1
|
VM=$1
|
||||||
2
vm_list.sh
Executable file
2
vm_list.sh
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/env bash
|
||||||
|
virsh list
|
||||||
@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/env bash
|
||||||
|
|
||||||
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
|
||||||
VM_USER="user"
|
VM_USER="user"
|
||||||
MAC_VM=
|
MAC_VM=
|
||||||
Reference in New Issue
Block a user