source: trunk/debirf/fs/usr/bin/debirf @ 897

Last change on this file since 897 was 897, checked in by jrollins, 5 years ago

debirf: improved install-kernel module to only download need package,
and slightly tweaked debirf and common. not installing apt-utils.

  • Property svn:executable set to *
File size: 10.9 KB
Line 
1#!/bin/bash -e
2
3# debirf: script to build debirf system.
4#
5# The debirf scripts were written by
6# Jameson Rollins <jrollins@fifthhorseman.net>
7# and
8# Daniel Kahn Gillmor <dkg-debian.org@fifthhorseman.net>.
9#
10# They are Copyright 2007, and are all released under the GPL,
11# version 3 or later.
12
13###############################################################
14### VARIABLES
15
16CMD=$(basename $0)
17
18DEBIRF_COMMON=${DEBIRF_COMMON:-"/usr/share/debirf/common"}
19source "$DEBIRF_COMMON"
20
21# default build type
22export ROOT_BUILD=false
23
24# stages to run by default
25STAGE_ROOT=true
26STAGE_MODULES=true
27STAGE_INITRD=true
28
29ROOT_WARNING=true
30
31# location of devices.tar.gz file
32export DEVICE_ARCHIVE=/usr/share/debirf/devices.tar.gz
33
34# list of packages to include/exclude from debootstrap
35export INCLUDE=less,udhcpc
36export EXCLUDE=apt-utils,bsdmainutils,cron,ed,dhcp3-common,dhcp3-client,info,logrotate,man-db,manpages,tasksel,tasksel-data,tcpd,traceroute
37
38###############################################################
39### FUNCTIONS
40
41usage() {
42    cat <<EOF
43Usage: $CMD [options] profile
44Create a debirf kernel and initramfs.  The 'profile' is a path to a debirf
45profile directory.
46
47options:
48  -h|--help               this help message
49  -c|--check-vars         check variables before make
50  -n|--new                create new root, even if old one exists
51  -o|--overwrite          debootstrap on top of old root if it exists
52  -s|--skip               skip debootstrap step if old root exists
53  -r|--root-build         use real chroot to build instead of fakechroot
54                          (requires superuser privileges or CAP_SYS_CHROOT)
55  -w|--no-warning         skip superuser warning
56  -i|--initrd-only        remake initramfs from existing root
57  -k|--kernel=KERNEL      install KERNEL .deb, instead of default kernel
58EOF
59}
60
61usage_profile() {
62    cat <<EOF
63It looks like your profile is not correctly formed.  Please refer to the
64README file included with this package on how to setup a profile.
65EOF
66}
67
68failure() {
69    echo "$1" >&2
70    exit ${2:-'1'}
71}
72
73create_debootstrap() {
74    mkdir -p "$DEBIRF_ROOT"
75    if [ "$ROOT_BUILD" = 'true' ] ; then
76        /usr/sbin/debootstrap --exclude="$EXCLUDE" "$DEBIRF_DISTRO" "$DEBIRF_ROOT" "$DEBIRF_MIRROR"
77    else
78        fakeroot_if_needed fakechroot /usr/sbin/debootstrap --variant=fakechroot --include="$INCLUDE" --exclude="$EXCLUDE" "$DEBIRF_DISTRO" "$DEBIRF_ROOT" "$DEBIRF_MIRROR"
79    fi
80}
81
82# fix the device tree in the debirf root if fakechroot variant was
83# used with debootstrap (default non-privileged behavior)
84fix_dev() {
85    if [ -L "$DEBIRF_ROOT"/dev -o ! -d "$DEBIRF_ROOT"/dev ] ; then
86        msg "fixing debirf root dev tree..."
87
88        # remove old dev
89        fakeroot_if_needed rm -f "$DEBIRF_ROOT"/dev
90
91        # create new dev from devices archive
92        fakeroot_if_needed sh -c "cd $DEBIRF_ROOT; tar -xzf $DEVICE_ARCHIVE"
93
94        # create /dev/console
95        fakeroot_if_needed sh -c "mknod $DEBIRF_ROOT/dev/console c 5 1; chmod 0600 $DEBIRF_ROOT/dev/console"
96    fi
97}
98export -f fix_dev
99
100run_modules() {
101    # export all the DEBIRF_* environment variables:
102    for var in ${!DEBIRF_*}; do
103        export $var
104    done
105    fakeroot_if_needed run-parts --verbose --exit-on-error "$DEBIRF_MODULES"
106}
107
108# pack the rootfs archive
109# takes one input argument as name of output archive file
110pack_rootfs() {
111    # need to pack archive in fakechroot/chroot so that symlinks correctly
112    # point within debirf root, instead of to host path
113    fakeroot_if_needed fakechroot chroot "$DEBIRF_ROOT" sh -c "find * | cpio --create -H newc" | gzip > "$1"
114}
115export -f pack_rootfs
116
117
118## create_initrd functions
119# stupid simple method
120create_initrd_stupid_simple() {
121    fakeroot_if_needed ln -sf /sbin/init "$DEBIRF_ROOT/init"
122    pack_rootfs "$DEBIRF_INITRD"
123}
124
125# nested cpio archives
126create_initrd_nested() {
127    local util lib
128    local NEST_ROOT="$DEBIRF_BUILDD"/nest
129
130    # make the nested root
131    rm -rf "$NEST_ROOT"
132    mkdir -p "$NEST_ROOT"/{bin,lib}
133
134    # copy needed executables into nest
135    cp -f /bin/{busybox,cpio} "$NEST_ROOT"/bin/
136    for util in sh mkdir mount ls gunzip grep awk free ; do
137        ln "$NEST_ROOT"/bin/busybox "$NEST_ROOT"/bin/"$util"
138    done
139    cp -f /usr/lib/klibc/bin/run-init "$NEST_ROOT"/bin/
140
141    # copy in needed libraries
142    for lib in $(ldd "$NEST_ROOT"/bin/* | egrep '*.so.[[:digit:]]+ \(0x[[:xdigit:]]{8}\)$' | sed -r 's|.*[[:space:]](/[^[[:space:]]*)[[:space:]]\(0x[[:xdigit:]]{8}\)$|\1|' | sort -u) ; do
143        # pull libraries from most basic place libraries can live
144        # (avoid arch change between build env and debirf)
145        lib=/lib/$(basename "$lib")
146        echo -e "$lib\n$(readlink -f $lib)" | cpio --pass-through --make-directories "$NEST_ROOT"/
147    done
148    cp -f /lib/klibc-* "$NEST_ROOT"/lib/
149
150    # create nest init
151    cat > "$NEST_ROOT"/init <<EOF
152#!/bin/sh
153mkdir /newroot
154MEMSIZE=\$(free | grep 'Mem:' | awk '{ print \$2 }')
155mount -t tmpfs -o size=\${MEMSIZE}k tmpfs /newroot
156cd /newroot
157echo unpacking rootfs...
158# specify /bin/cpio so that it gets used instead of the busybox builtin
159# busybox cpio returns "need to fix this" when unpacking hard links
160gunzip - < /rootfs.cgz | /bin/cpio -i
161echo running /sbin/init...
162exec /bin/run-init . /sbin/init < ./dev/console > ./dev/console
163EOF
164    chmod a+x "$NEST_ROOT"/init
165
166    msg "creating rootfs.cgz..."
167    fakeroot_if_needed ln -sf /sbin/init "$DEBIRF_ROOT/init"
168    pack_rootfs "$NEST_ROOT"/rootfs.cgz
169
170    msg "creating wrapper cgz..."
171    fakeroot_if_needed sh -c "cd $NEST_ROOT && find * | cpio --create -H newc" | gzip > "$DEBIRF_INITRD"
172}
173
174###############################################################
175### MAIN
176
177# option parsing
178TEMP=$(getopt --options -hcnosrwik: --longoptions help,check-vars,new,overwrite,skip,root-build,no-warning,initrd-only,kernel: -n "$CMD" -- "$@")
179
180if [ $? != 0 ] ; then
181    echo "Invalid options." >&2
182    usage
183    exit 1
184fi
185
186# Note the quotes around `$TEMP': they are essential!
187eval set -- "$TEMP"
188
189while true ; do
190    case "$1" in
191        -h|--help)
192            usage
193            exit 0
194            ;;
195        -c|--check-vars)
196            CHECK_VARS=true
197            shift 1
198            ;;
199        -n|--new)
200            WRITE_MODE=rewrite
201            shift 1
202            ;;
203        -o|--overwrite)
204            WRITE_MODE=overwrite
205            shift 1
206            ;;
207        -s|--skip)
208            WRITE_MODE=skip
209            shift 1
210            ;;
211        -r|--root-build)
212            ROOT_BUILD=true
213            shift 1
214            ;;
215        -w|--no-warning)
216            ROOT_WARNING=false
217            shift 1
218            ;;
219        -i|--initrd-only)
220            STAGE_ROOT=false
221            STAGE_MODULES=false
222            shift 1
223            ;;
224        -k|--kernel)
225            DEBIRF_KERNEL_PACKAGE="$2"
226            shift 2
227            ;;
228        --)
229            shift
230            ;;
231        *)
232            if (( $# < 1 )) ; then
233                echo "Improper number of input arguments."
234                usage
235                exit 1
236            fi
237            DEBIRF_PROFILE="$1"
238            break
239            ;;
240    esac
241done
242
243if [ $(id -u) = '0' ] ; then
244    cat <<EOF
245Warning: You are running debirf as root.  There is a potential
246for improperly written modules to damage your system.
247EOF
248    if [ "$ROOT_WARNING" = 'true' ] ; then
249        read -p "Are you sure you wish to continue? [y|N]: " OK; OK=${OK:=N}
250        if [ "${OK/y/Y}" != 'Y' ] ; then
251            failure "aborting."
252        fi
253    fi
254fi
255
256if [ "$DEBIRF_KERNEL_PACKAGE" ] ; then
257    if [ -f "$DEBIRF_KERNEL_PACKAGE" ] ; then
258        echo "Using kernel package '$DEBIRF_KERNEL_PACKAGE'."
259    else
260        failure "Kernel package '$DEBIRF_KERNEL_PACKAGE' not found."
261    fi
262fi
263
264# source debirf.conf defaults
265source /usr/share/debirf/debirf.conf.defaults
266
267# check profile
268if [ -d "$DEBIRF_PROFILE" ] ; then
269    echo "Loading profile '$DEBIRF_PROFILE'..."
270    DEBIRF_CONF="$DEBIRF_PROFILE/debirf.conf"
271    DEBIRF_MODULES="$DEBIRF_PROFILE/modules"
272else
273    echo "Profile '$DEBIRF_PROFILE' not found."
274    usage_profile
275    exit 1
276fi
277
278# source profile debirf.conf
279if [ -f "$DEBIRF_CONF" ] ; then
280    source "$DEBIRF_CONF"
281else
282    echo "Configuration file '$DEBIRF_CONF' not found."
283    usage_profile
284    exit 1
285fi
286
287# check modules directory
288if [ ! -d "$DEBIRF_MODULES" ] || [ -z "$(ls "$DEBIRF_MODULES")" ] ; then
289    echo "Modules directoy '$DEBIRF_MODULES' does not exist or is empty."
290    usage_profile
291    exit 1
292fi
293for MODULE in $(find "$DEBIRF_MODULES") ; do
294    if [ ! -s "$MODULE" ] ; then
295        failure "Module '$MODULE' is a broken link or empty file."
296    fi
297done
298
299# check buildd
300if [ -z "$DEBIRF_BUILDD" ] ; then
301    failure "DEBIRF_BUILDD is not set."
302fi
303
304# set root directory
305DEBIRF_ROOT="$DEBIRF_BUILDD/root"
306
307# set fakechroot save file
308DEBIRF_FAKEROOT_STATE="$DEBIRF_BUILDD/.fakeroot-state.${DEBIRF_LABEL}"
309if [ "$ROOT_BUILD" != 'true' ] ; then
310    > "$DEBIRF_FAKEROOT_STATE"
311fi
312
313# check variables
314if [ "$CHECK_VARS" ] ; then
315    echo "Debirf variables:"
316    for var in ${!DEBIRF_*}; do
317        if [ $var ] ; then
318            export $var
319        else
320            failure "Variable '$var' not properly set."
321        fi
322    done
323    env | /bin/grep "^DEBIRF_"
324    read -p "enter to continue: " OK
325fi
326
327### BUILD ROOT
328if [ "$STAGE_ROOT" = 'true' ] ; then
329
330# determine write mode
331if [ -d "$DEBIRF_ROOT" ] ; then
332    echo "Debirf root already exists."
333    if [ -z "$WRITE_MODE" ] ; then
334        echo "Select one of the following:"
335        CASE1='new: delete the old root and create a new one'
336        CASE2='overwrite: leave the old root and debootstrap on top of it'
337        CASE3='skip: skip building the root and go right to installing modules'
338        CASE4='exit'
339        select CASE in "$CASE1" "$CASE2" "$CASE3" "$CASE4" ; do
340            case "$REPLY" in
341                1)
342                    WRITE_MODE=rewrite
343                    ;;
344                2)
345                    WRITE_MODE=overwrite
346                    ;;
347                3)
348                    WRITE_MODE=skip
349                    ;;
350                *)
351                    failure "aborting."
352                    ;;
353            esac
354            break
355        done
356    fi
357else
358    WRITE_MODE=new
359fi
360case "$WRITE_MODE" in
361    'new')
362        msg "creating debirf root..."
363        create_debootstrap
364        ;;
365    'rewrite')
366        msg "clearing old debirf root..."
367        rm -rf "$DEBIRF_ROOT"
368        msg "creating debirf root..."
369        create_debootstrap
370        ;;
371    'overwrite')
372        msg "overwriting old debirf root..."
373        create_debootstrap
374        ;;
375    'skip')
376        msg "skipping debootstrap..."
377        ;;
378    *)
379        failure "aborting."
380        ;;
381esac
382
383# fix the dev tree if running as non-priv user (fakechroot debootstrap)
384fix_dev
385
386else
387    echo "Not building root."
388fi
389### END BUILD ROOT
390
391### RUN MODULES
392if [ "$STAGE_MODULES" = 'true' ] ; then
393    msg "executing modules..."
394    run_modules
395    msg "modules complete."
396else
397    echo "Not running modules."
398fi
399### END RUN MODULES
400
401### BUILD INITRD
402if [ "$STAGE_INITRD" = 'true' ] ; then
403    if [ ! -d "$DEBIRF_ROOT" ] ; then
404        failure "Debirf root '$DEBIRF_ROOT' not found."
405    fi
406    # determine initrd name
407    KERNEL_VERS=$(ls -1 "$DEBIRF_ROOT/lib/modules" | head -n1)
408    DEBIRF_INITRD="${DEBIRF_BUILDD}/${DEBIRF_LABEL}_${DEBIRF_DISTRO}_${KERNEL_VERS}.cgz"
409
410    msg "creating debirf initrd ('$DEBIRF_METHOD')..."
411    create_initrd_${DEBIRF_METHOD} "$DEBIRF_INITRD"
412
413    # final output
414    DEBIRF_KERNEL=$(ls "$DEBIRF_BUILDD" | grep "vmlinu" | grep "$KERNEL_VERS$")
415    msg "debirf initrd created."
416    if [ "$DEBIRF_BUILDD/$DEBIRF_KERNEL" ] ; then
417        msg "kernel: $DEBIRF_BUILDD/$DEBIRF_KERNEL"
418    fi
419    msg "initrd: $DEBIRF_INITRD"
420else
421    echo "Not creating initramfs."
422fi
423### END BUILD INITRD
Note: See TracBrowser for help on using the repository browser.