removed
[rrq/rescue-boot.git] / minbase-strap.sh
1 #!/bin/bash
2 #
3 # Utility script to debootstrap a minbase filesystem, with additions
4 # of kernel, busybox and an init script. Then make an initrd.gz from
5 # that and prepare a boot image file with syslinux from that.
6 #
7 if [ $(id -u) -ne 0 ] ; then
8     exec sudo env http_proxy=$http_proxy $0 $*
9     echo "** Abort: must be root" >&2
10     exit 1
11 fi
12 set -e -x
13
14 ARCH="${1-$(dpkg-architecture -q DEB_HOST_ARCH)}"
15 DIST=${2-ceres}
16 IMG=${3-boot-$DIST-$ARCH.img}
17 FS=${4-FS}
18
19 # Prepare or keep FS
20 DEBSTRAP=true
21 USRMERGE=true
22 if [ -d "$FS" ] ; then
23     select x in "keep existing $FS and skip debootstrap" \
24                     "remove existing $FS and debootstrap anew" \
25                     "abort" ; do
26         [ "$x" = abort ] && exit 1
27         [ -z "$x" ] || break
28     done
29     echo "selection: $REPLY"
30     [ "$REPLY" = 1 ] && DEBSTRAP=false
31 fi
32
33 stupid_links() {
34     mkdir -p $1/usr
35     for d in bin sbin lib ; do mkdir $1/usr/$d ; ln -s usr/$d $1/$d ; done
36 }
37
38 if $DEBSTRAP ; then
39     ## Optionally add the stupid-links
40     read -n 1 -p "prime $FS with stupid-links? [Yn]" x
41     [ "$x" = "n" ] && USRMERGE=false
42
43     rm -rf "$FS" # remove if existin
44
45     $USRMERGE && stupid_links "$FS"
46
47     ## bootstrap a filesystem, with exclusions
48     echo "http_proxy=$http_proxy debootstrap ..."
49     debootstrap --exclude=logrotate,cron,cron-daemon-common \
50                 --arch=$ARCH $DIST "$FS" http://deb.devuan.org/merged
51     chroot "$FS" apt-get install -y logrotate cron
52
53     ## Select and add a kernel
54     KERNELS=( $(chroot "$FS" apt-cache search linux-image-\* | \
55                     sed 's/\s.*//' | sort -h ) )
56     echo "** Please select kernel **"
57     select KERNEL in "${KERNELS[@]}" ; do [ -n "$KERNEL" ] && break ; done
58     VERSION=${KERNEL#linux-image-}
59     VERSION=${VERSION%-unsigned}
60     chroot "$FS" apt-get install -y $KERNEL
61     chroot "$FS" depmod -a $VERSION
62
63     chroot "$FS" apt-get install -y busybox-static debootstrap
64     touch "$FS"/usr/bin{linuxrc,init} # block these
65     chroot "$FS" /usr/bin/busybox --install -s /usr/bin
66
67 fi # End of $DEBSTRAP actions
68
69 ## Pick boot kernel, if there are many
70 LINUXES=( $(cd "$FS"/boot ; ls vmlinuz* 2>/dev/null) )
71 if [ ${#LINUXES[@]} -gt 1 ] ; then
72     echo "** Please select boot kernel"
73     select LINUX in $LINUXES ; do [ -n "$LINUX" ] && break ; done
74 elif [ -n "$LINUXES" ] ; then
75     LINUX="$FS"/boot/${LINUXES[0]}
76 else
77     echo "** Oh No! There is no $FS/boot/vmlinux-* ... bailing out!" >&2
78     exit 1
79 fi
80
81 #============================================================
82 # Prepare a temporary directory tree with a boot kernel and $FS packed
83 # up into an initrd.gz
84 TMP=$(mktemp -d XXXX)
85 trap "rm -r $TMP" 0 2 15
86
87 mkdir -p $TMP/prep/{proc,dev,tmp,sys,mnt,usr}
88 stupid_links $TMP/prep
89
90 # copy FS tree(s) in full into the TMP/prep tree
91 copyFStree() {
92     local D
93     for D in $* ; do
94         tar cf - -C "$FS" $D \
95             | tar -xf - --skip-old-files --keep-directory-symlink -C $TMP/prep
96     done
97 }
98
99 # Copy FS binary(s) with all its libraries into the TMP/prep tree
100 copyFSbin() {
101     local B BIN
102     for B in $* ; do
103         BIN="$(chroot "$FS" which "$B")"
104         tar cf - --dereference -C "$FS" ${BIN#/} \
105             $(chroot "$FS" ldd "$BIN" | grep -oE '/[^ ]*'|sed 's|/||')\
106             | tar -xf - --keep-directory-symlink -C $TMP/prep
107     done
108 }
109
110 INITRD="$FS"/boot/initrd.img${LINUX#*/vmlinuz}
111 if [ -r "$INITRD" ] ; then
112     #select X in my FS ; do [ -n "$X" ] && break ; done
113     X=FS
114 else
115     X=my
116 fi
117 case "$X" in
118     FS)
119         copyFStree lib/modules
120         zstdcat $INITRD | ( cd $TMP/prep && cpio -i )
121         VERSION=( $TMP/prep/lib/modules/* )
122         for V in ${VERSION[@]} ; do
123             depmod -a -b $TMP/prep ${V#$TMP/prep/lib/modules/}
124         done
125         ;;
126     my)
127         copyFStree lib/modules lib/udev
128         copyFSbin busybox sh cttyhack setsid mount mkdir
129         copyFSbin udevd udevadm modprobe modinfo kmod blkid
130         ;;
131 esac
132
133 ## (re)install /init
134 mv $TMP/prep/init{,.FS}
135 echo "** Please select /init template"
136 select INIT in none $(echo init*.template) ; do [ -n "$INIT" ] && break ; done
137 if [ "$INIT" != none ] ; then
138     cp $INIT $TMP/prep/init
139     chmod a+x $TMP/prep/init
140 fi
141
142 # Populate $TMP with /initrd.gz. /vmlinuz and /menu.cfg
143 ( cd "$TMP/prep" && find -printf '%P\n' | cpio -o -H newc ) | \
144     gzip > $TMP/initrd.gz
145 cp $LINUX $TMP/vmlinuz
146 rm -r $TMP/prep
147
148 # Common syslinux menu
149 CON="console=ttyS0,115200"
150 cat <<EOF > $TMP/menu.cfg
151 default menu.c32
152 label rescue (serial)
153     kernel /vmlinuz
154     append initrd=/initrd.gz init=/init $CON rescue
155 label rescue2 (vt1)
156     kernel /vmlinuz
157     append initrd=/initrd.gz init=/init rescue
158 label linux2 (sda2)
159     kernel /vmlinuz
160     append initrd=/initrd.gz root=/dev/sda2 rootfstype=squashfs $CON
161 label linux (sdb1)
162     kernel /vmlinuz
163     append initrd=/initrd.gz root=/dev/sdb1 $CON
164 EOF
165
166 . ./minbase-strap-bios.sh
167 . ./minbase-strap-uefi.sh
168 . ./minbase-strap-mkimg.sh
169
170 for E in $ENDING ; do $E ; done