#!/bin/bash # # Raspberry Pi Setup Script # Donald Burr # set to YES for debugging DEBUG="NO" # use older motion-mmal with its own built-in raspi camera driver USE_MMAL_MOTION="NO" # use newer (third party) version of node.js USE_THIRD_PARTY_NODE_JS="YES" # install newer (third party) ffmpeg in /usr? INSTALL_FFMPEG_IN_USR="NO" # disable the red LED that turns on when the camera module is active? DISABLE_CAMERA_LED="YES" # also install PHP when installing lighttpd? INSTALL_PHP="NO" # store location that this script is in D="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # convenience function, install a package but only if it isn't already present function install_package { local PACKAGE=$1 if dpkg -s $PACKAGE >/dev/null 2>&1; then echo "skipping install of $PACKAGE, it is already present" else echo "installing $PACKAGE" sudo aptitude -q=2 -y install $PACKAGE fi } # ffmpeg setup code is broken out into its own function because it # is used in 2 spots in this script function install_ffmpeg { if [ "$DEBUG" = "YES" ]; then echo "skipping install of ffmpeg, we are in DEBUG Mode" echo "NOTE: this may break other apps that depend on it." elif hash ffserver 2>/dev/null; then echo "skipping install of ffmpeg, it is already present" else echo "*** building current ffmpeg from source ***" mkdir $HOME/src cd $HOME/src git clone git://source.ffmpeg.org/ffmpeg.git cd ffmpeg if [ "$INSTALL_FFMPEG_IN_USR" = "YES" ]; then ./configure --prefix=/usr else ./configure fi make sudo make install echo "*** setting up symlinks ***" if [ "$INSTALL_FFMPEG_IN_USR" != "YES" ]; then for COMMAND in ffmpeg ffprobe ffserver; do sudo rm -f /usr/bin/$COMMAND && sudo ln -sf ../local/bin/$COMMAND /usr/bin/$COMMAND done fi fi } # start of script if ! dpkg -s screen >/dev/null 2>&1; then echo "*** BEGINNING RPI SETUP ***" echo "This script assumes you have gone through \`raspi-config' (must be run as root)" echo "and configured all the values there, especially Internationalization," echo "Keyboard and the Raspberry Pi Camera (if one is installed.)" echo "" echo "If you haven't performed those steps, hit Ctrl-C now and do so, then" echo -n "re-run this script. Otherwise, press Return to proceed. " read BLAH echo "" echo "*** performing initial setup ***" sudo aptitude -y update for PKG in screen mosh; do install_package $PKG done if grep -q raspberrypi /etc/hostname; then echo "You still have the default hostname set. We recommend changing the" echo "hostname so that your Pi can be uniquely identified." echo "If you wish to change it, enter a new hostname now, otherwise" echo -n "just press Return: " read NEW_HOSTNAME if [ ! -z "$NEW_HOSTNAME" ]; then echo "$NEW_HOSTNAME" > /tmp/HOSTNAME.$$ sudo rm -f /etc/hostname sudo mv /tmp/HOSTNAME.$$ /etc/hostname sudo chown root:root /etc/hostname sudo chmod 644 /etc/hostname sudo /etc/init.d/hostname.sh fi fi echo -n "Would you like to set up a Wi-Fi adapter? [yn] " read WIFI_YORN if [ "$WIFI_YORN" = "y" ]; then echo "Please make sure the Wi-Fi adapter is plugged in, then at the prompt below," echo "enter which type of adapter you wish to set up." echo "" echo "1. TP-LINK TL-WN725N" echo "2. Edimax EW-7811Un" echo "" WIFI_ADAPTER=0 VALID="NO" while [ "$VALID" = "NO" ]; do echo -n "Your choice: " read WIFI_ADAPTER if ! [[ "$WIFI_ADAPTER" =~ ^[0-9]+$ ]]; then echo "Error, that is not a valid answer." elif [ "$WIFI_ADAPTER" -lt 1 -o "$WIFI_ADAPTER" -gt 2 ]; then echo "Error, that is not a valid answer." else VALID="YES" fi done if [ $WIFI_ADAPTER -eq 1 ]; then # TP-link SKIP_RPI_UPDATE="YES" KERNEL_DATE_LONG=`uname -v | sed -e 's/^.*PREEMPT //g'` KERNEL_DATE=`date -d"$KERNEL_DATE_LONG" +%Y%m%d` if [ ! -f "$D/drivers/8188eu-$KERNEL_DATE.tar.gz" ]; then echo "Could not find a driver matching your kernel version. Will attempt to" echo "fetch one now." cd $D/drivers wget https://dl.dropboxusercontent.com/u/80256631/8188eu-$KERNEL_DATE.tar.gz fi if [ -f "$D/drivers/8188eu-$KERNEL_DATE.tar.gz" ]; then mkdir /tmp/wifi.$$ cd /tmp/wifi.$$ tar xzf $D/drivers/8188eu-$KERNEL_DATE.tar.gz sudo install -p -m 644 8188eu.ko /lib/modules/`uname -r`/kernel/drivers/net/wireless sudo insmod /lib/modules/`uname -r`/kernel/drivers/net/wireless/8188eu.ko sudo depmod -a PROCEED_WITH_WIFI_SETUP="YES" else echo "ERROR: could not find a version of the TP-link driver for your kernel." echo "Cannot proceed with wifi setup." PROCEED_WITH_WIFI_SETUP="NO" fi elif [ $WIFI_ADAPTER -eq 2 ]; then # edimax # no further configuration necessary, the driver is already in the kernel SKIP_RPI_UPDATE="NO" PROCEED_WITH_WIFI_SETUP="YES" else # fallthrough, we can't proceed SKIP_RPI_UPDATE="NO" PROCEED_WITH_WIFI_SETUP="NO" fi # the rest is common to all wifi adapters if [ "$PROCEED_WITH_WIFI_SETUP" = "YES" ]; then echo -n "Enter your wireless network's SSID: " read SSID PASSWORD="foo" PASSWORD_TEMP="bar" stty -echo while [ "$PASSWORD" != "$PASSWORD_TEMP" ]; do echo "Note: Only WPA and/or WPA2 passwords are currently supported." echo -n "Enter your wireless network's password: " read PASSWORD echo echo -n "Re-enter for verification: " read PASSWORD_TEMP echo if [ "$PASSWORD" != "$PASSWORD_TEMP" ]; then echo "Error: passwords do not match" fi done stty echo if [ -f /etc/network/interfaces ]; then sudo mv -f /etc/network/interfaces /etc/network/interfaces.bak fi sudo cp $D/configs/wifi/interfaces /etc/network/interfaces sudo chown root:root /etc/network/interfaces sudo chmod 644 /etc/network/interfaces if [ -f /etc/wpa_supplicant/wpa_supplicant.conf ]; then sudo mv -f /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf.bak fi sudo cp $D/configs/wifi/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf sudo sed -i.sed.bak -e "s/#SSID#/$SSID/g" -e "s/#PASSWORD#/$PASSWORD/g" /etc/wpa_supplicant/wpa_supplicant.conf sudo chown root:root /etc/wpa_supplicant/wpa_supplicant.conf sudo chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf echo "*** attempting to bring up Wi-Fi... ***" sudo ifdown wlan0 sudo ifdown --force wlan0 sudo ifup wlan0 fi fi # some wifi adapters haven't yet had their drivers updated to work with # the newer kernel installed by rpi-update, so we may have to skip it if [ "$SKIP_RPI_UPDATE" != "YES" ]; then echo "*** updating RPI firmware ***" install_package rpi-update sudo rpi-update fi echo "*** initial setup is now complete." echo "*** please reboot your Pi now." echo "*** after it has booted up, login and re-run this script." exit 0 fi # initial set up is done echo "*** Ready to perform second stage of setup." echo "*** This stage will take a long time. It is recommended to run this" echo "*** script within \`screen' so that it will continue running even if" echo "*** something bad were to occur (lose connection, etc.)" echo "*** If you are not currently running within \`screen', press Ctrl-C" echo "*** and re-run this script from within \`screen.' Otherwise," echo -n "*** press Return to proceed: " read FAILSAFE echo "*** installing additional packages ***" for PKG in cifs-utils git pv vim; do install_package $PKG done # for vlc/gstreamer echo -n "Install vlc & gstreamer? [yn] " read INSTALL_VLC if [ "$INSTALL_VLC" = "y" ]; then echo "*** setting up vlc and gstreamer streaming ***" for PKG in vlc gstreamer1.0 libasound2-dev; do install_package $PKG done fi # for bluetooth echo -n "Install bluetooth & ibeacon? [yn] " read INSTALL_BT if [ "$INSTALL_BT" = "y" ]; then echo "*** setting up bluetooth and ibeacon ***" for PKG in bluetooth bluez-utils blueman; do install_package $PKG done sudo cp $D/scripts/ibeacon /usr/bin sudo chown root:root /usr/bin/ibeacon sudo chmod 755 /usr/bin/ibeacon if ! sudo grep -q IBEACON_UUID /etc/sudoers; then echo "adding env_keep to sudoers" sudo sed -i '/Defaults.*env_reset/a \ Defaults env_keep += "IBEACON_UUID IBEACON_MAJOR IBEACON_MINOR IBEACON_POWER"' /etc/sudoers else echo "do not need to edit sudoers" fi fi # set up ffmpeg # NOTE: we are using the latest version from git instead of the packaged version # skip when debugging, it takes forever echo -n "Install latest ffmpeg from source (takes a LONG time, about 4-5 hours)? [yn] " read INSTALL_FFMPEG if [ "$INSTALL_FFMPEG" = "y" ]; then install_ffmpeg fi # set up avahi # http://holyarmy.org/2008/01/advertising-linux-services-via-avahibonjour/ echo -n "Install avahi (Bonjour/zeroconf autodiscovery)? [yn] " read INSTALL_AVAHI if [ "$INSTALL_AVAHI" = "y" ]; then echo "*** setting up avahi (bonjour/autodiscovery) ***" for PKG in avahi-daemon avahi-utils; do install_package $PKG done for F in $D/configs/avahi/*.service; do echo "installing $F..." sudo cp $F /etc/avahi/services done sudo chown root:root /etc/avahi/services/*.service sudo chmod 644 /etc/avahi/services/*.service sudo service avahi-daemon restart fi # set up lighttpd+php # http://www.instructables.com/id/Setup-a-Raspberry-Pi-PHP-web-server/?ALLSTEPS echo -n "Install Pi webserver environment (lighttpd+php)? [yn] " read INSTALL_LIGHTTPD if [ "$INSTALL_LIGHTTPD" = "y" ]; then echo "*** installing lighttpd and php packages ***" install_package lighttpd if [ "$INSTALL_PHP" = "YES" ]; then echo "*** installing php ***" for PKG in php5-common php5-cgi php5; do install_package $PKG done fi echo "*** enabling lighttpd modules ***" MODULES="cgi fastcgi userdir" if [ "$INSTALL_PHP" = "YES" ]; then MODULES="$MODULES fastcgi-php" fi for MODULE in $MODULES; do echo "...$MODULE" sudo lighty-enable-mod $MODULE done echo "*** enabling cgi-bin directories ***" sudo sed -i.bak -e 's/^\($HTTP\["url"\] =~ "\)[^"]*\(".*$\)/\1\/cgi-bin\/\2/' /etc/lighttpd/conf-available/10-cgi.conf echo "*** enabling directory listings for directories that lack index.html ***" sudo sed -i.bak -e '$adir-listing.activate = "enable"' /etc/lighttpd/lighttpd.conf echo "*** setting permissions for /var/www directory ***" sudo chown www-data:www-data /var/www sudo chmod 775 /var/www sudo usermod -a -G www-data pi echo "*** installing default www files ***" mkdir -p $HOME/public_html cp -a $D/configs/lighttpd/* $HOME/public_html chmod -R g+w $HOME/public_html sudo cp -a $D/configs/lighttpd/* /var/www sudo chmod -R g+w /var/www if [ -f /var/www/index.html.webroot ]; then cp /var/www/index.html.webroot /var/www/index.html fi if [ -f $HOME/public_html/index.html.home ]; then cp $HOME/public_html/index.html.home $HOME/public_html/index.html fi echo "*** restarting lighttpd ***" sudo service lighttpd force-reload fi # set up osss echo -n "Install OSSS (Open Source Surveillance & Security)? [yn] " read INSTALL_OSSS if [ "$INSTALL_OSSS" = "y" ]; then echo "*** setting up motion ***" if [ "$USE_MMAL_MOTION" = "YES" ]; then for PKG in libjpeg62 libjpeg62-dev libavformat53 libavformat-dev libavcodec53 libavcodec-dev libavutil51 libavutil-dev libc6-dev zlib1g-dev libmysqlclient18 libmysqlclient-dev libpq5 libpq-dev motion; do install_package $PKG done if [ ! -f /usr/bin/motion.orig ]; then echo "*** fetching version of motion patched for raspi camera ***" mkdir /tmp/motion.$$ cd /tmp/motion.$$ && wget https://www.dropbox.com/s/xdfcxm5hu71s97d/motion-mmal.tar.gz tar xzf motion-mmal.tar.gz sudo mv /usr/bin/motion /usr/bin/motion.stock sudo cp motion /usr/bin/motion.mmal sudo chown root:root /usr/bin/motion.mmal sudo chmod 755 /usr/bin/motion.mmal sudo ln -sf motion.stock /usr/bin/motion fi if [ ! -f /etc/motion.conf ]; then echo "*** installing motion-mmal config file ***" sudo cp $D/configs/motion/motion-mmal.conf /etc/motion.conf sudo sed -i.sed.bak "s/^.*\btext_left\b.*$/text_left `hostname`/" /etc/motion.conf sudo chown root:root /etc/motion.conf sudo chmod 644 /etc/motion.conf fi else for PKG in motion; do install_package $PKG done if [ ! -f /etc/motion/motion.conf.orig ]; then echo "*** installing motion config file ***" sudo mv /etc/motion/motion.conf /etc/motion/motion.conf.orig sudo cp $D/configs/motion/motion.conf /etc/motion/motion.conf sudo sed -i.sed.bak "s/^.*\btext_left\b.*$/text_left `hostname`/" /etc/motion/motion.conf sudo chown root:motion /etc/motion/motion.conf sudo chmod 644 /etc/motion/motion.conf fi if ! grep -q bcm2835-v4l2 /etc/modules; then echo "*** setting camera driver to load at boot (and loading it now) ***" sudo sed -i.bak -e "\$a\ bcm2835-v4l2" /etc/modules sudo modprobe bcm2835-v4l2 fi fi if [ ! -f /var/log/motion ]; then echo "*** creating motion log file ***" sudo touch /var/log/motion.log sudo chown motion:motion /var/log/motion.log sudo chmod 644 /var/log/motion.log fi if [ ! -d /var/spool/motion ]; then echo "*** creating motion spool directory ***" sudo mkdir /var/spool/motion sudo chown motion:motion /var/spool/motion sudo chmod 755 /var/spool/motion fi if ! grep -q "start_motion_daemon.*=.*yes" /etc/default/motion; then echo "*** enabling auto-run motion at startup ***" sudo sed -i 's/^\(start_motion_daemon\s*=\s*\).*$/\1yes/' /etc/default/motion fi if [ ! -d /home/motion ]; then echo "*** creating motion home directory ***" sudo mkdir /home/motion sudo chown motion:motion /home/motion fi echo "*** setting up node.js ***" if [ "$USE_THIRD_PARTY_NODE_JS" = "YES" ]; then echo "Downloading node.js..." mkdir -p /tmp/node.$$ cd /tmp/node.$$ && curl -L# https://gist.github.com/raw/3245130/v0.10.24/node-v0.10.24-linux-arm-armv6j-vfp-hard.tar.gz -o node-v0.10.24-linux-arm-armv6j-vfp-hard.tar.gz echo "Installing node.js..." pv /tmp/node.$$/node-v0.10.24-linux-arm-armv6j-vfp-hard.tar.gz | sudo tar --owner=root --group=root -C /usr/ -xzf - --strip=1 else for PKG in nodejs npm; do install_package $PKG done fi if [ "$USE_THIRD_PARTY_NODE_JS" != "YES" ]; then # raspbian standard node needs special ssl configuration # #echo "*** upgrading to SSL-compliant version of npm ***" #sudo npm install npm -g --ca="" echo "*** configuring npm to use standard SSL certificates ***" npm config set ca "" sudo npm config set ca "" fi # ffmpeg is used by the fluent-ffmpeg module echo "*** setting up ffmpeg (used by node.js modules) ***" echo "*** NOTE: this takes a LONG time (~3-4 hours) ***" install_ffmpeg echo "*** installing node.js modules ***" # express@2.5.1 MODULE_LIST="async express fluent-ffmpeg nstore ps-node" if [ "$USE_THIRD_PARTY_NODE_JS" = "YES" ]; then # only the newer node.js seems to like express MODULE_LIST="express express-generator@4 $MODULE_LIST" fi for MODULE in $MODULE_LIST; do echo "...$MODULE" sudo npm install -g $MODULE done if [ "$USE_THIRD_PARTY_NODE_JS" != "YES" ]; then # only needed for stock raspbian node.js echo "*** creating node -> nodejs symlink ***" sudo ln -sf nodejs /usr/bin/node fi echo "*** adding node.js modules path to bashrc ***" echo 'export NODE_PATH="'$(npm root -g)'"' >> $HOME/.bashrc if ! sudo grep -q NODE_PATH /etc/sudoers; then echo "adding env_keep NODE_PATH to sudoers" sudo sed -i '/Defaults.*env_reset/a \ Defaults env_keep += "NODE_PATH"' /etc/sudoers else echo "do not need to edit sudoers" fi if [ ! -f /home/motion/server.js ]; then echo "*** installing web app ***" if [ `hostname` = "pi-b" ]; then sudo ln -sf $D/configs/motion/server.js /home/motion/server.js else sudo cp $D/configs/motion/server.js /home/motion/server.js sudo chown motion:motion /home/motion/server.js sudo chmod 644 /home/motion/server.js fi sudo cp $D/configs/motion/run_server /home/motion/run_server sudo chown motion:motion /home/motion/run_server sudo chmod 755 /home/motion/run_server fi crontab -l > /tmp/crontab.$$ 2>&1 if [ $? -ne 0 ]; then NEEDS_CRONTAB="YES" elif ! grep -q SMB_BACKUP /tmp/crontab.$$; then NEEDS_CRONTAB="YES" else NEEDS_CRONTAB="NO" fi if [ "$NEEDS_CRONTAB" = "YES" ]; then echo "*** setting up backup script ***" crontab -l > /tmp/cron.$$ 2>/dev/null cat << _EOF_CRON_ >> /tmp/cron.$$ #SMB_BACKUP 0 * * * * /home/pi/sync_osss_files _EOF_CRON_ crontab /tmp/cron.$$ rm -f /tmp/cron.$$ fi # run server at boot if ! grep -q RUN_MOTION_SERVER /etc/rc.local; then echo "*** enabling motion web server at boot ***" sudo sed -i.bak '/^exit 0$/i\ #RUN_MOTION_SERVER\ cd /home/motion && nohup bash run_server &\ ' /etc/rc.local fi # disable camera LED if [ "$DISABLE_CAMERA_LED" = "YES" ]; then echo "*** disabling camera LED ***" if grep -q disable_camera_led /boot/config.txt; then sudo sed -i.bak -e 's/.*disable_camera_led.*/disable_camera_led=1/g' /boot/config.txt else sudo sed -i.bak -e '$adisable_camera_led=1' /boot/config.txt fi fi fi # set up streaming monitor # based on: https://github.com/Tomtomgo/raspberry_livestream #echo "Note: this install includes a build of ffmpeg and nginx which takes a" #echo "LONG time (about 3-4 hours.)" echo -n "Install streaming video server? [yn] " read INSTALL_STREAMER if [ "$INSTALL_STREAMER" = "y" ]; then # install needed packages # libav-tools for PACKAGE in ffmpeg libpcre3-dev libssl-dev supervisor; do install_package $PACKAGE done # needs ffmpeg #install_ffmpeg # build nginx echo "Fetching and building nginx..." mkdir /tmp/nginx.$$ && cd /tmp/nginx.$$ wget https://github.com/arut/nginx-rtmp-module/archive/master.zip wget http://nginx.org/download/nginx-1.7.9.tar.gz tar -zxvf nginx-1.7.9.tar.gz unzip master.zip cd nginx-1.7.9 ./configure --add-module=/tmp/nginx.$$/nginx-rtmp-module-master make && sudo make install # clone the rpi repo echo "Fetching streaming code..." cd /tmp/nginx.$$ git clone https://github.com/Tomtomgo/raspberry_livestream.git cd /tmp/nginx.$$/raspberry_livestream # edit stream.sh sudo cp nginx.conf /usr/local/nginx/conf/nginx.conf sudo cp stream.supervisor.conf /etc/supervisor/conf.d/stream.supervisor.conf cp stream.sh $HOME/stream.sh # restart #sudo service supervisor stop #sudo service supervisor start echo "NOTE: be sure and set STREAM_NAME and RASPBERRY_IP in \$HOME/stream.sh" echo "" echo "Stream will be available at the url: rtmp://RASPBERRY_IP/live/STREAM_NAME" echo "Use VLC or similar to test it out." echo "" echo "To set up a HTTP page with the stream, see:" echo "https://github.com/Tomtomgo/raspberry_livestream" fi echo "" echo "*** all done ***" echo "" echo "here is this machine's network info:" echo "" if ip a | grep -Eq ': eth0:.*state UP'; then eth_ip=$(ip addr | awk '/inet/ && /eth0/{sub(/\/.*$/,"",$2); print $2}') eth_mac=`ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'` echo "ethernet: IP=$eth_ip MAC=$eth_mac" fi if ip a | grep -Eq ': wlan0:.*state UP'; then wifi_ip=$(ip addr | awk '/inet/ && /wlan0/{sub(/\/.*$/,"",$2); print $2}') wifi_mac=`ifconfig wlan0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'` echo " wifi: IP=$wifi_ip MAC=$wifi_mac" fi echo "" echo "*** Reboot your Pi to ensure that all installed software comes up as expected." echo "" exit 0