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_default_isolinux_conf() {
  73. local kver="$1"
  74. if [ -r "$SPLASH_IMAGE" ]; then
  75. BACKGROUND="MENU BACKGROUND $(basename $SPLASH_IMAGE)"
  76. fi
  77. cat >> "$ISOLINUX_CFG" << _EOF
  78. UI vesamenu.c32
  79. PROMPT 0
  80. TIMEOUT 100
  81. ONTIMEOUT linux
  82. MENU TABMSG Press ENTER to boot or TAB to edit a menu entry
  83. MENU AUTOBOOT BIOS default device boot in # second{,s}...
  84. $BACKGROUND
  85. MENU WIDTH 78
  86. MENU MARGIN 1
  87. MENU ROWS 4
  88. MENU VSHIFT 2
  89. MENU TIMEOUTROW 8
  90. MENU TABMSGROW 2
  91. MENU CMDLINEROW 11
  92. MENU HELPMSGROW 16
  93. MENU HELPMSGENDROW 29
  94. MENU COLOR title * #FF5255FF *
  95. MENU COLOR border * #00000000 #00000000 none
  96. MENU COLOR sel * #ffffffff #FF5255FF *
  97. LABEL linux
  98. MENU LABEL Boot Void GNU/Linux ${kver} ($(uname -m))
  99. KERNEL vmlinuz
  100. APPEND initrd=initrd.lz root=live:CDLABEL=VoidLinux-live-$(uname -m)-${kver} \
  101. rootfstype=auto ro liveimg rd.luks=0 rd.md=0 rd.dm=0 \
  102. vconsole.keymap=${KEYMAP} vconsole.unicode=1 locale.LANG=${LOCALE}
  103. LABEL c
  104. MENU LABEL Boot first HD found by BIOS
  105. LOCALBOOT 0x80
  106. _EOF
  107. }
  108. write_conf_file() {
  109. cat > "$1" <<_EOF
  110. # *-*- sh -*-*
  111. # Default configuration file for vmklive-@VERSION@.
  112. #
  113. # List of packages to be installed into the live image.
  114. # At least 'base-system' or 'base-system-live' is required.
  115. PACKAGE_LIST="base-system-live"
  116. # Syslinux splash image.
  117. SPLASH_IMAGE=/usr/share/void-artwork/splash.png
  118. # Default keymap to use.
  119. KEYMAP=us
  120. # Default locale to use.
  121. LOCALE=en_US
  122. # Path to XBPS utilities.
  123. #XBPS_BIN_CMD=xbps-bin
  124. #XBPS_REPO_CMD=xbps-repo
  125. #XBPS_UHELPER_CMD=xbps-uhelper
  126. # XBPS cache directory to install packages from.
  127. #REPOSITORY_CACHE=/blah/foo
  128. _EOF
  129. chmod 644 "$1"
  130. }
  131. usage()
  132. {
  133. cat <<_EOF
  134. Usage: $(basename $0) [options]
  135. Options:
  136. -C file Path to configuration file (defaults to ~/.mklive.conf)
  137. -c (gzip|bzip2|xz) Compression type for the squashfs/initramfs image.
  138. -k version Kernel version to use.
  139. -o outfile Output file name for the ISO image.
  140. -s splash Splash image file for isolinux.
  141. -v volname ISO Volume name.
  142. _EOF
  143. exit 1
  144. }
  145. #
  146. # main()
  147. #
  148. while getopts "C:c:k:o:s:v:h" opt; do
  149. case $opt in
  150. C) CONFIG_FILE="$OPTARG";;
  151. c) COMPRESSTYPE="$OPTARG";;
  152. k) KERNELVERSION="$OPTARG";;
  153. o) OUTPUT_FILE="$OPTARG";;
  154. s) SPLASH_IMAGE="$OPTARG";;
  155. v) ISO_VOLUME="$OPTARG";;
  156. h) usage;;
  157. esac
  158. done
  159. shift $(($OPTIND - 1))
  160. if [ -z "$KERNELVERSION" ]; then
  161. KERNELVERSION="$(uname -r)"
  162. fi
  163. # Set defaults
  164. if [ -z "$CONFIG_FILE" ]; then
  165. CONFIG_FILE="$HOME/.mklive.conf"
  166. fi
  167. if [ -z "$OUTPUT_FILE" ]; then
  168. OUTPUT_FILE="$HOME/void-live-$(uname -m)-${KERNELVERSION}-$(date +%Y%m%d).iso"
  169. fi
  170. LOGFILE="$(mktemp -t vmklive-XXXXXXXXXX.log)"
  171. if [ -z "$ISO_VOLUME" ]; then
  172. ISO_VOLUME="VoidLinux-live-$(uname -m)-${KERNELVERSION}"
  173. fi
  174. if [ -z "$SYSLINUX_DATADIR" ]; then
  175. SYSLINUX_DATADIR=/usr/share/syslinux
  176. fi
  177. if [ -z "$SPLASH_IMAGE" ]; then
  178. SPLASH_IMAGE=/usr/share/void-artwork/splash.png
  179. fi
  180. if [ -z "$XBPS_REPO_CMD" ]; then
  181. XBPS_REPO_CMD=xbps-repo
  182. fi
  183. if [ -z "$XBPS_BIN_CMD" ]; then
  184. XBPS_BIN_CMD=xbps-bin
  185. fi
  186. if [ -z "$XBPS_UHELPER_CMD" ]; then
  187. XBPS_UHELPER_CMD=xbps-uhelper
  188. fi
  189. if [ -z "$COMPRESSTYPE" ]; then
  190. COMPRESSTYPE=xz
  191. fi
  192. # Create or read configuration file.
  193. if [ ! -r $CONFIG_FILE ]; then
  194. info_msg "Creating config file at $CONFIG_FILE."
  195. write_conf_file $CONFIG_FILE
  196. fi
  197. . $CONFIG_FILE
  198. if [ -z "$PACKAGE_LIST" ]; then
  199. PACKAGE_LIST="base-system-live"
  200. else
  201. PACKAGE_LIST="$PACKAGE_LIST"
  202. fi
  203. if [ ! -f $SYSLINUX_DATADIR/isolinux.bin ]; then
  204. echo "Missing required isolinux files in $SYSLINUX_DATADIR, exiting..."
  205. exit 1
  206. fi
  207. # Check for root permissions.
  208. if [ "$(id -u)" -ne 0 ]; then
  209. echo "Must be run as root, exiting..."
  210. exit 1
  211. fi
  212. BUILDDIR=$(mktemp --tmpdir=$HOME -d) || exit 1
  213. BUILDDIR=$(readlink -f $BUILDDIR)
  214. ROOTFS="$BUILDDIR/rootfs"
  215. ISOLINUX_DIR="$BUILDDIR/isolinux"
  216. ISOLINUX_CFG="$ISOLINUX_DIR/isolinux.cfg"
  217. #
  218. # Check there are repos registered before anything.
  219. #
  220. ${XBPS_REPO_CMD} list >/dev/null 2>&1
  221. if [ $? -ne 0 ]; then
  222. echo "No repositories available, exiting..."
  223. error_out
  224. fi
  225. #
  226. # Mount pseudofs in the target rootfs.
  227. #
  228. mount_pseudofs
  229. mkdir -p "$ROOTFS/tmp"
  230. mkdir -p "$ISOLINUX_DIR"
  231. XBPS_ARGS="-r $ROOTFS -y"
  232. if [ -n "$REPOSITORY_CACHE" ]; then
  233. XBPS_ARGS="$XBPS_ARGS -c $REPOSITORY_CACHE"
  234. fi
  235. XBPS_VERSION=$($XBPS_BIN_CMD -V|awk '{print $2}')
  236. case $XBPS_VERSION in
  237. # XBPS >= 0.16
  238. [0-9].[1-9][6-9]*) XBPS_016=1;;
  239. esac
  240. info_msg "Redirecting stdout/stderr to $LOGFILE ..."
  241. info_msg "[1/9] Installing packages into the rootfs..."
  242. for f in ${PACKAGE_LIST}; do
  243. info_msg " $f"
  244. done
  245. # Check that all pkgs are reachable.
  246. ${XBPS_BIN_CMD} ${XBPS_ARGS} -n install ${PACKAGE_LIST} >>$LOGFILE 2>&1
  247. if [ $? -ne 0 ]; then
  248. info_msg "Missing required binary packages, exiting..."
  249. error_out
  250. fi
  251. ${XBPS_BIN_CMD} ${XBPS_ARGS} install ${PACKAGE_LIST} \
  252. 2>&1|cat >> $LOGFILE || error_out
  253. ${XBPS_BIN_CMD} ${XBPS_ARGS} autoupdate \
  254. 2>&1|cat >> $LOGFILE || error_out
  255. ${XBPS_BIN_CMD} ${XBPS_ARGS} autoremove \
  256. 2>&1|cat >> $LOGFILE || error_out
  257. ${XBPS_BIN_CMD} -r "$ROOTFS" list > \
  258. "${OUTPUT_FILE%.iso}"-package-list.txt || error_out
  259. #
  260. # Prepare /etc/motd.
  261. #
  262. info_msg "[2/9] Creating /etc/motd..."
  263. mkdir -p "$ROOTFS"/etc
  264. write_etc_motd
  265. #
  266. # Create the initramfs with XZ compression.
  267. #
  268. info_msg "[3/9] Creating initramfs image ($COMPRESSTYPE)..."
  269. dracut --no-hostonly --add "dmsquash-live vmklive" --${COMPRESSTYPE} \
  270. "${ISOLINUX_DIR}/initrd.lz" ${KERNELVERSION} 2>/dev/null || error_out
  271. #
  272. # Copy the linux image to the target directory.
  273. #
  274. info_msg "[4/9] Copying kernel image/modules..."
  275. cp -f /boot/vmlinuz-${KERNELVERSION} "${ISOLINUX_DIR}/vmlinuz" || error_out $?
  276. mkdir -p "$ROOTFS/lib/modules"
  277. cp -a /lib/modules/${KERNELVERSION} "$ROOTFS/lib/modules" || error_out $?
  278. # Generate a sane xbps.conf for the rootfs.
  279. rm -f $ROOTFS/etc/xbps/xbps.conf
  280. echo "# xbps.conf generated by void-mklive-@@MKLIVE_VERSION@@" \
  281. > $ROOTFS/etc/xbps/xbps.conf
  282. echo "TransactionFrequencyFlush = 0" \
  283. >> $ROOTFS/etc/xbps/xbps.conf
  284. echo "virtual-package rsyslog { targets = syslog-daemon-0 }" \
  285. >> $ROOTFS/etc/xbps/xbps.conf
  286. echo "virtual-package dcron { targets = cron-daemon-0 }" \
  287. >> $ROOTFS/etc/xbps/xbps.conf
  288. echo "virtual-package kmod { targets = module-init-tools-3.17 }" \
  289. >> $ROOTFS/etc/xbps/xbps.conf
  290. _devel=$($XBPS_UHELPER_CMD -r $ROOTFS version xbps-devel)
  291. if [ -n "${_devel}" ]; then
  292. echo "virtual-package xbps-devel { targets = xbps-9999 }" \
  293. >> $ROOTFS/etc/xbps/xbps.conf
  294. fi
  295. # Generate a conf for local repositories.
  296. cat > $ROOTFS/etc/xbps/local-repos.conf <<_EOF
  297. repositories = {
  298. # XBPS >= 0.16
  299. /packages,
  300. # XBPS < 0.16
  301. /packages/noarch,
  302. /packages/i686,
  303. /packages/x86_64
  304. }
  305. _EOF
  306. # Generate a conf for remote repositories.
  307. cat > $ROOTFS/etc/xbps/network-repos.conf <<_EOF
  308. repositories = {
  309. # XBPS >= 0.16
  310. http://xbps.hosting-unlimited.org/binpkgs,
  311. http://xbps.goodluckwith.us/binpkgs,
  312. http://xbps.nopcode.org/repos/current,
  313. # XBPS < 0.16
  314. http://xbps.goodluckwith.us/binpkgs/i686,
  315. http://xbps.goodluckwith.us/binpkgs/noarch,
  316. http://xbps.goodluckwith.us/binpkgs/nonfree/i686,
  317. http://xbps.nopcode.org/repos/current/x86_64,
  318. http://xbps.nopcode.org/repos/current/noarch,
  319. http://xbps.nopcode.org/repos/current/nonfree/x86_64
  320. }
  321. _EOF
  322. chmod 644 $ROOTFS/etc/xbps/*.conf || error_out $?
  323. # Create local repos for base-system and grub packages required by
  324. # the void-installer pkg.
  325. pkgs=$($XBPS_BIN_CMD -r /tmp/blah -n install base-system grub)
  326. set -- ${pkgs}
  327. while [ $# -ne 0 ]; do
  328. pkgn=$1; action=$2; ver=$3; repo=$4; binpkg=$5; arch=$6
  329. if [ -z "$XBPS_016" ]; then
  330. arch=$(basename $repo)
  331. shift 5
  332. else
  333. shift 6
  334. fi
  335. mkdir -p $ROOTFS/packages/$arch
  336. bpkg=$repo/$arch/$binpkg
  337. cp -f $bpkg $ROOTFS/packages/$arch
  338. done
  339. if [ -n "$XBPS_016" ]; then
  340. $XBPS_REPO_CMD genindex $ROOTFS/packages 2>&1 >>$LOGFILE
  341. rm -f $ROOTFS/packages/index-files.plist
  342. else
  343. for f in $ROOTFS_REPODIR/*; do
  344. ${XBPS_REPO_CMD} genindex $f 2>&1 >>$LOGFILE
  345. rm -f $f/rindex-files.plist
  346. done
  347. fi
  348. # install lsblk and blkid from util-linux. to avoid installing
  349. # the whole package.
  350. _lsblk=$(which lsblk)
  351. _blkid=$(which blkid)
  352. install -Dm755 ${_lsblk} "$ROOTFS/usr/bin/lsblk" || error_out $?
  353. install -Dm755 ${_blkid} "$ROOTFS/sbin/blkid" || error_out $?
  354. #
  355. # The pseudofs aren't needed anymore in target rootfs.
  356. #
  357. umount_pseudofs
  358. #
  359. # Copy required isolinux files in the target rootfs.
  360. #
  361. info_msg "[5/9] Copying isolinux files..."
  362. cp -f $SYSLINUX_DATADIR/isolinux.bin "$ISOLINUX_DIR"
  363. cp -f $SYSLINUX_DATADIR/vesamenu.c32 "$ISOLINUX_DIR"
  364. write_default_isolinux_conf ${KERNELVERSION}
  365. if [ -f "$SPLASH_IMAGE" ]; then
  366. cp -f $SPLASH_IMAGE "$ISOLINUX_DIR"
  367. fi
  368. #
  369. # Prepare the squashed rootfs image.
  370. #
  371. info_msg "[6/9] Creating squashfs image ($COMPRESSTYPE) from rootfs..."
  372. # Find out required size for the rootfs and create an ext3fs image off it.
  373. ROOTFS_SIZE=$(du -sk "$ROOTFS"|awk '{print $1}')
  374. mkdir -p "$BUILDDIR/tmp/LiveOS"
  375. dd if=/dev/zero of="$BUILDDIR/tmp/LiveOS/ext3fs.img" \
  376. bs="$((${ROOTFS_SIZE}+($ROOTFS_SIZE/6)))K" count=1 2>&1 | cat >>$LOGFILE || error_out $?
  377. mkdir -p "$BUILDDIR/tmp-rootfs"
  378. mkfs.ext3 -F -m1 "$BUILDDIR/tmp/LiveOS/ext3fs.img" 2>&1 | cat >>$LOGFILE || error_out $?
  379. mount -o loop "$BUILDDIR/tmp/LiveOS/ext3fs.img" "$BUILDDIR/tmp-rootfs" || error_out $?
  380. cd $BUILDDIR
  381. cp -a rootfs/* tmp-rootfs/
  382. umount -f "$BUILDDIR/tmp-rootfs"
  383. mkdir -p "$BUILDDIR/LiveOS"
  384. mksquashfs "$BUILDDIR/tmp" "$BUILDDIR/LiveOS/squashfs.img" \
  385. -comp ${COMPRESSTYPE} 2>&1 | cat >> $LOGFILE || error_out
  386. chmod 444 "$BUILDDIR/LiveOS/squashfs.img" || error_out $?
  387. info_msg "[7/9] Removing rootfs directory..."
  388. rm -rf "$ROOTFS" "$BUILDDIR/tmp-rootfs" "$BUILDDIR/tmp" || error_out $?
  389. #
  390. # Prepare the ISO image.
  391. #
  392. info_msg "[8/9] Building ISO image..."
  393. mkisofs -J -r -V "$ISO_VOLUME" -b isolinux/isolinux.bin \
  394. -c isolinux/boot.cat -no-emul-boot \
  395. -boot-load-size 4 -boot-info-table \
  396. -o "$OUTPUT_FILE" "$BUILDDIR" 2>&1 | cat >>$LOGFILE || error_out $?
  397. info_msg "[9/9] 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