mkdebusb.sh 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #!/bin/bash
  2. # mkdebusb.sh (Persistent Debian live environment scripts) 0.0.8
  3. #
  4. # Currently only x86_64 is supported
  5. #
  6. # License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
  7. # This is free software: you are free to change and redistribute it.
  8. # There is NO WARRANTY, to the extent permitted by law.
  9. # initialize all option variables
  10. dev=
  11. iso=
  12. overlay=
  13. dependencies="syslinux grub-efi-amd64-bin"
  14. abort() {
  15. usage
  16. printf '\n%s\n' "$1" >&2
  17. exit 1
  18. }
  19. usage() {
  20. echo "Usage: mkdebusb.sh -d|--device=DEVICE_NODE -i|--iso=ISO_IMAGE [-o|--overlay=OVERLAY_ARCHIVE]
  21. Example: mkdebusb.sh -d /dev/sdb -i /path/to/Debian/live.iso"
  22. }
  23. show_help_overlay() {
  24. echo "To create an overlay archive of an already existent persistent Debian live device,
  25. simply mount the partition and tar cvzf the rw folder to a destination of choice.
  26. This archive can then be specified with the -o option during creation of a live media"
  27. }
  28. show_help() {
  29. usage
  30. echo "Creates a bootable USB device from a Debian live iso and enables persistence.
  31. Mandatory arguments to long options are mandatory for short options too.
  32. -d --device=PATH full path to the USB device node.
  33. -h --help display this help and exit
  34. -i --iso=PATH path to the original Debian live iso.
  35. -o --overlay=PATH a backup of an overlay tar.gz archive
  36. can be specified which will be
  37. extracted to the persistence
  38. partition. (optional)
  39. See -b for an explanation on how
  40. to create an overlay archive.
  41. --install-dependencies install the required dependencies
  42. only needs to be run once
  43. --debug print debug output
  44. only needs to be run once
  45. -v --version show version & licence and exit
  46. WARNING: all data on the given device node will be destroyed!"
  47. }
  48. show_version() {
  49. echo "mkdebusb.sh (Persistent Debian live environment scripts) 0.0.8
  50. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
  51. This is free software: you are free to change and redistribute it.
  52. There is NO WARRANTY, to the extent permitted by law."
  53. }
  54. # parse arguments
  55. while :; do
  56. case $1 in
  57. -h|--help)
  58. show_help
  59. exit 0
  60. ;;
  61. -b|--backup)
  62. show_help_overlay
  63. exit 0
  64. ;;
  65. -d|--device)
  66. if [ "$2" ]
  67. then
  68. dev="$2"
  69. shift
  70. fi
  71. ;;
  72. --device=?*)
  73. dev="${1#*=}"
  74. ;;
  75. --device=)
  76. abort '"--directory" must specify a path; see --help'
  77. ;;
  78. -i|--iso)
  79. if [ "$2" ]
  80. then
  81. iso="$2"
  82. shift
  83. fi
  84. ;;
  85. --iso=?*)
  86. iso="${1#*=}"
  87. ;;
  88. --iso=)
  89. abort '"--iso" must specify a path; see --help'
  90. ;;
  91. -o|--overlay)
  92. if [ "$2" ]
  93. then
  94. overlay="$2"
  95. shift
  96. fi
  97. ;;
  98. --overlay=?*)
  99. overlay="${1#*=}"
  100. ;;
  101. --overlay=)
  102. abort '"--overlay" must specify a path; see --help'
  103. ;;
  104. --install-dependencies)
  105. installdeps=true
  106. ;;
  107. --debug)
  108. debug=true
  109. ;;
  110. -u|--usage)
  111. usage
  112. exit 0
  113. ;;
  114. -v|--version)
  115. show_version
  116. exit 0
  117. ;;
  118. --)
  119. shift
  120. break
  121. ;;
  122. -?*)
  123. abort 'Unknown option. See "--help" for help or "--usage" for usage.'
  124. ;;
  125. *)
  126. break
  127. esac
  128. shift
  129. done
  130. confirmation() {
  131. read -n1 -rsp $'WARNING! All data on the specified device will be destroyed. Press any key to continue or Ctrl+C to exit...\n'
  132. }
  133. create_dirs() {
  134. mkdir /tmp/usb-efi /tmp/usb-live /tmp/usb-persistence /tmp/live-iso
  135. return 0
  136. }
  137. remove_dirs() {
  138. rmdir --ignore-fail-on-non-empty /tmp/usb-efi /tmp/usb-live /tmp/usb-persistence /tmp/live-iso
  139. }
  140. umount_dev() {
  141. umount "$dev"*
  142. return 0
  143. }
  144. create_partitions() {
  145. parted "$dev" --script mktable gpt
  146. parted "$dev" --script mkpart EFI fat16 1MiB 10MiB
  147. parted "$dev" --script mkpart live fat16 10MiB 3GiB
  148. parted "$dev" --script mkpart persistence ext4 3GiB 100%
  149. parted "$dev" --script set 1 msftdata on
  150. parted "$dev" --script set 2 legacy_boot on
  151. parted "$dev" --script set 2 msftdata on
  152. sync
  153. return 0
  154. }
  155. init_filesystems() {
  156. mkfs.vfat -n EFI "$dev"1
  157. mkfs.vfat -n LIVE "$dev"2
  158. mkfs.ext4 -F -L persistence "$dev"3
  159. }
  160. mount_filesystems() {
  161. mount "$dev"1 /tmp/usb-efi
  162. mount "$dev"2 /tmp/usb-live
  163. mount "$dev"3 /tmp/usb-persistence
  164. mount -oro "$iso" /tmp/live-iso
  165. return 0
  166. }
  167. unmount_filesystems() {
  168. umount /tmp/usb-efi /tmp/usb-live /tmp/usb-persistence /tmp/live-iso
  169. }
  170. copy_iso_content() {
  171. cp -ar /tmp/live-iso/* /tmp/usb-live
  172. }
  173. install_bootloader() {
  174. grub-install --no-uefi-secure-boot --removable --target=x86_64-efi --boot-directory=/tmp/usb-live/boot/ --efi-directory=/tmp/usb-efi "$dev"
  175. dd bs=440 count=1 conv=notrunc if=/usr/lib/syslinux/mbr/gptmbr.bin of="$dev"
  176. syslinux --install "$dev"2
  177. mv /tmp/usb-live/isolinux /tmp/usb-live/syslinux
  178. mv /tmp/usb-live/syslinux/isolinux.bin /tmp/usb-live/syslinux/syslinux.bin
  179. mv /tmp/usb-live/syslinux/isolinux.cfg /tmp/usb-live/syslinux/syslinux.cfg
  180. }
  181. configure_persistence() {
  182. echo "/ union" > /tmp/usb-persistence/persistence.conf
  183. sed --in-place 's#isolinux/splash#syslinux/splash#' /tmp/usb-live/boot/grub/grub.cfg
  184. sed --in-place '0,/boot=live/{s/\(boot=live .*\)$/\1 persistence persistence-storage=filesystem persistence-media=removable-usb/}' /tmp/usb-live/boot/grub/grub.cfg /tmp/usb-live/syslinux/menu.cfg
  185. # action item: make this configurable in the future
  186. sed --in-place '0,/boot=live/{s/\(boot=live .*\)$/\1 keyboard-layouts=ch locales=de_CH.UTF-8/}' /tmp/usb-live/boot/grub/grub.cfg /tmp/usb-live/syslinux/menu.cfg
  187. }
  188. extract_overlay() {
  189. if [ "$overlay" ]
  190. then
  191. tar xvzf "$overlay" -C /tmp/usb-persistence/
  192. fi
  193. }
  194. install_dependencies() {
  195. if [ "$installdeps" = true ]
  196. then
  197. echo "Installing dependencies..."
  198. apt-get update
  199. apt-get install -y $dependencies \
  200. && echo "Dependencies installed successfully" \
  201. || abort 'Installation failed!'
  202. exit 0
  203. fi
  204. }
  205. spin()
  206. {
  207. spinner="/|\\-/|\\-"
  208. while :
  209. do
  210. for i in `seq 0 7`
  211. do
  212. echo -n "${spinner:$i:1}"
  213. echo -en "\010"
  214. sleep 1
  215. done
  216. done
  217. }
  218. # make sure we are root & good to go
  219. if [ "$EUID" -ne 0 ]
  220. then
  221. abort 'Missing root privileges. Aborting.'
  222. fi
  223. install_dependencies
  224. if [ -z "$dev" ]
  225. then
  226. abort 'Error No device node specified!'
  227. fi
  228. if [ -z "$iso" ]
  229. then
  230. abort 'Error: No iso image specified!'
  231. fi
  232. confirmation
  233. if [[ ! $debug ]]
  234. then
  235. # Start the Spinner:
  236. spin &
  237. # Make a note of its Process ID (PID):
  238. SPIN_PID=$!
  239. fi
  240. exec 3>&1; if [[ ! $debug ]]; then exec >/dev/null 2>&1; fi
  241. umount_dev &&
  242. create_partitions &&
  243. init_filesystems &&
  244. create_dirs &&
  245. mount_filesystems &&
  246. copy_iso_content &&
  247. install_bootloader &&
  248. configure_persistence &&
  249. extract_overlay &&
  250. unmount_filesystems &&
  251. remove_dirs
  252. if [[ ! $debug ]]; then kill $SPIN_PID; fi
  253. printf 'Finished\n' >&3