Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / tools / rbd_recover_tool / test_rbd_recover_tool.sh
1 #!/bin/bash
2 #
3 # Copyright (C) 2015 Ubuntu Kylin
4 #
5 # Author: Min Chen <minchen@ubuntukylin.com>
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU Library Public License as published by
9 # the Free Software Foundation; either version 2, or (at your option)
10 # any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Library Public License for more details.
16 #
17
18 # unit test case for rbd-recover-tool
19
20 #prepare:
21 # - write config files: config/osd_host, config/mon_host, config/storage_path, config/mds_host if exist mds
22 #step 1. rbd export all images as you need
23 #step 2. stop all ceph services
24 #step 3. use ceph_rbd_recover_tool to recover all images
25 #step 4. compare md5sum of recover image with that of export image who has the same image name
26
27 ssh_opt="-o ConnectTimeout=1"
28 my_dir=$(dirname "$0")
29 tool_dir=$my_dir
30
31 #storage_path=$my_dir/config/storage_path
32 mon_host=$my_dir/config/mon_host
33 osd_host=$my_dir/config/osd_host
34 mds_host=$my_dir/config/mds_host
35
36 test_dir= # `cat $storage_path`
37 export_dir= #$test_dir/export
38 recover_dir= #$test_dir/recover
39 image_names= #$test_dir/image_names
40 online_images= #$test_dir/online_images, all images on ceph rbd pool
41 gen_db= #$test_dir/gen_db, label database if exist
42 pool=rbd
43 pool_id=2
44
45 function get_pool_id()
46 {
47   local pool_id_file=/tmp/pool_id_file.$$$$
48   ceph osd pool stats $pool|head -n 1|awk '{print $4}' >$pool_id_file
49   if [ $? -ne 0 ];then
50     echo "$func: get pool id failed: pool = $pool"
51     rm -f $pool_id_file
52     exit
53   fi
54   pool_id=`cat $pool_id_file`
55   echo "$func: pool_id = $pool_id"
56   rm -f $pool_id_file
57 }
58
59 function init()
60 {
61   local func="init"
62   if [ $# -eq 0 ];then
63     echo "$func: must input <path> to storage images, enough disk space is good"
64     exit
65   fi
66   if [ ! -s $osd_host ];then
67     echo "$func: config/osd_host not exists or empty"
68     exit
69   fi
70   if [ ! -s $mon_host ];then
71     echo "$func: config/mon_host not exists or empty"
72     exit
73   fi
74   if [ ! -e $mds_host ];then
75     echo "$func: config/mds_host not exists"
76     exit
77   fi
78   test_dir=$1
79   export_dir=$test_dir/export
80   recover_dir=$test_dir/recover
81   image_names=$test_dir/image_names
82   online_images=$test_dir/online_images
83   gen_db=$test_dir/gen_db
84
85   trap 'echo "ceph cluster is stopped ..."; exit;' INT
86   ceph -s >/dev/null
87   get_pool_id
88
89   mkdir -p $test_dir
90   mkdir -p $export_dir
91   mkdir -p $recover_dir
92   rm -rf $export_dir/*
93   rm -rf $recover_dir/*
94 }
95
96 function do_gen_database()
97 {
98   local func="do_gen_database"
99   if [ -s $gen_db ] && [ `cat $gen_db` = 1 ];then
100     echo "$func: database already existed"
101     exit
102   fi
103   bash $tool_dir/rbd-recover-tool database
104   echo 1 >$gen_db 
105 }
106
107 #check if all ceph processes are stopped
108 function check_ceph_service()
109 {
110   local func="check_ceph_service"
111   local res=`cat $osd_host $mon_host $mds_host|sort -u|tr -d [:blank:]|xargs -n 1 -I @ ssh $ssh_opt @ "ps aux|grep -E \"(ceph-osd|ceph-mon|ceph-mds)\"|grep -v grep"`
112   if [ "$res"x != ""x ];then
113     echo "$func: NOT all ceph services are stopped"
114     return 1
115     exit
116   fi
117   echo "$func: all ceph services are stopped"
118   return 0
119 }
120
121 function stop_ceph()
122 {
123   local func="stop_ceph"
124   #cat osd_host|xargs -n 1 -I @ ssh $ssh_opt @ "killall ceph-osd" 
125   while read osd
126   do
127   {
128     osd=`echo $osd|tr -d [:blank:]`
129     if [ "$osd"x = ""x ];then
130       continue
131     fi
132     #ssh $ssh_opt $osd "killall ceph-osd ceph-mon ceph-mds" </dev/null
133     ssh $ssh_opt $osd "killall ceph-osd" </dev/null
134   } &
135   done < $osd_host
136   wait
137   echo "waiting kill all osd ..."
138   sleep 1
139   #cat $mon_host|xargs -n 1 -I @ ssh $ssh_opt @ "killall ceph-mon ceph-osd ceph-mds" 
140   cat $mon_host|xargs -n 1 -I @ ssh $ssh_opt @ "killall ceph-mon" 
141   #cat $mds_host|xargs -n 1 -I @ ssh $ssh_opt @ "killall ceph-mds ceph-mon ceph-osd" 
142   cat $mds_host|xargs -n 1 -I @ ssh $ssh_opt @ "killall ceph-mds" 
143 }
144
145 function create_image()
146 {
147   local func="create_image"
148   if [ ${#} -lt 3 ];then
149     echo "create_image: parameters: <image_name> <size> <image_format>"
150     exit
151   fi
152   local image_name=$1
153   local size=$2
154   local image_format=$3
155   if [ $image_format -lt 1 ] || [ $image_format -gt 2 ];then
156     echo "$func: image_format must be 1 or 2"
157     exit
158   fi
159   local res=`rbd list|grep -E "^$1$"` 
160   echo "$func $image_name ..."
161   if [ "$res"x = ""x ];then
162     rbd -p $pool create $image_name --size $size --image_format $image_format
163   else
164     if [ $image_format -eq 2 ];then
165       rbd snap ls $image_name|tail -n +2|awk '{print $2}'|xargs -n 1 -I % rbd snap unprotect $image_name@%
166     fi
167     rbd snap purge $image_name
168     #rbd rm $image_name
169     rbd -p $pool resize --allow-shrink --size $size $image_name
170   fi
171 }
172
173 function export_image()
174 {
175   local func="export_image"
176
177   if [ $# -lt 2 ];then
178     echo "$func: parameters: <image_name> <image_format> [<image_size>]"
179     exit
180   fi
181
182   local image_name=$1
183   local format=$(($2)) 
184   local size=$(($3)) #MB
185   
186   if [ $format -ne 1 ] && [ $format -ne 2 ];then
187     echo "$func: image format must be 1 or 2"
188     exit
189   fi
190
191   if [ $size -eq 0 ];then
192     size=24 #MB
193     echo "$func: size = $size"
194   fi
195   local mnt=/rbdfuse 
196
197   mount |grep "rbd-fuse on /rbdfuse" &>/dev/null
198   if [ $? -ne 0 ];then
199     rbd-fuse $mnt
200   fi
201     
202   create_image $image_name $size $format
203  
204   dd conv=notrunc if=/dev/urandom of=$mnt/$image_name bs=4M count=$(($size/4))
205   
206   local export_image_dir=$export_dir/pool_$pool_id/$image_name
207   mkdir -p $export_image_dir
208   local export_md5_nosnap=$export_image_dir/@md5_nosnap
209   >$export_md5_nosnap
210  
211   local export_image_path=$export_image_dir/$image_name
212   rm -f $export_image_path
213
214   rbd export $pool/$image_name $export_image_path
215   md5sum $export_image_path |awk '{print $1}' >$export_md5_nosnap 
216 }
217
218 function recover_image()
219 {
220   local func="recover_snapshots"
221   if [ $# -lt 1 ];then
222     echo "$func: parameters: <image_name>"
223     exit
224   fi
225
226   local image_name=$1
227   #pool_id=29
228
229   local recover_image_dir=$recover_dir/pool_$pool_id/$image_name
230   mkdir -p $recover_image_dir
231   local recover_md5_nosnap=$recover_image_dir/@md5_nosnap
232   >$recover_md5_nosnap
233   local snapshot=
234   
235   bash $tool_dir/rbd-recover-tool recover $pool_id/$image_name $recover_dir
236   md5sum $recover_image_dir/$image_name|awk '{print $1}' >$recover_md5_nosnap
237 }
238
239 function make_snapshot()
240 {
241   local func="make_snapshot"
242   if [ $# -lt 5 ];then
243     echo "$func: parameters: <ofile> <seek> <count> <snap> <export_image_dir>"
244     exit
245   fi
246   local ofile=$1
247   local seek=$(($2))
248   local count=$(($3))
249   local snap=$4
250   local export_image_dir=$5
251
252   if [ $seek -lt 0 ];then
253     echo "$func: seek can not be minus"
254     exit
255   fi
256
257   if [ $count -lt 1 ];then
258     echo "$func: count must great than zero"
259     exit
260   fi
261
262   echo "[$snap] $func ..."
263   echo "$1 $2 $3 $4"
264   rbd snap ls $image_name|grep $snap;
265   
266   local res=$?
267   if [ $res -eq 0 ];then
268     return $res
269   fi
270
271   dd conv=notrunc if=/dev/urandom of=$ofile bs=1M count=$count seek=$seek 2>/dev/null
272   snapshot=$image_name@$snap 
273   rbd snap create $snapshot
274   rm -f $export_image_dir/$snapshot
275   rbd export $pool/$image_name $export_image_dir/$snapshot
276   pushd $export_image_dir >/dev/null
277   md5sum $snapshot >> @md5
278   popd >/dev/null
279 }
280
281 function recover_snapshots()
282 {
283   local func="recover_snapshots"
284   if [ $# -lt 1 ];then
285     echo "$func: parameters: <image_name>"
286     exit
287   fi
288
289   local image_name=$1
290   #pool_id=29
291
292   local recover_image_dir=$recover_dir/pool_$pool_id/$image_name
293   mkdir -p $recover_image_dir
294   local recover_md5=$recover_image_dir/@md5
295   >$recover_md5
296   local snapshot=
297
298   
299   # recover head
300   bash $tool_dir/rbd-recover-tool recover $pool_id/$image_name $recover_dir
301
302   # recover snapshots
303   for((i=1; i<10; i++))
304   do
305     snapshot=snap$i
306     bash $tool_dir/rbd-recover-tool recover $pool_id/$image_name@$snapshot $recover_dir
307     pushd $recover_image_dir >/dev/null
308     local chksum=`md5sum $image_name|awk '{print $1}'` 
309     echo "$chksum  $image_name@$snapshot" >>@md5
310     popd >/dev/null
311   done
312 }
313
314 function export_snapshots()
315 {
316   local func="export_snapshots"
317
318   if [ $# -lt 2 ];then
319     echo "$func: parameters: <image_name> <image_format> [<image_size>]"
320     exit
321   fi
322
323   local image_name=$1
324   local format=$(($2)) 
325   local size=$(($3)) #MB
326   
327   if [ $format -ne 1 ] && [ $format -ne 2 ];then
328     echo "$func: image format must be 1 or 2"
329     exit
330   fi
331
332   if [ $size -eq 0 ];then
333     size=24 #MB
334     echo "$func: size = $size"
335   fi
336   local mnt=/rbdfuse 
337
338   mount |grep "rbd-fuse on /rbdfuse" &>/dev/null
339   if [ $? -ne 0 ];then
340     rbd-fuse $mnt
341   fi
342     
343   create_image $image_name $size $format
344   
345   local export_image_dir=$export_dir/pool_$pool_id/$image_name
346   mkdir -p $export_image_dir
347   local export_md5=$export_image_dir/@md5
348   >$export_md5
349
350   # create 9 snapshots
351   # image = {object0, object1, object2, object3, object4, object5, ...}
352   #
353   # snap1 : init/write all objects 
354   # snap2 : write object0
355   # snap3 : write object1
356   # snap4 : write object2
357   # snap5 : write object3
358   # snap6 : write object4
359   # snap7 : write object5
360   # snap8 : write object0
361   # snap9 : write object3
362
363   make_snapshot $mnt/$image_name 0 $size snap1 $export_image_dir
364   make_snapshot $mnt/$image_name 0  1    snap2 $export_image_dir
365   make_snapshot $mnt/$image_name 4  1    snap3 $export_image_dir
366   make_snapshot $mnt/$image_name 8  1    snap4 $export_image_dir
367   make_snapshot $mnt/$image_name 12 1    snap5 $export_image_dir
368   make_snapshot $mnt/$image_name 16 1    snap6 $export_image_dir
369   make_snapshot $mnt/$image_name 20 1    snap7 $export_image_dir
370   make_snapshot $mnt/$image_name 1  1    snap8 $export_image_dir
371   make_snapshot $mnt/$image_name 13 1    snap9 $export_image_dir
372 }
373
374 function check_recover_nosnap()
375 {
376   local func="check_recover_nosnap"
377   if [ $# -lt 3 ];then
378     echo "$func: parameters: <export_md5_file> <recover_md5_file> <image_name>"
379   fi
380   local export_md5=$1
381   local recover_md5=$2
382   local image_name=$3
383
384   local ifpassed="FAILED"
385  
386   echo "================ < $image_name nosnap > ================" 
387
388   local export_md5sum=`cat $export_md5` 
389   local recover_md5sum=`cat $recover_md5` 
390
391   if [ "$export_md5sum"x != ""x ] && [ "$export_md5sum"x = "$recover_md5sum"x ];then
392     ifpassed="PASSED"
393   fi
394   echo "export:  $export_md5sum"
395   echo "recover: $recover_md5sum $ifpassed"
396 }
397
398 function check_recover_snapshots()
399 {
400   local func="check_recover_snapshots"
401   if [ $# -lt 3 ];then
402     echo "$func: parameters: <export_md5_file> <recover_md5_file> <image_name>"
403   fi
404   local export_md5=$1
405   local recover_md5=$2
406   local image_name=$3
407
408   local ifpassed="FAILED"
409  
410   echo "================ < $image_name snapshots > ================" 
411
412   OIFS=$IFS
413   IFS=$'\n'
414   local export_md5s=(`cat $export_md5`)
415   local recover_md5s=(`cat $recover_md5`)
416   for((i=0; i<9; i++))
417   do
418     OOIFS=$IFS
419     IFS=$'  '
420     local x=$(($i+1))
421     snapshot=snap$x
422
423     local export_arr=(`echo ${export_md5s[$i]}`)
424     local recover_arr=(`echo ${recover_md5s[$i]}`)
425     echo "export:  ${export_md5s[$i]}"
426     if [ "${export_arr[1]}"x != ""x ] && [ "${export_arr[1]}"x = "${recover_arr[1]}"x ];then
427       ifpassed="PASSED"
428     fi
429     echo "recover: ${recover_md5s[$i]} $ifpassed"
430     IFS=$OOIFS
431   done
432   IFS=$OIFS
433 }
434
435 # step 1: export image, snapshot
436 function do_export_nosnap()
437 {
438   export_image image_v1_nosnap 1
439   export_image image_v2_nosnap 2
440 }
441
442 function do_export_snap()
443 {
444   export_snapshots  image_v1_snap 1
445   export_snapshots  image_v2_snap 2
446 }
447
448 # step 2: stop ceph cluster and gen database
449 function stop_cluster_gen_database()
450 {
451   trap 'echo stop ceph cluster failed; exit;' INT HUP
452   stop_ceph 
453   sleep 2
454   check_ceph_service
455   local res=$?
456   while [ $res -ne 0 ]
457   do
458     stop_ceph
459     sleep 2
460     check_ceph_service
461     res=$?
462   done
463
464   echo 0 >$gen_db
465   do_gen_database
466 }
467
468 # step 3: recover image,snapshot
469 function do_recover_nosnap()
470 {
471   recover_image image_v1_nosnap
472   recover_image image_v2_nosnap
473 }
474
475 function do_recover_snap()
476 {
477   recover_snapshots image_v1_snap
478   recover_snapshots image_v2_snap
479 }
480
481 # step 4: check md5sum pair<export_md5sum, recover_md5sum>
482 function do_check_recover_nosnap()
483 {
484   local image1=image_v1_nosnap
485   local image2=image_v2_nosnap
486
487   local export_md5_1=$export_dir/pool_$pool_id/$image1/@md5_nosnap
488   local export_md5_2=$export_dir/pool_$pool_id/$image2/@md5_nosnap
489   local recover_md5_1=$recover_dir/pool_$pool_id/$image1/@md5_nosnap
490   local recover_md5_2=$recover_dir/pool_$pool_id/$image2/@md5_nosnap
491
492   check_recover_nosnap $export_md5_1 $recover_md5_1 $image1 
493   check_recover_nosnap $export_md5_2 $recover_md5_2 $image2
494 }
495
496 function do_check_recover_snap()
497 {
498   local image1=image_v1_snap
499   local image2=image_v2_snap
500
501   local export_md5_1=$export_dir/pool_$pool_id/$image1/@md5
502   local export_md5_2=$export_dir/pool_$pool_id/$image2/@md5
503   local recover_md5_1=$recover_dir/pool_$pool_id/$image1/@md5
504   local recover_md5_2=$recover_dir/pool_$pool_id/$image2/@md5
505
506   check_recover_snapshots $export_md5_1 $recover_md5_1 $image1 
507   check_recover_snapshots $export_md5_2 $recover_md5_2 $image2
508 }
509
510 function test_case_1()
511 {
512   do_export_nosnap
513   stop_cluster_gen_database
514   do_recover_nosnap
515   do_check_recover_nosnap
516 }
517
518 function test_case_2()
519 {
520   do_export_snap
521   stop_cluster_gen_database
522   do_recover_snap
523   do_check_recover_snap
524 }
525
526 function test_case_3()
527 {
528   do_export_nosnap
529   do_export_snap
530
531   stop_cluster_gen_database
532
533   do_recover_nosnap
534   do_recover_snap
535
536   do_check_recover_nosnap
537   do_check_recover_snap
538 }
539
540
541 init $*
542 test_case_3