Skip to content

Instantly share code, notes, and snippets.

@TroyKomodo
Created December 4, 2021 03:35
Show Gist options
  • Save TroyKomodo/eb2df4fda26922ecee110fbfb316c017 to your computer and use it in GitHub Desktop.
Save TroyKomodo/eb2df4fda26922ecee110fbfb316c017 to your computer and use it in GitHub Desktop.
A script to create a virtual machine
#!/bin/bash
echo "Configure a virtual machine!";
NAME=""
HOSTNAME=""
SSH=""
PASSWORD=""
SSH_PWAUTH="true"
ROOT_LOGIN="yes"
NETWORK=""
MEMORY=""
CPU=""
DISK=""
RELEASE=""
NETWORK=""
read -p "Name: " NAME
if [ -z "${NAME}" ]; then
echo "A vm name is required."
exit 1
fi
read -p "Hostname: " HOSTNAME
if [ -z "${HOSTNAME}" ]; then
HOSTNAME="ubuntu"
fi
read -p "SSH Public Key (blank for password auth): " SSH
if [ -z "${SSH}" ]; then
read -p "Password (blank for random): " PASSWORD
if [ -z "${PASSWORD}" ]; then
PASSWORD=$(cat /dev/urandom | tr -dc '[:alpha:]' | fold -w ${1:-20} | head -n 1)
fi
else
ssh-keygen -l -f $SSH 2> /dev/null
RET=$?
if [ $RET -ne 0 ]; then
echo "$SSH is not a valid ssh public key"
exit 1
fi
SSH=$(cat $SSH)
SSH=$(printf "ssh_authorized_keys:\n - $SSH")
SSH_PWAUTH="false"
ROOT_LOGIN="without-password"
PASSWORD=$(cat /dev/urandom | tr -dc '[:alpha:]' | fold -w ${1:-20} | head -n 1)
fi
read -p "Network Config: " NETWORK_FILE
[ -z "${NETWORK_FILE}" ] || NETWORK=" --network-config=$NETWORK_FILE"
read -p "Bridge: " BRIDGE
[ -z "${BRIDGE}" ] || BRIDGE=" --bridge=$BRIDGE"
while true; do
read -p "Memory (MB): " MEMORY
if [ -z "${MEMORY}" ]; then
echo "Using default memory: 4096MB"
MEMORY="4096"
fi
[[ $MEMORY =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; continue; }
break
done
while true; do
read -p "CPU Cores: " CPU
if [ -z "${CPU}" ]; then
echo "Using default CPU cores: 2"
CPU="2"
fi
[[ $CPU =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; continue; }
break
done
while true; do
read -p "Disk (GB): " DISK
if [ -z "${DISK}" ]; then
echo "Using default Disk: 40GB"
DISK="40"
fi
[[ $DISK =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; continue; }
break
done
echo "
Ubuntu Releases:
1. 16.04 LTS Xenial Xerus
2. 18.04 LTS Bionic Beaver
3. 18.10 Cosmic Cuttlefish
4. 19.04 Disco Dingo
5. 19.10 Eoan Ermine
6. 20.04 LTS Focal Fossa
7. 20.10 Groovy Gorilla
8. 21.04 Hirsute Hippo
9. 21.10 Impish Indri
"
while true; do
read -p "Release (default 9): " RELEASE
if [ -z "${RELEASE}" ]; then
echo "Using default Ubuntu 21.10 Impish Indri"
RELEASE="9"
fi
[[ $RELEASE =~ ^[0-9]+$ ]] || { echo "Please enter a valid version number"; continue; }
if ((RELEASE == 1)); then
RELEASE="xenial"
elif ((RELEASE == 2)); then
RELEASE="bionic"
elif ((RELEASE == 3)); then
RELEASE="cosmic"
elif ((RELEASE == 4)); then
RELEASE="disco"
elif ((RELEASE == 5)); then
RELEASE="eoan"
elif ((RELEASE == 6)); then
RELEASE="focal"
elif ((RELEASE == 7)); then
RELEASE="groovy"
elif ((RELEASE == 8)); then
RELEASE="hirsute"
elif ((RELEASE == 9)); then
RELEASE="impish"
else
echo "Version number out of range, 1-9"
continue
fi
break;
done
uvt-simplestreams-libvirt sync --source https://cloud-images.ubuntu.com/minimal/releases/ release=${RELEASE} arch=amd64
RET=$?
if [ $RET -ne 0 ]; then
echo "$RELEASE was not able to be downloaed."
exit 1
fi
CONFIG=$(cat /dev/urandom | tr -dc '[:alpha:]' | fold -w ${1:-20} | head -n 1).yaml;
cat > ./${CONFIG} << EOF
#cloud-config
hostname: ${HOSTNAME}
ssh_pwauth: ${SSH_PWAUTH}
disable_root: false
package_update: true
package_upgrade: true
chpasswd:
expire: false
list:
- root:${PASSWORD}
${SSH}
runcmd:
- [ userdel, -r, -f, ubuntu ]
- [ wget, -O, /tmp/install.sh, https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh ]
- [ chmod, +x, /tmp/install.sh ]
- [ runuser, -l, root, -c, '/tmp/install.sh --unattended' ]
- [ rm, install.sh ]
- [ usermod, --shell, /bin/zsh, root]
- [ perl, -i, -pe, 's/#PermitRootLogin .*/PermitRootLogin ${ROOT_LOGIN}/', /etc/ssh/sshd_config ]
- [ perl, -i, -pe, 's/#TCPKeepAlive .*/TCPKeepAlive yes/', /etc/ssh/sshd_config ]
- [ perl, -i, -pe, 's/#ClientAliveInterval .*/ClientAliveInterval 60/', /etc/ssh/sshd_config ]
- [ reboot ]
packages:
- git
- vim
- openssh-server
- screen
- ufw
- iputils-ping
- zsh
- zip
- unzip
- curl
- wget
- perl
EOF
uvt-kvm create --memory=${MEMORY} --disk=${DISK} --cpu=${CPU}${BRIDGE}${NETWORK} --user-data=./${CONFIG} ${NAME} arch="amd64" release=${RELEASE} label="minimal release";
RET=$?
if [ $RET -ne 0 ]; then
rm ./${CONFIG}
exit 1
fi
cat > ./${NAME}.configure << EOF
Created Virtual Machine $NAME
To remove or destroy the Virtual Machine type
uvt-kvm destroy $NAME
--------------------------------------------------------
The login details are:
username: root
password: $PASSWORD
--------------------------------------------------------
# ${CONFIG}
$(cat ./${CONFIG})
# ${NETWORK_FILE:-'no network file specified'})
$(cat ./${NETWORK_FILE:-'/dev/null'})
# command used
uvt-kvm create --memory=${MEMORY} --disk=${DISK} --cpu=${CPU}${BRIDGE}${NETWORK} --user-data=./${CONFIG} ${NAME} arch="amd64" release=${RELEASE} label="minimal release"
EOF
head ./${NAME}.configure
rm ./${CONFIG}
version: 2
ethernets:
enp1s0:
addresses:
- 192.168.0.10/29 # ipv4 external
- 2a01:4f8::3/64 # ipv6 external
routes:
- on-link: true # required for ipv4 external
to: 0.0.0.0/0
via: 192.168.0.9 # ip of host on this subnet
- on-link: true # required for ipv6 external
to: ::/0
via: 2a01:4f8::2 # ip on host with this subnet
gateway6: 2a01:4f8::2 # required for ipv6 external (ip on host with this subnet)
nameservers:
addresses:
- 1.1.1.1 # required for ipv4 external
- 2606:4700:4700::1111 # required for ipv6 external
- 1.0.0.1 # required for ipv4 external
- 2606:4700:4700::1001 # required for ipv6 external
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment