mknet.sh.in 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #!/bin/sh
  2. #
  3. # vim: set ts=4 sw=4 et:
  4. #
  5. #-
  6. # Copyright (c) 2009-2015 Juan Romero Pardines.
  7. # All rights reserved.
  8. #
  9. # Redistribution and use in source and binary forms, with or without
  10. # modification, are permitted provided that the following conditions
  11. # are met:
  12. # 1. Redistributions of source code must retain the above copyright
  13. # notice, this list of conditions and the following disclaimer.
  14. # 2. Redistributions in binary form must reproduce the above copyright
  15. # notice, this list of conditions and the following disclaimer in the
  16. # documentation and/or other materials provided with the distribution.
  17. #
  18. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19. # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20. # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23. # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. #-
  29. trap "error_out $LINENO $?" INT TERM 0
  30. readonly REQUIRED_PKGS="base-files libgcc dash coreutils sed tar gawk syslinux squashfs-tools"
  31. readonly INITRAMFS_PKGS="binutils xz device-mapper dracut-network dhclient dialog"
  32. readonly PROGNAME=$(basename $0)
  33. info_msg() {
  34. printf "\033[1m$@\n\033[m"
  35. }
  36. die() {
  37. info_msg "ERROR: $@"
  38. error_out 1
  39. }
  40. print_step() {
  41. CURRENT_STEP=$((CURRENT_STEP+1))
  42. info_msg "[${CURRENT_STEP}/${STEP_COUNT}] $@"
  43. }
  44. mount_pseudofs() {
  45. for f in sys dev proc; do
  46. mkdir -p $ROOTFS/$f
  47. mount --bind /$f $ROOTFS/$f
  48. done
  49. }
  50. umount_pseudofs() {
  51. umount -f $ROOTFS/sys >/dev/null 2>&1
  52. umount -f $ROOTFS/dev >/dev/null 2>&1
  53. umount -f $ROOTFS/proc >/dev/null 2>&1
  54. }
  55. error_out() {
  56. umount_pseudofs
  57. [ -d "$BUILDDIR" -a -z "$KEEP_BUILDDIR" ] && rm -rf "$BUILDDIR"
  58. exit ${1:=0}
  59. }
  60. usage() {
  61. cat <<_EOF
  62. Usage: $PROGNAME [options]
  63. Options:
  64. -a <xbps-arch> Set XBPS_ARCH (do not use it unless you know what it is)
  65. -b <system-pkg> Set an alternative base-system package (defaults to base-system).
  66. -r <repo-url> Use this XBPS repository (may be specified multiple times).
  67. -c <cachedir> Use this XBPS cache directory (/var/cache/xbps if unset).
  68. -k <keymap> Default keymap to use (us if unset)
  69. -l <locale> Default locale to use (en_US.UTF-8 if unset).
  70. -i <lz4|gzip|bzip2|xz> Compression type for the initramfs image (lz4 if unset).
  71. -o <file> Output file name for the netboot tarball (auto if unset).
  72. -C "cmdline args" Add additional kernel command line arguments.
  73. -T "title" Modify the bootloader title.
  74. -K Do not remove builddir.
  75. The $PROGNAME script generates a network-bootable tarball of Void Linux
  76. This *.tar.gz contains only the autoinstaller.
  77. _EOF
  78. exit 1
  79. }
  80. copy_void_keys() {
  81. mkdir -p "$1"/var/db/xbps/keys
  82. cp keys/*.plist "$1"/var/db/xbps/keys
  83. }
  84. copy_void_conf() {
  85. install -Dm644 data/void-vpkgs.conf "$1"/usr/share/xbps.d/void-virtualpkgs.conf
  86. }
  87. copy_netmenu_files() {
  88. mkdir -p $1/usr/lib/dracut/modules.d/05netmenu
  89. cp dracut/netmenu/* $1/usr/lib/dracut/modules.d/05netmenu/
  90. # The netmenu can directly launch the manual installer from the initrd
  91. cp installer.sh $1/usr/lib/dracut/modules.d/05netmenu/
  92. }
  93. copy_autoinstaller_files() {
  94. mkdir -p $1/usr/lib/dracut/modules.d/01autoinstaller
  95. cp dracut/autoinstaller/* $1/usr/lib/dracut/modules.d/01autoinstaller/
  96. }
  97. install_prereqs() {
  98. copy_void_conf $VOIDHOSTDIR
  99. XBPS_ARCH=$ARCH $XBPS_INSTALL_CMD -r $VOIDHOSTDIR $XBPS_REPOSITORY \
  100. $XBPS_HOST_CACHEDIR -y ${REQUIRED_PKGS}
  101. [ $? -ne 0 ] && die "Failed to install required software, exiting..."
  102. }
  103. install_packages() {
  104. copy_void_conf $ROOTFS
  105. XBPS_ARCH=$BASE_ARCH ${XBPS_INSTALL_CMD} -r $ROOTFS \
  106. $XBPS_REPOSITORY $XBPS_CACHEDIR -yn ${PACKAGE_LIST} ${INITRAMFS_PKGS}
  107. [ $? -ne 0 ] && die "Missing required binary packages, exiting..."
  108. mount_pseudofs
  109. LANG=C XBPS_ARCH=$BASE_ARCH ${XBPS_INSTALL_CMD} -U -r $ROOTFS \
  110. $XBPS_REPOSITORY $XBPS_CACHEDIR -y ${PACKAGE_LIST} ${INITRAMFS_PKGS}
  111. [ $? -ne 0 ] && die "Failed to install $PACKAGE_LIST"
  112. xbps-reconfigure -r $ROOTFS -f base-files >/dev/null 2>&1
  113. chroot $ROOTFS env -i xbps-reconfigure -f base-files
  114. # Enable choosen UTF-8 locale and generate it into the target rootfs.
  115. if [ -f $ROOTFS/etc/default/libc-locales ]; then
  116. sed -e "s/\#\(${LOCALE}.*\)/\1/g" -i $ROOTFS/etc/default/libc-locales
  117. fi
  118. chroot $ROOTFS env -i xbps-reconfigure -a
  119. if [ -x installer.sh ]; then
  120. install -Dm755 installer.sh $ROOTFS/usr/sbin/void-installer
  121. else
  122. install -Dm755 /usr/sbin/void-installer $ROOTFS/usr/sbin/void-installer
  123. fi
  124. # Cleanup and remove useless stuff.
  125. rm -rf $ROOTFS/var/cache/* $ROOTFS/run/* $ROOTFS/var/run/*
  126. }
  127. copy_include_directory() {
  128. find $INCLUDE_DIRECTORY -mindepth 1 -maxdepth 1 -exec cp -rfpPv {} $ROOTFS/ \;
  129. }
  130. generate_initramfs() {
  131. local _args
  132. copy_netmenu_files $ROOTFS
  133. copy_autoinstaller_files $ROOTFS
  134. if [ "$BASE_SYSTEM_PKG" = "base-system-systemd" ]; then
  135. _args="--add systemd"
  136. else
  137. _args="--omit systemd"
  138. fi
  139. chroot $ROOTFS env -i /usr/bin/dracut -N --${INITRAMFS_COMPRESSION} \
  140. --add-drivers "ahci" --force-add "autoinstaller netmenu" ${_args} "/boot/initrd" $KERNELVERSION
  141. [ $? -ne 0 ] && die "Failed to generate the initramfs"
  142. mv $ROOTFS/boot/initrd $BOOT_DIR
  143. cp $ROOTFS/boot/vmlinuz-$KERNELVERSION $BOOT_DIR/vmlinuz
  144. chmod 0644 $BOOT_DIR/initrd
  145. }
  146. generate_pxelinux_boot() {
  147. cp -f $SYSLINUX_DATADIR/pxelinux.0 "$BOOT_DIR"
  148. cp -f $SYSLINUX_DATADIR/ldlinux.c32 "$BOOT_DIR"
  149. cp -f $SYSLINUX_DATADIR/libcom32.c32 "$BOOT_DIR"
  150. cp -f $SYSLINUX_DATADIR/vesamenu.c32 "$BOOT_DIR"
  151. cp -f $SYSLINUX_DATADIR/libutil.c32 "$BOOT_DIR"
  152. cp -f $SYSLINUX_DATADIR/chain.c32 "$BOOT_DIR"
  153. cp -f pxelinux.cfg/pxelinux.cfg.in "$PXELINUX_DIR"/default
  154. cp -f ${SPLASH_IMAGE} "$BOOT_DIR"
  155. sed -i -e "s|@@SPLASHIMAGE@@|$(basename ${SPLASH_IMAGE})|" \
  156. -e "s|@@KERNVER@@|${KERNELVERSION}|" \
  157. -e "s|@@KEYMAP@@|${KEYMAP}|" \
  158. -e "s|@@ARCH@@|$BASE_ARCH|" \
  159. -e "s|@@LOCALE@@|${LOCALE}|" \
  160. -e "s|@@BOOT_TITLE@@|${BOOT_TITLE}|" \
  161. -e "s|@@BOOT_CMDLINE@@|${BOOT_CMDLINE}|" \
  162. $PXELINUX_DIR/default
  163. }
  164. generate_netboot_tarball() {
  165. cd $IMAGEDIR/tftp
  166. tar -zcvf $CURDIR/$OUTPUT_FILE.tar.gz .
  167. cd $CURDIR
  168. }
  169. #
  170. # main()
  171. #
  172. while getopts "a:b:r:c:C:T:Kk:l:i:o:p:h" opt; do
  173. case $opt in
  174. a) BASE_ARCH="$OPTARG";;
  175. b) BASE_SYSTEM_PKG="$OPTARG";;
  176. r) XBPS_REPOSITORY="--repository=$OPTARG $XBPS_REPOSITORY";;
  177. c) XBPS_CACHEDIR="--cachedir=$OPTARG";;
  178. K) readonly KEEP_BUILDDIR=1;;
  179. k) KEYMAP="$OPTARG";;
  180. l) LOCALE="$OPTARG";;
  181. i) INITRAMFS_COMPRESSION="$OPTARG";;
  182. o) OUTPUT_FILE="$OPTARG";;
  183. p) PACKAGE_LIST="$OPTARG";;
  184. C) BOOT_CMDLINE="$OPTARG";;
  185. T) BOOT_TITLE="$OPTARG";;
  186. h) usage;;
  187. esac
  188. done
  189. shift $((OPTIND - 1))
  190. XBPS_REPOSITORY="$XBPS_REPOSITORY --repository=http://repo.voidlinux.eu/current --repository=http://repo.voidlinux.eu/current/musl"
  191. ARCH=$(xbps-uhelper arch)
  192. # Set defaults
  193. : ${BASE_ARCH:=$(uname -m)}
  194. : ${XBPS_CACHEDIR:=-c $(pwd -P)/xbps-cachedir-${BASE_ARCH}}
  195. : ${XBPS_HOST_CACHEDIR:=-c $(pwd -P)/xbps-cachedir-${ARCH}}
  196. : ${KEYMAP:=us}
  197. : ${LOCALE:=en_US.UTF-8}
  198. : ${INITRAMFS_COMPRESSION:=xz}
  199. : ${SQUASHFS_COMPRESSION:=xz}
  200. : ${BASE_SYSTEM_PKG:=base-system}
  201. : ${BOOT_TITLE:="Void Linux"}
  202. # Required packages in the image for a working system.
  203. PACKAGE_LIST="$BASE_SYSTEM_PKG $PACKAGE_LIST"
  204. # Check for root permissions.
  205. if [ "$(id -u)" -ne 0 ]; then
  206. die "Must be run as root, exiting..."
  207. fi
  208. readonly CURDIR="$PWD"
  209. ISO_VOLUME="VOID_LIVE"
  210. if [ -n "$ROOTDIR" ]; then
  211. BUILDDIR=$(mktemp --tmpdir="$ROOTDIR" -d)
  212. else
  213. BUILDDIR=$(mktemp --tmpdir="$(pwd -P)" -d)
  214. fi
  215. BUILDDIR=$(readlink -f $BUILDDIR)
  216. IMAGEDIR="$BUILDDIR/image"
  217. ROOTFS="$IMAGEDIR/rootfs"
  218. VOIDHOSTDIR="$BUILDDIR/void-host"
  219. BOOT_DIR="$IMAGEDIR/tftp"
  220. PXELINUX_DIR="$BOOT_DIR/pxelinux.cfg"
  221. PXELINUX_CFG="$PXELINUX_DIR/default"
  222. CURRENT_STEP=0
  223. STEP_COUNT=6
  224. [ -n "${INCLUDE_DIRECTORY}" ] && ((STEP_COUNT=STEP_COUNT+1))
  225. : ${SYSLINUX_DATADIR:=$VOIDHOSTDIR/usr/share/syslinux}
  226. : ${SPLASH_IMAGE:=data/splash.png}
  227. : ${XBPS_INSTALL_CMD:=xbps-install}
  228. : ${XBPS_REMOVE_CMD:=xbps-remove}
  229. : ${XBPS_QUERY_CMD:=xbps-query}
  230. : ${XBPS_RINDEX_CMD:=xbps-rindex}
  231. : ${XBPS_UHELPER_CMD:=xbps-uhelper}
  232. : ${XBPS_RECONFIGURE_CMD:=xbps-reconfigure}
  233. mkdir -p $ROOTFS $VOIDHOSTDIR $PXELINUX_DIR
  234. print_step "Synchronizing XBPS repository data..."
  235. copy_void_keys $ROOTFS
  236. copy_void_keys $VOIDHOSTDIR
  237. XBPS_ARCH=$BASE_ARCH $XBPS_INSTALL_CMD -r $ROOTFS ${XBPS_REPOSITORY} -S
  238. XBPS_ARCH=$ARCH $XBPS_INSTALL_CMD -r $VOIDHOSTDIR $XBPS_REPOSITORY -S
  239. _linux_series=$(XBPS_ARCH=$BASE_ARCH $XBPS_QUERY_CMD -r $ROOTFS ${XBPS_REPOSITORY:=-R} -x linux|head -1)
  240. _kver=$(XBPS_ARCH=$BASE_ARCH $XBPS_QUERY_CMD -r $ROOTFS ${XBPS_REPOSITORY:=-R} -p pkgver ${_linux_series})
  241. KERNELVERSION=$($XBPS_UHELPER_CMD getpkgversion ${_kver})
  242. : ${OUTPUT_FILE="void-netboot-${BASE_ARCH}-${KERNELVERSION}-$(date +%Y%m%d)"}
  243. print_step "Installing software to generate the image: ${REQUIRED_PKGS} ..."
  244. install_prereqs
  245. mkdir -p "$ROOTFS"/etc
  246. [ -s data/motd ] && cp data/motd $ROOTFS/etc
  247. [ -s data/issue ] && cp data/issue $ROOTFS/etc
  248. print_step "Installing void pkgs into the rootfs: ${PACKAGE_LIST} ..."
  249. install_packages
  250. print_step "Generating initramfs image ($INITRAMFS_COMPRESSION)..."
  251. generate_initramfs
  252. print_step "Generating pxelinux support..."
  253. generate_pxelinux_boot
  254. print_step "Generating netboot tarball..."
  255. generate_netboot_tarball
  256. info_msg "Created $(readlink -f $CURDIR/$OUTPUT_FILE) ($hsize) successfully."