-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkvm_vm_manager.sh
More file actions
221 lines (204 loc) · 5.49 KB
/
kvm_vm_manager.sh
File metadata and controls
221 lines (204 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#!/bin/bash
function create_vm() {
# Validate inputs
[[ -z $image_name ]] && echo "image_name is empty" && exit 1
[[ -z $vm_name ]] && echo "vm_name is empty" && exit 1
[[ -z $cpu ]] && echo "cpu is empty" && exit 1
[[ -z $memory ]] && echo "memory is empty" && exit 1
[[ -z $disk_size ]] && echo "disk_size is empty" && exit 1
[[ -z $username ]] && echo "username is empty" && exit 1
[[ -z $password ]] && echo "password is empty" && exit 1
[[ -z $ip_address ]] && echo "ip_address is empty" && exit 1
[[ -z $netmask ]] && echo "netmask is empty" && exit 1
[[ -z $gateway ]] && echo "gateway is empty" && exit 1
[[ -z $dns1 ]] && dns1="8.8.8.8" && echo "Setting Default DNS $dns1 for dns1"
[[ -z $dns2 ]] && dns2="4.2.2.4" && echo "Setting Default DNS $dns2 for dns1"
# Create /opt/kvm_pool if it doesn't exist
[[ ! -d /opt/kvm_pool ]] && mkdir -p /opt/kvm_pool
# Copy the base image and rename it
[[ ! -f ./$image_name ]] && echo "You need to put your qcow2 disk near the script, file $image_name Not Found." && exit 1
cp ./$image_name /opt/kvm_pool
mv /opt/kvm_pool/$image_name /opt/kvm_pool/$vm_name.img
qemu-img resize /opt/kvm_pool/$vm_name.img $disk_size"G"
# Generate the hashed password and escape any $ characters in the hash
hashed_password=$(echo "$password" | mkpasswd -m sha-512 -s)
# Create cloud-init configuration with the appropriate values
echo "
#cloud-config
hostname: $vm_name
timezone: Asia/Tehran
users:
- name: $username
sudo: ALL=(ALL) ALL
groups: [ sudo ]
shell: /bin/bash
lock_passwd: false
ssh_pwauth: True
passwd: \"$hashed_password\"
ntp:
servers:
- time1.google.com
- time2.google.com
- time3.google.com
write_files:
- path: /etc/ssh/sshd_config
content: |
PasswordAuthentication yes
PermitRootLogin no # Optional: Disable root login for security
runcmd:
- systemctl restart sshd
" > $vm_name-config
echo "
version: 2
ethernets:
enp1s0:
dhcp4: no
addresses:
- ${ip_address}/${netmask}
gateway4: $gateway
nameservers:
addresses:
- $dns1
- $dns2
" > $vm_name-config-network
# Create the cloud-init ISO
cloud-localds cloudinit.iso $vm_name-config -N $vm_name-config-network
# Install the VM using virt-install
sudo virt-install \
--name $vm_name \
--vcpus $cpu \
--memory $memory \
--disk path=/opt/kvm_pool/$vm_name.img,format=qcow2 \
--disk path=cloudinit.iso,device=cdrom \
--network network=nat \
--os-variant debian12 \
--import \
--noautoconsole
# Cleanup temporary files
rm -f cloudinit.iso $vm_name-config $vm_name-config-network
virsh detach-device $vm_name --file disk.xml --config
}
function help_me() {
echo "To create a VM, please download a cloud-ready (qcow2) image (debian or ubuntu) then place it near this script."
echo "Initialize your KVM settings (nat.xml) and create the /opt/kvm_pool directory. Install the dependencies (qemu-img, mkpasswd, virt-install)."
echo "Then you are good to go."
echo "Example usage:"
echo "bash kvm-vm-manager.sh create debian12.img --hostname vmtest --cpu 1 --memory 1024 --disk 10 --ip 172.16.0.1 --gateway 172.16.0.254 --netmask 24 --username debian --password 123 --dns1 8.8.8.8 --dns2 4.2.2.4"
}
function kill_vm(){
local vm_name=$1
vm=$(virsh list --all | grep -iw $vm_name | awk '{print $2}')
virsh destroy $vm
virsh undefine $vm --remove-all-storage --nvram
}
function kill_allvm() {
vm_list=$(virsh list --all | awk 'NR>2 {print $2}')
for vm in ${vm_list[@]} ; do
kill_vm $vm
done
}
function get_inputs() {
while [ $# -gt 0 ]; do
case $1 in
kill | remove | delete)
kill_vm $2 && {
echo "$2 Vm removed."
exit 0
} || {
echo Failed to Remove $2 VM.
exit 1
}
;;
killall | removeall | deleteall)
kill_allvm && {
echo "All Vms removed."
exit 0
} || {
echo Failed to Remove all or some VMs.
exit 1
}
;;
--ip)
ip_address=$2
shift
shift
;;
--gateway)
gateway=$2
shift
shift
;;
--netmask)
netmask=$2
shift
shift
;;
--hostname)
vm_name=$2
shift
shift
;;
create | run)
image_name=$2
create_virtualmachine="true"
shift
shift
;;
--username)
username=$2
shift
shift
;;
--password)
password=$2
shift
shift
;;
--cpu)
cpu=$2
shift
shift
;;
--memory)
memory=$2
shift
shift
;;
--disk)
disk_size=$2
shift
shift
;;
--dns1)
dns1=$2
shift
shift
;;
--dns2)
dns2=$2
shift
shift
;;
--help | help | -h)
help_me
exit 0
;;
*)
cmd="$@"
shift
;;
esac
done
}
# Check dependencies before running
command -v mkpasswd >/dev/null 2>&1 || { echo "mkpasswd is required but not installed. Exiting."; exit 1; }
command -v qemu-img >/dev/null 2>&1 || { echo "qemu-img is required but not installed. Exiting."; exit 1; }
command -v virt-install >/dev/null 2>&1 || { echo "virt-install is required but not installed. Exiting."; exit 1; }
# Process inputs and create the VM
get_inputs $@
if [[ $create_virtualmachine == "true" ]]; then
create_vm || {
echo "VM Creation Failed."
exit 1
}
fi