-
Notifications
You must be signed in to change notification settings - Fork 15
/
storage-volumes-vm
executable file
·216 lines (186 loc) · 8.33 KB
/
storage-volumes-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
#!/bin/bash
set -eux
# Install dependencies
install_deps genisoimage
# Install LXD
install_lxd
IMAGE="${TEST_IMG:-ubuntu-minimal-daily:24.04}"
# XXX: skip ceph for now
poolDriverList="${1:-dir btrfs lvm lvm-thin zfs}"
# Configure LXD
lxc project switch default
lxc network create lxdbr0
lxc project create test -c features.images=false
lxc project switch test
lxc profile device add default eth0 nic network=lxdbr0
poolName="vmpool$$"
for poolDriver in $poolDriverList
do
echo "==> Create storage pool using driver ${poolDriver}"
if [ "${poolDriver}" = "dir" ]; then
lxc storage create "${poolName}" "${poolDriver}" volume.size=5GB
elif [ "${poolDriver}" = "ceph" ]; then
lxc storage create "${poolName}" "${poolDriver}" source="${poolName}" volume.size=5GB
elif [ "${poolDriver}" = "lvm" ]; then
lxc storage create "${poolName}" "${poolDriver}" size=40GiB lvm.use_thinpool=false volume.size=5GB
elif [ "${poolDriver}" = "lvm-thin" ]; then
lxc storage create "${poolName}" lvm size=20GiB volume.size=5GB
elif [ "${poolDriver}" = "powerflex" ]; then
createPowerFlexPool "${poolName}"
else
lxc storage create "${poolName}" "${poolDriver}" size=20GB volume.size=5GB
fi
echo "==> Create VM"
lxc init "${IMAGE}" v1 --vm -s "${poolName}"
lxc init "${IMAGE}" v2 --vm -s "${poolName}"
echo "==> Create custom block volume and attach it to VM"
if [ "${poolDriver}" != "powerflex" ]; then
lxc storage volume create "${poolName}" vol1 --type=block size=10MB
else
lxc storage volume create "${poolName}" vol1 --type=block size=8GiB
fi
lxc storage volume attach "${poolName}" vol1 v1
echo "==> Create custom volume and attach it to VM"
if [ "${poolDriver}" != "powerflex" ]; then
lxc storage volume create "${poolName}" vol4 size=10MB
else
lxc storage volume create "${poolName}" vol4 size=8GiB
fi
lxc storage volume attach "${poolName}" vol4 v1 /foo
echo "==> Start VM and add content to custom block volume"
lxc start v1
waitInstanceReady v1
lxc exec v1 -- test -b /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol1
lxc exec v1 -- /bin/sh -c "mkfs.ext4 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol1 && mount /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol1 /mnt && echo foo > /mnt/bar && umount /mnt"
echo "==> Stop VM and detach custom volumes"
lxc stop -f v1
lxc storage volume detach "${poolName}" vol1 v1
lxc storage volume detach "${poolName}" vol4 v1
echo "==> Test custom block volume hotplugging"
lxc start v1
waitInstanceReady v1
lxc storage volume attach "${poolName}" vol1 v1
sleep 3
BLOCK_SPECIAL_FILE="$(lxc exec v1 -- readlink -f /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol1)"
lxc exec v1 -- test -b "$BLOCK_SPECIAL_FILE"
lxc storage volume detach "${poolName}" vol1 v1
sleep 3
! lxc exec v1 -- stat "$BLOCK_SPECIAL_FILE" || false
! lxc exec v1 -- stat /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol1 || false
lxc stop -f v1
echo "==> Backup custom block volume"
lxc storage volume export "${poolName}" vol1 vol1.tar.gz
lxc storage volume export "${poolName}" vol1 vol1-optimized.tar.gz --optimized-storage
echo "==> Import custom block volume"
lxc storage volume import "${poolName}" vol1.tar.gz vol2
lxc storage volume import "${poolName}" vol1-optimized.tar.gz vol3
rm vol1.tar.gz
rm vol1-optimized.tar.gz
if hasNeededAPIExtension custom_volume_iso; then
echo "==> Import custom ISO volume"
tmp_iso_dir="$(mktemp -d)"
echo foo > "${tmp_iso_dir}/foo"
genisoimage -o vol5.iso "${tmp_iso_dir}"
rm -f "${tmp_iso_dir}/foo"
echo bar > "${tmp_iso_dir}/bar"
genisoimage -o vol6.iso "${tmp_iso_dir}"
rm -rf "${tmp_iso_dir}"
lxc storage volume import "${poolName}" vol5.iso vol5
lxc storage volume import "${poolName}" vol6.iso vol6
rm -f vol5.iso vol6.iso
else
echo "==> Skipping custom ISO volume tests, not supported"
fi
echo "==> Attach custom block volumes to VM"
# Both volumes can be attached at the same time. The VM will have /dev/sdb and /dev/sdc.
# It doesn't matter which volume is which device as they contain the same content.
lxc storage volume attach "${poolName}" vol2 v1
lxc storage volume attach "${poolName}" vol3 v1
echo "==> Share a custom block volume"
if hasNeededAPIExtension shared_custom_block_volumes; then
! lxc storage volume attach "${poolName}" vol2 v2 || false
lxc storage volume set "${poolName}" vol2 security.shared true
lxc storage volume attach "${poolName}" vol2 v2
! lxc storage volume set "${poolName}" vol2 security.shared false || false
lxc storage volume detach "${poolName}" vol2 v2
lxc storage volume set "${poolName}" vol2 security.shared false
else
# Sharing is allowed by default without shared_custom_block_volumes extension
lxc storage volume attach "${poolName}" vol2 v2
lxc storage volume detach "${poolName}" vol2 v2
fi
if hasNeededAPIExtension custom_volume_iso; then
echo "==> Attach custom ISO volumes to VM"
lxc storage volume attach "${poolName}" vol5 v1
lxc storage volume attach "${poolName}" vol6 v1
lxc storage volume attach "${poolName}" vol5 v2
lxc storage volume attach "${poolName}" vol6 v2
echo "===> Check if /dev/disk/by-id representations are accurate"
lxc start v1 v2
waitInstanceReady v1
waitInstanceReady v2
lxc exec v1 -- test -b /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol5
lxc exec v1 -- test -b /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol6
lxc exec v2 -- test -b /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol5
lxc exec v2 -- test -b /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol6
lxc stop -f v1 v2
else
echo "==> Skipping custom ISO volume tests, not supported"
fi
echo "==> Start VM and check content"
lxc storage volume attach "${poolName}" vol1 v1
lxc start v1
waitInstanceReady v1
echo "==> Verify that block volumes vol1 and vol2 (export/import) are bit for bit identical"
lxc exec v1 -- cmp /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol1 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol2
echo "==> Verify that block volumes vol1 and vol3 (optimized export/import) are bit for bit identical"
lxc exec v1 -- cmp /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol1 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol3
# shellcheck disable=2016
lxc exec v1 -- /bin/sh -c 'mount /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol2 /mnt && [ $(cat /mnt/bar) = foo ] && umount /mnt'
# shellcheck disable=2016
lxc exec v1 -- /bin/sh -c 'mount /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_lxd_vol3 /mnt && [ $(cat /mnt/bar) = foo ] && umount /mnt'
if hasNeededAPIExtension custom_volume_iso; then
lxc start v2
waitInstanceReady v2
# mount ISOs and check content
# shellcheck disable=2016
lxc exec v1 -- /bin/sh -c 'mount /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol5 /mnt && [ $(cat /mnt/foo) = foo ] && ! touch /mnt/foo && umount /mnt'
# shellcheck disable=2016
lxc exec v1 -- /bin/sh -c 'mount /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol6 /mnt && [ $(cat /mnt/bar) = bar ] && ! touch /mnt/bar && umount /mnt'
# concurrent readonly ISO mounts
# shellcheck disable=2016
lxc exec v1 -- /bin/sh -c 'mount /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol5 /mnt && [ $(cat /mnt/foo) = foo ] && ! touch /mnt/foo'
# shellcheck disable=2016
lxc exec v2 -- /bin/sh -c 'mount /dev/disk/by-id/scsi-0QEMU_QEMU_CD-ROM_lxd_vol5 /mnt && [ $(cat /mnt/foo) = foo ] && ! touch /mnt/foo'
lxc exec v1 -- umount /mnt
lxc exec v2 -- umount /mnt
else
echo "==> Skipping custom ISO volume tests, not supported"
fi
echo "==> Detaching volumes"
lxc exec v1 -- "sync"
lxc stop -f v1
lxc delete -f v2
lxc storage volume detach "${poolName}" vol1 v1
lxc storage volume detach "${poolName}" vol2 v1
lxc storage volume detach "${poolName}" vol3 v1
lxc storage volume detach "${poolName}" vol6 v1 || true # optional ISO
echo "==> Deleting VM"
lxc delete v1
echo "==> Deleting storage pool and volumes"
lxc storage volume rm "${poolName}" vol1
lxc storage volume rm "${poolName}" vol2
lxc storage volume rm "${poolName}" vol3
lxc storage volume rm "${poolName}" vol4
lxc storage volume rm "${poolName}" vol5 || true # optional ISO
lxc storage volume rm "${poolName}" vol6 || true # optional ISO
lxc storage rm "${poolName}"
done
# Cleanup
echo "==> Cleaning up"
lxc profile device remove default eth0
lxc project switch default
lxc project delete test
lxc network delete lxdbr0
# shellcheck disable=SC2034
FAIL=0