Compare commits

...

32 Commits

Author SHA1 Message Date
9b20cd9adb Merge branch 'hotfix/hostNetwork_creation' 2025-09-04 12:35:46 +02:00
b4afbc05d0 Fixed host only network creation 2025-09-04 12:35:36 +02:00
9748468415 Disabling_LRO_and_TSO on virtio devices on FreeBSD Guests 2025-08-29 17:08:06 +02:00
96071811de Revert "Disabling_LRO_and_TSO on virtio devices on FreeBSD Guests"
This reverts commit 658a104a6f.
2025-08-29 17:06:39 +02:00
658a104a6f Disabling_LRO_and_TSO on virtio devices on FreeBSD Guests 2025-08-29 16:54:24 +02:00
38e1a94306 Not already done. DNSMASQ Support 2025-08-27 19:13:04 +02:00
febd3b76d3 Added Debian Trixie as new Debian stable guest. Fixed host only things on scripts 2025-08-27 16:13:45 +02:00
aaa3fd5b32 Added isolated network available when install 2025-08-27 15:32:28 +02:00
41574c143a Added install software on VM guest feature 2025-08-12 20:02:42 +02:00
5cce3a0337 Added fedora guest VM support 2025-08-01 15:42:27 +02:00
c75eae71b2 Improved setup process. Tested on Fedora 2025-08-01 13:39:13 +02:00
9f61021a86 Added qemu-guest-agent support 2025-07-30 21:10:52 +02:00
2ee8bdf9cc Merge branch 'develop' 2025-07-29 20:01:04 +02:00
854393f4de added git to preinstalled vm packages 2025-07-29 20:00:40 +02:00
a025a70f72 Merge branch 'develop' 2025-07-23 21:29:33 +02:00
4f12846b60 openbsd mention on README 2025-07-23 21:29:18 +02:00
e0ba8a28f3 Merge branch 'develop' 2025-07-23 21:07:08 +02:00
9ff68afe74 README wording improved 2025-07-23 21:06:45 +02:00
43dd2a0ed0 Merge branch 'develop' 2025-07-23 20:56:07 +02:00
d37d70fcef README.md updated 2025-07-23 20:55:26 +02:00
d731aa3814 Merge branch 'develop' 2025-07-23 20:29:15 +02:00
732d0a4ee8 added openbsd guest support 2025-07-23 20:28:21 +02:00
8cd2eb5a05 Reviewed the messages on the screen. Added information messages 2025-07-23 13:09:27 +02:00
03b533f8b1 Merge branch 'develop' 2025-07-23 12:50:55 +02:00
7dd6a29b08 Fixed install.sh script 2025-07-23 12:50:22 +02:00
d1367ae99d Merge branch 'develop' 2025-07-23 01:28:30 +02:00
3cbde1469a added FreeBSD zfs flavour. Improved user-data file for freebsd 2025-07-23 01:27:37 +02:00
9b8d0b5a35 Merge pull request 'develop' (#3) from develop into main
Reviewed-on: #3
2025-07-22 19:59:56 +02:00
d7a5596068 Merge branch 'feature/freebsd_guest' into develop 2025-07-22 19:45:53 +02:00
c6c3bb3fe9 FreeBSD geust added Qemu test folder deleted. 2025-07-22 19:45:31 +02:00
f658307bf4 FreeBSD guest added 2025-07-22 19:42:01 +02:00
c9e5b68eba Merge pull request 'develop pull requesy' (#1) from develop into main
Reviewed-on: #1
2025-07-17 17:47:56 +02:00
38 changed files with 1375 additions and 282 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.img
*.qcow2
./openbsd-cloud-image

202
README.md
View File

@ -1,19 +1,81 @@
# kvm-cloudimage
Use cloud images on baremetal using libvirt/kvm
Use cloud images on bare metal with libvirt/KVM.
Currently, the following base operating systems are supported for guest VMs:
- Debian 12
- Ubuntu 20.04
- Ubuntu 22.04
- FreeBSD 14.3 with UFS filesystem
- FreeBSD 14.2 with ZFS filesystem
- OpenBSD 7.7
## Pre-requisites
- openssh
- mkpass (whois)
- arp
## Links
The following tools must be installed on the host system:
* `openssh`
* `arp`
* `wget`
* `curl`
* `libvirt`
To create OpenBSD images, you will also need:
* `python3`
* `sudo`
* `signify` (Debian: `signify-openbsd` and `signify-openbsd-keys`)
* `qemu-system-x86_64`
## Links and credits
Livbirt host installation
- [Debian guide](https://wiki.debian.org/KVM)
- [Ubuntu guide](https://documentation.ubuntu.com/server/how-to/virtualisation/libvirt/)
- [Fedora guide](https://docs.fedoraproject.org/en-US/quick-docs/virtualization-getting-started/)
Inspirational sites for the project
- [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://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
For OpenBSD images with cloud-init support, this project uses: [hcartiaux's openbsd-cloud-image](https://github.com/hcartiaux/openbsd-cloud-image.git)
### Create bridge network
## Preparing the Host
1. Configure the [variables](env_scripts/common.sh) file (`env_scripts/common.sh`).
It is recommended to place this directory in your home folder to avoid libvirt permission issues.
2. Run the installation script: `install.sh`
## Networking
Two networks are installed when you run `install.sh`:
| Name | Type |DCHP Range |Default route |Host device |
| ----- | -------- |-------------|----------------|--------------|
| vmnetwork | NAT |192.168.100.100 - 254| 192.168.100.1| virb1|
| host-only | Isolated Network |-|-| -|
**Table 1:** Default Available Networks
You can network names changing on [env_scripts/common.sh](env_scripts/common.sh)
```
VM_NETWORK_HOSTONLY="host-only"
VM_USERNAME="user"
```
You can create a VM with isolated network but an extra interface with NAT network if added, because when guest is initialized, it get updated and some packages are installed (dependend on linux-user-metadata). You can delete NAT interface after VM guest is initialized.
### AppArmor exception (if needed)
If AppArmor is blocking libvirtd, disable the profile temporarily:
```shell
ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/
apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd
```
<!-- ### Create bridge network
```shell
sudo virsh --connect qemu:///session net-define /dev/stdin << EOF
@ -23,63 +85,62 @@ sudo virsh --connect qemu:///session net-define /dev/stdin << EOF
<bridge name='brbackend' />
</network>
EOF
```
#### AppArmor exception
``` -->
## Command Usage
### Command help
```shell
ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/
apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd
NAME
./vm_manage.sh
USAGE
Usage: ./vm_manage.sh create -n NAME [-b BRIDGE] [-r RAM] [-c VCPUS] [-s DISK] [-v]
./vm_manage.sh delete NAME
./vm_manage.sh info NAME
./vm_manage.sh connect NAME
./vm_manage.sh install NAME
./vm_manage.sh list
ACTIONS
create Create a new virtual machine
delete Delete a virtual machine
list List all defined virtual machines
info Show information about a virtual machine
connect Connect to the console of a virtual machine
install Install specific software into an existing VM
OPTIONS
-h Show this help message
-n NAME Host name (required)
-b BRIDGE Bridge interface name
-r RAM RAM in MB (default: 1024)
-c VCPUS Number of VCPUs (default: 1)
-s DISK Disk size in GB (default: 10)
-v Verbose mode
AUTHOR
Victor Gracia Enguita <victor@burufalla.ovh>
COPYRIGHT
This is free software; see the source for copying conditions.
```
## Creating VMs
### Usage
### Create VM
Using default values:
```shell
usage: ./vm_create.sh options
Quickly create guest VMs using cloud image files and cloud-init.
OPTIONS:
-h Show this message
-n Host name (required)
-b bridge interface name (bridge network is used)
-r RAM in MB (defaults to 2048)
-c Number of VCPUs (defaults to 2)
-s Amount of storage to allocate in GB (defaults to 20)
-v Verbose
./vm_manage.sh create -ntestMachine
```
__Note__: Default values can be customized in the [env_scripts/common.sh](env_scripts/common.sh) file.
The only required parameter is the hostname, but you can also set RAM size (in MB), number of VCPUs or storage size (in GB), if these parameters are not set, default values will used:
- RAM: 20248MB
- VCPUs: 2
- DISK: 20GB
Actually, you can select these base OS for Guests
- Debian 12
- Ubuntu 20.04
- Ubuntu 22.04
- FreeBSD 14.1
### Examples
With custom specifications:
```shell
./vm_create.sh -ntestMachine
./vm_manage.sh create -ntestMachine -r4098 -c4 -s100
```
A VM will ve created with default values
```shell
./vm_create.sh -ntestMachine -r4098 -c4 -s100
```
A VM will be created with 4098 MB of RAM, 4 vCPUs and 100Gb of storage
#### FreeBSD VMs
__Please note that FreeBSD-based VMs do not currently support cloud-init, so once they are created, you need to connect to the machine through the console (using virt-manager or virs-console) and use the root user (without a password). Once inside, you add a password to root and I recommend that you add a non-root user and that the ssh connection is through that user.
Also note that since there is no cloud-init support, you will have to manually copy the generated ssh keys to the machine. I apologize for the inconvenience but I have not yet been able to make it work any other way.__
This creates a VM with 4096 MB of RAM, 4 vCPUs, and 100 GB of disk space.
## List VMs
```shell
./vm_list.sh
./vm_manage.sh list
Id Nombre Estado
-------------------------------
7 debianTest ejecutando
@ -87,14 +148,13 @@ Also note that since there is no cloud-init support, you will have to manually c
```
## Connect to an VM
```shell
./vm_connect.sh debianTest
./vm_manage.sh connect debianTest
```
## Get ip of VM
Use as parameter machine name
```shell
./vm_get_ip.sh ubuntuTest
./vm_manage.sh info ubuntuTest
192.168.122.234
```
@ -102,7 +162,7 @@ Use as parameter machine name
Use as parameter machine name
```shell
./vm_delete.sh ubuntuTest
./vm_dmanage.sh delete ubuntuTest
Are you sure you want to remove the VM 'ubuntuTest' (y/N)? y
Domain 'ubuntuTest' destroyed
@ -110,18 +170,34 @@ Domain 'ubuntuTest' has been undefined
VM 'ubuntuTest' removed successfully.
```
## Install software on VM
`./vm_manage.sh install VM_NAME`
Example:
```shell
./vm_manage.sh install Debian
Select software to install:
--------------
1. Docker
2. Podman
3. Gitlab CE
4. Gitlab Runner
Enter your choice [1-4]:
```
## TODO
- FreeBSD support is still in progress
- Check if used commands are available
./vm_create.sh: línea 52: mkpasswd: orden no encontrada
- Maybe add more BSD flavours guests support
- add non debian linux derivatives guests support
<!-- ./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
qemu-img wget curl 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
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)

View File

@ -1,16 +1,22 @@
#!/bin/env bash
LIBVIRT_NET_MODEL="virtio"
LIBVIRT_NET_OPTION="network=$VM_NETWORK,model=$LIBVIRT_NET_MODEL"
OS_JSON_FILE="files/os_options.json"
DISTRO=""
#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_DISK_EXTENSION="img"
VM_NETWORK_NAT="vmnetwork"
VM_NETWORK_HOSTONLY="host-only"
VM_NETWORK_TYPE="nat"
VM_USERNAME="user"
VM_SOFT="";
VM_IMAGE_PATH="${VM_BASE_DIR}/images/$1.img"
CI_IMAGE_PATH="${VM_BASE_DIR}/images/$1-cidata.iso"
VM_NETWORK="vmnetwork"
REPO_BRANCH="main"
REPO_SOURCE="https://raw.githubusercontent.com/vgenguita/kvm-cloudimage/refs/heads/${REPO_BRANCH}/env_scripts/"
LIBVIRT_NET_MODEL="virtio"
LIBVIRT_NET_OPTION="network=${VM_NETWORK_NAT},model=${LIBVIRT_NET_MODEL}"
OS_JSON_FILE="files/os_options.json"
OS_JSON_FILE_INSTALL="files/software.json"
# REPO_BRANCH="main"
# REPO_SOURCE="https://raw.githubusercontent.com/vgenguita/kvm-cloudimage/refs/heads/${REPO_BRANCH}/env_scripts/"

View File

@ -1,6 +1,81 @@
#!/bin/env bash
#!/usr/bin/env -S bash
# Functions
pause()
{
read -s -n 1 -p "Press any key to continue . . ."
echo ""
}
# Printe messages
print_info() {
echo -e "\e[1;34m[INFO]\e[0m $1"
}
print_success() {
echo -e "\e[1;32m[OK]\e[0m $1"
}
print_error() {
echo -e "\e[1;31m[ERROR]\e[0m $1"
}
# Detectar distribución
detect_distro()
{
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO=$ID
# elif [ -f /etc/centos-release ] || [ -f /etc/fedora-release ]; then
# if grep -q "Fedora" /etc/fedora-release; then
# DISTRO="fedora"
# else
# DISTRO="centos"
# fi
else
print_error "No se pudo detectar la distribución."
exit 1
fi
}
install_debian_ubuntu() {
print_info "Updating packages..."
sudo apt update || { print_error "Error updating packages."; exit 1; }
print_info "Installing libvirt"
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils|| {
print_error "Error installing packages."
exit 1
}
# Habilitar e iniciar el servicio
sudo systemctl enable libvirtd || sudo systemctl enable libvirt-bin
sudo systemctl start libvirtd || sudo systemctl start libvirt-bin
}
install_arch() {
print_info "Updating packages..."
sudo pacman -Syu --noconfirm || { print_error "Error updating packages."; exit 1; }
print_info "Installing libvirt."
sudo pacman -S --noconfirm qemu libvirt virt-manager dnsmasq iptables bridge-utils|| {
print_error "Error installing packages."
exit 1
}
}
install_fedora() {
print_info "Updating packages..."
sudo dnf upgrade -y|| { print_error "Error updating packages."; exit 1; }
print_info "Installing libvirt."
sudo sudo dnf install -y @virtualization qemu libvirt bridge-utils|| {
print_error "Error installing packages."
exit 1
}
}
check_host_os()
{
@ -12,54 +87,130 @@ check_host_os()
fi
}
show_vm_menu()
{
# Show dinamic menu
echo "Select VM OS:"
for entry in $(jq -r '.os_variants[] | @base64' "$OS_JSON_FILE"); do
decoded=$(echo "$entry" | base64 --decode)
id=$(echo "$decoded" | jq -r .id)
name=$(echo "$decoded" | jq -r .name)
echo "$id. $name"
done
# ID_MAX calculation
ID_MAX=$(jq -r '[.os_variants[].id] | max' "$OS_JSON_FILE")
# Read input
read -r -p "Enter your choice [1-${ID_MAX}]: " answer
if ! [[ "$answer" =~ ^[0-9]+$ ]] || (( answer < 1 || answer > ID_MAX )); then
echo "Invalid option. Please enter a number between 1 and ${ID_MAX}."
exit 1
chown_image_permissions(){
if [[ "${DISTRO}" == "fedora" ]]; then
USER_GROUP="$USER:qemu"
else
USER_GROUP="$USER:libvirt-qemu"
fi
selected=$(jq -r ".os_variants[] | select(.id == $answer)" "$OS_JSON_FILE")
if [ -z "$selected" ]; then
echo "Invalid option."
exit 1
fi
# Asignar variables
VM_OS_VARIANT=$(echo "$selected" | jq -r .variant)
VM_BASE_IMAGE_URL=$(echo "$selected" | jq -r .url)
VM_BASE_IMAGE=$(echo "$selected" | jq -r .origin_image_name)
VM_BOOT_TYPE=$(echo "$selected" | jq -r .boot_type)
VM_CHECKSUMS_URL=$(echo "$selected" | jq -r .md5sum)
}
generate_openbsd_image()
{
local CURRENT_PATH="$PWD"
VM_BASE_IMAGE_NAME=${VM_BASE_IMAGE%%.*}
VM_BASE_IMAGE_EXTENSION=${VM_BASE_IMAGE#*.}
git clone https://github.com/hcartiaux/openbsd-cloud-image.git
cd openbsd-cloud-image
./build_openbsd_qcow2.sh \
--image-file ${VM_BASE_IMAGE_NAME}.${VM_BASE_IMAGE_EXTENSION} \
--disklabel custom/disklabel.cloud \
--size ${VM_DISK_SIZE} \
-b
if ! test -f "${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}"; then
mv images/${VM_BASE_IMAGE_NAME}.${VM_BASE_IMAGE_EXTENSION} ${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}
sudo chown -R ${USER_GROUP} ${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}
cd ${CURRENT_PATH}
rm -r openbsd-cloud-image
else
echo "${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION} already exists. Delete VM with "delete" option"
cd ${CURRENT_PATH}
rm -r openbsd-cloud-image
exit 1
fi
}
show_vm_menu() {
# Display dynamic OS selection menu
echo "Select VM OS:"
echo "--------------"
# Array to store valid IDs for validation
VALID_IDS=()
while IFS= read -r entry; do
DECODED=$(echo "$entry" | base64 --decode)
ID=$(echo "$DECODED" | jq -r '.id')
NAME=$(echo "$DECODED" | jq -r '.name')
printf "%2s. %s\n" "$ID" "$NAME"
VALID_IDS+=("$ID")
done < <(jq -r '.os_variants[] | @base64' "$OS_JSON_FILE")
# Calculate max ID for range validation
ID_MAX=$(jq -r '[.os_variants[].id] | max' "$OS_JSON_FILE")
ID_MIN=$(jq -r '[.os_variants[].id] | min' "$OS_JSON_FILE")
# Read user input
read -r -p "Enter your choice [${ID_MIN}-${ID_MAX}]: " CHOICE
# Validate input: must be a number and within range
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]]; then
echo "Error: Please enter a valid number." >&2
exit 1
fi
if (( CHOICE < ID_MIN || CHOICE > ID_MAX )); then
echo "Error: Please enter a number between ${ID_MIN} and ${ID_MAX}." >&2
exit 1
fi
# Get selected OS variant
SELECTED=$(jq -r ".os_variants[] | select(.id == ${CHOICE})" "$OS_JSON_FILE")
if [ -z "$SELECTED" ]; then
echo "Error: Invalid selection." >&2
exit 1
fi
# Export variables in uppercase
VM_OS_VARIANT=$(echo "$SELECTED" | jq -r '.variant')
VM_OS_TYPE=$(echo "$SELECTED" | jq -r '.os_type')
VM_BASE_IMAGE_URL=$(echo "$SELECTED" | jq -r '.url')
VM_BASE_IMAGE=$(echo "$SELECTED" | jq -r '.origin_image_name')
VM_BOOT_TYPE=$(echo "$SELECTED" | jq -r '.boot_type')
VM_CHECKSUMS_URL=$(echo "$SELECTED" | jq -r '.md5sum')
# Optional: Debug
# echo "Selected OS variant: ${VM_OS_VARIANT}"
}
compare_checksum()
{
CHECKSUM_TMP_FOLDER=$(mktemp)
curl -s -o "${CHECKSUM_TMP_FOLDER}" "${VM_CHECKSUMS_URL}"
VM_BASE_IMAGE_CHECKSUM=$(grep "$VM_BASE_IMAGE_NAME.${VM_BASE_IMAGE_EXTENSION}" "${CHECKSUM_TMP_FOLDER}" | awk '{print $1}')
if [[ "${VM_CHECKSUMS_URL}" == *"SHA256SUMS"* ]]; then
HASH_CMD="sha256sum"
elif [[ "${VM_CHECKSUMS_URL}" == *"SHA512SUMS"* ]]; then
HASH_CMD="sha512sum"
curl -L -o "${CHECKSUM_TMP_FOLDER}" \
"${VM_CHECKSUMS_URL}"
# wget --recursive \
# --user-agent="Mozilla/5.0 (X11; Linux x86_64)" \
# -O "${CHECKSUM_TMP_FOLDER}" \
# "${VM_CHECKSUMS_URL}"
if [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"freebsd"* ]]; then
if [[ "${VM_BASE_IMAGE}" == *"zfs"* ]]; then
VM_BASE_IMAGE_CHECKSUM=$(grep "FreeBSD-14.3-STABLE-amd64-BASIC-CLOUDINIT" "${CHECKSUM_TMP_FOLDER}" | grep "zfs.qcow2.xz" | awk '{print $4}')
else
VM_BASE_IMAGE_CHECKSUM=$(grep "FreeBSD-14.3-STABLE-amd64-BASIC-CLOUDINIT" "${CHECKSUM_TMP_FOLDER}" | grep "ufs.qcow2.xz" | awk '{print $4}')
fi
else
echo "ERROR: Unknown checksum type in URL: $CHECKSUM_URL"
exit 1
#Fedora things
if [[ "${VM_OS_VARIANT}" == "fedora41" ]]; then
VM_BASE_IMAGE_CHECKSUM=$(grep "${VM_BASE_IMAGE_NAME}.${VM_BASE_IMAGE_EXTENSION}" "${CHECKSUM_TMP_FOLDER}" | grep -v \# | awk '{print $4}')
else
VM_BASE_IMAGE_CHECKSUM=$(grep "${VM_BASE_IMAGE_NAME}.${VM_BASE_IMAGE_EXTENSION}" "${CHECKSUM_TMP_FOLDER}" | awk '{print $1}')
fi
fi
if [[ "${VM_CHECKSUMS_URL}" == *"SHA256"* || "${VM_CHECKSUMS_URL}" == *"sha256"* ]]; then
HASH_CMD="sha256sum"
elif [[ "${VM_CHECKSUMS_URL}" == *"SHA512"* ]]; then
HASH_CMD="sha512sum"
#Fedora things
else
if grep -qi "SHA256" "${CHECKSUM_TMP_FOLDER}"; then
HASH_CMD="sha256sum"
elif grep -qi "SHA512" "${CHECKSUM_TMP_FOLDER}"; then
HASH_CMD="sha512sum"
else
echo "ERROR: Cannot determinate checksum type on ${CHECKSUM_TMP_FOLDER}"
exit 1
fi
fi
BASE_FILE_CHECKSUM=$(${HASH_CMD} ${VM_BASE_IMAGE_LOCATION} | awk '{print $1}')
if [ "${BASE_FILE_CHECKSUM}" = "${VM_BASE_IMAGE_CHECKSUM}" ]; then
@ -80,7 +231,7 @@ vm_list()
vm_net_get_mac()
{
local VM=$1
MAC_VM=$(virsh domiflist "$VM" | awk '{ print $5 }' | tail -2 | head -1)
MAC_VM=$(virsh domiflist "${VM}" | grep "${VM_NETWORK_NAT}"| awk '{ print $5 }' | tail -2 | head -1)
echo $MAC_VM
}
## Get VM ip (only on NAT)
@ -90,13 +241,13 @@ vm_net_get_ip()
# 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'"
echo "Error: The MAC address could not be found for '$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'"
echo "Error: Could not find IP address for MAC address '$MAC_VM'"
return 1
fi
echo "$VM_IP_ADDRESS"
@ -142,10 +293,10 @@ vm_net_bridge_set_ip()
ssh -i ${VM_BASE_DIR}/ssh/${VM} -l${VM_USERNAME} ${CURRENT_IP} "bash -s" -- < ../vm_example_scripts/apply_netplan.sh
}
vm_net_set_bridge_mode()
vm_net_set_network_type()
{
if [[ -n $VM_BRIDGE_INT ]]; then
LIBVIRT_NET_OPTION="model=virtio,bridge=${VM_BRIDGE_INT}"
if [[ "${VM_NETWORK_TYPE}" == "bridge" ]]; then
LIBVIRT_NET_OPTION="model=virtio,bridge=${VM_BRIDGE_INT}"
fi
}
## Connect to an existent VM using ssh
@ -160,7 +311,6 @@ vm_connect()
vm_delete ()
{
local VM=$1
echo "VM: $VM"
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
@ -185,29 +335,52 @@ vm_delete ()
}
vm_download_base_image()
{
VM_BASE_IMAGE_NAME=${VM_BASE_IMAGE%%.*}
VM_BASE_IMAGE_EXTENSION=${VM_BASE_IMAGE#*.}
if [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"freebsd"* ]]; then
if [[ "${VM_BASE_IMAGE}" == *"zfs"* ]]; then
VM_BASE_IMAGE_NAME="${VM_OS_VARIANT}-zfs"
else
VM_BASE_IMAGE_NAME="${VM_OS_VARIANT}-ufs"
fi
VM_BASE_IMAGE_EXTENSION="qcow2.xz"
else
VM_BASE_IMAGE_NAME=${VM_BASE_IMAGE%%.*}
VM_BASE_IMAGE_EXTENSION=${VM_BASE_IMAGE#*.}
fi
VM_BASE_IMAGE_LOCATION="${VM_BASE_DIR}/${VM_BASE_IMAGES}/${VM_BASE_IMAGE_NAME}.${VM_BASE_IMAGE_EXTENSION}"
if ! test -f "${VM_BASE_IMAGE_LOCATION}"; then
wget -O "${VM_BASE_IMAGE_LOCATION}" ${VM_BASE_IMAGE_URL}
# wget \
# --user-agent="Mozilla/5.0 (X11; Linux x86_64)" \
# -O "${VM_BASE_IMAGE_LOCATION}" \
# ${VM_BASE_IMAGE_URL}
curl -L ${VM_BASE_IMAGE_URL} \
-o ${VM_BASE_IMAGE_LOCATION} \
fi
}
vm_create_guest_image()
{
echo "Creating a qcow2 image file ${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION} that uses the cloud image file ${VM_BASE_IMAGE_LOCATION} as its base"
if [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"freebsd"* ]]; then
if ! test -f "${VM_BASE_DIR}/images/${VM_HOSTNAME}.qcow"; then
xz -d ${VM_BASE_IMAGE_LOCATION}
fi
VM_BASE_IMAGE_EXTENSION="qcow2"
VM_BASE_IMAGE_LOCATION="${VM_BASE_DIR}/${VM_BASE_IMAGES}/${VM_BASE_IMAGE_NAME}.${VM_BASE_IMAGE_EXTENSION}"
fi
if ! test -f "${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}"; then
qemu-img convert \
-O qcow2 \
"${VM_BASE_IMAGE_LOCATION}" \
"${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}"
qemu-img resize \
"${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}" \
"${VM_DISK_SIZE}G"
sudo chown -R $USER:libvirt-qemu "${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}"
qemu-img convert \
-O qcow2 \
"${VM_BASE_IMAGE_LOCATION}" \
"${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}"
qemu-img resize \
"${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}" \
"${VM_DISK_SIZE}G"
sudo chown -R ${USER_GROUP} ${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION}
else
echo "${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION} already exists. Delete VM with "delete" option"
exit 1
echo "${VM_BASE_DIR}/images/${VM_HOSTNAME}.${VM_DISK_EXTENSION} already exists. Delete VM with "delete" option"
exit 1
fi
}
@ -221,34 +394,102 @@ vm_generate_ssh_hey()
#rm "${VM_BASE_DIR}/ssh/${VM_HOSTNAME}".pub.txt
}
vm_gen_linux_user_data()
{
VM_USER_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 8; echo)
VM_USER_PASS_HASH=$(mkpasswd --method=SHA-512 --rounds=4096 ${VM_USER_PASS})
cat <<EOF > "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
#cloud-config
hostname: ${VM_HOSTNAME}
# manage_etc_hosts: false
ssh_pwauth: true
disable_root: true
users:
- name: ${VM_USERNAME}
hashed_passwd: ${VM_USER_PASS_HASH}
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
lock-passwd: false
ssh_authorized_keys:
- ${SSH_PUB_KEY}
EOF
}
# vm_gen_user_data()
# {
# VM_USER_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 8; echo)
# VM_USER_PASS_HASH=$(mkpasswd --method=SHA-512 --rounds=4096 ${VM_USER_PASS})
# #FREEBSD GUEST
# if [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"freebsd"* ]]; then
# VM_ROOT_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 8; echo)
# VM_ROOT_PASS_HASH=$(mkpasswd --method=SHA-512 --rounds=4096 ${VM_ROOT_PASS})
# cat <<EOF > "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
# #cloud-config
# hostname: ${VM_HOSTNAME}
# package_reboot_if_required: true
# package_update: true
# package_upgrade: true
# packages:
# - sudo
# - vim
# ssh_pwauth: false
# users:
# - name: root
# lock_passwd: false
# hashed_passwd: ${VM_ROOT_PASS_HASH}
# - name: ${VM_USERNAME}
# ssh_authorized_keys:
# - ${SSH_PUB_KEY}
# lock_passwd: true
# groups: wheel
# shell: /bin/tcsh
# write_files:
# - path: /usr/local/etc/sudoers
# content: |
# %wheel ALL=(ALL) NOPASSWD: ALL
# append: true
# EOF
# #OPENBSD
# elif [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"openbsd"* ]]; then
# #"disable_root": true
# cat <<EOF > "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
# #cloud-config
# "hostname": ${VM_HOSTNAME}
# "package_upgrade": true
# "packages":
# - "bash"
# - "vim--no_x11"
# "ssh_pwauth": false
# "users":
# - "name": ${VM_USERNAME}
# "sudo": "ALL=(ALL) NOPASSWD:ALL"
# "groups": wheel
# "hashed_passwd": "!"
# "lock_passwd": true
# "shell": "/usr/local/bin/bash"
# "ssh_authorized_keys":
# - ${SSH_PUB_KEY}
# - "name": "root"
# "hashed_passwd": "!"
# "lock_passwd": true
# write_files:
# - path: /etc/sudoers
# content: |
# %wheel ALL=(ALL) NOPASSWD: ALL
# append: true
# EOF
# else
# cat <<EOF > "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
# #cloud-config
# hostname: ${VM_HOSTNAME}
# # manage_etc_hosts: false
# ssh_pwauth: true
# disable_root: true
# users:
# - name: ${VM_USERNAME}
# hashed_passwd: ${VM_USER_PASS_HASH}
# sudo: ALL=(ALL) NOPASSWD:ALL
# shell: /bin/bash
# lock-passwd: false
# ssh_authorized_keys:
# - ${SSH_PUB_KEY}
# EOF
# fi
# }
vm_gen_user_data()
{
VM_USER_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 8; echo)
VM_USER_PASS_HASH=$(mkpasswd --method=SHA-512 --rounds=4096 ${VM_USER_PASS})
cp files/user-data "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
sed -i "s|__SSH_KEY__|${SSH_PUB_KEY}|g" "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
sed -i "s| __USER_PASSWORD__|${VM_USER_PASS_HASH}|g" "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
if [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"freebsd"* ]]; then
VM_USER_DATA_FILE="files/freebsd-user-data"
elif [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"openbsd"* ]]; then
VM_USER_DATA_FILE="files/openbsd-user-data"
else
VM_USER_DATA_FILE="files/linux-user-data"
fi
cp ${VM_USER_DATA_FILE} "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
sed -i "s|__SSH_PUB_KEY__|${SSH_PUB_KEY}|g" "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
sed -i "s|__VM_USERNAME__|${VM_USERNAME}|g" "$VM_BASE_DIR/init/${VM_HOSTNAME}-user-data"
}
vm_gen_meta_data()
@ -257,6 +498,20 @@ vm_gen_meta_data()
sed -i "s|__VMname__|${VM_HOSTNAME}|g" "$VM_BASE_DIR/init/${VM_HOSTNAME}-meta-data"
}
vm_set_guest_type()
{
if [[ "$VM_OS_TYPE" == "BSD" ]]; then
if [[ "${VM_OS_VARIANT}" == *"freebsd"* ]]; then
VM_OS_VARIANT=${GUEST_OS_TYPE_FREEBSD}
fi
if [[ "${VM_OS_VARIANT}" == *"openbsd"* ]]; then
VM_OS_VARIANT=${GUEST_OS_TYPE_OPENBSD}
fi
elif [[ "${VM_OS_VARIANT}" == *"debian13"* ]]; then
VM_OS_VARIANT=${GUEST_OS_TYPE_DEBIAN}
fi
}
vm_guest_install()
{
VM_INSTALL_OPTS=""
@ -266,14 +521,146 @@ vm_guest_install()
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}"
if [[ "${VM_NETWORK_TYPE}" == "isolated" ]]; then
LIBVIRT_NET_OPTION="network=${VM_NETWORK_HOSTONLY},model=${LIBVIRT_NET_MODEL}"
VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --network ${LIBVIRT_NET_OPTION}"
fi
VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --autostart"
VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --import --noautoconsole"
VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --cloud-init user-data=${VM_BASE_DIR}/init/${VM_HOSTNAME}-user-data,meta-data=$VM_BASE_DIR/init/${VM_HOSTNAME}-meta-data"
VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --channel unix,mode=bind,target_type=virtio,name=org.qemu.guest_agent.0"
if [ "$VM_BOOT_TYPE" = "UEFI" ]; then
VM_INSTALL_OPTS="${VM_INSTALL_OPTS} --boot uefi"
fi
eval virt-install $VM_INSTALL_OPTS
virsh dumpxml "${VM_HOSTNAME}" > "${VM_BASE_DIR}/xml/${VM_HOSTNAME}.xml"
#clear
echo "VM ${VM_HOSTNAME} Created!"
echo "NOTE: It may take some time for the virtual machine to be available if it is a BSD flavor. You can check the status of the virtual machine with the following command:"
echo "root pass is(only for BSD flavour): ${VM_USER_PASS}"
echo "user pass is: ${VM_USER_PASS}"
echo "virsh console ${VM_HOSTNAME} --safe"
}
vm_get_guest_info()
{
# Obtener el ID del sistema operativo
# Obtener el ID del sistema operativo
OS_ID=$(grep -o 'id="[^"]*"' "$1" | tr -d '"' | awk '{print $1}')
# Eliminar el protocolo y el dominio del ID
OS_ID=$(echo "$OS_ID" | cut -d '/' -f 2-)
#echo $OS_ID
# Convertir la URL a un nombre de distribución y versión
VM_DISTRO=$(echo "$OS_ID" | awk -F '/' '{print $3}')
VM_VERSION=$(echo "$OS_ID" | awk -F '/' '{print $4}')
}
show_software_menu() {
# Display dynamic OS selection menu
echo "Select software to install:"
echo "--------------"
# Array to store valid IDs for validation
VALID_IDS=()
while IFS= read -r entry; do
DECODED=$(echo "$entry" | base64 --decode)
ID=$(echo "$DECODED" | jq -r '.id')
NAME=$(echo "$DECODED" | jq -r '.show_name')
printf "%2s. %s\n" "$ID" "$NAME"
VALID_IDS+=("$ID")
done < <(jq -r '.software[] | @base64' "$OS_JSON_FILE_INSTALL")
# Calculate max ID for range validation
ID_MAX=$(jq -r '[.software[].id] | max' "$OS_JSON_FILE_INSTALL")
ID_MIN=$(jq -r '[.software[].id] | min' "$OS_JSON_FILE_INSTALL")
# Read user input
read -r -p "Enter your choice [${ID_MIN}-${ID_MAX}]: " CHOICE
# Validate input: must be a number and within range
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]]; then
echo "Error: Please enter a valid number." >&2
exit 1
fi
if (( CHOICE < ID_MIN || CHOICE > ID_MAX )); then
echo "Error: Please enter a number between ${ID_MIN} and ${ID_MAX}." >&2
exit 1
fi
# Get selected OS variant
SELECTED=$(jq -r ".software[] | select(.id == ${CHOICE})" "$OS_JSON_FILE_INSTALL")
if [ -z "$SELECTED" ]; then
echo "Error: Invalid selection." >&2
exit 1
fi
# Export variables in uppercase
VM_SOFT=$(echo "$SELECTED" | jq -r '.name')
}
vm_install_utils()
{
local VM=$1
local SCRIPT=''
local VM_DISTRO=''
local VM_VERSION=''
local VM_IP=$(vm_net_get_ip "$VM")
vm_get_guest_info ${VM_BASE_DIR}/xml/${VM}.xml
case ${VM_SOFT} in
docker)
if [[ "$VM_DISTRO" == "debian" ]]; then
SCRIPT='vm_example_scripts/docker_debian.sh'
elif [[ "$VM_DISTRO" == "ubuntu" ]]; then
SCRIPT='vm_example_scripts/docker_ubuntu.sh'
elif [[ "$VM_DISTRO" == "fedora" ]]; then
SCRIPT='vm_example_scripts/docker_fedora.sh'
elif [[ "$VM_DISTRO" == "freebsd" ]]; then
echo "Automated installation for Docker on ${VM_DISTRO} is not available."
echo "It's better to use Pidman instead"
exit 1
fi
;;
podman)
if [[ "$VM_DISTRO" == "debian" || "$VM_DISTRO" == "ubuntu" ]]; then
SCRIPT='vm_example_scripts/podman_deb.sh'
elif [[ "$VM_DISTRO" == "fedora" ]]; then
SCRIPT='vm_example_scripts/podman_fedora.sh'
elif [[ "$VM_DISTRO" == "freebsd" ]]; then
SCRIPT='vm_example_scripts/podman_freebsd.sh'
fi
;;
gitlab_ce)
if [[ "$VM_DISTRO" == "debian" || "$VM_DISTRO" == "ubuntu" ]]; then
SCRIPT='vm_example_scripts/gitlab_ce_deb.sh'
elif [[ "$VM_DISTRO" == "fedora" || "$VM_DISTRO" == "freebsd" ]]; then
#SCRIPT='vm_example_scripts/gitlab_ce_fedora.sh'
echo "Automated installation for Gitlab CE on ${VM_DISTRO} is not available by the moment."
exit 1
fi
;;
gitlab_runner)
if [[ "$VM_DISTRO" == "debian" || "$VM_DISTRO" == "ubuntu" ]]; then
SCRIPT='vm_example_scripts/gitlab_runner_deb.sh'
elif [[ "$VM_DISTRO" == "fedora" ]]; then
SCRIPT='vm_example_scripts/gitlab_runner_fedora.sh'
elif [[ "$VM_DISTRO" == "freebsd" ]]; then
SCRIPT='vm_example_scripts/gitlab_runner_freebsd.sh'
fi
;;
*)
echo "Unknown action: ${ACTION}" >&2
usage
;;
esac
#Exec script
#bash ${SCRIPT}
if [[ "$VM_DISTRO" == "freebsd" ]]; then
ssh -i ${VM_BASE_DIR}/ssh/${VM} -l${VM_USERNAME} ${VM_IP} "sudo sh -s" - < ${SCRIPT}
else
ssh -i ${VM_BASE_DIR}/ssh/${VM} -l${VM_USERNAME} ${VM_IP} "sudo bash -s" - < ${SCRIPT}
fi
}

View File

@ -0,0 +1,4 @@
#!/bin/env bash
GUEST_OS_TYPE_DEBIAN="debian13"
GUEST_OS_TYPE_FREEBSD="freebsd14.2"
GUEST_OS_TYPE_OPENBSD="openbsd7.6"

View File

@ -1,2 +1,4 @@
#!/bin/env bash
GUEST_OS_TYPE_DEBIAN="debian11"
GUEST_OS_TYPE_DEBIAN="debian11"
GUEST_OS_TYPE_FREEBSD="freebsd13.1"
GUEST_OS_TYPE_OPENBSD="openbsd7.0"

36
files/freebsd-user-data Normal file
View File

@ -0,0 +1,36 @@
#cloud-config
package_reboot_if_required: true
package_update: true
package_upgrade: true
packages:
- sudo
- vim
- git
- qemu-guest-agent
ssh_pwauth: false
config:
- type: physical
name: vtnet0
subnets:
- type: dhcp
users:
- name: __VM_USERNAME__
sudo: "ALL=(ALL) NOPASSWD:ALL"
groups: wheel
hashed_passwd: "!"
lock_passwd: true
shell: /bin/tcsh
ssh_authorized_keys:
- __SSH_PUB_KEY__
- name: root
hashed_passwd: "!"
lock_passwd: true
write_files:
- path: /usr/local/etc/sudoers
content: |
%wheel ALL=(ALL) NOPASSWD: ALL
append: true
runcmd:
- sysrc qemu_guest_agent_enable=YES
- sysrc ifconfig_vtnet0="DHCP -tso4 -tso6 -lro -vlanhwtso"
- sysrc ifconfig_DEFAULT=""

19
files/linux-user-data Normal file
View File

@ -0,0 +1,19 @@
#cloud-config
ssh_pwauth: true
disable_root: true
package_reboot_if_required: true
package_update: true
package_upgrade: true
packages:
- sudo
- vim
- git
- qemu-guest-agent
users:
- name: __VM_USERNAME__
ssh_authorized_keys:
- __SSH_PUB_KEY__
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
groups: sudo
shell: /bin/bash
lock-passwd: true

View File

@ -0,0 +1,5 @@
<network>
<name>YOURNETWORK</name>
<bridge name='YOURNETWORK' stp='on' delay='0'/>
<!-- <domain name='hostonly.local'/> -->
</network>

28
files/openbsd-user-data Normal file
View File

@ -0,0 +1,28 @@
#cloud-config
package_reboot_if_required: true
package_update: true
package_upgrade: true
packages:
- sudo
- vim
- git
- qemu-guest-agent
ssh_pwauth: false
users:
- name: __VM_USERNAME__
sudo: "ALL=(ALL) NOPASSWD:ALL"
groups: wheel
hashed_passwd: "!"
lock_passwd: true
shell: /usr/local/bin/bash
ssh_authorized_keys:
- __SSH_PUB_KEY__
- name: root
hashed_passwd: "!"
lock_passwd: true
write_files:
- path: /etc/sudoers
content: |
%wheel ALL=(ALL) NOPASSWD: ALL
append: true

View File

@ -2,17 +2,19 @@
"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",
"name": "Debian Stable",
"variant": "debian13",
"os_type": "GNULinux",
"url": "http://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2",
"origin_image_name": "debian-13-generic-amd64.qcow2",
"md5sum": "http://cloud.debian.org/images/cloud/trixie/latest/SHA512SUMS",
"boot_type": "bios"
},
{
"id": 2,
"name": "Ubuntu 20.04 server",
"variant": "ubuntu20.04",
"os_type": "GNULinux",
"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",
@ -23,6 +25,7 @@
"id": 3,
"name": "Ubuntu 20.04 minimal",
"variant": "ubuntu20.04",
"os_type": "GNULinux",
"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",
@ -32,6 +35,7 @@
"id": 4,
"name": "Ubuntu 22.04 server",
"variant": "ubuntu22.04",
"os_type": "GNULinux",
"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",
@ -41,6 +45,7 @@
"id": 5,
"name": "Ubuntu 22.04 minimal",
"variant": "ubuntu22.04",
"os_type": "GNULinux",
"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",
@ -50,6 +55,7 @@
"id": 6,
"name": "Ubuntu 24.04 server",
"variant": "ubuntu22.04",
"os_type": "GNULinux",
"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",
@ -58,11 +64,49 @@
{
"id": 7,
"name": "Ubuntu 24.04 minimal",
"os_type": "GNULinux",
"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"
} ,
{
"id": 8,
"name": "Fedora CLoud",
"os_type": "GNULinux",
"variant": "fedora41",
"url": " https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2",
"origin_image_name": "Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2",
"md5sum": "https://fedora.mirrorservice.org/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-42-1.1-x86_64-CHECKSUM",
"boot_type": "bios"
} ,
{
"id": 9,
"name": "FreeBSD 14.3 UFS",
"os_type": "BSD",
"variant": "freebsd14.2",
"url": "https://download.freebsd.org/ftp/snapshots/VM-IMAGES/14.3-STABLE/amd64/Latest/FreeBSD-14.3-STABLE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz",
"origin_image_name": "FreeBSD-14.3-STABLE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz",
"md5sum": "https://download.freebsd.org/ftp/snapshots/VM-IMAGES/14.3-STABLE/amd64/Latest/CHECKSUM.SHA512"
} ,
{
"id": 10,
"name": "FreeBSD 14.3 ZFS",
"os_type": "BSD",
"variant": "freebsd14.2",
"url": "https://download.freebsd.org/ftp/snapshots/VM-IMAGES/14.3-STABLE/amd64/Latest/FreeBSD-14.3-STABLE-amd64-BASIC-CLOUDINIT-zfs.qcow2.xz",
"origin_image_name": "FreeBSD-14.3-STABLE-amd64-BASIC-CLOUDINIT-zfs.qcow2.xz",
"md5sum": "https://download.freebsd.org/ftp/snapshots/VM-IMAGES/14.3-STABLE/amd64/Latest/CHECKSUM.SHA512"
} ,
{
"id": 11,
"name": "OpenBSD 7.7 generic",
"os_type": "BSD",
"variant": "openbsd7.6",
"url": "",
"origin_image_name": "openbsd-generic.qcow2",
"md5sum": ""
}
]
}

24
files/software.json Normal file
View File

@ -0,0 +1,24 @@
{
"software": [
{
"id": 1,
"show_name": "Docker",
"name": "docker"
},
{
"id": 2,
"show_name": "Podman",
"name": "podman"
},
{
"id": 3,
"show_name": "Gitlab CE",
"name": "gitlab_ce"
},
{
"id": 4,
"show_name": "Gitlab Runner",
"name": "gitlab_runner"
}
]
}

View File

@ -1,12 +0,0 @@
ssh_pwauth: true
disable_root: true
users:
- name: user
ssh_authorized_keys:
- __SSH_KEY__
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
groups: sudo
shell: /bin/bash
hashed_passwd: __USER_PASSWORD__
lock-passwd: false

45
install.sh Normal file → Executable file
View File

@ -2,12 +2,43 @@
#Define variable names on env_scripts/common.sh
#VM_NETWORK=
#VM_BASE_DIR=
#Install dependencies - TODO
source variables/common.sh
#Install dependencies
source env_scripts/common.sh
source env_scripts/functions.sh
detect_distro
case $DISTRO in
ubuntu|debian)
install_debian_ubuntu
;;
arch)
install_arch
;;
fedora)
install_fedora
;;
*)
print_error "Distribution not supported: $DISTRO"
print_info "Supported: Ubuntu, Debian, Arch, Fedora"
exit 1
;;
esac
sudo usermod -aG libvirt $(whoami)
sudo usermod -aG kvm $(whoami)
sudo systemctl enable libvirtd
sudo systemctl start libvirtd
mkdir -p "${VM_BASE_DIR}"/{images,xml,init,base,ssh}
cp files/network.xml ${VM_BASE_DIR}/xml/network.xml
sed -i "s/YOURNETWORK/${VM_NETWORK}/g" ${VM_BASE_DIR}/xml/network.xml
virsh net-define ${VM_BASE_DIR}/xml/network.xml
virsh net-autostart ${VM_NETWORK}
virsh net-start ${VM_NETWORK}
#Isolated network
cp files/network-host-only.xml ${VM_BASE_DIR}/xml/network-host-only.xml
sed -i "s/YOURNETWORK/${VM_NETWORK_HOSTONLY}/g" ${VM_BASE_DIR}/xml/network-host-only.xml
virsh net-define ${VM_BASE_DIR}/xml/network-host-only.xml
virsh net-autostart ${VM_NETWORK_HOSTONLY}
virsh net-start ${VM_NETWORK_HOSTONLY}
#NAT
cp files/network-nat.xml ${VM_BASE_DIR}/xml/network-nat.xml
sed -i "s/YOURNETWORK/${VM_NETWORK_NAT}/g" ${VM_BASE_DIR}/xml/network-nat.xml
virsh net-define ${VM_BASE_DIR}/xml/network-nat.xml
virsh net-autostart ${VM_NETWORK_NAT}
virsh net-start ${VM_NETWORK_NAT}
newgrp libvirt

View File

@ -1,3 +1,3 @@
#!/bin/bash
#!/usr/bin/env bash
sudo mv /home/user/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml
sudo netplan apply

View File

@ -0,0 +1,150 @@
#!/bin/sh -
#VARIABLES
# === Security and initialization ===
IFS=' ' # Reset IFS to prevent parsing attacks
# === Default values ===
ENABLE_DNS="yes"
ENABLE_DHCP="no"
ENABLE_PXE="no"
DNSMASQ_DCONF_DIR="/usr/local/etc/dnsmasq.conf.d"
DNSMASQ_CONFIG_FILE="/usr/local/etc/dnsmasq.conf"
LOCAL_NETWORK="192.168.1"
LOCAL_NETWORK_GATEWAY="${LOCAL_NETWORK}.1"
LOCAL_NETWORK_RANGE="${LOCAL_NETWORK}.0/24"
LOCAL_NETWORK_DHCP_FIRST_IP="50"
LOCAL_NETWORK_DHCP_LAST_IP="254"
LOCAL_NETWORK_NETMASK="255.255.255.0"
LOCAL_NETWORK_DHCP_LEASE="12h"
LOCAL_DOMAIN="pozal.lan"
#FUNCTIONS
# === Function: print header ===
print_header()
{
printf '%s\n' "================================"
printf '%s\n' " Dnsmasq Service Enabler"
printf '%s\n' "================================"
}
# === Function: ask yes/no ===
ask_yes_no()
{
# Usage: ask_yes_no "Question?" default(y/n)
prompt="$1"
default="$2"
while true; do
printf '%s ' "${prompt} (y/n) [${default}]: "
read -r response
case "${response:-${default}}" in
[Yy]|[Yy][Ss])
echo "yes"
return 0
;;
[Nn]|[Nn][Oo])
echo "no"
return 0
;;
*)
printf '%s\n' "Please answer yes or no."
;;
esac
done
}
change_config()
{
REPLACEMENTS_FILE=$1
if [ ! -f "${DNSMASQ_CONFIG_FILE}" ]; then
echo "Error: Config file '${DNSMASQ_CONFIG_FILE}' not found." >&2
exit 1
fi
if [ ! -r "${REPLACEMENTS_FILE}" ]; then
echo "Error: Replacements file '${REPLACEMENTS_FILE}' not found or not readable." >&2
exit 1
fi
cp "${DNSMASQ_CONFIG_FILE}" "${DNSMASQ_CONFIG_FILE}.bak" || {
echo "Error: Failed to create backup." >&2
exit 1
}
while IFS='@@@' read -r old new || [ -n "${old}" ]; do
# Saltar líneas vacías o comentarios
case "${old}" in
""|\#*) continue ;;
esac
# Aplicar sustitución con sed (usando | como delimitador)
if ! sed -i '' "s|${old}|${new}|g" "${DNSMASQ_CONFIG_FILE}"; then
echo "Error: Failed to replace '${old}' with '${new}'." >&2
exit 1
fi
echo "Replaced: '${old}' -> '${new}'"
done < "${REPLACEMENTS_FILE}"
echo "All replacements applied successfully."
}
change_dnsmasq_config()
{
if [ "${ENABLE_DNS}" = "yes" ]; then
enable_dns
fi
if [ "${ENABLE_DHCP}" = "yes" ]; then
enable_dhcp
fi
if [ "${ENABLE_PXE}" = "yes" ]; then
enable_pxe
fi
}
enable_dns()
{
change_config vm_template_files/dnsmasq_conf_dns
echo "dhcp-option=6,\"${JAIL_IP_ADDRESS},1.1.1.1\"" >> "${DNSMASQ_CONFIG_FILE}"
DNSMASQ_LISTS="vm_template_files/dnsmasq_lists.txt"
while IFS='@@@' read -r url file|| [ -n "${url}" ]; do
# Saltar líneas vacías o comentarios
case "${url}" in
""|\#*) continue ;;
esac
curl -L -o "${file}" \
"${{url}}"
done < "${DNSMASQ_LISTS}"
}
enable_dhcp()
{
change_config vm_template_files/dnsmasq_conf_dhcp
}
enable_pxe()
{
#change_config vm_template_files/dnsmasq_conf_pxe
echo "dhcp-option=66,\"0.0.0.0\"" >> "${DNSMASQ_CONFIG_FILE}"
}
#MAIN
#Install package
pkg install dnsmasq
#Apply config
# === Main ===
print_header
# Ask for each service
ENABLE_DHCP="$(ask_yes_no "Enable DHCP server" "n")"
ENABLE_PXE="$(ask_yes_no "Enable PXE boot server" "n")"
change_dnsmasq_config
sysrc dnsmasq_enable="YES"
sysrc dnsmasq_conf="/usr/local/etc/dnsmasq.conf"

View File

@ -1,20 +1,36 @@
#!/bin/sh
#SOURCE: https://docs.docker.com/engine/install/debian/
# https://docs.docker.com/engine/install/linux-postinstall/
export DEBIAN_FRONTEND=noninteractive
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get -y install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
#!/usr/bin/env bash
# SOURCE: https://docs.docker.com/engine/install/debian/
# https://docs.docker.com/engine/install/linux-postinstall/
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
# Remove old conflicting packages
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
apt-get remove -y "$pkg" 2>/dev/null || true
done
# Add Docker's official GPG key
apt-get update
apt-get -y install ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources
# shellcheck disable=SC2027,SC2046 # We handle word splitting safely here
# shellcheck source=/dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update and install Docker
apt-get update
apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Add user to docker group
usermod -aG docker "${USER}"
# Refresh group membership (optional, user may need to log out)
newgrp docker

View File

@ -0,0 +1,24 @@
#!/usr/bin/env bash
#SOURCE: https://docs.docker.com/engine/install/fedora/
# https://docs.docker.com/engine/install/linux-postinstall/
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
dnf -y remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
dnf -y install dnf-plugins-core
dnf-3 config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker
usermod -aG docker "$USER"
echo "To use docker execute :"
echo "newgrp docker"

View File

@ -1,18 +1,50 @@
#!/bin/bash
export DEBIAN_FRONTEND=noninteractive
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker
#!/usr/bin/env bash
# SOURCE: https://docs.docker.com/engine/install/ubuntu/
# https://docs.docker.com/engine/install/linux-postinstall/
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
# Remove old or conflicting packages
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
apt-get remove -y "$pkg" 2>/dev/null || true
done
# Install prerequisites
apt-get update
apt-get install -y ca-certificates curl gnupg
# Create keyrings directory and add Docker GPG key
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# Add Docker repository
# shellcheck source=/dev/null
. /etc/os-release
ARCH=$(dpkg --print-architecture)
CODENAME="$VERSION_CODENAME"
echo "deb [arch=$ARCH signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $CODENAME stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update and install Docker
apt-get update
apt-get install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
# Add user to docker group
usermod -aG docker "$USER"
# Refresh group membership
echo "Docker installation completed."
echo "To use Docker without sudo, run:"
echo " newgrp docker"
echo "Or log out and back"

View File

@ -1,13 +1,17 @@
#!/bin/sh
#!/usr/bin/env bash
#SOURCE: https://about.gitlab.com/install/#debian
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
NET_DEVICE='enp1s0'
GITLAB_URL=$(ip -o -4 addr list ${NET_DEVICE} | awk '{print $4}' | cut -d/ -f1)
#Base dependencies
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates perl
apt-get update
apt-get install -y curl openssh-server ca-certificates perl
#OPTIONAL: postfix
#sudo apt-get install -y postfix
#apt-get install -y postfix
#Add gitlab repo
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo EXTERNAL_URL="${GITLAB_URL}" apt-get install gitlab-ee
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | bash
EXTERNAL_URL="${GITLAB_URL}" apt-get install gitlab-ee

View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
#Source: https://docs.gitlab.com/install/package/almalinux/?tab=Community+Edition
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
NET_DEVICE='enp1s0'
GITLAB_URL=$(ip -o -4 addr list ${NET_DEVICE} | awk '{print $4}' | cut -d/ -f1)
#Enable sshd. enabled on cloud-image by default
#systemctl enable --now sshd
#Set firewall rules
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=ssh
systemctl reload firewalld
#Add repo
curl "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh" | bash
#Install Gitlab CE
EXTERNAL_URL="${GITLAB_URL}" dnf install gitlab-ce

View File

@ -1,12 +0,0 @@
#!/bin/sh
#SOURCE: https://about.gitlab.com/install/#debian
export DEBIAN_FRONTEND=noninteractive
cat <<EOF | sudo tee /etc/apt/preferences.d/pin-gitlab-runner.pref
Explanation: Prefer GitLab provided packages over the Debian native ones
Package: gitlab-runner
Pin: origin packages.gitlab.com
Pin-Priority: 1001
EOF
sudo apt-get update
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get -y install gitlab-runner

View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
#SOURCE: https://about.gitlab.com/install/#debian
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
# cat <<EOF | tee /etc/apt/preferences.d/pin-gitlab-runner.pref
# Explanation: Prefer GitLab provided packages over the Debian native ones
# Package: gitlab-runner
# Pin: origin packages.gitlab.com
# Pin-Priority: 1001
# EOF
apt-get update
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | bash
apt-get -y install gitlab-runner

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
#SOURCE: https://docs.gitlab.com/runner/install/
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash
sudo dnf -Y install gitlab-runner

View File

@ -0,0 +1,60 @@
#!/usr/bin/env sh
#SOURCE: https://docs.gitlab.com/runner/install/
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
#Creating gitlab user
sudo pw group add -n gitlab-runner
sudo pw user add -n gitlab-runner -g gitlab-runner -s /bin/sh
sudo mkdir /home/gitlab-runner
sudo chown gitlab-runner:gitlab-runner /home/gitlab-runner
#Downloading binary and giving permissions
sudo fetch -o /usr/local/bin/gitlab-runner https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/binaries/gitlab-runner-freebsd-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
#Creating logfile and giving permissions
sudo touch /var/log/gitlab_runner.log && sudo chown gitlab-runner:gitlab-runner /var/log/gitlab_runner.log
#Creating rc service
mkdir -p /usr/local/etc/rc.d
sudo sh -c 'cat > /usr/local/etc/rc.d/gitlab_runner' << "EOF"
#!/bin/sh
# PROVIDE: gitlab_runner
# REQUIRE: DAEMON NETWORKING
# BEFORE:
# KEYWORD:
. /etc/rc.subr
name="gitlab_runner"
rcvar="gitlab_runner_enable"
user="gitlab-runner"
user_home="/home/gitlab-runner"
command="/usr/local/bin/gitlab-runner"
command_args="run"
pidfile="/var/run/${name}.pid"
start_cmd="gitlab_runner_start"
gitlab_runner_start()
{
export USER=${user}
export HOME=${user_home}
if checkyesno ${rcvar}; then
cd ${user_home}
/usr/sbin/daemon -u ${user} -p ${pidfile} ${command} ${command_args} > /var/log/gitlab_runner.log 2>&1
fi
}
load_rc_config $name
run_rc_command $1
EOF
sudo chmod +x /usr/local/etc/rc.d/gitlab_runner
echo "Now register a runner and then:"
echo "sudo sysrc gitlab_runner_enable=YES"
echo "sudo service gitlab_runner start"

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
HAPROXY_URL="https://github.com/haproxytech/kubernetes-ingress/releases/download/v1.10.11/haproxy-ingress-controller_1.10.11_Linux_x86_64.tar.gz"
# Install HAProxy
apt update

0
vm_example_scripts/init_freebsd.sh Normal file → Executable file
View File

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
helm repo add jenkins https://charts.jenkins.io
helm repo update
kubectl create namespace jenkins

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
VM_BASE_DIR=${VM_BASE_DIR:-"${HOME}/vms"}
VM_USER="user"
VM=$1

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
apt-get update
apt-get -y install podman buildah

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Exit on error, undefined vars, and pipe failures
set -euo pipefail
dnf update
dnf -y install podman buildah

View File

@ -0,0 +1,62 @@
#!/usr/bin/env sh
# Source: https://podman.io/docs/installation#installing-on-freebsd-140
# Variables
LINE='fdesc /dev/fd fdescfs rw 0 0'
FSTAB="/etc/fstab"
FD_MOUNTPOINT="/dev/fd"
FSTYPE="fdescfs"
SERVICE_NAME='linux'
# Enable Linux compatibility
sysrc linux_enable=YES
# Start the service if not running
if ! service "${SERVICE_NAME}" status >/dev/null 2>&1; then
if ! service "${SERVICE_NAME}" start; then
echo "Error: Cannot start ${SERVICE_NAME}." >&2
exit 1
fi
echo "Service ${SERVICE_NAME} started"
fi
# Add fdescfs to /etc/fstab if not present
if ! grep -q 'fdesc[[:space:]]\+/dev/fd[[:space:]]\+fdescfs[[:space:]]\+rw[[:space:]]\+0[[:space:]]\+0' "$FSTAB"; then
printf '%s\n' "$LINE" | tee -a "$FSTAB" > /dev/null
fi
# Install and enable Podman
pkg install -y podman-suite
service podman enable
# Mount fdescfs if not already mounted
if ! mount | grep -w "${FD_MOUNTPOINT}" | grep -q "$FSTYPE"; then
mount -t fdescfs fdesc /dev/fd
fi
# Configure pf firewall
cp /usr/local/etc/containers/pf.conf.sample /etc/pf.conf
sed -i '' 's/ix0/vtnet0/g' /etc/pf.conf
# Enable pf at boot
if ! grep -q 'pf_load="YES"' "/boot/loader.conf"; then
echo 'pf_load="YES"' | tee -a /boot/loader.conf > /dev/null
fi
# Load pf module and enable local filtering
kldload pf
sysctl net.pf.filter_local=1
if ! grep -q 'net.pf.filter_local=1' "/etc/sysctl.conf.local"; then
echo 'net.pf.filter_local=1' | tee -a /etc/sysctl.conf.local > /dev/null
fi
service pf enable
service pf restart
# Configure storage backend
if pgrep -x zfskern >/dev/null 2>&1; then
zfs create -o mountpoint=/var/db/containers zroot/containers
else
sed -I .bak -e 's/driver = "zfs"/driver = "vfs"/' /usr/local/etc/containers/storage.conf
fi

View File

@ -1,4 +1,4 @@
#!/bin/env bash
#!/usr/bin/env -S bash
source env_scripts/common.sh
source env_scripts/functions.sh
@ -9,30 +9,44 @@ VM_DISK_SIZE=10
# Function to display usage message
usage() {
echo "Usage: $0 create -n NAME [-b BRIDGE] [-r RAM] [-c VCPUS] [-s DISK] [-v]"
echo " $0 delete -n NAME"
echo " $0 info -n NAME"
echo " $0 connect -n NAME"
echo " $0 list"
echo ""
echo "Actions:"
echo " create Create a new virtual machine"
echo " delete Delete a virtual machine"
echo " list List all defined virtual machines"
echo " info Show information about a virtual machine"
echo " connect Connect to the console of a virtual machine"
echo ""
echo "Options for 'create':"
echo " -h Show this help message"
echo " -n NAME Host name (required)"
echo " -b BRIDGE Bridge interface name"
echo " -r RAM RAM in MB (default: ${VM_MEM_SIZE})"
echo " -c VCPUS Number of VCPUs (default: ${VM_VCPUS})"
echo " -s DISK Disk size in GB (default: ${VM_DISK_SIZE})"
echo " -v Verbose mode"
less << EOF
NAME
$0
USAGE
Usage: $0 create -n NAME [-b BRIDGE] [-r RAM] [-c VCPUS] [-s DISK] [-v]
$0 delete NAME
$0 info NAME
$0 connect NAME
$0 install NAME
$0 list
ACTIONS
create Create a new virtual machine
delete Delete a virtual machine
list List all defined virtual machines
info Show information about a virtual machine
connect Connect to the console of a virtual machine
install Install specific software into an existing VM
OPTIONS
-h Show this help message
-n NAME Host name (required)
-b BRIDGE Bridge interface name
-H Host Only Network
-r RAM RAM in MB (default: ${VM_MEM_SIZE})
-c VCPUS Number of VCPUs (default: ${VM_VCPUS})
-s DISK Disk size in GB (default: ${VM_DISK_SIZE})
-v Verbose mode
AUTHOR
Victor Gracia Enguita <victor@burufalla.ovh>
COPYRIGHT
This is free software; see the source for copying conditions.
EOF
exit 1
}
# Check if at least one argument is provided
if [ $# -eq 0 ]; then
usage
@ -46,8 +60,8 @@ case "${ACTION}" in
# Parse options for create command
VERBOSE=false
NAME_SET=false
while getopts ":hn:b:r:c:s:v" opt; do
source env_scripts/common.sh
while getopts ":hn:b:Hr:c:s:v" opt; do
case "${opt}" in
h)
usage
@ -57,8 +71,12 @@ case "${ACTION}" in
NAME_SET=true
;;
b)
BRIDGE_INTERFACE="${OPTARG}"
VM_BRIDGE_INT="${OPTARG}"
VM_NETWORK_TYPE="bridge"
;;
H)
VM_NETWORK_TYPE="isolated"
;;
r)
VM_MEM_SIZE="${OPTARG}"
;;
@ -87,26 +105,35 @@ case "${ACTION}" in
echo "Error: The -n option is required for create action." >&2
usage
fi
source env_scripts/common.sh
detect_distro
#Check network type
vm_net_set_bridge_mode
vm_net_set_network_type
#Check host os for guest debian type
check_host_os
#Read os_options.json and generate guests menu
#Select guest
show_vm_menu
#Download cloud image
vm_download_base_image
#Compare hashes
compare_checksum
#Create guest image
vm_create_guest_image
#Set guest type based on check_host_os
vm_set_guest_type
#set image permissions
chown_image_permissions
if [[ "$VM_OS_TYPE" == "BSD" && "${VM_OS_VARIANT}" == *"openbsd"* ]]; then
generate_openbsd_image
else
#Download cloud image
vm_download_base_image
#Compare hashes
compare_checksum
#Create guest image
vm_create_guest_image
fi
#Generate ssh key
vm_generate_ssh_hey
#Generate meta-data file for VM
vm_gen_meta_data
#Generate user-data file for VM
vm_gen_linux_user_data
vm_gen_user_data
#Install VM
vm_guest_install
;;
@ -119,8 +146,6 @@ case "${ACTION}" in
fi
VM_HOSTNAME="$1"
source env_scripts/common.sh
echo "Action: ${ACTION}"
echo "VM Name: ${VM_HOSTNAME}"
if [[ "${ACTION}" == 'delete' ]]; then
vm_delete ${VM_HOSTNAME}
elif [[ "${ACTION}" == 'info' ]]; then
@ -129,9 +154,12 @@ case "${ACTION}" in
vm_connect ${VM_HOSTNAME}
fi
;;
install)
VM_HOSTNAME="$1"
show_software_menu
vm_install_utils $VM_HOSTNAME
;;
list)
#echo "Action: list"
vm_list
;;

View File

@ -0,0 +1,3 @@
#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h@@@dhcp-range=${LOCAL_NETWORK}.${LOCAL_NETWORK_DHCP_FIRST_IP},${LOCAL_NETWORK_DHCP_LAST_IP},${LOCAL_NETWORK_DHCP_LEASE}
#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8@@@dhcp-option=121,${LOCAL_NETWORK_RANGE},${LOCAL_NETWORK_GATEWAY}
#dhcp-option=3,1.2.3.4@@@dhcp-option=3,${LOCAL_NETWORK_GATEWAY}

View File

@ -0,0 +1,11 @@
#interface=@@@interface=${INTERFACE}
#domain-needed@@@domain-needed
#bogus-priv@@@bogus-priv
#local=/localnet/@@@local=/local/
#listen-address=@@@listen-adress=${JAIL_IP_ADDRESS}
#bind-interfaces@@@bind-interfaces
#no-hosts@@@no-hosts
#cache-size=150@@@cache-size=1000
#conf-dir=/etc/dnsmasq.d/,*.conf@@@conf-dir=/usr/local/etc/dnsmasq.conf.d/,*.conf
#conf-file=/usr/local/share/dnsmasq/trust-anchors.conf@@@conf-file=/usr/local/share/dnsmasq/trust-anchors.conf
#dnssec@@@dnssec

View File

@ -0,0 +1,3 @@
#enable-tftp@@@enable-tftp
#tftp-root=/var/ftpd@@@tftp-root=/var/lib/tftp
#dhcp-boot=pxelinux.0@@@dhcp-boot=netboot.xyz.kpxe

View File

@ -0,0 +1,3 @@
https://blocklistproject.github.io/Lists/dnsmasq-version/ads-dnsmasq.txt@@@${DNSMASQ_DCONF_DIR}/01-ads-dnsmasq.conf
https://blocklistproject.github.io/Lists/dnsmasq-version/facebook-dnsmasq.txt@@@${DNSMASQ_DCONF_DIR}/02-facebook-dnsmasq.conf
https://blocklistproject.github.io/Lists/dnsmasq-version/tracking-dnsmasq.txt@@@${DNSMASQ_DCONF_DIR}/03-tracking-dnsmasq.conf