-
Notifications
You must be signed in to change notification settings - Fork 195
/
xo-vm-import.sh
executable file
·235 lines (193 loc) · 8.34 KB
/
xo-vm-import.sh
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
#!/bin/bash
#########################################################################
# Title: XenOrchestraInstallerUpdater #
# Author: Roni Väyrynen #
# Repository: https://github.com/ronivay/XenOrchestraInstallerUpdater #
#########################################################################
# image url is static and not configurable by user
IMAGE_URL="https://xo-image.yawn.fi/downloads/image.xva.gz"
function OSCheck {
set -e
if [[ -z $(command -v xe 2>/dev/null) ]]; then
echo "this scripts needs xe command. make sure you're on xenserver/xcp-ng host"
exit 1
fi
echo
echo "Welcome. This script will import a preconfigured Debian 11 VM image which has Xen Orchestra installed using https://github.com/ronivay/XenOrchestraInstallerUpdater"
echo "You need at least 2vCPU/4GB/10GB disk free resources to import VM"
echo
echo "Please report any issues to this github project"
echo
}
function NetworkChoose {
set +e
# get network name/uuid of all available networks configured in the pool
# shellcheck disable=SC1117
IFS=$'\n' read -r -d '' -a networks <<<"$(xe network-list | grep "uuid\|name-label" | cut -d':' -f2 | sed 's/^ //' | paste - -)"
echo
echo "Which network should the VM use?"
echo
local PS3="Pick a number. CTRL+C to exit: "
select network in "${networks[@]}"; do
# get only the network uuid from array which we need later on when adding vif
read -r -a network_split <<<"$network"
networkuuid=${network_split[0]}
# print a menu where to choose network from
case $network in
*)
# save network uuid for later
vifuuid="$networkuuid"
break
;;
esac
done
}
function StorageChoose {
set +e
# get storage name/uuid of all available storages with content-type=user which should match all usable storage repositories
# shellcheck disable=SC1117
IFS=$'\n' read -r -d '' -a storages <<<"$(xe sr-list content-type=user | grep "uuid\|name-description" | cut -d':' -f2 | sed 's/^ //' | paste - -)"
# bail out if no storage repositories are found
if [[ ${#storages[@]} -eq 0 ]]; then
echo "No storage repositories found, can't import VM"
echo "Create SR and try again. More information: https://xcp-ng.org/docs/storage.html"
exit 1
fi
echo "Which storage repository should the VM use?"
echo "default will attempt to use pool default SR"
echo
local PS3="Pick a number. CTRL+C to exit: "
select storage in "${storages[@]}" "default"; do
# get only the storage repository uuid which we need later on when importing image
read -r -a storage_split <<<"$storage"
storageuuid=${storage_split[0]}
# print a menu where to choose storage from
case $storage in
default)
# this value is handled during import if set to default
sruuid=default
break
;;
*)
# save storage uuid for later
sruuid=$storageuuid
break
;;
esac
done
}
function NetworkSettings {
set -e
ipregex="^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
echo
echo "Set network settings for VM. Leave IP-address as blank to use DHCP"
echo
# read ip address from user input. dhcp is default if left empty
read -r -p "IP address: " ipaddress
ipaddress=${ipaddress:-dhcp}
# if not using dhcp, we need more information
if [[ "$ipaddress" != "dhcp" ]]; then
# get network details from user and prompt again if input doesn't match ip address regex
while ! [[ $ipaddress =~ $ipregex ]]; do
echo "Check IP address format"
read -r -p "IP address: " ipaddress
done
read -r -p "Netmask [255.255.255.0]: " netmask
netmask=${netmask:-255.255.255.0}
while ! [[ $netmask =~ $ipregex ]]; do
echo "Check gateway format"
read -r -p "Netmask [255.255.255.0]: " netmask
netmask=${netmask:-255.255.255.0}
done
read -r -p "Gateway: " gateway
while ! [[ $gateway =~ $ipregex ]] && [[ $gateway != "" ]]; do
echo "Check gateway format"
read -r -p "Gateway: " gateway
done
read -r -p "DNS [8.8.8.8]: " dns
dns=${dns:-8.8.8.8}
while ! [[ $dns =~ $ipregex ]]; do
echo "Check dns format"
read -r -p "DNS [8.8.8.8]: " dns
dns=${dns:-8.8.8.8}
done
fi
}
function VMImport {
set -e
echo
echo "Downloading and importing XVA image..."
echo
# Import image. We pipe through zcat because xe vm-import should transparently decompress gzipped image, but doesn't seem to understand when stream ends when piped through curl/wget whatnot.
# if SR was not defined, we leave that parameter out
if [[ $sruuid == "default" ]]; then
uuid=$(curl "$IMAGE_URL" | zcat | xe vm-import filename=/dev/stdin)
else
uuid=$(curl "$IMAGE_URL" | zcat | xe vm-import filename=/dev/stdin sr-uuid="$sruuid")
fi
# exit if import failed for any reason
# shellcheck disable=SC2181
if [[ $? != "0" ]]; then
echo "Import failed"
exit 1
fi
echo
echo "Import complete"
# no network interface included in the image, we need to create one based on network uuid set by user earlier
xe vif-create network-uuid="$vifuuid" vm-uuid="$uuid" device=0 >/dev/null
# VM startup script reads network details from xenstore and configures interface based on that so set values based on user input earlier
if [[ "$ipaddress" != "dhcp" ]]; then
xe vm-param-set uuid="$uuid" xenstore-data:vm-data/ip="$ipaddress" xenstore-data:vm-data/netmask="$netmask" xenstore-data:vm-data/gateway="$gateway" xenstore-data:vm-data/dns="$dns"
fi
# remove all other boot options except disk to speed startup
xe vm-param-remove uuid="$uuid" param-name=HVM-boot-params param-key=order
xe vm-param-set uuid="$uuid" HVM-boot-params:"order=c"
echo
echo "Starting VM..."
xe vm-start uuid="$uuid"
set +e
# loop max 300 seconds for VM to startup and xen tools to announce ip-address value
count=0
limit=10
ip=$(xe vm-param-get uuid="$uuid" param-name=networks param-key=0/ip 2>/dev/null)
while [[ -z "$ip" ]] && [[ "$count" -lt "$limit" ]]; do
echo "Waiting for VM to start and announce it got IP-address"
sleep 30
ip=$(xe vm-param-get uuid="$uuid" param-name=networks param-key=0/ip 2>/dev/null)
((count++))
done
# network details are needed in xenstore only during first startup so remove them at this point since VM should be running
if [[ "$ipaddress" != "dhcp" ]]; then
xe vm-param-remove param-name=xenstore-data param-key=vm-data/ip uuid="$uuid" 2>/dev/null
xe vm-param-remove param-name=xenstore-data param-key=vm-data/netmask uuid="$uuid" 2>/dev/null
xe vm-param-remove param-name=xenstore-data param-key=vm-data/gateway uuid="$uuid" 2>/dev/null
xe vm-param-remove param-name=xenstore-data param-key=vm-data/dns uuid="$uuid" 2>/dev/null
fi
# if we got ip-address value from VM, we print how to access it...
if [[ "$ip" != "" ]]; then
echo
echo "VM Started successfully"
echo
echo "You can access Xen Orchestra at https://$ip and via SSH at $ip"
echo "Default credentials for UI: admin@admin.net/admin"
echo "Default credentials for SSH: xo/xopass"
echo
echo "Remember to change both passwords before putting VM to use!"
# ... and print the same without ip-address information if ip-address value was missing
else
echo
echo "VM started but we couldn't fetch it's ip-address from xentools"
echo
echo "Check VM status/ip-address manually. If VM started correctly, it should have Web UI and SSH accessible at it's ip-address"
echo "Default credentials for UI: admin@admin.net/admin"
echo "Default credentials for SSH: xo/xopass"
echo
echo "Remember to change both passwords before putting VM to use!"
fi
}
# run all functions in a specific order
OSCheck
StorageChoose
NetworkChoose
NetworkSettings
VMImport