mklive.sh.in 13 KB

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