]> git.proxmox.com Git - ceph.git/blob - ceph/qa/workunits/rbd/cli_migration.sh
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / qa / workunits / rbd / cli_migration.sh
1 #!/usr/bin/env bash
2 set -ex
3
4 . $(dirname $0)/../../standalone/ceph-helpers.sh
5
6 TEMPDIR=
7 IMAGE1=image1
8 IMAGE2=image2
9 IMAGE3=image3
10 IMAGES="${IMAGE1} ${IMAGE2} ${IMAGE3}"
11
12 cleanup() {
13 cleanup_tempdir
14 remove_images
15 }
16
17 setup_tempdir() {
18 TEMPDIR=`mktemp -d`
19 }
20
21 cleanup_tempdir() {
22 rm -rf ${TEMPDIR}
23 }
24
25 create_base_image() {
26 local image=$1
27
28 rbd create --size 1G ${image}
29 rbd bench --io-type write --io-pattern rand --io-size=4K --io-total 256M ${image}
30 rbd snap create ${image}@1
31 rbd bench --io-type write --io-pattern rand --io-size=4K --io-total 64M ${image}
32 rbd snap create ${image}@2
33 rbd bench --io-type write --io-pattern rand --io-size=4K --io-total 128M ${image}
34 }
35
36 export_raw_image() {
37 local image=$1
38
39 rm -rf "${TEMPDIR}/${image}"
40 rbd export ${image} "${TEMPDIR}/${image}"
41 }
42
43 export_base_image() {
44 local image=$1
45
46 export_raw_image "${image}"
47 export_raw_image "${image}@1"
48 export_raw_image "${image}@2"
49 }
50
51 remove_image() {
52 local image=$1
53
54 (rbd migration abort $image || true) >/dev/null 2>&1
55 (rbd snap purge $image || true) >/dev/null 2>&1
56 (rbd rm $image || true) >/dev/null 2>&1
57 }
58
59 remove_images() {
60 for image in ${IMAGES}
61 do
62 remove_image ${image}
63 done
64 }
65
66 show_diff()
67 {
68 local file1=$1
69 local file2=$2
70
71 xxd "${file1}" > "${file1}.xxd"
72 xxd "${file2}" > "${file2}.xxd"
73 sdiff -s "${file1}.xxd" "${file2}.xxd" | head -n 64
74 rm -f "${file1}.xxd" "${file2}.xxd"
75 }
76
77 compare_images() {
78 local src_image=$1
79 local dst_image=$2
80 local ret=0
81
82 export_raw_image ${dst_image}
83 if ! cmp "${TEMPDIR}/${src_image}" "${TEMPDIR}/${dst_image}"
84 then
85 show_diff "${TEMPDIR}/${src_image}" "${TEMPDIR}/${dst_image}"
86 ret=1
87 fi
88 return ${ret}
89 }
90
91 test_import_native_format() {
92 local base_image=$1
93 local dest_image=$2
94
95 rbd migration prepare --import-only "rbd/${base_image}@2" ${dest_image}
96 rbd migration abort ${dest_image}
97
98 local pool_id=$(ceph osd pool ls detail --format xml | xmlstarlet sel -t -v "//pools/pool[pool_name='rbd']/pool_id")
99 cat > ${TEMPDIR}/spec.json <<EOF
100 {
101 "type": "native",
102 "pool_id": ${pool_id},
103 "pool_namespace": "",
104 "image_name": "${base_image}",
105 "snap_name": "2"
106 }
107 EOF
108 cat ${TEMPDIR}/spec.json
109
110 rbd migration prepare --import-only \
111 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
112
113 compare_images "${base_image}@1" "${dest_image}@1"
114 compare_images "${base_image}@2" "${dest_image}@2"
115
116 rbd migration abort ${dest_image}
117
118 rbd migration prepare --import-only \
119 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
120 rbd migration execute ${dest_image}
121
122 compare_images "${base_image}@1" "${dest_image}@1"
123 compare_images "${base_image}@2" "${dest_image}@2"
124
125 rbd migration abort ${dest_image}
126
127 rbd migration prepare --import-only \
128 --source-spec "{\"type\": \"native\", \"pool_id\": "${pool_id}", \"image_name\": \"${base_image}\", \"snap_name\": \"2\"}" \
129 ${dest_image}
130 rbd migration abort ${dest_image}
131
132 rbd migration prepare --import-only \
133 --source-spec "{\"type\": \"native\", \"pool_name\": \"rbd\", \"image_name\": \"${base_image}\", \"snap_name\": \"2\"}" \
134 ${dest_image}
135 rbd migration execute ${dest_image}
136 rbd migration commit ${dest_image}
137
138 compare_images "${base_image}@1" "${dest_image}@1"
139 compare_images "${base_image}@2" "${dest_image}@2"
140
141 remove_image "${dest_image}"
142 }
143
144 test_import_qcow_format() {
145 local base_image=$1
146 local dest_image=$2
147
148 if ! qemu-img convert -f raw -O qcow rbd:rbd/${base_image} ${TEMPDIR}/${base_image}.qcow; then
149 echo "skipping QCOW test"
150 return 0
151 fi
152 qemu-img info -f qcow ${TEMPDIR}/${base_image}.qcow
153
154 cat > ${TEMPDIR}/spec.json <<EOF
155 {
156 "type": "qcow",
157 "stream": {
158 "type": "file",
159 "file_path": "${TEMPDIR}/${base_image}.qcow"
160 }
161 }
162 EOF
163 cat ${TEMPDIR}/spec.json
164
165 set +e
166 rbd migration prepare --import-only \
167 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
168 local error_code=$?
169 set -e
170
171 if [ $error_code -eq 95 ]; then
172 echo "skipping QCOW test (librbd support disabled)"
173 return 0
174 fi
175 test $error_code -eq 0
176
177 compare_images "${base_image}" "${dest_image}"
178
179 rbd migration abort ${dest_image}
180
181 rbd migration prepare --import-only \
182 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
183
184 compare_images "${base_image}" "${dest_image}"
185
186 rbd migration execute ${dest_image}
187
188 compare_images "${base_image}" "${dest_image}"
189
190 rbd migration commit ${dest_image}
191
192 compare_images "${base_image}" "${dest_image}"
193
194 remove_image "${dest_image}"
195 }
196
197 test_import_qcow2_format() {
198 local base_image=$1
199 local dest_image=$2
200
201 # create new image via qemu-img and its bench tool since we cannot
202 # import snapshot deltas into QCOW2
203 qemu-img create -f qcow2 ${TEMPDIR}/${base_image}.qcow2 1G
204
205 qemu-img bench -f qcow2 -w -c 65536 -d 16 --pattern 65 -s 4096 \
206 -S $((($RANDOM % 262144) * 4096)) ${TEMPDIR}/${base_image}.qcow2
207 qemu-img convert -f qcow2 -O raw ${TEMPDIR}/${base_image}.qcow2 \
208 "${TEMPDIR}/${base_image}@snap1"
209 qemu-img snapshot -c "snap1" ${TEMPDIR}/${base_image}.qcow2
210
211 qemu-img bench -f qcow2 -w -c 16384 -d 16 --pattern 66 -s 4096 \
212 -S $((($RANDOM % 262144) * 4096)) ${TEMPDIR}/${base_image}.qcow2
213 qemu-img convert -f qcow2 -O raw ${TEMPDIR}/${base_image}.qcow2 \
214 "${TEMPDIR}/${base_image}@snap2"
215 qemu-img snapshot -c "snap2" ${TEMPDIR}/${base_image}.qcow2
216
217 qemu-img bench -f qcow2 -w -c 32768 -d 16 --pattern 67 -s 4096 \
218 -S $((($RANDOM % 262144) * 4096)) ${TEMPDIR}/${base_image}.qcow2
219 qemu-img convert -f qcow2 -O raw ${TEMPDIR}/${base_image}.qcow2 \
220 ${TEMPDIR}/${base_image}
221
222 qemu-img info -f qcow2 ${TEMPDIR}/${base_image}.qcow2
223
224 cat > ${TEMPDIR}/spec.json <<EOF
225 {
226 "type": "qcow",
227 "stream": {
228 "type": "file",
229 "file_path": "${TEMPDIR}/${base_image}.qcow2"
230 }
231 }
232 EOF
233 cat ${TEMPDIR}/spec.json
234
235 rbd migration prepare --import-only \
236 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
237
238 compare_images "${base_image}@snap1" "${dest_image}@snap1"
239 compare_images "${base_image}@snap2" "${dest_image}@snap2"
240 compare_images "${base_image}" "${dest_image}"
241
242 rbd migration abort ${dest_image}
243
244 rbd migration prepare --import-only \
245 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
246
247 compare_images "${base_image}@snap1" "${dest_image}@snap1"
248 compare_images "${base_image}@snap2" "${dest_image}@snap2"
249 compare_images "${base_image}" "${dest_image}"
250
251 rbd migration execute ${dest_image}
252
253 compare_images "${base_image}@snap1" "${dest_image}@snap1"
254 compare_images "${base_image}@snap2" "${dest_image}@snap2"
255 compare_images "${base_image}" "${dest_image}"
256
257 rbd migration commit ${dest_image}
258
259 compare_images "${base_image}@snap1" "${dest_image}@snap1"
260 compare_images "${base_image}@snap2" "${dest_image}@snap2"
261 compare_images "${base_image}" "${dest_image}"
262
263 remove_image "${dest_image}"
264 }
265
266 test_import_raw_format() {
267 local base_image=$1
268 local dest_image=$2
269
270 cat > ${TEMPDIR}/spec.json <<EOF
271 {
272 "type": "raw",
273 "stream": {
274 "type": "file",
275 "file_path": "${TEMPDIR}/${base_image}"
276 }
277 }
278 EOF
279 cat ${TEMPDIR}/spec.json
280
281 cat ${TEMPDIR}/spec.json | rbd migration prepare --import-only \
282 --source-spec-path - ${dest_image}
283 compare_images ${base_image} ${dest_image}
284 rbd migration abort ${dest_image}
285
286 rbd migration prepare --import-only \
287 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
288 rbd migration execute ${dest_image}
289 rbd migration commit ${dest_image}
290
291 compare_images ${base_image} ${dest_image}
292
293 remove_image "${dest_image}"
294
295 cat > ${TEMPDIR}/spec.json <<EOF
296 {
297 "type": "raw",
298 "stream": {
299 "type": "file",
300 "file_path": "${TEMPDIR}/${base_image}"
301 },
302 "snapshots": [{
303 "type": "raw",
304 "name": "snap1",
305 "stream": {
306 "type": "file",
307 "file_path": "${TEMPDIR}/${base_image}@1"
308 }
309 }, {
310 "type": "raw",
311 "name": "snap2",
312 "stream": {
313 "type": "file",
314 "file_path": "${TEMPDIR}/${base_image}@2"
315 }
316 }]
317 }
318 EOF
319 cat ${TEMPDIR}/spec.json
320
321 rbd migration prepare --import-only \
322 --source-spec-path ${TEMPDIR}/spec.json ${dest_image}
323
324 rbd snap create ${dest_image}@head
325 rbd bench --io-type write --io-pattern rand --io-size=32K --io-total=32M ${dest_image}
326
327 compare_images "${base_image}" "${dest_image}@head"
328 compare_images "${base_image}@1" "${dest_image}@snap1"
329 compare_images "${base_image}@2" "${dest_image}@snap2"
330 compare_images "${base_image}" "${dest_image}@head"
331
332 rbd migration execute ${dest_image}
333
334 compare_images "${base_image}@1" "${dest_image}@snap1"
335 compare_images "${base_image}@2" "${dest_image}@snap2"
336 compare_images "${base_image}" "${dest_image}@head"
337
338 rbd migration commit ${dest_image}
339
340 remove_image "${dest_image}"
341 }
342
343 # make sure rbd pool is EMPTY.. this is a test script!!
344 rbd ls 2>&1 | wc -l | grep -v '^0$' && echo "nonempty rbd pool, aborting! run this script on an empty test cluster only." && exit 1
345
346 setup_tempdir
347 trap 'cleanup $?' INT TERM EXIT
348
349 create_base_image ${IMAGE1}
350 export_base_image ${IMAGE1}
351
352 test_import_native_format ${IMAGE1} ${IMAGE2}
353 test_import_qcow_format ${IMAGE1} ${IMAGE2}
354 test_import_qcow2_format ${IMAGE2} ${IMAGE3}
355 test_import_raw_format ${IMAGE1} ${IMAGE2}
356
357 echo OK