spacepaste

  1.  
  2. #!/bin/bash
  3. # Backup script for Gentoo Linux
  4. #
  5. # mkstage4.sh is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # mkstage4.sh is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # Copyright: Reto Glauser aka blinkeye
  16. # Mailto: stage4 at blinkeye dot ch
  17. # Homepage: http://blinkeye.ch
  18. # Forum post: http://forums.gentoo.org/viewtopic-t-312817.html
  19. # Date: 2009-04-02
  20. version=v3.7
  21. basename=`basename $0`
  22. find=/usr/bin/find
  23. tar=/bin/tar
  24. # these are the commands we actually need for the backup
  25. command_list=(cut date echo $find grep hostname mount sh split $tar umount uname which)
  26. # verify that each command we use exists. if one can't be found use $PATH and make a suggestion if possible.
  27. for command in ${command_list[@]}; do
  28. if [ ! -x "`which $command 2>&1`" ]; then
  29. echo -e "\nERROR: $command not found! "
  30. base=`basename $command`
  31. if [ "`which $base 2>&1 | grep "no \`basename $command\` in"`" != "" ]; then
  32. echo -e "ERROR: $base is not in your \$PATH."
  33. fi
  34. exit -1
  35. fi
  36. done
  37. help="\nUsage:\n\nsh `basename $0` [[-v]|[--verbose]] [[-s]|[--split]] \n\nTo run the script NOT in verbose mode comes in handy if you want to see only the errors that occur during the backup.\n"
  38. # Defaults to creating one tarball
  39. tar_output="--file"
  40. # split command
  41. split_options="--suffix-length=1 --bytes=685m"
  42. # options for the tar command
  43. tarOptions=" --preserve-permissions --create --absolute-names --totals --ignore-failed-read"
  44. # where to put the stage4
  45. stage4Location=/mnt/backups/stage4
  46. # name prefix
  47. stage4prefix=`hostname`-stage4-`date +\%Y.\%m.\%d`
  48. # patterns which should not be backed up (like iso files).
  49. # example: default_exclude_pattern="*.iso *.divx"
  50. # These pattern count only for files NOT listed in the $custom_include_list.
  51. default_exclude_pattern=""
  52. # these files/directories are always excluded. don't add trailing slashes.
  53. # don't touch it unless you know what you are doing!
  54. # /var/db and /var/cache/edb are intentionally added here. they are listed
  55. # in $default_include_folders
  56. default_exclude_list="
  57. /dev
  58. /lost+found
  59. /mnt
  60. /proc
  61. /sys
  62. /tmp
  63. /usr/portage
  64. /usr/src
  65. /var/log
  66. /var/tmp
  67. /var/db
  68. /var/cache/edb
  69. $stage4Location
  70. `echo $CCACHE_DIR`"
  71. # files/devices/folders, which need to be backed up (preserve folder structure).
  72. # don't touch it unless you know what you are doing! no recursive backup of folders.
  73. # use $default_include_folders instead.
  74. default_include_files="
  75. /dev/null
  76. /dev/console
  77. /home
  78. /mnt
  79. `find /mnt -name .keep`
  80. /proc
  81. /sys
  82. /tmp
  83. /usr/portage
  84. /usr/src
  85. /var/log/emerge.log
  86. /usr/src/linux-`uname -r`/.config"
  87. # folders, which need to be backed up recursively on every backup.
  88. # don't touch it unless you know what you are doing! the reason for this
  89. # variable is that some users add /var to the $default_exclude_list. here
  90. # we ensure that portage's memory is backed up in any case.
  91. default_include_folders="
  92. /var/db"
  93. # IMPORTANT: A minimal backup will EXCLUDE files/folders listed here. A custom backup will
  94. # include/exclude these files/folders depening on your answer.
  95. custom_include_list="
  96. /home/*
  97. /usr/src/linux-`uname -r`"
  98. # add files/folders here which are subfolders of a folder listed in $custom_include_list which should NOT
  99. # be backed up. eg.
  100. #custom_exclude_list="/home/foo/mp3 /home/foo/downloads /home/foo/.*"
  101. custom_exclude_list=""
  102. # Only files/folders within the $custom_include_list are checked against these patterns
  103. # custom_exclude_pattern="*.mp3 *.iso"
  104. custom_exclude_pattern=""
  105. # the find_command
  106. find_command="$find /*"
  107. # don't backup anything which matches pattern listed in $default_exclude_pattern
  108. for pattern in $default_exclude_pattern; do
  109. find_command="$find_command -not -name $pattern"
  110. done
  111. # assemble the find_command
  112. function find_files()
  113. {
  114. for folder in $default_exclude_list; do
  115. find_command="$find_command -path $folder -prune -o"
  116. done
  117. find_command="$find_command -print"
  118. for i in $default_include_files; do
  119. find_command="echo $i; $find_command"
  120. done
  121. for i in $default_include_folders; do
  122. if [ -d $i ]; then
  123. find_command="$find $i; $find_command"
  124. else
  125. find_command="echo $i; $find_command"
  126. fi
  127. done
  128. }
  129. # check the exclude/include variables for non-existing entries
  130. function verify()
  131. {
  132. for i in $1; do
  133. if [ ! -e "`echo "$i" | cut -d'=' -f2 | cut -d'*' -f1`" -a "$i" != "/lost+found" -a "$i" != "$stage4Location" ]; then
  134. echo "ERROR: `echo "$i" | cut -d'=' -f2` not found! Check your "$2
  135. exit 0
  136. fi
  137. done
  138. }
  139. # check input parameters
  140. while [ $1 ]; do
  141. case $1 in
  142. "-h" | "--help")
  143. echo -e $help
  144. exit 0;;
  145. "-v" | "--verbose")
  146. verbose=$1;;
  147. "-s" | "--split")
  148. tar_output="--split";;
  149. "");;
  150. *)
  151. echo -e $help
  152. exit 0;;
  153. esac
  154. shift
  155. done
  156. echo ""
  157. # check folder/files listed in $default_exclude_list exist
  158. verify "$default_exclude_list" "\$default_exclude_list"
  159. # check files listed in $default_include_files exist
  160. verify "$default_include_files" "\$default_include_files"
  161. # check folder listed in $default_include_folders exist
  162. verify "$default_include_folders" "\$default_include_folders"
  163. #check folder listed in $custom_include_list exist
  164. verify "$custom_include_list" "\$custom_include_list"
  165. #check folder listed in $custom_exclude_list exist
  166. verify "$custom_exclude_list" "\$custom_exclude_list"
  167. # print out the version
  168. echo -e "\nBackup script $version"
  169. echo -e "=================="
  170. # how do you want to backup?
  171. echo -e "\nWhat do you want to do? (Use CONTROL-C to abort)\n
  172. Fast (tar.gz):
  173. (1) Minimal backup
  174. (2) Interactive backup
  175. Best (tar.bz2):
  176. (3) Minimal backup
  177. (4) Interactive backup\n"
  178. while [ "$option" != '1' -a "$option" != '2' -a "$option" != '3' -a "$option" != '4' ]; do
  179. echo -en "Please enter your option: "
  180. read option
  181. done
  182. case $option in
  183. [1,3])
  184. stage4Name=$stage4Location/$stage4prefix-minimal.tar;;
  185. [2,4])
  186. stage4Name=$stage4Location/$stage4prefix-custom.tar
  187. for folder in $custom_include_list; do
  188. echo -en "\nDo you want to backup" `echo "$folder" | cut -d'=' -f2`"? (y/n) "
  189. read answer
  190. while [ "$answer" != 'y' -a "$answer" != 'n' ]; do
  191. echo -en "Do you want to backup" `echo "$folder" | cut -d'=' -f2`"? (y/n) "
  192. read answer
  193. done
  194. if [ "$answer" == 'n' ]; then
  195. find_command="$find_command -path $folder -prune -o"
  196. else
  197. custom_find="$find $folder"
  198. for i in $custom_exclude_pattern; do
  199. custom_find="$custom_find -name $i -o"
  200. done
  201. for i in $custom_exclude_list; do
  202. custom_find="$custom_find -path $i -prune -o"
  203. done
  204. find_command="$custom_find -print; $find_command"
  205. fi
  206. done ;;
  207. esac
  208. # add $custom_include_list to the $default_exclude_list as we assembled
  209. # $custom_find with $custom_include_list already.
  210. default_exclude_list="$default_exclude_list $custom_include_list"
  211. case $option in
  212. [1,2])
  213. stage4postfix="gz"
  214. zip="--gzip";;
  215. [3,4])
  216. stage4postfix="bz2"
  217. zip="--bzip2";;
  218. esac
  219. # mount boot
  220. echo -e "\n* mounting boot"
  221. mount /boot >/dev/null 2>&1
  222. # find the files/folder to backup
  223. find_files
  224. find_command="($find_command)"
  225. # create the final command
  226. if [ "$tar_output" == "--file" ]; then
  227. tar_command="$find_command | $tar $zip $tarOptions $verbose --file $stage4Name.$stage4postfix --no-recursion -T -"
  228. else
  229. tar_command="$find_command | $tar $zip $tarOptions $verbose --no-recursion -T - | split $split_options - "$stage4Name.$stage4postfix"_"
  230. fi
  231. if [ "$verbose" ]; then
  232. echo -e "\n* creating the stage4 in $stage4Location with the following command:\n\n"$tar_command
  233. fi
  234. # everything is set, are you sure to continue?
  235. echo -ne "\nDo you want to continue? (y/n) "
  236. read answer
  237. while [ "$answer" != 'y' ] && [ "$answer" != 'n' ]; do
  238. echo -ne "Do you want to continue? (y/n) "
  239. read answer
  240. done
  241. if [ "$answer" == 'y' ]; then
  242. # check whether the file already exists.
  243. if [ "$tar_output" == "--split" ]; then
  244. overwrite="`ls "$stage4Name.$stage4postfix"_* 2>&1 | grep -v 'No such file'`"
  245. else
  246. overwrite="$stage4Name.$stage4postfix"
  247. fi
  248. if [ -a "`echo "$overwrite" | grep "$overwrite" -m1`" ]; then
  249. echo -en "\nDo you want to overwrite $overwrite? (y/n) "
  250. read answer
  251. while [ "$answer" != 'y' ] && [ "$answer" != 'n' ]; do
  252. echo -en "Do you want to overwrite $overwrite? (y/n) "
  253. read answer
  254. done
  255. if [ "$answer" == 'n' ]; then
  256. echo -e "\n* There's nothing to do ... Exiting"
  257. exit 0;
  258. fi
  259. fi
  260. # if necessary, create the stage4Location
  261. if [ ! -d "$stage4Location" ] ; then
  262. echo "* creating directory $stage4Location"
  263. mkdir -p $stage4Location
  264. fi
  265. echo -e "\n* Please wait while the stage4 is being created.\n"
  266. # do the backup.
  267. sh -c "$tar_command"
  268. # finished, clean up
  269. echo -e "\n* stage4 is done"
  270. echo "* umounting boot"
  271. umount /boot >/dev/null 2>&1
  272. # Integrity check
  273. echo -e "* Checking integrity"
  274. if [ "$zip" == "--gzip" ]; then
  275. zip="gzip"
  276. else
  277. zip="bzip2"
  278. fi
  279. if [ "$tar_output" == "--split" ]; then
  280. if [ "`cat "$stage4Name.$stage4postfix"_*"" | $zip --test 2>&1`" != "" ]; then
  281. echo -e "* Integrity check failed. Re-run the script and check your hardware."
  282. exit -1
  283. fi
  284. else
  285. if [ "`$zip --test $stage4Name.$stage4postfix 2>&1`" != "" ]; then
  286. echo -e "* Integrity check failed. Re-run the script and check your hardware."
  287. exit -1
  288. fi
  289. fi
  290. # everything went smoothly
  291. echo -e "* Everything went smoothly. You successfully created a stage4."
  292. else
  293. echo -e "\n* There's nothing to do ... Exiting"
  294. fi
  295.