master 5 years ago
commit
b4d859d15f
3 changed files with 421 additions and 0 deletions
  1. 1 0
      README.md
  2. 9 0
      demo/create_image.sh
  3. 411 0
      kvm-snapshot.sh

+ 1 - 0
README.md

@@ -0,0 +1 @@
1
+Скрипт для снятия сильно сжатых образов через утилиту ntfsclone с образа виртуальной машины.

+ 9 - 0
demo/create_image.sh

@@ -0,0 +1,9 @@
1
+#!/bin/bash
2
+## the size create image disk
3
+exit 0
4
+size_disk=3G;
5
+image="swop_disk.img";
6
+
7
+fallocate -l $size_disk $image ;
8
+echo ok...
9
+exit 0

+ 411 - 0
kvm-snapshot.sh

@@ -0,0 +1,411 @@
1
+#!/bin/bash
2
+# The script is designed to create or restore an image of a virtual machine kvm (c) 2018
3
+# author Koshuba V.O.
4
+# license: MIT
5
+# version: 4.0.0
6
+##
7
+
8
+#<manual_parameters>
9
+path_kvm=( "/kvm/win7x64" 
10
+           "/kvm/win2kx64" );					# path kvm machines
11
+path_bak=( "/arhive/backup/kvm/win7x64" 
12
+           "/arhive/backup/kvm/win2kx64" );			# path backup kvm machines
13
+img_dev=( "disk_c.img" 
14
+          "disk_c.img" );					# storage kvm
15
+img_part=( '"sda1" "sda2"' 
16
+           '"sda1"' );						# sections in media kvm
17
+img_offset=( '"1048576" "105906176"' 
18
+           '"32256"' );						# offset for switch section media kvm
19
+#</manual_parameters>
20
+
21
+#<script_value>
22
+version="4.0.0";
23
+owner="(c) script by Koshuba V.O. 2018";
24
+msg_dat=( '"Script to save or restore the image KVM" "Скрипт сохранения или восстановления образа KVM"'
25
+          '"MAIN MENU" "ГЛАВНОЕ МЕНЮ"'
26
+          '"RESTORE KVM MACHINE" "ВОССТАНОВЛЕНИЕ ГОСТЕВОЙ МАШИНЫ KVM"'
27
+          '"SAVE KVM MACHINE" "СОХРАНЕНИЕ ГОСТЕВОЙ МАШИНЫ KVM"'
28
+          '"EXIT" "ВЫХОД"'
29
+          '"Today:" "Сегодня:"'
30
+          '"Available free space from Backup:" "Доступно свободного места в"' 
31
+          '"SAVE GUEST MACHINE KVM" "СОХРАНИТЬ ГОСТЕВУЮ МАШИНУ KVM"'
32
+          '"RESTORE GUEST MACHINE KVM" "ВОССТАНОВИТЬ ГОСТЕВУЮ МАШИНУ KVM"'
33
+          '"Quit the program" "Выйти из программы"' 
34
+          '"Select kvm machine" "Выберите машину KVM"'
35
+          '"Select kvm image" "Выберите образ KVM"'
36
+          '"{Space} key selection" "Выбор клавиша {Пробел}"'
37
+          '"Not found dialog package, please install." "Не найден пакет: dialog, пожалуйста установите."'
38
+          '"Found the file kvmsnapshot.lock - work is stopped!" "Найден файл kvmsnapshot.lok - работа остановлена!"'
39
+          '"Starting kvm-snapshot script." "Запуск скрипта kvm-snapshot."'
40
+          '"Ending work kvm-snapshot script." "Окончание работы скрипта kvm-snapshot."'
41
+          '"Not found save images!" "Не найдены сохраненные образы!"' );
42
+	  # msg[17]
43
+msg=();											# set current messages
44
+esc_title="";										# title escape menu
45
+esc_msg="";										# message escape menu
46
+esc_menu="";										# return menu escape
47
+set_lang="0";                                                                           # lang messages
48
+menu_mode="";										# type menu select kvm
49
+set_kvm="";										# selected kvm for processing
50
+set_img="";										# selected image for restore kvm machine
51
+rdate=$(date +%d.%m.%y);                                                                # real data
52
+signlok="/tmp/run-kvmsnapshot.lok;";							# sign of work 
53
+scriptlog="/var/log/vm.log";								# log file
54
+DIALOG=${DIALOG=dialog};								# dialog lib
55
+#<Define the dialog exit status codes>
56
+: ${DIALOG_OK=0}
57
+: ${DIALOG_CANCEL=1}
58
+: ${DIALOG_HELP=2}
59
+: ${DIALOG_EXTRA=3}
60
+: ${DIALOG_ITEM_HELP=4}
61
+: ${DIALOG_ESC=255}
62
+#</Define>
63
+scr_tmp=$(tempfile 2>/dev/null) || scr_tmp=/tmp/choise.tmp;				# tmp file
64
+trap "rm -f $scr_tmp" 0 1 2 5 15;
65
+dform="/tmp/dform.tmp";
66
+#</script_value>
67
+
68
+#<functions_&_operations>
69
+operation_menu=( "clear" "getTools" "langMsg" "testproc" "sMainMenu" );
70
+operation_savekvm=( "clear" "saveKvm" "endproc" "exit" );
71
+operation_restorekvm=( "clear" "restoreKvm" "endproc" "exit" );
72
+operation_exit=( "clear" "endproc" "exit" );
73
+#</function_&_operations>
74
+
75
+
76
+#<tools_script>
77
+get_tools=( "ntfsclone" "pigz" "locale" "du" "ntfsfix" "gunzip" );           # tools for script
78
+#</tools_script>
79
+
80
+
81
+#<dialogs>
82
+function sMainMenu() {
83
+local check_dialog=$(apt-cache policy dialog | grep status|wc -m );
84
+if [[ $check_dialog = 0 ]];
85
+    then
86
+    echo -e "${msg[13]}";
87
+    sleep 2
88
+    exit 0
89
+fi
90
+
91
+#<esc_value>
92
+esc_title="${msg[4]}";
93
+esc_msg="${msg[9]}";
94
+esc_menu="sMainMenu";
95
+#</esc_value>
96
+
97
+$DIALOG --clear --backtitle "                ${msg[0]} | $owner | version: $version" \
98
+        --title "${msg[1]}" "$@" \
99
+        --menu " ${msg[5]} $(date +%c) \n
100
+==============================================\n
101
+                                              \n" 20 51 5 \
102
+        "1." "${msg[3]}" \
103
+        "2." "${msg[2]}" \
104
+        "3." "${msg[4]}" 2>$scr_tmp;
105
+input=$(cat $scr_tmp && rm -f $scr_tmp);
106
+
107
+case "$input" in
108
+
109
+"1." | "1." )
110
+ menu_mode="${msg[7]}";
111
+ menuSaveKVM;
112
+;;
113
+
114
+"2." | "2." )
115
+ menu_mode="${msg[8]}";
116
+ menuRestoreKVM;
117
+;;
118
+
119
+"3." | "3." )
120
+ escScript 
121
+;;
122
+
123
+* )
124
+# default select
125
+ escScript;
126
+;;
127
+esac
128
+}
129
+
130
+function escScript() {
131
+$DIALOG --clear --backtitle "                ${msg[0]} | $owner | version: $version"\
132
+        --title "$esc_title"\
133
+        --yesno "\n
134
+\n
135
+        $esc_msg?" 10 50
136
+
137
+case $? in
138
+    0)
139
+        clear;
140
+	execute_func=( ${operation_exit[@]} );
141
+	executor;
142
+        exit 0;
143
+        ;;
144
+    1)
145
+        $esc_menu;
146
+        ;;
147
+    255)
148
+        $esc_menu;
149
+        ;;
150
+esac
151
+}
152
+
153
+
154
+function menuSaveKVM() {
155
+formSetKVM;
156
+source $dform;
157
+slc="$?";
158
+set_kvm=$( echo $(($(cat $scr_tmp && rm -f $scr_tmp && rm -f $dform)-1)));
159
+
160
+case $slc in
161
+    "0" | "0")
162
+    clear;
163
+    execute_func=( ${operation_savekvm[@]} );
164
+    executor;
165
+    ;;
166
+    "1" | "1")
167
+        sMainMenu;
168
+    ;;
169
+    "255" | "255")
170
+        sMainMenu;
171
+    ;;
172
+esac
173
+}
174
+
175
+function menuRestoreKVM() {
176
+formSetKVM;
177
+source $dform;
178
+slc="$?";
179
+set_kvm=$( echo $(($(cat $scr_tmp && rm -f $scr_tmp && rm -f $dform)-1)));
180
+
181
+case $slc in
182
+    "0" | "0")
183
+    clear;
184
+	menuImg;
185
+    ;;
186
+    "1" | "1")
187
+        sMainMenu;
188
+    ;;
189
+    "255" | "255")
190
+        sMainMenu;
191
+    ;;
192
+esac
193
+
194
+}
195
+
196
+function menuImg() {
197
+formSetImg;
198
+
199
+source $dform;
200
+slc="$?";
201
+set_img=$(cat $scr_tmp && rm -f $scr_tmp && rm -f $dform);
202
+case $slc in
203
+    "0" | "0")
204
+    clear;
205
+    execute_func=( ${operation_restorekvm[@]} );
206
+    executor;
207
+    ;;
208
+    "1" | "1")
209
+        menuRestoreKVM;
210
+    ;;
211
+    "255" | "255")
212
+        menuRestoreKVM;
213
+    ;;
214
+esac
215
+
216
+}
217
+
218
+#</dialogs>
219
+
220
+#<functions>
221
+#<Fn test lock file>
222
+testproc(){
223
+if [ -f $scriptlog ];
224
+ then
225
+    echo > $scriptlog;
226
+fi
227
+
228
+if [ -f "$signlok" ];
229
+ then
230
+  echo "$(date) -- ${msg[14]}">>$scriptlog;
231
+  exit 0;
232
+ else
233
+  echo '1'>$signlok; 						# up trigger
234
+  echo "$(date) -- ${msg[15]}" >>$scriptlog;
235
+fi
236
+}
237
+
238
+endproc(){
239
+if [ -f $signlok ];
240
+ then
241
+rm -f $signlok;
242
+fi
243
+echo "$(date) -- ${msg[16]}" >> $scriptlog;
244
+}
245
+
246
+#<Fn_executor>
247
+function executor() {
248
+if [[ ${#execute_func[@]} -eq 0 ]] 
249
+    then echo "exit";
250
+         exit 0; 
251
+fi
252
+for ((ex_index=0; ex_index != ${#execute_func[@]}; ex_index++))
253
+ do
254
+    ## !! debug operation...
255
+    ##echo "execution: function ${execute_func[ex_index]}"
256
+ ${execute_func[ex_index]};
257
+done
258
+}
259
+
260
+#<Fn_get-tools>
261
+function getTools() {
262
+for ((itools=0; itools != ${#get_tools[@]}; itools++))
263
+ do
264
+eval get_${get_tools[$itools]}=$(whereis -b ${get_tools[$itools]}|awk '/^'${get_tools[$itools]}':/{print $2}');
265
+list_tools[${#list_tools[@]}]="$(whereis -b ${get_tools[$itools]}|awk '/^'${get_tools[$itools]}':/{print $2}')";
266
+done
267
+}
268
+
269
+#<Fn_get-lang>
270
+function langMsg() {
271
+if [[ ! $($get_locale|grep 'LANG='|sed 's/\LANG=//g'|grep 'ru_RU.UTF-8'|wc -m) -eq 0 ]];
272
+    then
273
+        set_lang="1";
274
+    else
275
+        set_lang="0";
276
+fi
277
+
278
+for ((ilang=0; ilang != ${#msg_dat[@]}; ilang++))
279
+ do
280
+    eval tmsg="(" $(echo -e ${msg_dat[$ilang]}) ")"; 
281
+    msg[$ilang]=${tmsg[$set_lang]};
282
+done
283
+}
284
+
285
+function formSetKVM() {
286
+echo>$dform;
287
+echo '$DIALOG --backtitle "                '${msg[0]}' | '$owner'" \'>>$dform
288
+echo '  --title "'$menu_mode'" --clear \' >>$dform
289
+echo '  --radiolist "\n              '${msg[10]}'"' '20 60 '${#path_kvm[@]}' \' >>$dform
290
+#<input_list>
291
+if [[ ${#path_kvm[@]} = 0 ]];
292
+    then
293
+    echo " don't find KVM!"
294
+    sleep 1;
295
+    rm -f $dform;
296
+    exit 0;
297
+fi
298
+
299
+for ((ilist=0; ilist != ${#path_kvm[@]}; ilist++))
300
+ do
301
+
302
+    local fmark='';
303
+    local dmark='';
304
+    if [[ $ilist = 0 ]];
305
+        then
306
+        fmark='ON';
307
+        else
308
+        fmark='off';
309
+    fi
310
+    if [[ ! $ilist = $(echo $((${#path_kvm[@]} -1))) ]];
311
+        then
312
+        dmark='\';
313
+        else
314
+        dmark='2> $scr_tmp';
315
+    fi
316
+echo -e '"'"$(echo $(($ilist+1)))"'"' '"'"${path_kvm[$ilist]}"'"' $fmark $dmark >>$dform;
317
+done
318
+
319
+}
320
+
321
+function formSetImg() {
322
+local get_path_bak=${path_bak[$set_kvm]};
323
+eval local get_imgs="(" $(find "$get_path_bak"/* -maxdepth 0 -type d -printf '%f\n') ")";
324
+echo>$dform;
325
+echo '$DIALOG --backtitle "                '${msg[0]}' | '$owner'" \'>>$dform
326
+echo '  --title "'$menu_mode'" --clear \' >>$dform
327
+echo '  --radiolist " '${msg[11]}': '$get_path_bak'\n '${msg[12]}'"' '20 60 '${#get_imgs[@]}' \' >>$dform
328
+#<input_list>
329
+if [[ ${#get_imgs[@]} = 0 ]];
330
+    then
331
+    rm -f $dform;
332
+#<esc_value>
333
+esc_title="${msg[4]}";
334
+esc_msg="${msg[17]} \n           ${msg[9]}";
335
+esc_menu="menuRestoreKVM";
336
+#</esc_value>
337
+    escScript;
338
+fi
339
+
340
+for ((iget=0; iget != ${#get_imgs[@]}; iget++))
341
+ do
342
+
343
+    local fmark='';
344
+    local dmark='';
345
+    if [[ $iget = 0 ]];
346
+        then
347
+        fmark='ON';
348
+        else
349
+        fmark='off';
350
+    fi
351
+    if [[ ! $iget = $(echo $((${#get_imgs[@]} -1))) ]];
352
+        then
353
+        dmark='\';
354
+        else
355
+        dmark='2> $scr_tmp';
356
+    fi
357
+echo -e '"'"${get_imgs[$iget]}"'"' '""' $fmark $dmark >>$dform;
358
+done
359
+}
360
+
361
+function saveKvm() {
362
+local save_kvm="${path_kvm[$set_kvm]}";
363
+local save_bak="${path_bak[$set_kvm]}/$rdate";
364
+local save_img="${img_dev[$set_kvm]}";
365
+eval local save_dev="(" $(echo -e ${img_part[$set_kvm]}) ")";
366
+eval local save_offset="(" "$(echo -e ${img_offset[$set_kvm]})" ")";
367
+local set_loop_main="$(losetup -f|grep -v loop-control|sed 's/\/\dev\///g')";
368
+losetup /dev/$set_loop_main $save_kvm/$save_img;
369
+
370
+if [[ ! -d $save_bak ]];
371
+    then
372
+    mkdir -p $save_bak;
373
+fi
374
+
375
+sfdisk -d /dev/$set_loop_main >$save_bak/info.txt;
376
+dd if=/dev/$set_loop_main of=$save_bak/winboot.img bs=512 count=1;
377
+
378
+for ((iskvm=0; iskvm != ${#save_dev[@]}; iskvm++))
379
+ do
380
+    local set_loop_dev="$(losetup -f|grep -v loop-control|sed 's/\/\dev\///g')";
381
+    losetup -o ${save_offset[$iskvm]} /dev/$set_loop_dev /dev/$set_loop_main;
382
+    ntfsclone --save-image -o - /dev/$set_loop_dev| pigz -p2 -c9>$save_bak/${save_dev[$iskvm]}.img.gz;
383
+    losetup -d /dev/$set_loop_dev;
384
+done
385
+losetup -d /dev/$set_loop_main;
386
+}
387
+
388
+function restoreKvm() {
389
+local rest_kvm="${path_kvm[$set_kvm]}";
390
+local rest_bak="${path_bak[$set_kvm]}/$set_img";
391
+local rest_img="${img_dev[$set_kvm]}";
392
+eval local rest_dev="(" $(echo -e ${img_part[$set_kvm]}) ")";
393
+eval local rest_offset="(" "$(echo -e ${img_offset[$set_kvm]})" ")";
394
+local set_loop_rmain="$(losetup -f|grep -v loop-control|sed 's/\/\dev\///g')";
395
+losetup /dev/$set_loop_rmain $rest_kvm/$rest_img;
396
+dd if=$rest_bak/winboot.img of=/dev/$set_loop_rmain bs=512 count=1;
397
+sleep 1
398
+for ((irkvm=0; irkvm != ${#rest_dev[@]}; irkvm++))
399
+ do
400
+    local set_loop_rdev="$(losetup -f|grep -v loop-control|sed 's/\/\dev\///g')";
401
+    losetup -o ${rest_offset[$irkvm]} /dev/$set_loop_rdev /dev/$set_loop_rmain;
402
+    gunzip -c $rest_bak/${rest_dev[$irkvm]}.img.gz|ntfsclone --restore-image -O /dev/$set_loop_rdev -;
403
+    losetup -d /dev/$set_loop_rdev;
404
+done
405
+losetup -d /dev/$set_loop_rmain;
406
+}
407
+
408
+#</functions>
409
+
410
+execute_func=( ${operation_menu[@]} );
411
+executor;