Skip to content

Instantly share code, notes, and snippets.

@sirovenmitts
Created May 17, 2013 08:24
Show Gist options
  • Save sirovenmitts/5597732 to your computer and use it in GitHub Desktop.
Save sirovenmitts/5597732 to your computer and use it in GitHub Desktop.
Got a sweet Samsung Chromebook? Why not spruce it up a little with a fanny pack! This script will download an Arch rootfs and install it at /usr/local/fpack so you can chroot into it and have access to a package manager, compiler, and much more. It'll also create a script at /usr/local/bin/enter that will take care of mounting everything for you…
#!/bin/bash
# This script starts background processes, so I need to murder them.
function abort { kill $! &>/dev/null ; red ":(\n" ; exit 1 ; }
# For debugging purposes
function log { echo -e "Stardate `date`: $1" >> "$LOG" ; }
# Shove heredocs into variables.
function define { IFS='' read -r -d '' ${1} ; }
function red { tput setaf 1 ; echo -en "$1" ; tput sgr0 ; }
function green { tput setaf 2 ; echo -en "$1" ; tput sgr0 ; }
function blue { tput setaf 6 ; echo -en "$1" ; tput sgr0 ; }
# Crosh seems to think I mean italicize when I say blink.
function emphasize { tput blink ; echo -en "$1" ; tput sgr0 ; }
function ok { echo -n ... ; green OK ; echo ; }
function ohno { red "Uh oh" ; red "\n\n${!1}" ; echo "$LOG" ; abort ; }
function check {
blue "$1"
for _ in $( seq 1 $(( 75 - ${#1} ))) ; do echo -n . ; done
$2 && ok || ohno "$3"
}
function task {
log "I started the task: \"$1\""
DOTS=$[ 75 - ${#1} ]
DOTS_PRINTED=0
blue "$1"
$2
disown -a
# The unboxing process seems to fail hard unless I sleep here. I don't
# pretend to know why.
sleep 1
PERCENT_COMPLETE=0
while [[ $PERCENT_COMPLETE -lt 100 ]] ; do
$3
[[ -z $PERCENT_COMPLETE ]] && PERCENT_COMPLETE=0
while [[ $[ PERCENT_COMPLETE * DOTS / 100 ] -gt $DOTS_PRINTED ]] ; do
echo -n .
DOTS_PRINTED=$[ DOTS_PRINTED + 1 ]
done
done
ok
}
function download { URL="${!2}" task "Fetch $1" start_download during_download ; }
function ask { read -p "`blue "$1? "`" -i "$2" -e $3 ; }
function start_download {
wget -O `basename "$URL"` -a "$LOG" "$URL" &>/dev/null &
}
function during_download { PERCENT_COMPLETE=`tail -n 4 "$LOG" | grep -o ...% | tail -1 | cut -d % -f 1` ; }
function start_unboxing {
# I skip unpacking /dev in the rootfs because it has a bunch of special files
# in it I don't care about. Still, I need /dev, so why not make it here?
mkdir -p "$PACK_PATH/$PACK_NAME/dev"
BYTES_EXTRACTED=0
TOTAL_BYTES=`gzip -l "$ROOTFS" | tail -1 | awk '{print $2}'`
tar -xf "$ROOTFS" --exclude dev --totals=SIGHUP -C "$PACK_PATH/$PACK_NAME" >>"$LOG" 2>&1 &
}
function during_unboxing {
kill -s SIGHUP $! || break
BYTES_EXTRACTED=`tail -1 "$LOG" | cut -d " " -f 4 | tail -1`
PERCENT_COMPLETE=`awk -v a=$BYTES_EXTRACTED -v b=$TOTAL_BYTES 'BEGIN { printf "%1i", a/b*100 }'`
}
function is_connected_to_the_internet { [[ `cat /sys/class/net/mlan0/carrier` -eq 1 ]] ; return $? ; }
function chroot_checks_out {
echo "`cat $MD5 | cut -d " " -f 1 | sed -e "s/$/ $ROOTFS/"`" > "$MD5"
md5sum --quiet -c "$MD5" &>/dev/null
return $?
}
function is_positive_response { [[ "yes yeah ok yup sure" =~ `echo "$1" | tr [:upper:] [:lower:]` ]] ; }
function install_scripts {
mkdir -p /usr/local/bin
echo "$ENTER_SCRIPT" 2>"$LOG" > /usr/local/bin/enter
echo "$UNMOUNT_SCRIPT" 2>"$LOG" > /usr/local/bin/unfanny
chmod a+x /usr/local/bin/enter
chmod a+x /usr/local/bin/unfanny
}
ROOTFS_URL=http://os.archlinuxarm.org/os/ArchLinuxARM-imx6-latest.tar.gz
MD5_URL="$ROOTFS_URL.md5"
ROOTFS=`basename "$ROOTFS_URL"`
MD5="$ROOTFS.md5"
DOWNLOADED_FILE=`basename "$ROOTFS_URL"`
LOG=`mktemp`
PACK_PATH=/usr/local/
PACK_NAME=fpack
define ENTER_SCRIPT <<ENTERING
#!/bin/bash
[[ \`id -u\` -ne 0 ]] && exec sudo "\$0"
function is_mounted { grep -qs "\$1" /proc/mounts ; }
function unless_mounted { if ! is_mounted "\$1" ; then "\${@:2}" ; fi ; }
cp /etc/resolv.conf /usr/local/fpack/etc/resolv.conf
unless_mounted /usr/local/fpack/dev mount -o bind /dev/ /usr/local/fpack/dev
unless_mounted /usr/local/fpack/dev/pts mount -t devpts -o rw,nosuid,noexec,relatime,mode=620,gid=5 none /usr/local/fpack/dev/pts
unless_mounted /usr/local/fpack/proc mount -t proc proc /usr/local/fpack/proc
unless_mounted /usr/local/fpack/sys mount -t sysfs sys /usr/local/fpack/sys
unless_mounted /usr/local/fpack/root mount -o bind /home/chronos/user /usr/local/fpack/root
chroot /usr/local/fpack /bin/bash
ENTERING
define UNMOUNT_SCRIPT <<UNMOUNT_IT_ALL
#!/bin/bash
[[ \`id -u\` -ne 0 ]] && exec sudo "\$0"
grep fpack /proc/mounts | cut -d " " -f 2 | xargs -e sudo umount
UNMOUNT_IT_ALL
define PREAMBLE <<THE_PREAMBLE
Hey, that's a pretty sweet ensemble you've got there. Too bad your silver
jumpsuit doesn't have any pockets. You've got no place to put your electric
harmonophone. And how are you going to get along without a place to hold your 7
function Swiss Army comb? It's cool and useful, but no one wants to be seen
holding one on the dance floor.
Friend, you need a fanny pack. And bollocks to what the brits think I'm talking
about - you need a portable, aerodynamic, sling-pocket strapped to your waist.
You can put everything in there. Anyways, I'll fit you for one.
THE_PREAMBLE
define WARNING <<"A_WARNING"
__ __ ______ _______ __ __ ______ __ __ ______
/ | _ / | / \ / \ / \ / |/ |/ \ / | / \
$$ | / \ $$ |/$$$$$$ |$$$$$$$ |$$ \ $$ |$$$$$$/ $$ \ $$ |/$$$$$$ |
$$ |/$ \$$ |$$ |__$$ |$$ |__$$ |$$$ \$$ | $$ | $$$ \$$ |$$ | _$$/
$$ /$$$ $$ |$$ $$ |$$ $$< $$$$ $$ | $$ | $$$$ $$ |$$ |/ |
$$ $$/$$ $$ |$$$$$$$$ |$$$$$$$ |$$ $$ $$ | $$ | $$ $$ $$ |$$ |$$$$ |
$$$$/ $$$$ |$$ | $$ |$$ | $$ |$$ |$$$$ | _$$ |_ $$ |$$$$ |$$ \__$$ |
$$$/ $$$ |$$ | $$ |$$ | $$ |$$ | $$$ |/ $$ |$$ | $$$ |$$ $$/
$$/ $$/ $$/ $$/ $$/ $$/ $$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/
I am providing no warranty with this. If you slip and fall while doing the Bit
Banana Smush it's not my fault. Also, same goes for some hooligans beating you
up cause you look like a weirdo wearing this.
A_WARNING
define QUESTIONNAIRE <<SOME_QUESTIONS
My buddy owns a research company, and he asked me to have you answer some
questions before you cross this bridge. Please, answer honestly and don't
forget that I already know the answers, so do whatever you want, really...
SOME_QUESTIONS
define PREREQUISITES <<THE_PREREQS
OK, before I can fit you I need your measurements. To prepare yourself for the
awesome power of a fanny pack you must:
THE_PREREQS
define NOW_DOWNLOADING <<DOWNDOWNDOWN
Perfect! You are now ready to don the pack of the gods, but I've still gotta
run it through a byte replicator and hit it with a coat of paint. Please be
patient, as this `emphasize could` take a while...
DOWNDOWNDOWN
define NOW_WORKING <<WORKWORKWORK
Here we go; I'll gently lace these straps around your waist and tie you in...
WORKWORKWORK
define POSTAMBLE <<AMBLE_AWAY
Great! Everything's in place, and you look fantastic! Just two more things:
1) When you decide you want to chroot around in your pack, use the command
"enter" - it'll take care of ensuring the hyperblasters are set to neutral. If
you decide not to use it you'll probably have to do a bunch of work, like learn
how the mount command works.
2) If you need to take your fanny pack off because you decided to put a badger
in it, or maybe cause you're on fire and don't want to damage the pack, just
use the unfanny command; it'll disengage the tumblers and power down the
reactor.
Well, good luck, and have fun on that dance floor.
PS: If you decide you want to take the pack off, for spaghetti's sake please
PLEASE `emphasize PLEASE` unmount everything before removing it - if you don't
you might just wipe EVERYTHING from your home folder, cause I kind of mounted
that for you. I should know, I've done it at least once.
AMBLE_AWAY
define SHOULD_BE_CONNECTED_TO_THE_NET<<INTERNET_CONNECTION_MESSAGE
Whoa there tiger! You've got no network connection. I can't help you unless you
help yourself. Get an internet connection and then we'll talk.
INTERNET_CONNECTION_MESSAGE
define ROOTFS_COULD_NOT_BE_VERIFIED <<SHOULD_VERIFY_ROOTFS
Oh man, this is bad. I downloaded a rootfs, but something (or someone) altered
the rootfs in transit. It's probably just some corruption during download, but
you might want to make sure the government isn't after you.
SHOULD_VERIFY_ROOTFS
trap abort SIGINT
[[ `id -u` -ne 0 ]] && exec sudo bash $0
log "I was launched into orbit"
echo -n "$PREAMBLE"
red "$WARNING"
echo "$PREREQUISITES"
check "Be connected to the internet" is_connected_to_the_internet SHOULD_BE_CONNECTED_TO_THE_NET
echo "$QUESTIONNAIRE"
ask "Do you want to install a sweet fanny pack on your hip" yes SHOULD_CONTINUE
is_positive_response "$SHOULD_CONTINUE" || abort
[[ -z "$SHOULD_CONTINUE" ]] && abort
echo "$NOW_DOWNLOADING"
download "the pack" ROOTFS_URL
download "unboxing instructions" MD5_URL
check "Make sure I got the right pack" chroot_checks_out ROOTFS_COULD_NOT_BE_VERIFIED
echo "$NOW_WORKING"
task "Unbox the pack" start_unboxing during_unboxing
check "Check the zipper" install_scripts
echo "$POSTAMBLE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment