2025-03-23 06:12:34 -05:00
#!/bin/bash
cd " $( dirname " $( readlink -f " $0 " ) " ) "
2025-03-28 20:58:33 -05:00
#define defaults
2025-03-23 06:24:25 -05:00
cpu = 1
2025-03-28 20:58:33 -05:00
memory = 1
2025-03-23 06:24:25 -05:00
root_disk = 10
2025-03-23 06:12:34 -05:00
variant = "archlinux"
2025-03-28 20:58:33 -05:00
path = "/virtual/disks/"
2025-03-23 06:12:34 -05:00
dhcp_opts = ""
2025-03-23 06:35:03 -05:00
ssh_key_dir = "../../identity_files"
2025-03-28 20:58:33 -05:00
dhcp_dir = "../../dhcp_files"
2025-03-23 06:12:34 -05:00
mac = 52:54:00:` openssl rand -hex 1` :` openssl rand -hex 1` :` openssl rand -hex 1`
branch = "prod"
2025-03-28 20:58:33 -05:00
deflate = "y"
2025-03-29 16:59:44 -05:00
ansible = "y"
2025-03-28 20:58:33 -05:00
#get variables
numre = '^[0-9]+$'
macre = '^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$'
ipsegre = '^[0-255]$'
2025-03-23 06:12:34 -05:00
2025-03-28 20:58:33 -05:00
while true; do read -p "Name of new vm/server (caps allowed, not fqdn): " v; if [ -z $v ] ; then echo "error: name is required" ; else name = $v ; break; fi ; done
while true; do read -p " Number of CPU cores (default $cpu ): " v; if [ -z $v ] ; then break; else if ! [ [ $v = ~ $numre ] ] ; then echo "error: not a number" ; else cpu = $v ; break; fi ; fi ; done
while true; do read -p " Ram in GB (default $memory ): " v; if [ -z $v ] ; then break; else if ! [ [ $v = ~ $numre ] ] ; then echo "error: not a number" ; else memory = $v ; break; fi ; fi ; done
while true; do read -p " Root disk size in GB (default $root_disk ): " v; if [ -z $v ] ; then break; else if ! [ [ $v = ~ $numre ] ] ; then echo "error: not a number" ; else root_disk = $v ; break; fi ; fi ; done
2025-03-29 17:11:24 -05:00
while true; do read -p " Path to store root disk (default $path ): " v; if [ -z $v ] ; then path = " $path / $name .qcow2 " ; break; else if ! [ -d $v ] ; then echo "error: not a directory" ; else path = " $v / $name .qcow2 " ; break; fi ; fi ; done
2025-03-28 20:58:33 -05:00
variant = $( dialog --clear --title "Select Linux variant to use" --menu "Choose one of the following options:" 15 40 4 \
archlinux "Arch Linux" \
alma "Alma Linux 9" \
2>& 1 >/dev/tty) ; clear
while true; do read -p " Mac address (default $mac ): " v; if [ -z $v ] ; then break; else if ! [ [ $v = ~ $macre ] ] ; then echo "error: invalid mac address" ; else mac = $v ; break; fi ; fi ; done
#add subnet list
eval "dhcp_sets=(`grep " #" $dhcp_dir/subnets/172.* | grep -o 172.* | sort -t . -k 1,1n -k 2,2n -k 3,3n | sed -e "s/:# /.* \'/" | sed -e "s/$/\'/"`)"
subnet = $( dialog --clear --title "Select subnet to use" --menu "Choose one of the following: " 20 100 10 " ${ dhcp_sets [@] } " 2>& 1 >/dev/tty) ; subnet = ` echo $subnet | grep -oP "172.16.\d+" ` ; clear;
while true; do read -p "Specify last segment of IP (defaults to next available): " v; if [ -z $v ] ; then break; else if ! [ [ $v = ~ $numre ] ] ; then echo "error: not a number" ; else ip = $v ; break; fi ; fi ; done
while true; do read -p " Specify branch of build_ansible to use (defult $branch ): " v; if [ -z $v ] ; then break; else branch = $v ; break; fi ; done
while true; do read -p "Full path to extra disk to attach (if applicable, default none): " v; if [ -z $v ] ; then break; else if ! [ -f $v ] ; then echo "error: file doesn't exist" ; else attach = $v ; break; fi ; fi ; done
while true; do read -p " Autodeflate memory on use y/n (default $deflate )? " v; if [ -z $v ] ; then break; elif [ " $v " = = "y" ] ; then break; elif [ " $v " = = "n" ] ; then deflate = $v ; break; else echo "error: select y or n" ; fi ; done
2025-03-29 16:59:44 -05:00
while true; do read -p " Autorun ansible build script (default $ansible )? " v; if [ -z $v ] ; then break; elif [ " $v " = = "y" ] ; then break; elif [ " $v " = = "n" ] ; then ansible = $v ; break; else echo "error: select y or n" ; fi ; done
2025-03-28 14:49:26 -05:00
2025-03-28 20:58:33 -05:00
echo ""
echo " Name: $name "
echo " CPU: $cpu "
echo " Ram: $memory "
echo " Root Disk: $root_disk "
echo " Path: $path "
echo " Variant: $variant "
echo " Mac: $mac "
echo " Subnet: $subnet "
echo " IP: $ip "
echo " Branch: $branch "
echo " Attach: $attach "
echo " Deflate: $deflate "
2025-03-29 16:59:44 -05:00
echo " Run Ansible: $ansible "
2025-03-28 20:58:33 -05:00
echo ""
2025-03-23 06:12:34 -05:00
2025-03-28 20:58:33 -05:00
read -p "Is this correct (y/n)? " v; if [ " $v " != "y" ] ; then "Exiting, restart to reenter info" ; exit; fi
2025-03-23 06:12:34 -05:00
2025-03-28 20:58:33 -05:00
if [ -n $subnet ] ; then dhcp_opts = " -s $subnet " ; fi
if [ -n $ip ] ; then dhcp_opts += " -i $ip " ; fi
2025-03-23 06:12:34 -05:00
lname = ` echo $name | tr '[:upper:]' '[:lower:]' `
img = ` ./shared_scripts/download_install_image.sh $variant `
2025-03-29 17:02:50 -05:00
memory = $(( memory*1024))
2025-03-23 06:12:34 -05:00
#update DHCP
./shared_scripts/update_dhcp.sh $dhcp_opts $lname
2025-03-23 06:24:25 -05:00
# determine if extra disk should be attached
if [ -n " $attach " ] ; then attach = " --disk ${ attach } ,discard=unmap " ; fi
2025-03-28 14:49:26 -05:00
#determine if deflate should be on
2025-03-28 20:58:33 -05:00
if [ [ " $deflate " = = "y" ] ] ; then deflate = "--memballoon model=virtio,autodeflate=on" ; else deflate = "--memballoon model=virtio" ; fi
2025-03-28 15:08:09 -05:00
case " $variant " in
"archlinux" )
# create cloud-init - replace by grabbing these directly from git
mkdir -p /tmp/cloud-init
echo " #cloud-config
2025-03-23 06:59:37 -05:00
- name: root
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILG56T1k766Cru14kyXI8WXSJwlO2sVhmH6JeRWy+mfe root@host.actcur.com" > /tmp/cloud-init/user-data
2025-03-28 14:49:26 -05:00
# create new base VM
virt-install --name= $name --vcpus= $cpu --memory= $memory --disk path = $path ,size= $root_disk ,sparse= true,discard= unmap,bus= scsi ${ attach } --os-variant= $variant --network bridge = br1,mac= $mac $deflate --cdrom= $img --graphics vnc --cloud-init user-data= "/tmp/cloud-init/user-data" --autoconsole= none
#wait until server is available
echo "Waiting for server to be available"
while true
do
sleep 1
ping -c 1 ${ lname } .actcur.com 2>& 1 > /dev/null
if [ $? -eq 0 ] ; then break; fi
done
echo "server up, waiting for ssh"
sleep 30
sed " s/REPLACE_HOSTNAME/ ${ lname } .actcur.com/g " ../base_files/user_configuration.json > /tmp/user_configuration.json
rs = $(( root_disk*1024-206))
sed -i " s/REPLACE_SIZE/ ${ rs } /g " /tmp/user_configuration.json
ssh-keygen -R ${ lname } .actcur.com
ssh-keyscan ${ lname } .actcur.com | grep -v "#" | grep "ecdsa-sha2-nistp256" >> ~/.ssh/known_hosts
scp -i $ssh_key_dir /id_arch_builder /tmp/user_configuration.json ${ lname } .actcur.com:/tmp/user_configuration.json
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "systemctl mask reflector.service; echo 'Server = https://pkg.actcur.com/repo/archlinux/\$repo/os/\$arch' > /etc/pacman.d/mirrorlist"
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "archinstall --config /tmp/user_configuration.json --silent"
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "ln -s /usr/lib/systemd/system/sshd.service /mnt/archinstall/etc/systemd/system/multi-user.target.wants/sshd.service"
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "cp -r /root/.ssh/ /mnt/archinstall/root/;reboot"
; ;
2025-03-23 06:12:34 -05:00
"alma" )
2025-03-23 06:24:25 -05:00
# set up kickstart file
sed " s/REPLACE_HOSTNAME/ ${ lname } .actcur.com/g " ../base_files/kickstart.cfg > /tmp/kickstart.cfg
2025-03-23 06:12:34 -05:00
2025-03-23 06:24:25 -05:00
# create new VM
2025-03-28 14:49:26 -05:00
virt-install --name= $name --vcpus= $cpu --memory= $memory --disk path = $path ,size= $root_disk ,sparse= true,discard= unmap,bus= scsi --os-variant= almalinux9 --network bridge = br1,mac= $mac $deflate --location= $img --graphics vnc --initrd-inject /tmp/kickstart.cfg --extra-args "inst.ks=file:/kickstart.cfg" --autoconsole= none
2025-03-23 06:12:34 -05:00
2025-03-23 06:24:25 -05:00
echo "server up, waiting for install to complete"
2025-03-23 06:12:34 -05:00
2025-03-23 06:24:25 -05:00
sleep 60
2025-03-23 06:12:34 -05:00
2025-03-23 06:24:25 -05:00
# wait for install to complete and server to shut down/reboot
while true
do
sleep 1
ping -c 1 ${ lname } .actcur.com 2>& 1 > /dev/null
if [ $? -ne 0 ] ; then break; fi
done
; ;
esac
2025-03-23 06:12:34 -05:00
sleep 10
virsh start $name
#wait until server is available
echo "Waiting for server to be available"
while true
do
sleep 1
ping -c 1 ${ lname } .actcur.com 2>& 1 > /dev/null
if [ $? -eq 0 ] ; then break; fi
done
echo "server up, waiting for ssh"
sleep 30
ssh-keygen -R ${ lname } .actcur.com
ssh-keyscan ${ lname } .actcur.com | grep -v "#" | grep "ecdsa-sha2-nistp256" >> ~/.ssh/known_hosts
# install some dependencies
2025-03-23 06:24:25 -05:00
case " $variant " in
"arch" )
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "pacman -Sy --noconfirm ansible-core git"
; ;
"alma" )
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "dnf config-manager --set-enabled crb;yum install -y ansible-core git epel-release"
; ;
esac
2025-03-23 06:12:34 -05:00
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "ansible-galaxy collection install community.general"
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "ansible-galaxy collection install community.crypto"
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "ansible-galaxy collection install ansible.posix"
# run ansible
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com " mkdir /ansible/; curl -k 'https://git.actcur.com/actcur-ansible/playbook-builder/raw/branch/ $branch /build_ansible.sh' -H 'accept: application/raw' -o /ansible/build_ansible.sh;echo " $branch " > /ansible/branch;/bin/bash /ansible/build_ansible.sh"
2025-03-29 16:59:44 -05:00
if [ [ " $deflate " = = "y" ] ] ; then
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "/bin/bash /ansible/build_ansible.sh"
fi
2025-03-23 06:12:34 -05:00
ssh -i $ssh_key_dir /id_arch_builder ${ lname } .actcur.com "git config --global user.email 'ejparker@actcur.com';git config --global user.name 'Beth Parker'"
systemctl restart nfs-server