summaryrefslogtreecommitdiff
path: root/others/vm.sh
diff options
context:
space:
mode:
Diffstat (limited to 'others/vm.sh')
-rwxr-xr-xothers/vm.sh316
1 files changed, 0 insertions, 316 deletions
diff --git a/others/vm.sh b/others/vm.sh
deleted file mode 100755
index ceafde4..0000000
--- a/others/vm.sh
+++ /dev/null
@@ -1,316 +0,0 @@
1#!/bin/bash
2
3help(){
4 echo -e "\n$0
5 info
6 create\n -vcpu\n -ram \n -disk \n -ssh-keys-dir \n -add-disk-block\n -public-ssh-port
7 manage\n -start\n -shutdown\n -reboot\n -kill\n -erase
8 disk\n -attach\n -detach\n -resize\n"
9 exit 1
10}
11
12case "$1" in
13 "create")
14 if [[ $# -lt 2 ]]; then
15 echo ""
16 echo -e "$0 $1 [VM_NAME]"
17 echo -e "default: -vcpu 8 -ram 8 -disk 60 --ssh-keys-dir keys/"
18 echo -e "args[GB]:\n -vcpu\n -ram \n -disk \n -ssh-keys-dir \n -add-disk-block\n -public-ssh-port)"
19 echo ""
20 exit 1
21 fi
22
23 VM_NAME=$2
24 VCPU=8
25 RAM_GB=8000 #memory is noted as mb in the virt-install program
26 DISK_GB=64
27 SSH_KEYS_DIR="keys/"
28 DISK_BLOCK_GB=0
29 PSP=${PSP:-0}
30
31 while [[ $# -gt 0 ]]; do
32 case "$1" in
33 create)
34 shift 2
35 ;;
36 -vcpu)
37 VCPU=$2
38 shift 2
39 ;;
40 -ram)
41 RAM_GB=$(($2*1000))
42 shift 2
43 ;;
44 -disk)
45 DISK_GB=$2
46 shift 2
47 ;;
48 -ssh-keys-dir)
49 SSH_KEYS_DIR=$2
50 shift 2
51 ;;
52 -add-disk-block)
53 DISK_BLOCK_GB=$2
54 shift 2
55 ;;
56 -public-ssh-port)
57 PSP=$2
58 shift 2
59 ;;
60 *)
61 echo "Unknown argument: $1"
62 exit 1
63 ;;
64 esac
65 done
66 download_url="https://download.rockylinux.org/pub/rocky/9.3/images/x86_64/Rocky-9-GenericCloud-LVM-9.3-20231113.0.x86_64.qcow2"
67 dir_path="/var/lib/libvirt/images/"
68 src_file="/var/lib/libvirt/images/Rocky9.3.qcow2"
69 seed_iso="/var/lib/libvirt/images/seed.iso"
70 packages=("nc" "htop" "wireguard-tools" "bind-utils" "tmux" "net-tools" "curl" "mlocate" "dnsmasq" "qemu-kvm" "libvirt" "libvirt-client" "bridge-utils" "virt-install" "virt-manager" "genisoimage")
71 NEW_IMG_PATH="/var/lib/libvirt/images/${VM_NAME}.qcow2"
72 XML_PATH="/tmp/${VM_NAME}.xml"
73 DISK_BLOCK_GB_BASE_PATH="/var/lib/libvirt/images/${VM_NAME}-vm-disks/"
74 DISK_BLOCK_GB_PATH="${DISK_BLOCK_GB_BASE_PATH}${VM_NAME}-vda-${DISK_BLOCK_GB}G.qcow2"
75 ssh_private=$(cat /home/s22/man1)
76
77 function check_package_installed() {
78 local package_name=$1
79 rpm -q "$package_name" &> /dev/null
80 }
81
82 for package in "${packages[@]}"; do
83 if ! check_package_installed "$package"; then
84 #echo "Downloading packages..."
85 sudo dnf install -y "$package" &> /dev/null
86 fi
87 done
88
89 [ ! -d $dir_path ] && mkdir -p $dir_path &> /dev/null
90 [ ! -f "$src_file" ] && (wget -O "$src_file" "$download_url" &> /dev/null || { echo "Failed to download Rocky"; exit 1; })
91
92 echo -e "#cloud-config\nusers:\n - name: root\n ssh-authorized-keys:" > user-data
93
94 for key in "$SSH_KEYS_DIR"/*.pub; do
95 echo " - $(cat "$key")" >> user-data
96 done
97
98 echo " sudo: ['ALL=(ALL) NOPASSWD:ALL']
99 groups: sudo
100 shell: /bin/bash" >> user-data
101
102 if [ "$PSP" -ne 0 ]; then
103 echo "write_files:" >> user-data
104 echo " - path: /root/man1" >> user-data
105 echo " content: |" >> user-data
106 while read -r line; do
107 echo " $line" >> user-data
108 done <<< "${ssh_private}"
109 fi
110
111 echo 'runcmd:' >> user-data
112 #echo ' - [ /usr/bin/wget, "http://example.com/file", -O, /tmp/examplefile ]' >> user-data
113 #echo ' - touch /root/test1.txt' >> user-data
114 if [ "$DISK_BLOCK_GB" -ne 0 ]; then
115 echo "echo to disksetup in vm"
116 echo "vm name 1 ${VM_NAME}"
117 echo ' - echo "#!/bin/bash" > /root/disk-setup.sh' >> user-data
118 # echo ' - echo "sleep 40;" >> /root/disk-setup.sh' >> user-data
119 echo " - echo \"DISK='/dev/vda'; MOUNT_PATH='/home/${VM_NAME}-vda-${DISK_BLOCK_GB}G';\" >> /root/disk-setup.sh" >> user-data
120 echo " - echo '[ ! -d \$MOUNT_PATH ] && mkdir -p \$MOUNT_PATH;' >> /root/disk-setup.sh" >> user-data
121 echo " - echo 'blkid | grep -q \$DISK || mkfs.ext4 \$DISK;' >> /root/disk-setup.sh" >> user-data
122 echo " - echo 'grep -q \$DISK /etc/fstab || echo \"\$DISK \$MOUNT_PATH ext4 defaults,nofail 0 0\" >> /etc/fstab;' >> /root/disk-setup.sh" >> user-data
123 echo ' - echo "mount -a;" >> /root/disk-setup.sh' >> user-data
124 echo ' - echo "systemctl daemon-reload" >> /root/disk-setup.sh' >> user-data
125 echo ' - chmod +x /root/disk-setup.sh' >> user-data
126 echo ' - /root/disk-setup.sh' >> user-data
127 echo ' - rm -f /root/disk-setup.sh' >> user-data
128 fi
129
130 if [ "$PSP" -ne 0 ]; then
131 echo ' - chmod 600 /root/man1' >> user-data
132 #kill ssh and reconnect every 4 hours
133 ##echo " - (echo \"0 */4 * * * PIDS=\\\$(pgrep -f \\\"ssh.*root@64.176.179.97\\\"); if [ -n \\\"\\\${PIDS}\\\" ]; then kill \\\${PIDS}; fi; /usr/bin/ssh -fN -i /root/man1 -R ${PSP}:localhost:22 -o StrictHostKeyChecking=no root@64.176.179.97\") | crontab -" >> user-data
134 echo " - (echo \"* * * * * /root/initial.sh\") | crontab -" >> user-data
135 echo " - echo 'PIDS=\$(pgrep -f \"ssh.*root@64.176.179.97\"); if [ -z \"\${PIDS}\" ]; then /usr/bin/ssh -fN -i /root/man1 -R ${PSP}:localhost:22 -o StrictHostKeyChecking=no root@64.176.179.97; fi' > /root/initial.sh" >> user-data
136 echo " - chmod +x /root/initial.sh" >> user-data
137 echo " - /root/initial.sh" >> user-data
138 fi
139
140 #nofail is present in the fstab which means that boot will continue even if it fails to mount
141 echo ' - growpart /dev/sda 4 ' >> user-data #do note that restart is required for the system to register the increased disk size
142 echo ' - sudo lvresize -l +100%FREE /dev/rocky/lvroot' >> user-data
143 echo ' - sudo dnf install -y epel-release dnf-utils' >> user-data
144 echo ' - sudo dnf install -y nc xclip tmux htop tar tree wget curl mlocate nano vim unzip net-tools git python3 python3-pip make'>> user-data
145 echo ' - touch /root/runcmd_done' >> user-data
146
147 echo -e "instance-id: iid-ihatecs\nlocal-hostname: cloudimg" > meta-data
148
149 genisoimage -output "$seed_iso" -volid cidata -joliet -rock user-data meta-data &> /dev/null || { echo "Failed to create seed.iso."; exit 1; }
150
151 cp $src_file $NEW_IMG_PATH &> /dev/null || { echo "Failed to create a new image."; exit 1; }
152
153 if virsh list --all | grep -q "$VM_NAME"; then
154 echo -e "\n$VM_NAME already exist. Delete it using \n$0 manage -erase $VM_NAME\nExiting..."
155 exit 1
156 fi
157
158 sudo virt-install --name $VM_NAME \
159 --vcpus $VCPU \
160 --ram $RAM_GB \
161 --disk path=$NEW_IMG_PATH,size=$DISK_GB,format=qcow2 \
162 --disk path=$seed_iso,device=cdrom \
163 --os-type linux \
164 --os-variant rhl9 \
165 --virt-type kvm \
166 --graphics none \
167 --network bridge=virbr0,model=virtio \
168 --print-xml > $XML_PATH || { echo "Failed to print XML."; exit 1; }
169
170 sudo virsh define $XML_PATH &> /dev/null || { echo "Failed to define the new VM."; exit 1; }
171
172 sudo qemu-img resize $NEW_IMG_PATH +$DISK_GB"G" #&> /dev/null
173
174 virsh start $VM_NAME
175 echo ""
176
177 if [ $DISK_BLOCK_GB -ne 0 ]; then
178 mkdir -p $DISK_BLOCK_GB_BASE_PATH
179 qemu-img create -f qcow2 $DISK_BLOCK_GB_PATH "${DISK_BLOCK_GB}G"
180 virsh attach-disk $VM_NAME $DISK_BLOCK_GB_PATH vda --cache none --subdriver qcow2
181 fi
182
183 message="waiting 29s to begin finding ip address..."
184 duration=29
185 for ((i=$duration; i>=1; i--)); do
186 printf "\r%s%2ds" "$message" $i
187 sleep 1
188 done
189 echo
190
191 while true; do
192 OUTPUT=$($0 info | grep "$VM_NAME")
193 if [[ "$OUTPUT" != "" ]]; then
194 IP_ADDRESS=$(echo "$OUTPUT" | grep -oP '\d+\.\d+\.\d+\.\d+')
195 # If IP address is found and is not empty
196 if [[ ! -z "$IP_ADDRESS" ]]; then
197 echo -e "\nIP address of $VM_NAME is:\n$IP_ADDRESS"
198 break
199 else
200 echo "IP address for $VM_NAME not found. Retrying in 1 second..."
201 sleep 1
202 fi
203 else
204 echo "$VM_NAME not found. Exiting..."
205 exit 1
206 fi
207 done
208
209 #do take note that df -h will not reflect until reboot
210
211 ;;
212 "manage")
213 if [[ $# -lt 2 ]]; then
214 echo ""
215 echo -e "$0 $1 arg [VM_1] [VM_2] [VM_3] \n$0 $1 arg --all"
216 echo -e "args:\n -start\n -shutdown\n -kill\n -erase "
217 echo ""
218 exit 1
219 fi
220
221 arg=$2
222 shift 2
223
224 if [[ "$1" == "--all" ]]; then
225 vms=$(virsh list --all --name) # List all running VMs by name
226 set -- $vms # Set the positional parameters to the VM names
227 fi
228
229 case $arg in
230 "-shutdown")
231 for vm in "$@"; do
232 virsh shutdown "$vm" > /dev/null 2>&1
233 printf "%-50s%10s\n" "Shutting down $vm..." $([[ $? -eq 0 ]] && echo "Successful" || echo "Failed")
234 done
235 ;;
236 "-kill")
237 for vm in "$@"; do
238 virsh destroy "$vm" > /dev/null 2>&1
239 printf "%-50s%10s\n" "Destroying $vm..." $([[ $? -eq 0 ]] && echo "Successful" || echo "Failed")
240 done
241 ;;
242 "-erase")
243 echo -e "\nWARNING: THIS IS IRREVERSIBLE. Sleeping for 10 seconds. Ctrl-C to stop. WARNING.\n"
244 sleep 10
245 echo -e "\nErasing image(s) from /var/lib/libvirt/images/\n"
246 for vm in "$@"; do
247 virsh destroy "$vm" > /dev/null 2>&1
248 virsh undefine "$vm" --remove-all-storage > /dev/null 2>&1
249 printf "%-50s%10s\n" "Removing $vm..." $([[ $? -eq 0 ]] && echo "Successful" || echo "Failed")
250 done
251 ;;
252 "-start")
253 for vm in "$@"; do
254 virsh start "$vm" > /dev/null 2>&1
255 printf "%-50s%10s\n" "Starting $vm..." $([[ $? -eq 0 ]] && echo "Successful" || echo "Failed")
256 done
257 ;;
258 "-reboot")
259 for vm in "$@"; do
260 virsh shutdown "$vm" > /dev/null 2>&1
261 virsh start "$vm" > /dev/null 2>&1
262 printf "%-50s%10s\n" "Rebooting $vm..." $([[ $? -eq 0 ]] && echo "Successful" || echo "Failed")
263 done
264 ;;
265 *)
266 echo "Unknown argument: $arg"
267 exit 1
268 ;;
269 esac
270 ;;
271 "info")
272 printf "%-4s %-10s %-15s %-10s %-10s %-6s %-8s %-12s\n" "Id" "Name" "IP" "State" "Network" "vCPUs" "RAM(GB)" "Disk(GB)"
273 printf "%-4s %-10s %-15s %-10s %-10s %-6s %-8s %-12s\n" "----" "----------" "---------------" "----------" "----------" "-----" "-------" "-----------"
274
275 vms=$(virsh list --name --all)
276
277 id=1
278 for vm in $vms; do
279 # Get the MAC address of the VM
280 mac=$(virsh dumpxml $vm | grep "mac address" | awk -F\' '{ print $2}')
281
282 # Get the network name
283 net=$(virsh dumpxml $vm | grep "<source network" | awk -F\' '{print $2}')
284
285 # Assign "default" if no network name is found
286 if [ -z "$net" ]
287 then
288 net="default"
289 fi
290
291 # Get the IP address of the VM
292 ip=$(virsh net-dhcp-leases $net | grep $mac | awk '{print $5}' | cut -f1 -d'/')
293
294 # Get the state of the VM
295 state=$(virsh domstate $vm)
296
297 # Get the vCPUs, RAM and Disk details of the VM
298 vcpus=$(virsh dominfo $vm | grep "CPU(s)" | awk '{print $2}')
299
300 ram=$(bc <<< "scale=2; $(virsh dominfo $vm | grep "Max memory" | awk '{print $3}')/1000000")
301
302 # Use du to get the size of the disk file in GB
303 disk=$(du -sk /var/lib/libvirt/images/${vm}.qcow2 | awk '{ printf "%.2f", $1/1024/1024 }' )
304
305 printf "%-4s %-10s %-15s %-10s %-10s %-6s %-8s %-12s\n" "$id" "$vm" "$ip" "$state" "$net" "$vcpus" "$ram" "$disk"
306 id=$((id+1))
307 done
308 exit 1
309 ;;
310 *)
311 help
312 exit 1
313 ;;
314esac
315
316