#!/sbin/runscript # The purpose of this script is to load the Alpine runtime modules and the # local config that belongs to. SFIC=`which sfic 2>/dev/null` COMMITED_TDB=/var/lib/apk/commited.tdb TMP=/tmp/init.d-runtimes # search for a kernel argument get_kopt () { for i in `cat /proc/cmdline` ; do case $i in $1=*) echo $i | sed 's|'$1'=||' return 0 ;; esac done return 1 } get_pkg_list() { sed 's/\#.*//' $1 } preload_users_and_groups() { tar -C / -zxf "$1" etc/passwd etc/group 2>/dev/null } # merge the unpacked config merge_config() { local dev mnt ovl f ovllist ovlfile dev=$1 ovlfile="$2" mnt=$(dirname "$2") ovl=$(basename "$2") cp -ar $TMP/* / # remember to remove leading / ovllist=`find $TMP/* | sed "s:^$TMP/::"` if [ "$ovllist" ] ; then lbu update $ovllist 2>/dev/null return 0 else return 1 fi } find_ovl() { local mnt="$1" local ovl local lines # first search kernel cmdline for "pkg_ovl" ovl=$( get_kopt pkg_ovl ) if [ x"$ovl" != x ] ;then echo "$ovl" return 0 fi # look for apkovl's on mounted media ovl=$( ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null ) || return 1 lines=$(echo "$ovl" | wc -l) if [ $lines -gt 1 ] ; then echo "ERROR: More than one apkovl file was found on $(basename $mnt). None will be read." >&2 exit 1 fi echo "$ovl" } # read ahead so the packages are in cache when installed readahead_pkgs() { local i pkgs for i in $* ; do pkgs="$pkgs $APK_PATH_MOUNTED/$i-[0-9]*" done readahead $pkgs 2>/dev/null & } load_pkgs_from_list() { local list="$1" local prompt="$2" local pkgs dummy # apk_fetch -u -q pkgs=$( sed 's/\#.*//' "$list" ) readahead_pkgs $pkgs IGNORE_ERRORS=yes apk_add -v $pkgs 2>&1 | roller } load_pkgs() { local pkglist mlist pkg pkgs local dev=$1 local mnt=$2 # get kernel opt pkg_list or use /packages.list pkglist=`get_kopt pkg_list` # here we should issue a warning in future versions if found on cmdline pkglist=${pkglist:-/packages.list} # aww... we move from /mnt/packages.list to var/lib/apk/world to # etc/lbu/packages.list. Hopefully this code can be simplified in # future. mlist="$mnt/$pkglist" wlist="$TMP/var/lib/apk/world" plist="$TMP/etc/lbu/packages.list" [ -f "$plist" ] && wlist="$plist" if [ -f "$wlist" ] ; then load_pkgs_from_list "$wlist" # its re-generated rm -rf "$wlist" elif [ -f "$mlist" ] ; then #ok, we are upgrading... local line i eeinfo " NOTE: Using packages.list from $dev. This file has moved to etc/lbu/packages.list and will be included in the apkovl. " load_pkgs_from_list "$mlist" # lets clean up the world file echo "# This file was generated by /etc/init.d/runtimes" >/etc/init.d/packages.list for i in $(apk_glob '*') ; do reqby=$(apk_info -qr $i); # only add the packages who has no REQUIRED_BY [ -z "$reqby" ] && echo $i done | sed 's/-[0-9].*//' >> /etc/lbu/packages.list fi } # load packages from mounted media load_pkgs_and_config() { # params: # $1 = device # $2 = path to mounted media local ovlfile local mnt=$2 local dev=$1 local dest cd / # look for apk overlays. ovlfile=$( find_ovl "$mnt" ) || return 1 mkdir -p "$TMP" ebegin "Loading setup from $dev://$(basename $ovlfile)" case "$ovlfile" in *.apkovl.tar.gz.*) local cipher=${ovlfile##*.} local count=0 if ! openssl list-cipher-commands \ | grep "^$cipher$" > /dev/null; then eend 1 "Cipher $cipher is not supported" return 1 fi echo "" while true ; do count=$(( $count + 1 )) openssl enc -d -$cipher -in "$ovlfile" \ | tar -C "$TMP" -zx 2>/dev/null if [ $? -eq 0 ]; then break elif [ $count -ge 3 ]; then eend 1 return fi done ;; *) # unpack the ovl if ! tar -C "$TMP" -zxf "$ovlfile" ; then eend $? return fi esac # copy the passwd file [ -f "$TMP/etc/passwd" ] && cp $TMP/etc/passwd /etc [ -f "$TMP/etc/group" ] && cp $TMP/etc/group /etc # install the packages load_pkgs $dev $mnt # copy the config merge_config eend $? # clean up rm -rf "$TMP" } # find where to install packages from set_apk_path() { local dev fs mnt pref subdir # if pkg_path is not specified as kernel arg, look for the packages # on mounted cdrom APK_PATH=`get_kopt pkg_path` APK_DEV=`get_kopt pkg_dev` # return if pkg_dev is empty if [ x"$APK_DEV" = x ] ; then export APK_PATH return fi # split dev:fs dev=`echo $APK_DEV | cut -d: -f1` fs=`echo $APK_DEV | cut -d: -f2` # find mountpoint in fstab mnt=$( awk '/^\/dev\/'$dev'/ { print $2 }' /etc/fstab ) # remove leading '/media/'. we assume the mount is in /media prefix=${mnt#/media/} # if there is no mountpoint in /media, then append one if [ x"$prefix" = x"$mnt" ] || [ x"$mnt" = x ] ; then prefix=$dev echo -e "/dev/$dev\t/media/$prefix\t$fs\tnoauto\t0 0" >> /etc/fstab mkdir -p /media/$prefix fi # construct the URI subdir=`get_kopt pkg_subdir` APK_PATH=$prefix:/${subdir:-/apks} # read configs if available [ -f /etc/apk/apk.conf ] && . /etc/apk/apk.conf export APK_PATH export APK_PATH_MOUNTED=/media/$prefix/$subdir } # mount dev $2 with type $1 on /mnt mount_dev() { local fs=$1 local dev=$2 local i mountok # special handling for usb devices case $dev in usb*) # check for attatched devices if grep usb-storage /sys/class/scsi_host/host*/proc_name >/dev/null 2>&1 ; then ebegin "Waiting for usb-storage" for i in $(seq 0 9); do if mount -t $fs -o ro /dev/$dev /mnt >/dev/null 2>&1; then eend 0 return 0 else echo -n "." sleep 2 fi done eend 1 return 1 # timed out... fi ;; esac # not usb, just try to mount as normal mount -t $fs -o ro /dev/$dev /mnt >/dev/null 2>&1 return } start() { local cfgdevs m # just in case... modprobe usb-storage 2>/dev/null modprobe sd_mod 2>/dev/null modprobe floppy 2>/dev/null modprobe cdrom 2>/dev/null set_apk_path cfgdevs=$( echo $( get_kopt cfg_dev ) | tr , ' ') for m in ${cfgdevs:-usba1:vfat fd0:vfat cdrom:iso9660}; do local dev fs skip_umount mnt loaded # split 'dev:fs' dev=${m%%:*} fs=${m##*:} # try to mount device on /mnt or abort mnt=$( awk '$1 ~ /^\/dev\/'$dev'/ { print $2 }' /proc/mounts ) if [ x$mnt = x ] ; then skip_umount="" mount_dev $fs $dev || continue mnt=/mnt else skip_umount=yes fi # look for package listings and config overlays load_pkgs_and_config $dev $mnt && loaded=yes # lazy unmount [ "$skip_umount" = yes ] || umount -l $mnt [ "$loaded" = yes ] && break done # if there are no /etc/apk/apk.conf, create one if ! [ -f /etc/apk/apk.conf ] ; then mkdir -p /etc/apk echo "APK_PATH=$APK_PATH" > /etc/apk/apk.conf fi }