-
Notifications
You must be signed in to change notification settings - Fork 14
/
configure-fast-vm
executable file
·257 lines (230 loc) · 11.3 KB
/
configure-fast-vm
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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#!/bin/sh
config_file="/etc/fast-vm.conf"
## terminal colors
c_red=$(tput setaf 1)
c_yellow=$(tput setaf 3)
c_green=$(tput setaf 2)
c_cyan=$(tput setaf 6)
c_normal=$(tput sgr0)
## common outputs
o_err="[${c_red}err${c_normal}]"
o_wrn="[${c_yellow}wrn${c_normal}]"
o_inf="[${c_cyan}inf${c_normal}]"
o_ok="[${c_green}ok${c_normal}]"
# load defaults and old configuration if exists
if [ -f /usr/share/fast-vm/fast-vm.conf.defaults ]; then
. /usr/share/fast-vm/fast-vm.conf.defaults
fi
if [ -f "$config_file" ]; then
. $config_file
else
touch $config_file
fi
ask_question () {
question="$1"
default_value="$2"
config_variable="$3"
# lets get meaningfull answer from user
success=0
while [ "$success" -eq 0 ];
do
printf "[?] $question \n[$default_value]: "
read answer
if [ -z "$default_value" ] && [ -z "$answer" ]; then
printf "$o_err You must provide value\n"
else
success=1
fi
echo
done
# and write the output into configuration file
sed -i "/^$config_variable=/d" $config_file
if [ -z "$answer" ]; then
echo "$config_variable=$default_value" >> $config_file
else
echo "$config_variable=$answer" >> $config_file
fi
. $config_file
}
test_appliance () {
tmp_appliance_test=$(mktemp)
printf "$o_inf Running appliance test (libguestfs-test-tool)...\n"
if LIBGUESTFS_PATH=/var/lib/fast-vm/appliance libguestfs-test-tool >"$tmp_appliance_test" 2>&1; then
printf "$o_inf Appliance test looks OK\n"
rm -f "$tmp_appliance_test"
return 0
else
printf "$o_err Appliance test failed with error, check the '$tmp_appliance_test' file for details\n"
return 1
fi
}
printf "$o_inf ==>> fast-vm configuration script\nYou can run this script repeatedly and interrupt it with ctrl+c.\nScript will always recheck all configuration options. fast-vm system configuration will be saved in /etc/fast-vm.conf.\n\n"
## check if we can connect to libvirt and if not, inform the user that it is needed
virsh_test=$(virsh --connect qemu:///system exit >/dev/null 2>&1)
if [ "$?" != '0' ]; then
printf "$o_err libvirt daemon is not running or we cannot connect to it.\nEnsure that libvirt service is running and that you can connect to it using command 'virsh --connect qemu:///system' and then re-run this configuration script.\n"
exit 1
fi
success=0
while [ "$success" -eq 0 ];
do
if command -v systemctl >/dev/null && command -v losetup >/dev/null && command -v truncate >/dev/null; then
printf "$o_inf (Optional) On systemd systems fast-vm can automatically setup loop device to provide storage for fast-vm VG. \n This option is intended for uses where no VFree is available on system. \n"
printf "[?] Would you like to start the fast-vm-loop-device.service? (y/n) [n] "
read answer
if [ "$answer" = "y" ]; then
if [ ! -f "/var/lib/fast-vm/loop/device.img" ]; then
printf "[?] Loop device (sparse file) size in GB: [51] "
read loopdev_size
if [ -z "$loopdev_size" ]; then loopdev_size='51'; fi
if [ ! -d "/var/lib/fast-vm/loop" ]; then mkdir -p /var/lib/fast-vm/loop; fi
printf "$o_inf Creating ${loopdev_size}GB file /var/lib/fast-vm/loop/device.img with VG fastvm-loopdevice.\n"
truncate -s "${loopdev_size}G" /var/lib/fast-vm/loop/device.img
fi
printf "$o_inf Enabling on boot and starting now the 'fast-vm-loop-device.service' ...\n"
systemctl enable --now fast-vm-loop-device.service
vgcreate fastvm-loopdevice /dev/loop100
printf "$o_inf You should see now the new VG named 'fastvm-loopdevice'.\n This VG can be used for fast-vm storage in next steps. \n\n"
else
printf "$o_inf If it turns out you don't have any VFree in system, \n you can re-run config and choose to start the 'fast-vm-loop-device.service'. \n\n"
fi
fi
available_vgs=$(vgs -o vg_name,vg_attr,vg_size,vg_free)
ask_question "VG for LVM thin pool\n fast-vm is using LVM thin LV to store VM images and data.\n Available VGs on your system are: \n $available_vgs\n ====== \n Choose the VG with sufficient VFree space for fast-vm use (at least 10GB recommended).\n If you lack sufficient VFree space you can use the 'fastvm-loopdevice'. \n ====== \n On which existing VG should be this thin LV?" "$THINPOOL_VG" "THINPOOL_VG"
ask_question "LVM thin pool name\n Name the thin LV on which data would be stored.\n NOTE: This can be both 'name of existing thinpool LV' or 'name for a new one'.\n If LV with this name doesn't exists, it will get created by this setup." "$THINPOOL_LV" "THINPOOL_LV"
lvdisplay "$THINPOOL_VG/$THINPOOL_LV" >/dev/null 2>&1
if [ ! "$?" -eq "0" ]; then
ask_question "LVM thin pool size\n You can use units understood by LVM like M,G,T.\n NOTE: This applies only when thin LV doesn't exists yet." "$THINPOOL_SIZE" "THINPOOL_SIZE"
fi
ask_question "VM name prefix in libvirt\n Prefix is used in VM names and VM drive names." "$VM_PREFIX" "VM_PREFIX"
ask_question "Users that want to use fast-vm must be members of following group.\n WARNING: if this group is different from 'libvirt' you would have to adjust libvirt configuration.\n Please check the fast-vm.conf(5) if setting this to something else than 'libvirt'." "$FASTVM_GROUP" "FASTVM_GROUP"
if [ "$FASTVM_GROUP" != "libvirt" ]; then
printf "$o_wrn You are using non-default group for FASTVM_GROUP.\n Please check the fast-vm.conf(5) on how to configure libvirtd for this to work properly.\n\n"
fi
ask_question "Libvirt network (bridge) name\n This configuration will create a libvirt \n network with this name providing NAT for VMs." "$LIBVIRT_NETWORK" "LIBVIRT_NETWORK"
ask_question "Libvirt subnet number (192.168.XX.0/24)" "$SUBNET_NUMBER" "SUBNET_NUMBER"
ask_question "Only 'root' and 'owner' of VM should be able to delete VM through fast-vm?\n \"yes\" - only 'root' and 'owner' can delete VM\n \"no\" - anyone allowed to use fast-vm can delete VM (default in versions =< 0.9)" "$FASTVM_OWNER_ONLY_DELETE" "FASTVM_OWNER_ONLY_DELETE"
ask_question "Generate or Import libguestfs appliance used by hack files for this system? ('Generate' will generate appliance localy, while 'import' allows to import pre-build Fedora appliance from Internet.\nFASTVM_APPLIANCE_URL=$FASTVM_APPLIANCE_URL\nSome fast-vm images may require the Fedora appliance otherwise their hack files fails.)" "$FASTVM_APPLIANCE" "FASTVM_APPLIANCE"
ask_question "Default password for fast-vm keydist operation (use 'none' to disable this feature)" "$FASTVM_KEYDIST_PASSWORD" "FASTVM_KEYDIST_PASSWORD"
if [ "$FASTVM_KEYDIST_PASSWORD" = 'none' ]; then sed -i '/^FASTVM_KEYDIST_PASSWORD=/g' "$config_file"; fi
## reload the configuration file and check the system for changes
. $config_file
# redefine the sudoers file
sed -i -e "s/^\%[^ ]* \(.* \/usr\/libexec\/fast-vm-helper\.sh\)$/\%${FASTVM_GROUP} \1/" /etc/sudoers.d/fast-vm-sudoers >/dev/null 2>&1
# LVM VG check
vgdisplay "$THINPOOL_VG" >/dev/null 2>&1
if [ ! "$?" -eq '0' ]; then
printf "$o_err VG '$THINPOOL_VG' not found\n"
continue
fi
# LVM thinpool LV check
lvdisplay "$THINPOOL_VG/$THINPOOL_LV" >/dev/null 2>&1
if [ ! "$?" -eq "0" ]; then
printf "$o_wrn LV '$THINPOOL_VG/$THINPOOL_LV' not found\n"
echo "Following commands would be executed to create thin pool:"
echo " lvcreate -n $THINPOOL_LV -L $THINPOOL_SIZE $THINPOOL_VG"
echo " lvconvert --type thin-pool $THINPOOL_VG/$THINPOOL_LV"
printf "[?] Create now? (y/n) "
read answer
if [ "$answer" = "y" ]; then
printf "$o_inf Creating ...\n"
## create thin pool
lvcreate -n "$THINPOOL_LV" -L "$THINPOOL_SIZE" "$THINPOOL_VG"
if [ ! "$?" -eq "0" ]; then
printf "$o_err Error while creating LV for thin pool, aborting\n"
exit 1
fi
lvconvert --type thin-pool "$THINPOOL_VG/$THINPOOL_LV"
if [ ! "$?" -eq "0" ]; then
printf "$o_err Error while converting LV into thin pool, aborting\n"
exit 1
fi
printf "$o_ok LVM thinpool successfuly created\n"
else
printf "$o_wrn fast-vm will not work without thinpool LV!\n"
fi
fi
# check if the LV is a thinpool
is_thin_pool=$(lvdisplay "/dev/$THINPOOL_VG/$THINPOOL_LV" 2>/dev/null|grep 'LV Pool'|wc -l)
if [ ! "$is_thin_pool" -eq "2" ]; then
printf "$o_err LV /dev/$THINPOOL_VG/$THINPOOL_LV is not a thin pool. To create a thinpool for fast-vm delete this LV a run the configuration again\n"
exit 1
fi
# check for the libvirt network
virsh --connect qemu:///system net-info "$LIBVIRT_NETWORK" >/dev/null 2>&1
if [ ! "$?" -eq "0" ]; then
printf "[?] Network $LIBVIRT_NETWORK is not defined in libvirt, define now? (y/n) "
read answer
if [ "$answer" = "y" ]; then
printf "$o_inf Creating ...\n"
tmp_file=$(mktemp --suffix=.xml)
sed -e "s/NET_NAME/$LIBVIRT_NETWORK/g; s/SUBNET_NUMBER/$SUBNET_NUMBER/g" /usr/share/fast-vm/fast-vm-network.xml > "$tmp_file"
virsh --connect qemu:///system net-define "$tmp_file"
if [ ! "$?" -eq "0" ]; then
printf "$o_err Error creating libvirt network, aborting\n"
exit 1
fi
virsh --connect qemu:///system net-autostart "$LIBVIRT_NETWORK"
if [ ! "$?" -eq "0" ]; then
printf "$o_err Error marking libvirt network as autostarted, aborting\n"
exit 1
fi
virsh --connect qemu:///system net-start "$LIBVIRT_NETWORK"
if [ ! "$?" -eq "0" ]; then
printf "$o_err Error starting libvirt network, aborting\n"
exit 1
fi
printf "$o_inf fast-vm libvirt network created and autostarted\n"
else
printf "$o_wrn fast-vm will not work without libvirt network!\n"
fi
fi
is_subnet_number=$(virsh --connect qemu:///system net-dumpxml "$LIBVIRT_NETWORK" 2>/dev/null|grep 'ip address'|cut -d. -f3)
if [ "$is_subnet_number" != "$SUBNET_NUMBER" ];then
printf "$o_err Libvirt network subnet is different from one provided in fast-vm configuration. Fix fast-vm configuration or libvirt network configuration\n"
exit 1
fi
if [ -n "$FASTVM_NOTES_DIR" ] && [ "$(whoami)" = "root" ]; then
printf "[!] Configuration option FASTVM_NOTES_DIR is deprecated from fast-vm version 1.8.\n"
printf " If you need to convert notes from old format then use configure-fast-vm from version 1.7.\n"
if [ ! -d "$FASTVM_NOTES_DIR" ]; then
printf "[i] Please remove FASTVM_NOTES_DIR from /etc/fast-vm.conf\n"
printf " as directory ($FASTVM_NOTES_DIR) defined in it doesn't exist.\n"
fi
fi
if test_appliance; then
printf "$o_inf Current appliance looks OK. No changes needed. If you wanna replace it, then remove /var/lib/fast-vm/appliance directory\n"
else
case "$FASTVM_APPLIANCE" in
import)
printf "$o_inf Downloading appliance from $FASTVM_APPLIANCE_URL\n"
tmp_file=$(mktemp)
curl "$FASTVM_APPLIANCE_URL" > "$tmp_file"
printf "$o_inf Extracting file into /var/lib/fast-vm\n"
if [ ! -d "/var/lib/fast-vm" ]; then mkdir -p /var/lib/fast-vm; fi
tar xvf "$tmp_file" -C /var/lib/fast-vm
rm -f "$tmp_file"
test_appliance
;;
generate)
if command -v libguestfs-make-fixed-appliance >/dev/null 2>&1; then
printf "$o_inf Generating locally new appliance (this can take around minutes)\n"
libguestfs-make-fixed-appliance /var/lib/fast-vm/appliance
test_appliance
else
printf "$o_err Command 'libguestfs-make-fixed-appliance' not found.\n"
printf "$o_err Try installing package containing it (usually 'libguestfs-devel') or\n"
printf "$o_err choose to 'import' appliance instead of generating it.\n"
fi
;;
skip)
printf "$o_wrn Skipping appliance import/generation\n"
;;
*)
printf "$o_err Unrecognized option. Use one of 'import', 'generate' or 'skip'.\n"
;;
esac
fi
printf "$o_ok fast-vm configured\n"
success=1
done