mklive.sh.in 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. #!/bin/sh
  2. #-
  3. # Copyright (c) 2009-2012 Juan Romero Pardines.
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. # 1. Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. #
  15. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17. # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24. # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. #-
  26. trap "echo; error_out $?" INT QUIT
  27. info_msg() {
  28. printf "\033[1m$@\n\033[m"
  29. }
  30. mount_pseudofs() {
  31. local fs
  32. for fs in sys proc dev; do
  33. if [ ! -d "$ROOTFS/$fs" ]; then
  34. mkdir -p "$ROOTFS/$fs"
  35. fi
  36. mount --bind /$fs "$ROOTFS/$fs" || error_out $?
  37. done
  38. }
  39. umount_pseudofs() {
  40. local fs
  41. for fs in sys proc dev; do
  42. umount -f "$ROOTFS/$fs" >/dev/null 2>&1
  43. done
  44. }
  45. error_out() {
  46. umount_pseudofs
  47. info_msg "There was an error! cleaning up $BUILDDIR, exiting..."
  48. [ -d "$BUILDDIR" ] && rm -rf "$BUILDDIR"
  49. [ -f "$LOGFILE" ] && rm -f "$LOGFILE"
  50. exit 1
  51. }
  52. write_etc_motd() {
  53. cat >> "$ROOTFS/etc/motd" <<_EOF
  54. ###############################################################################
  55. Autogenerated by void-mklive @@MKLIVE_VERSION@@
  56. -------------------------------------------------------------------------------
  57. Welcome to the Void Linux Live system, you have been autologged in.
  58. This user has full sudo(8) permissions without any password, be careful
  59. executing commands through sudo(8).
  60. To play with package management use the xbps-bin(8) and xbps-repo(8)
  61. utilities. Please visit:
  62. http://code.google.com/p/xbps/
  63. for more information and/or documentation about using the X Binary
  64. Package System. If you think it is useful, please make a donation
  65. to improve further development from the above URL, thanks.
  66. To start the installation please type:
  67. $ sudo void-installer
  68. and follow the on-screen instructions. Thanks for trying Void Linux.
  69. ###############################################################################
  70. _EOF
  71. }
  72. write_conf_file() {
  73. cat > "$1" <<_EOF
  74. # *-*- sh -*-*
  75. # Default configuration file for vmklive-@VERSION@.
  76. #
  77. # List of packages to be installed into the live image.
  78. # At least 'base-system' or 'base-system-live' is required.
  79. PACKAGE_LIST="base-system-live"
  80. # Syslinux splash image.
  81. SPLASH_IMAGE=/usr/share/void-artwork/splash.png
  82. # Default keymap to use.
  83. KEYMAP=us
  84. # Default locale to use.
  85. LOCALE=en_US
  86. # Path to XBPS utilities.
  87. #XBPS_BIN_CMD=xbps-bin
  88. #XBPS_REPO_CMD=xbps-repo
  89. #XBPS_UHELPER_CMD=xbps-uhelper
  90. # XBPS cache directory to install packages from.
  91. #REPOSITORY_CACHE=/blah/foo
  92. _EOF
  93. chmod 644 "$1"
  94. }
  95. usage()
  96. {
  97. cat <<_EOF
  98. Usage: $(basename $0) [options]
  99. Options:
  100. -C file Path to configuration file (defaults to ~/.mklive.conf)
  101. -c (gzip|bzip2|xz) Compression type for the squashfs/initramfs image.
  102. -k version Kernel version to use.
  103. -o outfile Output file name for the ISO image.
  104. -s splash Splash image file for isolinux.
  105. _EOF
  106. exit 1
  107. }
  108. #
  109. # main()
  110. #
  111. while getopts "C:c:k:o:s:h" opt; do
  112. case $opt in
  113. C) CONFIG_FILE="$OPTARG";;
  114. c) COMPRESSTYPE="$OPTARG";;
  115. k) KERNELVERSION="$OPTARG";;
  116. o) OUTPUT_FILE="$OPTARG";;
  117. s) SPLASH_IMAGE="$OPTARG";;
  118. h) usage;;
  119. esac
  120. done
  121. shift $(($OPTIND - 1))
  122. if [ -z "$KERNELVERSION" ]; then
  123. KERNELVERSION="$(uname -r)"
  124. fi
  125. # Set defaults
  126. if [ -z "$CONFIG_FILE" ]; then
  127. CONFIG_FILE="$HOME/.mklive.conf"
  128. fi
  129. if [ -z "$OUTPUT_FILE" ]; then
  130. OUTPUT_FILE="$HOME/void-live-$(uname -m)-${KERNELVERSION}-$(date +%Y%m%d).iso"
  131. fi
  132. LOGFILE="$(mktemp -t vmklive-XXXXXXXXXX.log)"
  133. if [ -z "$SYSLINUX_DATADIR" ]; then
  134. SYSLINUX_DATADIR=/usr/share/syslinux
  135. fi
  136. if [ -z "$GRUB_DATADIR" ]; then
  137. GRUB_DATADIR=/usr/share/grub
  138. fi
  139. if [ -z "$MKLIVE_DATADIR" ]; then
  140. MKLIVE_DATADIR=/usr/share/void-mklive
  141. fi
  142. if [ -z "$SPLASH_IMAGE" ]; then
  143. SPLASH_IMAGE=/usr/share/void-artwork/splash.png
  144. fi
  145. if [ -z "$XBPS_REPO_CMD" ]; then
  146. XBPS_REPO_CMD=xbps-repo
  147. fi
  148. if [ -z "$XBPS_BIN_CMD" ]; then
  149. XBPS_BIN_CMD=xbps-bin
  150. fi
  151. if [ -z "$XBPS_UHELPER_CMD" ]; then
  152. XBPS_UHELPER_CMD=xbps-uhelper
  153. fi
  154. if [ -z "$COMPRESSTYPE" ]; then
  155. COMPRESSTYPE=xz
  156. fi
  157. # Create or read configuration file.
  158. if [ ! -r $CONFIG_FILE ]; then
  159. info_msg "Creating config file at $CONFIG_FILE."
  160. write_conf_file $CONFIG_FILE
  161. fi
  162. . $CONFIG_FILE
  163. if [ -z "$PACKAGE_LIST" ]; then
  164. PACKAGE_LIST="base-system-live"
  165. else
  166. PACKAGE_LIST="$PACKAGE_LIST"
  167. fi
  168. if [ ! -f $SYSLINUX_DATADIR/isolinux.bin ]; then
  169. echo "Missing required isolinux files in $SYSLINUX_DATADIR, exiting..."
  170. exit 1
  171. fi
  172. # Check for root permissions.
  173. if [ "$(id -u)" -ne 0 ]; then
  174. echo "Must be run as root, exiting..."
  175. exit 1
  176. fi
  177. ISO_VOLUME="VOID_LIVE"
  178. BUILDDIR=$(mktemp --tmpdir=$HOME -d) || exit 1
  179. BUILDDIR=$(readlink -f $BUILDDIR)
  180. ROOTFS="$BUILDDIR/rootfs"
  181. BOOT_DIR="$BUILDDIR/boot"
  182. ISOLINUX_DIR="$BOOT_DIR/isolinux"
  183. GRUB_DIR="$BOOT_DIR/grub"
  184. ISOLINUX_CFG="$ISOLINUX_DIR/isolinux.cfg"
  185. #
  186. # Check there are repos registered before anything.
  187. #
  188. ${XBPS_REPO_CMD} list >/dev/null 2>&1
  189. if [ $? -ne 0 ]; then
  190. echo "No repositories available, exiting..."
  191. error_out
  192. fi
  193. #
  194. # Mount pseudofs in the target rootfs.
  195. #
  196. mount_pseudofs
  197. mkdir -p "$ROOTFS/tmp" "$ISOLINUX_DIR" "$GRUB_DIR"
  198. XBPS_ARGS="-r $ROOTFS -y"
  199. if [ -n "$REPOSITORY_CACHE" ]; then
  200. XBPS_ARGS="$XBPS_ARGS -c $REPOSITORY_CACHE"
  201. fi
  202. XBPS_VERSION=$($XBPS_BIN_CMD -V|awk '{print $2}')
  203. case $XBPS_VERSION in
  204. # XBPS >= 0.16
  205. [0-9].[1-9][6-9]*) XBPS_016=1;;
  206. esac
  207. info_msg "Redirecting stdout/stderr to $LOGFILE ..."
  208. info_msg "[1/10] Installing packages into the rootfs..."
  209. for f in ${PACKAGE_LIST}; do
  210. info_msg " $f"
  211. done
  212. # Check that all pkgs are reachable.
  213. ${XBPS_BIN_CMD} ${XBPS_ARGS} -n install ${PACKAGE_LIST} >>$LOGFILE 2>&1
  214. if [ $? -ne 0 ]; then
  215. info_msg "Missing required binary packages, exiting..."
  216. error_out
  217. fi
  218. ${XBPS_BIN_CMD} ${XBPS_ARGS} install ${PACKAGE_LIST} \
  219. 2>&1|cat >> $LOGFILE || error_out
  220. ${XBPS_BIN_CMD} ${XBPS_ARGS} autoupdate \
  221. 2>&1|cat >> $LOGFILE || error_out
  222. ${XBPS_BIN_CMD} ${XBPS_ARGS} autoremove \
  223. 2>&1|cat >> $LOGFILE || error_out
  224. ${XBPS_BIN_CMD} -r "$ROOTFS" list > \
  225. "${OUTPUT_FILE%.iso}"-package-list.txt || error_out
  226. #
  227. # Prepare /etc/motd.
  228. #
  229. info_msg "[2/10] Creating /etc/motd..."
  230. mkdir -p "$ROOTFS"/etc
  231. write_etc_motd
  232. #
  233. # Create the initramfs with XZ compression.
  234. #
  235. info_msg "[3/10] Creating initramfs image ($COMPRESSTYPE)..."
  236. dracut --no-hostonly --add "dmsquash-live vmklive" --${COMPRESSTYPE} \
  237. "${BOOT_DIR}/initrd.lz" ${KERNELVERSION} 2>/dev/null || error_out
  238. #
  239. # Copy the linux image to the target directory.
  240. #
  241. info_msg "[4/10] Copying kernel image/modules..."
  242. cp -f /boot/vmlinuz-${KERNELVERSION} "${BOOT_DIR}/vmlinuz" || error_out $?
  243. mkdir -p "$ROOTFS/lib/modules"
  244. cp -a /lib/modules/${KERNELVERSION} "$ROOTFS/lib/modules" || error_out $?
  245. # Generate a sane xbps.conf for the rootfs.
  246. rm -f $ROOTFS/etc/xbps/xbps.conf
  247. echo "# xbps.conf generated by void-mklive-@@MKLIVE_VERSION@@" \
  248. > $ROOTFS/etc/xbps/xbps.conf
  249. echo "TransactionFrequencyFlush = 0" \
  250. >> $ROOTFS/etc/xbps/xbps.conf
  251. echo "virtual-package rsyslog { targets = syslog-daemon-0 }" \
  252. >> $ROOTFS/etc/xbps/xbps.conf
  253. echo "virtual-package dcron { targets = cron-daemon-0 }" \
  254. >> $ROOTFS/etc/xbps/xbps.conf
  255. echo "virtual-package kmod { targets = module-init-tools-3.17 }" \
  256. >> $ROOTFS/etc/xbps/xbps.conf
  257. _devel=$($XBPS_UHELPER_CMD -r $ROOTFS version xbps-devel)
  258. if [ -n "${_devel}" ]; then
  259. echo "virtual-package xbps-devel { targets = xbps-9999 }" \
  260. >> $ROOTFS/etc/xbps/xbps.conf
  261. fi
  262. # Generate a conf for local repositories.
  263. cat > $ROOTFS/etc/xbps/local-repos.conf <<_EOF
  264. repositories = {
  265. # XBPS >= 0.16
  266. /packages,
  267. }
  268. _EOF
  269. # Generate a conf for remote repositories.
  270. cat > $ROOTFS/etc/xbps/network-repos.conf <<_EOF
  271. repositories = {
  272. # XBPS >= 0.16
  273. http://xbps.hosting-unlimited.org/binpkgs,
  274. http://xbps.goodluckwith.us/binpkgs,
  275. http://xbps.nopcode.org/repos/current,
  276. }
  277. _EOF
  278. chmod 644 $ROOTFS/etc/xbps/*.conf || error_out $?
  279. # Create local repos for base-system and grub packages required by
  280. # the void-installer pkg.
  281. pkgs=$($XBPS_BIN_CMD -r /tmp/blah -n install base-system grub)
  282. set -- ${pkgs}
  283. while [ $# -ne 0 ]; do
  284. pkgn=$1; action=$2; ver=$3; repo=$4; binpkg=$5; arch=$6
  285. if [ -z "$XBPS_016" ]; then
  286. arch=$(basename $repo)
  287. shift 5
  288. else
  289. shift 6
  290. fi
  291. mkdir -p $ROOTFS/packages/$arch
  292. bpkg=$repo/$arch/$binpkg
  293. cp -f $bpkg $ROOTFS/packages/$arch
  294. done
  295. if [ -n "$XBPS_016" ]; then
  296. $XBPS_REPO_CMD genindex $ROOTFS/packages 2>&1 >>$LOGFILE
  297. rm -f $ROOTFS/packages/index-files.plist
  298. else
  299. for f in $ROOTFS_REPODIR/*; do
  300. ${XBPS_REPO_CMD} genindex $f 2>&1 >>$LOGFILE
  301. rm -f $f/rindex-files.plist
  302. done
  303. fi
  304. # install lsblk and blkid from util-linux. to avoid installing
  305. # the whole package.
  306. _lsblk=$(which lsblk)
  307. _blkid=$(which blkid)
  308. install -Dm755 ${_lsblk} "$ROOTFS/usr/bin/lsblk" || error_out $?
  309. install -Dm755 ${_blkid} "$ROOTFS/sbin/blkid" || error_out $?
  310. # install mount from util-linux.
  311. install -Dm755 /bin/mount "$ROOTFS/bin/mount" || error_out $?
  312. #
  313. # The pseudofs aren't needed anymore in target rootfs.
  314. #
  315. umount_pseudofs
  316. #
  317. # Prepare isolinux files in the target rootfs.
  318. #
  319. info_msg "[5/10] Preparing isolinux support for BIOS..."
  320. cp -f $SYSLINUX_DATADIR/isolinux.bin "$ISOLINUX_DIR" || error_out $?
  321. cp -f $SYSLINUX_DATADIR/vesamenu.c32 "$ISOLINUX_DIR" || error_out $?
  322. cp -f $MKLIVE_DATADIR/isolinux.cfg.in \
  323. "$ISOLINUX_DIR"/isolinux.cfg || error_out $?
  324. if [ -f "$SPLASH_IMAGE" ]; then
  325. cp -f $SPLASH_IMAGE "$ISOLINUX_DIR" || error_out $?
  326. fi
  327. sed -i -e "s|@@SPLASHIMAGE@@|$(basename $SPLASH_IMAGE)|" \
  328. -e "s|@@KERNVER@@|${KERNELVERSION}|" \
  329. -e "s|@@KEYMAP@@|${KEYMAP}|" \
  330. -e "s|@@LOCALE@@|${LOCALE}|" $ISOLINUX_DIR/isolinux.cfg
  331. #
  332. # Prepare grub files for EFI.
  333. #
  334. info_msg "[6/10] Preparing GRUB support for EFI..."
  335. cp -f $MKLIVE_DATADIR/grub.cfg $GRUB_DIR || error_out $?
  336. cp -f $MKLIVE_DATADIR/grub_void.cfg.in $GRUB_DIR/grub_void.cfg || error_out $?
  337. sed -i -e "s|@@SPLASHIMAGE@@|$(basename $SPLASH_IMAGE)|" \
  338. -e "s|@@KERNVER@@|${KERNELVERSION}|" \
  339. -e "s|@@KEYMAP@@|${KEYMAP}|" \
  340. -e "s|@@LOCALE@@|${LOCALE}|" $GRUB_DIR/grub_void.cfg
  341. mkdir -p $GRUB_DIR/fonts $GRUB_DIR/locale || error_out $?
  342. cp -f $GRUB_DATADIR/unicode.pf2 $GRUB_DIR/fonts || error_out $?
  343. cp -f /boot/grub/locale/* $GRUB_DIR/locale || error_out $?
  344. # Create EFI vfat image.
  345. dd if=/dev/zero of=$GRUB_DIR/efiboot.img bs=1024 count=4096 \
  346. 2>&1 | cat >>$LOGFILE || error_out $?
  347. mkfs.vfat -F12 -S 512 -n "grub_uefi" "$GRUB_DIR/efiboot.img" \
  348. 2>&1 | cat >>$LOGFILE || error_out $?
  349. GRUB_EFI_TMPDIR="$(mktemp --tmpdir=$HOME -d)"
  350. LOOP_DEVICE="$(losetup --show --find ${GRUB_DIR}/efiboot.img)"
  351. mount -o rw,flush -t vfat "${LOOP_DEVICE}" "${GRUB_EFI_TMPDIR}" \
  352. 2>&1 | cat >>$LOGFILE || error_out $?
  353. mkdir -p "${GRUB_EFI_TMPDIR}/EFI/boot/" || error_out $?
  354. cd "$BUILDDIR" || error_out $?
  355. grub-mkstandalone --directory="/usr/lib/grub/x86_64-efi" --format="x86_64-efi" \
  356. --compression="xz" --output="${GRUB_EFI_TMPDIR}/EFI/boot/bootx64.efi" \
  357. "boot/grub/grub.cfg" 2>&1 | cat >>$LOGFILE || error_out $?
  358. umount "$GRUB_EFI_TMPDIR" || error_out $?
  359. losetup --detach "${LOOP_DEVICE}" || error_out $?
  360. rm -rf $GRUB_EFI_TMPDIR || error_out $?
  361. #
  362. # Prepare the squashed rootfs image.
  363. #
  364. info_msg "[7/10] Creating squashfs image ($COMPRESSTYPE) from rootfs..."
  365. # Find out required size for the rootfs and create an ext3fs image off it.
  366. ROOTFS_SIZE=$(du -sk "$ROOTFS"|awk '{print $1}')
  367. mkdir -p "$BUILDDIR/tmp/LiveOS"
  368. dd if=/dev/zero of="$BUILDDIR/tmp/LiveOS/ext3fs.img" \
  369. bs="$((${ROOTFS_SIZE}+($ROOTFS_SIZE/6)))K" count=1 2>&1 | cat >>$LOGFILE || error_out $?
  370. mkdir -p "$BUILDDIR/tmp-rootfs"
  371. mkfs.ext3 -F -m1 "$BUILDDIR/tmp/LiveOS/ext3fs.img" 2>&1 | cat >>$LOGFILE || error_out $?
  372. mount -o loop "$BUILDDIR/tmp/LiveOS/ext3fs.img" "$BUILDDIR/tmp-rootfs" || error_out $?
  373. cd $BUILDDIR
  374. cp -a rootfs/* tmp-rootfs/
  375. umount -f "$BUILDDIR/tmp-rootfs"
  376. mkdir -p "$BUILDDIR/LiveOS"
  377. mksquashfs "$BUILDDIR/tmp" "$BUILDDIR/LiveOS/squashfs.img" \
  378. -comp ${COMPRESSTYPE} 2>&1 | cat >> $LOGFILE || error_out
  379. chmod 444 "$BUILDDIR/LiveOS/squashfs.img" || error_out $?
  380. info_msg "[8/9] Removing rootfs directory..."
  381. rm -rf "$ROOTFS" "$BUILDDIR/tmp-rootfs" "$BUILDDIR/tmp" || error_out $?
  382. #
  383. # Prepare the ISO image.
  384. #
  385. info_msg "[9/10] Building ISO image..."
  386. xorriso -as mkisofs \
  387. -iso-level 3 -rock -joliet \
  388. -max-iso9660-filenames -omit-period \
  389. -omit-version-number -relaxed-filenames -allow-lowercase \
  390. -volid "VOID_LIVE" \
  391. -eltorito-boot boot/isolinux/isolinux.bin \
  392. -eltorito-catalog boot/isolinux/boot.cat \
  393. -no-emul-boot -boot-load-size 4 -boot-info-table \
  394. -eltorito-alt-boot --efi-boot boot/grub/efiboot.img -no-emul-boot \
  395. -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \
  396. -output "$OUTPUT_FILE" "$BUILDDIR" 2>&1 | cat >>$LOGFILE || error_out $?
  397. info_msg "[10/10] Removing build directory..."
  398. rm -rf "$BUILDDIR" || error_out $?
  399. hsize=$(du -sh "$OUTPUT_FILE"|awk '{print $1}')
  400. info_msg "Created $(readlink -f $OUTPUT_FILE) ($hsize) successfully."
  401. exit 0