#!/bin/bash # Copyright (C) 2019 Lee C. Bussy (@LBussy) # This file is part of LBussy's Raspberry Pints Tools (RPints-Tools). #Modified RandR+ with contributions from day_trippr's and tobor # # Raspberry Pints Tools is free software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # Raspberry Pints Tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License along # with Raspberry Pints Tools. If not, see . ############ ### Global Declarations ############ # General constants declare THISSCRIPT VERSION PACKAGE VERBOSE REPLY CMDLINE declare SCRIPTNAME APTPACKAGES VERBOSE HOMEPATH REALUSER # Packages to be installed via apt APTPACKAGES="mariadb-server php php-mysql php-curl php-xml git ttf-mscorefonts-installer x11-xserver-utils unclutter vim kompare" INSTALLPACKAGES="dialog" ATPPACKAGES_JESSIE="dialog php5 mysql-client mysql-server php5-mysql git ttf-mscorefonts-installer x11-xserver-utils unclutter vim" RASPBIANPACKAGES=" phpmyadmin chromium-browser " APACHEPACKAGESBEFORE=" apache2 " APACHEPACKAGESAFTER=" libapache2-mod-php " NGINXPACKAGES=" nginx php-fpm " MQTTPACKAGES=" mosquitto mosquitto-clients " MQTTPYTHONPACKAGES=" requests paho-mqtt " FLOW_METERS_PACKAGES="arduino python-serial python-mysqldb php-cli xdotool dos2unix i2c-tools" FLOW_METERS_PACKAGES_JESSIE="arduino python-serial python-mysqldb php5-cli xdotool dos2unix i2c-tools" FLOW_METERS_PACKAGES_BULLSEYE="arduino php-cli xdotool dos2unix i2c-tools" # the base github repo name DEFAULT_REPO=https://github.com/RaspberryPints/RaspberryPints.git CUSTOM_REPO=https://github.com/rtlindne/RaspberryPints.git FLOW_METERS_REPO=https://github.com/wyolum/alamode/raw/master/bundles/alamode-setup.tar.gz FLOW_METERS_STRETCH_REPO=https://github.com/wyolum/alamode/raw/master/alamode-setup/stretch-setup FLOW_METERS_BUSTER_REPO=https://github.com/wyolum/alamode/raw/master/alamode-setup/stretch-setup FLOW_METERS_BULLSEYE_REPO=https://github.com/wyolum/alamode/raw/master/alamode-setup/stretch-setup # RPints Archive from Tobor # From: https://www.homebrewtalk.com/forum/threads/version-2-release-raspberrypints-digital-taplist-solution.487694/page-116#post-8609646 TOBOR_SOURCE="https://www.homebrewtalk.com/forum/attachments/raspberrypints-2-1-0-000-zip.640232/" TOBOR_ARCHIVE="RaspberryPints-2.1.0.002.zip" REPO_CHOICE=1 WEBSERVER_APACHE=apache2 WEBSERVER_NGINX=nginx WEBSERVER=$WEBSERVER_APACHE NGINX_SUB=RPints NGIXConfigName="default" RPINTS_INSTALL_DETECTED=0 RPINTS_INSTALLED="" RECONFIG_PI=0 UPDATE_RPINTS=0 FERMTRACK_INSTALLED=0 # the branch to pull BRANCH=master INIT_DIRECTORY=/etc/init.d ADMIN_INCLUDES_DIRECTORY=${DIRECTORY}/admin/includes/ BOOT_CONFIG_FILE="/boot/config.txt" START_CONFIG_FILE=/home/pi/.config/lxsession/LXDE-pi/autostart GLOBAL_CONFIG_FILE=/etc/xdg/lxsession/LXDE-pi/autostart MODULE_CONFIG_FILE=/etc/modules BLACKLIST_CONFIG_FILE=/etc/modprobe.d/raspi-blacklist.conf MYSQL_SERVER="localhost" MYSQL_DB_NAME="raspberrypints" MYSQL_USER="" MYSQL_PASS="" MYSQL_RP_USER="RaspberryPints" MYSQL_RP_PASS="RaspberryPints" MYSQL_TIME_FORMAT="Y-m-d H:i:s A" USE_FLOW_METERS=N USE_RFID=N MQTT_CONFIG_PATH="/etc/mosquitto/conf.d/rpints.conf" MQTT_SERVER="localhost" MQTT_PORT=1883 MQTT_USERNAME="RaspberryPints" MQTT_PASSWORD="RaspberryPints" ############ ### Init ############ init() { # Set up some project variables we won't have running as a curled script PACKAGE="RPints-Tools" THISSCRIPT="rpints_install.sh" VERSION="0.0.0.1" #CMDLINE="curl -L https://raw.githubusercontent.com/rtlindne/RaspberryPints/master/util/installRaspberryPints | sudo bash" CMDLINE="curl -L install.rpints.com | sudo bash" SCRIPTNAME="${THISSCRIPT%%.*}" } ############ ### Handle logging ############ timestamp() { # Add date in '2019-02-26 08:19:22' format to log [[ "$VERBOSE" == "true" ]] && length=999 || length=60 # Allow full logging while read -r; do # Clean and trim line to 60 characters to allow for timestamp on one line REPLY="$(clean "$REPLY" $length)" # Strip blank lines if [ -n "$REPLY" ]; then # Add date in '2019-02-26 08:19:22' format to log printf '%(%Y-%m-%d %H:%M:%S)T %s\n' -1 "$REPLY" fi done } clean() { # Cleanup log line local input length input="$1" length="$2" # Strip color codes input="$(echo "$input" | sed 's,\x1B[[(][0-9;]*[a-zA-Z],,g')" # Strip beginning spaces input="$(printf "%s" "${input#"${input%%[![:space:]]*}"}")" # Strip ending spaces input="$(printf "%s" "${input%"${input##*[![:space:]]}"}")" # Squash any repeated whitespace within string input="$(echo "$input" | awk '{$1=$1};1')" # Log only first $length chars to allow for date/time stamp input="$(echo "$input" | cut -c-"$length")" echo "$input" } log() { [[ "$*" == *"-nolog"* ]] && return # Turn off logging # Tee all output to log file in home directory sudo -u "$REALUSER" touch "$HOMEPATH/$SCRIPTNAME.log" exec > >(tee >(timestamp >> "$HOMEPATH/$SCRIPTNAME.log")) 2>&1 } ############ ### Command line arguments ############ # usage outputs to stdout the --help usage message. usage() { cat << EOF $PACKAGE $THISSCRIPT version $VERSION Usage: sudo ./$THISSCRIPT" EOF } # version outputs to stdout the --version message. version() { cat << EOF $THISSCRIPT ($PACKAGE) $VERSION Copyright (C) 2019 Lee C. Bussy (@LBussy) This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. There is NO WARRANTY, to the extent permitted by law. EOF } # Parse arguments and call usage or version arguments() { local arg while [[ "$#" -gt 0 ]]; do arg="$1" case "$arg" in --h* ) usage; exit 0 ;; --v* ) version; exit 0 ;; --u* ) UPDATE_RPINTS=1 RPINTS_INSTALLED=1 shift # past argument ;; --i* ) WWWPATH=$2; WWWPATH_SET=1; shift # past argument shift # past value ;; --f* ) FORCE_UPDATE=1; shift # past argument ;; * ) break;; esac done } ############ ### Make sure command is running with sudo ############ checkroot() { local retval shadow if [ -n "$SUDO_USER" ]; then REALUSER="$SUDO_USER"; else REALUSER=$(whoami); fi if [ "$REALUSER" == "root" ] && [ -z "$WWWPATH_SET" ] ; then # We're not gonna run as the root user echo -e "\nThis script may not be run from the root account, use 'sudo' instead." exit 1 fi ### Check if we have root privs to run if [[ "$EUID" -ne 0 ]]; then sudo -n true 2> /dev/null retval="$?" if [ "$retval" -eq 0 ]; then echo -e "\nNot running as root, relaunching correctly." sleep 2 eval "$CMDLINE" exit "$?" else # sudo not available, give instructions echo -e "\nThis script must be run with root privileges." echo -e "Enter the following command as one line:" echo -e "$CMDLINE" 1>&2 exit 1 fi fi # And get the user home directory shadow="$( (getent passwd "$REALUSER") 2>&1)" retval="$?" if [ "$retval" -eq 0 ]; then HOMEPATH="$(echo "$shadow" | cut -d':' -f6)" else echo -e "\nUnable to retrieve $REALUSER's home directory. Manual install may be necessary." exit 1 fi } ############ ### Functions to catch/display errors during execution ############ warn() { local fmt fmt="$1" command shift 2>/dev/null echo -e "$fmt" echo -e "${@}" echo -e "\n*** ERROR ERROR ERROR ERROR ERROR ***" > /dev/tty echo -e "-------------------------------------" > /dev/tty echo -e "\nSee above lines for error message." > /dev/tty echo -e "Setup NOT completed.\n" > /dev/tty } die() { local st st="$?" warn "$@" exit "$st" } ############ ### Ask the user for a Y/N response ### args prompttext, default value ### returns user Response == Y ############ promptYN(){ local options yesResponse case $2 in [Nn]* ) options=y/N;; * ) options=Y/n;; esac while true; do read -rp "${1} [$options]: " yn < /dev/tty if [ -z "$yn" ]; then yn=$2 fi case "$yn" in [Yy]* ) return 0 ;; [Nn]* ) return 1 ;; * ) echo "Must Enter Y(es) or N(o)" ;; esac done } detectRPintsInstall(){ if [ -z "$WWWPATH_SET" ] ; then RPINTS_INSTALL_DETECTED=0 RECONFIG_PI=0 UPDATE_RPINTS=0 RPINTS_INSTALLED=$(find / -wholename "*admin/includes*" -name "conn.php" 2>/dev/null) if [ -n "$RPINTS_INSTALLED" ] ; then RPINTS_INSTALL_DETECTED=1 EXISTS_OPTIONS=(1 "Update RPints" 2 "Reconfigure Pi/Enable Features" 3 "Reinstall RPints" 4 "Exit") EXISTS_CHOICE=$(dialog --clear \ --backtitle "Install Dectected" \ --title "RPints Install Detected." \ --menu "Choose what you want this installer to do" \ 20 40 6 \ "${EXISTS_OPTIONS[@]}" \ 2>&1 >/dev/tty); case ${EXISTS_CHOICE} in 1 ) UPDATE_RPINTS=1 ;; 2 ) RECONFIG_PI=1 ;; #Set to no RPints detected so that load logic executes 3 ) RPINTS_INSTALL_DETECTED=0 ;; * ) echo -e "\nNothing to do, bye" && exit 3 esac fi fi } ############ ### Instructions ############ instructions() { clear cat << EOF ============================================================================= -----=====>>>>> Raspberry Pints Tools <<<<<=====----- ============================================================================= You will be presented with some choices during the install. Most frequently you will see a 'yes or no' choice, with the default choice capitalized like so: [y/N]. Default means if you hit without typing anything, you will make the capitalized choice, i.e. hitting when you see [Y/n] will default to 'yes.' Yes/no choices are not case sensitive. However; passwords, system names and install paths are. Be aware of this. There is generally no difference between 'y', 'yes', 'YES', 'Yes'; you get the idea. In some areas you are asked for a path; the default/recommended choice is in braces like: [/var/www/html]. Pressing without typing anything will take the default/recommended choice. EOF read -n 1 -s -r -p "Press any key when you are ready to proceed. " < /dev/tty echo -e "" } ############ ### Check for default 'pi' password and gently prompt to change it now ############ checkpass() { local user_exists salt extpass match badpwd yn setpass user_exists=$(id -u 'pi' > /dev/null 2>&1; echo $?) if [ "$user_exists" -eq 0 ]; then salt=$(getent shadow "pi" | cut -d$ -f3) extpass=$(getent shadow "pi" | cut -d: -f2) match=$(python -c 'import crypt; print (crypt.crypt("'"raspberry"'", "$6$'${salt}'"))') [ "${match}" == "${extpass}" ] && badpwd=true || badpwd=false if [ "$badpwd" = true ]; then echo -e "\nDefault password found for the 'pi' account. This should be changed." if promptYN "Do you want to change the password now?" "Y"; then setpass=1; fi fi if [ -n "$setpass" ]; then echo until passwd pi < /dev/tty; do sleep 2; echo; done echo -e "\nYour password has been changed, remember it or write it down now." sleep 5 fi fi } ############ ### Set timezone ########### settime() { local date tz date=$(date) echo -e "\nThe time is currently set to $date." tz="$(date +%Z)" if [ "$tz" == "GMT" ] || [ "$tz" == "BST" ]; then # Probably never been set if ! promptYN "Is this correct?" "N"; then dpkg-reconfigure tzdata; fi else # Probably been set if ! promptYN "Is this correct?" "Y"; then dpkg-reconfigure tzdata; fi fi } ############ ### Change hostname ########### host_name() { local oldHostName yn sethost host1 host2 newHostName oldHostName=$(hostname) if [ "$oldHostName" = "raspberrypi" ]; then echo -e "\nYour hostname is set to '$oldHostName'. Each machine on your network should" echo -e "have a unique name to prevent issues.\n" if promptYN "Do you want to change it now, maybe to 'rpints'" "Y"; then echo echo -e "You will now be asked to enter a new hostname." while read -rp "Enter new hostname: " host1 < /dev/tty read -rp "Enter new hostname again: " host2 < /dev/tty [[ -z "$host1" || "$host1" != "$host2" ]] do echo -e "\nHost names blank or do not match.\n"; sleep 1 done echo newHostName=$(echo "$host1" | awk '{print tolower($0)}') eval "sed -i 's/$oldHostName/$newHostName/g' /etc/hosts"||die eval "sed -i 's/$oldHostName/$newHostName/g' /etc/hostname"||die hostnamectl set-hostname "$newHostName" /etc/init.d/avahi-daemon restart echo -e "\nYour hostname has been changed to '$newHostName'.\n" echo -e "(If your hostname is part of your prompt, your prompt will not change until" echo -e "you log out and in again. This will have no effect on anything but the way" echo -e "the prompt looks.)" sleep 5 fi fi } ############ ### Check OS is available to run Raspberry Pints ## AND setup the correct packages ############ checkOS(){ # make sure I am running on a raspbian os! if [ ! -f /etc/os-release ]; then echo -e "You do not appear to be running Raspbian" exit 2 fi . /etc/os-release if [ "$ID" != "raspbian" ] && [ -z "$WWWPATH_SET" ] ; then echo -e "You appear to be running $ID NOT Raspbian, setup may throw unexpected errors" if ! promptYN "Continue Anyways?" "N"; then exit 2; fi fi VER_NAME="$(echo $VERSION | grep -oP '(?<=\()[^\)]+')" OSID=$ID } ############ ### Install or update required packages ############ installationPackages() { for pkg in $INSTALLPACKAGES; do pkgOk=$(dpkg-query -W --showformat='${Status}\n' "$pkg" | \ grep "install ok installed") if [ -z "$pkgOk" ]; then echo -e "\nInstalling '$pkg'." apt-get install "$pkg" -y -q=2 < /dev/tty ||die fi done } packages() { local lastUpdate nowTime pkgOk upgradesAvail pkg didUpdate # Run 'apt update' if last run was > 1 week ago lastUpdate=$(stat -c %Y /var/lib/apt/lists) nowTime=$(date +%s) if [ $(($nowTime - $lastUpdate)) -gt 604800 ] ; then echo -e "\nLast apt update was over a week ago. Running apt update before updating" echo -e "dependencies." apt-get update -q < /dev/tty||die echo -e "\nRunning apt upgrade to upgrade any previously installed system tools and" echo -e "installed dependencies." apt-get upgrade -y < /dev/tty||die didUpdate=1 fi if echo "$VER_NAME" | grep -iq "^jessie" ; then APTPACKAGES=$ATPPACKAGES_JESSIE fi WEBSERVER_OPTIONS=(1 "apache (RPints/BrewPi)" 2 "nginx (Fermentrack)") WEBSERVER_CHOICE=$(dialog --clear \ --backtitle "Webserver" \ --title "Webserver Options" \ --menu "Choose which webserver you would like to use for RaspberryPints" \ 20 40 6 \ "${WEBSERVER_OPTIONS[@]}" \ 2>&1 >/dev/tty); case ${WEBSERVER_CHOICE} in 1 ) WEBSERVER=$WEBSERVER_APACHE ;; 2 ) WEBSERVER=$WEBSERVER_NGINX ;; esac clear if [ "$WEBSERVER" = "$WEBSERVER_APACHE" ]; then APTPACKAGES="${APACHEPACKAGESBEFORE}${APTPACKAGES}${APACHEPACKAGESAFTER}" else APTPACKAGES="${NGINXPACKAGES}${APTPACKAGES}" fi if [ "$OSID" = "raspbian" ]; then APTPACKAGES="${APTPACKAGES}${RASPBIANPACKAGES}" fi # Now install any necessary packages if they are not installed echo -e "\nChecking and installing required dependencies via apt." for pkg in $APTPACKAGES; do pkgOk=$(dpkg-query -W --showformat='${Status}\n' "$pkg" | \ grep "install ok installed") if [ -z "$pkgOk" ]; then echo -e "\nInstalling '$pkg'." apt-get install "$pkg" -y -q=2 < /dev/tty ||die fi done # Get list of installed packages with updates available if [ ! "$didUpdade" == 1 ]; then echo -e "\nUpdating any installed packages which may require it." upgradesAvail=$(dpkg --get-selections | xargs apt-cache policy {} | \ grep -1 Installed | sed -r 's/(:|Installed: |Candidate: )//' | \ uniq -u | tac | sed '/--/I,+1 d' | tac | sed '$d' | sed -n 1~2p) # Loop through the required packages and see if they need an upgrade for pkg in $APTPACKAGES; do if [[ "$upgradesAvail" == *"$pkg"* ]]; then echo -e "\nUpgrading '$pkg'." apt-get install "$pkg" -y -q=2||die fi done echo -e "\nUpdating Packages which may require it - Complete." fi checkNginx configurePHPMyAdmin } checkNginx(){ if [ "$WEBSERVER" = "$WEBSERVER_NGINX" ]; then if [ -f "/etc/nginx/sites-enabled/default-fermentrack" ]; then if promptYN "Fermentrack detected, do you want to place 'Rpints' Under it (i.e. http://fermtrack.ip/$NGINX_SUB)" "N"; then NGIXConfigName="default-fermentrack" FERMTRACK_INSTALLED=1 else NGIXConfigName="default-rpints" FERMTRACK_INSTALLED=-1 fi fi fi } configureNginx(){ #echo -e "configureNginx - Start." if [ "$WEBSERVER" = "$WEBSERVER_NGINX" ]; then PHPSOCKET=$(find /var/run/ -name php*.sock 2>/dev/null) #echo -e "PHP Socket $PHPSOCKET" if [ $FERMTRACK_INSTALLED -ne 1 ] ; then wget -O "/etc/nginx/sites-available/$NGIXConfigName" https://raw.githubusercontent.com/rtlindne/RaspberryPints/master/util/nginx-confs/default &>> "$HOMEPATH/$SCRIPTNAME.log" FIND_STR="#PHPSOCKET#" REPL_STR="$PHPSOCKET" sed -i "s_${FIND_STR}_${REPL_STR}_" "/etc/nginx/sites-available/$NGIXConfigName" if [ $FERMTRACK_INSTALLED -eq -1 ] ; then FIND_STR="80" REPL_STR="81" sed -i "s_${FIND_STR}_${REPL_STR}_" "/etc/nginx/sites-available/$NGIXConfigName" fi if [ ! -f "/etc/nginx/sites-enabled/$NGIXConfigName" ]; then ln -s "/etc/nginx/sites-available/$NGIXConfigName" "/etc/nginx/sites-enabled/$NGIXConfigName" &>> "$HOMEPATH/$SCRIPTNAME.log" fi fi NGIXConfig="/etc/nginx/sites-available/$NGIXConfigName" echo -e "\nUpdated $NGIXConfig" if [ $FERMTRACK_INSTALLED -eq 1 ] ; then #echo -e grep -q "location /$NGINX_SUB" "$NGIXConfig" result $? #echo -e "\nUpdated $NGIXConfigName With location /$NGINX_SUB - Start" sed -i -r "s|^(\s*location\s*$NGINX_SUB)|#\1|g" "$NGIXConfig" #remove the last } so we can add in our configuration sed -i '$ d' $NGIXConfig echo " location $NGINX_SUB {alias ${WWWPATH};index index.php index.html;}" >> $NGIXConfig #readd last } echo "}" >> $NGIXConfig #echo -e "Updated $NGIXConfigName With location /$NGINX_SUB" fi #if the config doesnt already have php enabled if ! grep -q "^\s*location.*php" "$NGIXConfig"; then #echo -e grep -q "\s*location.*php" "$NGIXConfig" result $? #echo -e "\nUpdated $NGIXConfigName With PHP- Start" #remove the last } so we can add in our configuration sed -i '$ d' $NGIXConfig echo " location ~ [^/]\.php(/|$) {" >> $NGIXConfig echo " fastcgi_split_path_info ^(.+?\.php)(/.*)$;" >> $NGIXConfig echo " if (!-f \$document_root\$fastcgi_script_name) {" >> $NGIXConfig echo " return 404;" >> $NGIXConfig echo " }" >> $NGIXConfig echo " fastcgi_pass unix:$PHPSOCKET;" >> $NGIXConfig echo " fastcgi_index index.php;" >> $NGIXConfig echo " include fastcgi_params;" >> $NGIXConfig echo " fastcgi_param SCRIPT_FILENAME \$document_root/\$fastcgi_script_name;" >> $NGIXConfig echo " }" >> $NGIXConfig #readd last } echo "}" >> $NGIXConfig #echo -e "Updated $NGIXConfigName With PHP - Complete" fi if ! grep -q "^\s*location.*\.ht" "$NGIXConfig"; then #echo -e grep -q "\s*location.*\.ht" "$NGIXConfig" result $? #echo -e "\nUpdated $NGIXConfigName With htaccess deny - start" #remove the last } so we can add in our configuration sed -i '$ d' $NGIXConfig echo " location ~ /\.ht {" >> $NGIXConfig echo " deny all;" >> $NGIXConfig echo " }" >> $NGIXConfig #readd last } echo "}" >> $NGIXConfig #echo -e "Updated $NGIXConfigName With htaccess deny - complete" fi systemctl reload $WEBSERVER &>> "$HOMEPATH/$SCRIPTNAME.log" log "Restart $WEBSERVER complete" fi #echo -e "configureNginx - Complete." } configureApache(){ #echo -e "configureApache - Start." if [ "$WEBSERVER" = "$WEBSERVER_APACHE" ]; then if promptYN "Keep RPints as the default webpage" "Y"; then sed -i -r "s|^(\s*DocumentRoot\s*).*|\1$WWWPATH|g" "/etc/apache2/sites-available/000-default.conf" else # ask the user what port to use read -e -p "What port do you want to server RPints on? : " -i "81" ANSWER < /dev/tty if [ "$ANSWER" = "" ]; then ANSWER="81" fi NGINX_SUB=":"$ANSWER if [ -f /etc/apache2/sites-available/000-default.conf ]; then cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/rpints.conf sed -i -r "s|^(\s*|g" "/etc/apache2/sites-available/rpints.conf" sed -i -r "s|^(\s*DocumentRoot\s*).*|\1$WWWPATH|g" "/etc/apache2/sites-available/rpints.conf" a2ensite rpints.conf fi fi log "Restarting $WEBSERVER" systemctl reload $WEBSERVER &>> "$HOMEPATH/$SCRIPTNAME.log" log "Restart $WEBSERVER complete" fi #echo -e "configureApache - Complete." } configurePHPMyAdmin(){ sed -i "s/|\s*\((count(\$analyzed_sql_results\['select_expr'\]\)/| (\1)/g" /usr/share/phpmyadmin/libraries/sql.lib.php # now, enable phpmyadmin if necessary if [ "$WEBSERVER" = "$WEBSERVER_APACHE" ]; then if [ -f /etc/phpmyadmin/apache.conf ]; then if [ ! -f /etc/$WEBSERVER/sites-available/phpmyadmin.conf ]; then ln -s /etc/phpmyadmin/apache.conf /etc/$WEBSERVER/sites-available/phpmyadmin.conf fi a2ensite phpmyadmin.conf fi log "Restarting $WEBSERVER" systemctl reload $WEBSERVER &>> "$HOMEPATH/$SCRIPTNAME.log" log "Restart $WEBSERVER complete" else log "Restarting $WEBSERVER" #PHPMyAdmin is only installed with raspbian if [ "$OSID" = "raspbian" ]; then if [ ! -e /var/www/html/phpmyadmin ]; then sudo ln -s /usr/share/phpmyadmin /var/www/html fi fi systemctl reload $WEBSERVER &>> "$HOMEPATH/$SCRIPTNAME.log" log "Restart $WEBSERVER complete" fi } ############ ### Create a banner ############ banner() { local adj adj="$1" echo -e "\n***Script $THISSCRIPT $adj.***" } ############ ### Check for free space ############ checkfree() { local req freek freem freep req=512 freek=$(df -Pk | grep -m1 '\/$' | awk '{print $4}') freem="$((freek / 1024))" freep=$(df -Pk | grep -m1 '\/$' | awk '{print $5}') if [ "$freem" -le "$req" ]; then echo -e "\nDisk usage is $freep, free disk space is $freem MB," echo -e "Not enough space to continue setup. Installing $PACKAGE requires" echo -e "at least $req MB free space." if ! promptYN "Continue Anyways?" "N"; then exit 1; fi else echo -e "\nDisk usage is $freep, free disk space is $freem MB." fi } ############ ### Web path setup ############ getwwwpath() { local WEBROOT # Find web path based on $WEBSERVER config echo -e "\nSearching for default web location." if [ "$WEBSERVER" = "$WEBSERVER_APACHE" ]; then WWWPATH="$(grep DocumentRoot /etc/$WEBSERVER/sites-enabled/000-default* |xargs |cut -d " " -f2)" else #if 1 then we are nesting RPints under Fermentrack so gets its root if [ $FERMTRACK_INSTALLED -eq 1 ]; then WWWPATH="$(grep root /etc/$WEBSERVER/sites-enabled/default* |xargs |cut -d " " -f2)" WEBROOT="${WWWPATH//;}" WWWPATH="${WWWPATH//;}/${NGINX_SUB}" fi fi if [ -n "$WWWPATH" ]; then echo -e "\nFound $WWWPATH in /etc/$WEBSERVER/sites-enabled/." else WWWPATH="/var/www/html" fi if [ -z $WEBROOT ]; then WEBROOT="${WWWPATH}" fi ApacheConf=0 # ask the user where they want to install to (default is WEBROOT) read -e -p "Where do you want to install RaspberryPints? : " -i "${WWWPATH}" ANSWER < /dev/tty if [ "$ANSWER" = "" ]; then ANSWER="${WWWPATH}" else if [ "$ANSWER" != "$WWWPATH" ]; then WWWPATH="${ANSWER}" configureApache ApacheConf=1 ANSWER="${WWWPATH}" fi fi WWWPATH="${ANSWER}" echo -e "Installing to: ${WWWPATH}" if [ $FERMTRACK_INSTALLED -eq 1 ]; then NGINX_SUB="${WWWPATH#"$WEBROOT"}" if [ "$NGINX_SUB" = "$WWWPATH" ]; then NGINX_SUB="" fi fi if [ $FERMTRACK_INSTALLED -eq -1 ]; then NGINX_SUB=":81" fi if [ $FERMTRACK_INSTALLED -eq -0 ] && [ $ApacheConf -eq 0 ]; then NGINX_SUB= fi if [ -n "$NGINX_SUB" ]; then if [ $FERMTRACK_INSTALLED -eq 1 ]; then if [[ ${NGINX_SUB:0:1} != "/" ]]; then NGINX_SUB="/${NGINX_SUB}" fi fi echo -e "URL's Sub Folder: ${NGINX_SUB}" fi configureNginx } ############ ### Test apache and PHP ############ testapache() { local retval echo -e "\nTesting $WEBSERVER." if [ ! -f "$WWWPATH/index.html" ]; then if [ ! -d ${WWWPATH} ]; then mkdir ${WWWPATH}; fi echo 'test' > "$WWWPATH/index.html" fi wget -q --spider localhost$NGINX_SUB > /dev/null 2>&1 retval="$?" rm -f "$WWWPATH/index.html" if [ "$retval" -ne 0 ]; then echo -e "\nERROR: $WEBSERVER test failed." exit 1 fi echo -e "\nTesting PHP at localhost$NGINX_SUB/test.php." echo '' > "$WWWPATH/test.php" wget -q --spider localhost$NGINX_SUB/test.php > /dev/null 2>&1 retval="$?" rm "${WWWPATH:?}/test.php" if [ "$retval" -ne 0 ]; then echo -e "\nERROR: PHP test failed." exit 1 fi echo -e "\n$WEBSERVER and PHP test ok." } ############ ### CreateDB ############ dbauser() { if ! promptYN "Will this pi host the database" "Y"; then PACKAGES=${PACKAGES/mysql-server /} read -e -p "What computer will Host RaspberryPints Database? (default is: localhost): " ANSWER < /dev/tty if [ "$ANSWER" != "" ]; then MYSQL_SERVER=$ANSWER fi read -e -p "MySql Admin User for server ${MYSQL_SERVER}?: " ANSWER < /dev/tty MYSQL_USER=$ANSWER ANSWER="" read -s -e -p "MySql Admin Password for server ${MYSQL_SERVER}?: " ANSWER < /dev/tty MYSQL_PASS=$ANSWER echo else if echo "$VER_NAME" | grep -iq "^jessie" ; then ANSWER="" read -s -e -p "MySql Admin Password to be used for server ${MYSQL_SERVER}?: " ANSWER < /dev/tty MYSQL_PASS=$ANSWER echo fi fi read -e -p "RaspberryPints Database Name? (default is: ${MYSQL_DB_NAME}): " ANSWER < /dev/tty if [ "$ANSWER" != "" ]; then MYSQL_DB_NAME=$ANSWER fi read -e -p "RaspberryPints Database User Name? (default is: ${MYSQL_RP_USER}): " ANSWER < /dev/tty if [ "$ANSWER" != "" ]; then MYSQL_RP_USER=$ANSWER fi # setup respberrypints mysql user read -s -e -p "RaspberryPints Database User Password? (default is: ${MYSQL_RP_PASS}): " ANSWER < /dev/tty if [ "$ANSWER" != "" ]; then MYSQL_RP_PASS=$ANSWER fi echo MYSQL_CMD="-h${MYSQL_SERVER}" if [ "${MYSQL_USER}" != "" ]; then MYSQL_CMD="${MYSQL_CMD} -u${MYSQL_USER}" fi if [ "${MYSQL_PASS}" != "" ] ; then MYSQL_CMD="${MYSQL_CMD} -p${MYSQL_PASS}" fi USER_EXISTS="$(mysql $MYSQL_CMD -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '${MYSQL_RP_USER}')")" if [ $USER_EXISTS = 0 ]; then mysql ${MYSQL_CMD} -e "CREATE USER ${MYSQL_RP_USER}@'%' IDENTIFIED BY '${MYSQL_RP_PASS}';" else mysql ${MYSQL_CMD} -e "SET PASSWORD FOR ${MYSQL_RP_USER}@'%' = PASSWORD('${MYSQL_RP_PASS}');" fi mysql ${MYSQL_CMD} -e "GRANT ALL PRIVILEGES ON *.* TO ${MYSQL_RP_USER}@'%';" TIME_FORMAT_OPTION=(1 "YYYY-mm-dd hh:mm:ss AM/PM" 2 "YYYY-mm-dd hh:mm:ss" 3 "YYYY-dd-mm hh:mm:ss AM/PM" 4 "YYYY-dd-mm hh:mm:ss" 5 "mm-dd-YYYY hh:mm:ss AM/PM" 6 "mm-dd-YYYY hh:mm:ss" 7 "dd-mm-YYYY hh:mm:ss AM/PM" 8 "dd-mm-YYYY hh:mm:ss") user_choice=$(dialog --clear \ --backtitle "Time Format" \ --title "Time Format" \ --menu "Choose how Rpints displays Time" \ 20 40 6 \ "${TIME_FORMAT_OPTION[@]}" \ 2>&1 >/dev/tty); clear case $user_choice in 1) ;; 2) MYSQL_TIME_FORMAT="Y-m-d H:i:s" ;; 3) MYSQL_TIME_FORMAT="Y-d-m H:i:s A" ;; 4) MYSQL_TIME_FORMAT="Y-d-m H:i:s" ;; 5) MYSQL_TIME_FORMAT="m-d-Y H:i:s A" ;; 6) MYSQL_TIME_FORMAT="m-d-Y H:i:s" ;; 7) MYSQL_TIME_FORMAT="d-m-Y H:i:s A" ;; 8) MYSQL_TIME_FORMAT="d-m-Y H:i:s" ;; esac outputRPintsConfigs setupDatabase } outputRPintsConfigs(){ local INCLUDES_DIRECTORY ADMIN_INCLUDES_DIRECTORY INCLUDES_DIRECTORY=${WWWPATH}/includes/ ADMIN_INCLUDES_DIRECTORY=${WWWPATH}/admin/includes/ if [ -f "${INCLUDES_DIRECTORY}/config.php" ]; then rm ${INCLUDES_DIRECTORY}/config.php fi if [ ${REPO_CHOICE} -eq 1 ] ; then echo "> ${INCLUDES_DIRECTORY}/config.php echo " function db() {" >> ${INCLUDES_DIRECTORY}/config.php echo " return new mysqli('${MYSQL_SERVER}', '${MYSQL_RP_USER}', '${MYSQL_RP_PASS}', '${MYSQL_DB_NAME}');" >> ${INCLUDES_DIRECTORY}/config.php echo " }" >> ${INCLUDES_DIRECTORY}/config.php echo ' $rpintsversion='"\"2.9.0.1\";" >> ${INCLUDES_DIRECTORY}/config.php echo "?>" >> ${INCLUDES_DIRECTORY}/config.php fi if [ ${REPO_CHOICE} -eq 2 ] ; then echo "> ${INCLUDES_DIRECTORY}/config.php echo " function dbRPintsConnect() {" >> ${INCLUDES_DIRECTORY}/config.php echo " return mysqli_connect('${MYSQL_SERVER}', '${MYSQL_RP_USER}', '${MYSQL_RP_PASS}', '${MYSQL_DB_NAME}');" >> ${INCLUDES_DIRECTORY}/config.php echo " }" >> ${INCLUDES_DIRECTORY}/config.php echo ' $rpintsversion='"\"2.1.0.000\";" >> ${INCLUDES_DIRECTORY}/config.php echo "?>" >> ${INCLUDES_DIRECTORY}/config.php fi if [ ${REPO_CHOICE} -eq 3 ] ; then echo "> ${INCLUDES_DIRECTORY}/config.php echo " function db() {" >> ${INCLUDES_DIRECTORY}/config.php echo " /$link = mysql_connect('${MYSQL_SERVER}', '${MYSQL_RP_USER}', '${MYSQL_RP_PASS}');" >> ${INCLUDES_DIRECTORY}/config.php echo " mysql_select_db('${MYSQL_DB_NAME}') or die("cannot select DB");" >> ${INCLUDES_DIRECTORY}/config.php echo " }" >> ${INCLUDES_DIRECTORY}/config.php echo ' $rpintsversion='"\"1.0.0.279\";" >> ${INCLUDES_DIRECTORY}/config.php echo "?>" >> ${INCLUDES_DIRECTORY}/config.php fi if [ -f "${ADMIN_INCLUDES_DIRECTORY}/conn.php" ]; then rm ${ADMIN_INCLUDES_DIRECTORY}/conn.php fi echo "> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo ' //show/hide SQL statements in errors' >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo ' //$showSqlState = true;' >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo " \$host=\"${MYSQL_SERVER}\"; // Host name" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo " \$username=\"${MYSQL_RP_USER}\"; // Mysql username" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo " \$password=\"${MYSQL_RP_PASS}\"; // Mysql password" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo " \$db_name=\"${MYSQL_DB_NAME}\"; // Database name" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo " \$tbl_name=\"users\";" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo ' //Connect to server and select database.' >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php if [ ${REPO_CHOICE} -eq 1 ] ; then echo " \$mysqli = new mysqli(\"\$host\", \"\$username\", \"\$password\", \"\$db_name\") or die(\"cannot connect to server\");" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo " \$timeFormat = '${MYSQL_TIME_FORMAT}';" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php fi if [ ${REPO_CHOICE} -eq 2 ] ; then echo " \$adminLink = mysqli_connect(\"\$host\", \"\$username\", \"\$password\", \"\$db_name\") or die(\"cannot connect to server\");" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php fi if [ ${REPO_CHOICE} -eq 3 ] ; then echo " mysql_connect(\"\$host\", \"\$username\", \"\$password\") or die(\"cannot connect to server\");" >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php echo " mysql_select_db('${MYSQL_DB_NAME}') or die("cannot select DB");" >> ${INCLUDES_DIRECTORY}/config.php fi echo '?>' >> ${ADMIN_INCLUDES_DIRECTORY}/conn.php if [ ${REPO_CHOICE} -eq 2 ] || [ ${REPO_CHOICE} -eq 3 ] ; then if [ -f "${ADMIN_INCLUDES_DIRECTORY}/configp.php" ]; then rm ${ADMIN_INCLUDES_DIRECTORY}/configp.php fi echo "> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo ' //show/hide SQL statements in errors' >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo ' //$showSqlState = true;' >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$host=\"${MYSQL_SERVER}\"; // Host name" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$username=\"${MYSQL_RP_USER}\"; // Mysql username" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$password=\"${MYSQL_RP_PASS}\"; // Mysql password" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$db_name=\"${MYSQL_DB_NAME}\"; // Database name" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$tbl_name=\"users\";" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo ' //Connect to server and select database.' >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$conn = new PDO(\"mysql:host=\$host;dbname=\$db_name\",\$username,\$password);" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$stmt = \$conn->prepare('SELECT * from config WHERE showOnPanel = 1');" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$stmt->execute();" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo " \$result = \$stmt->fetchAll();" >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php echo '?>' >> ${ADMIN_INCLUDES_DIRECTORY}/configp.php fi } setupDatabase(){ mysql ${MYSQL_CMD} -e "DROP DATABASE IF EXISTS $MYSQL_DB_NAME;" mysql ${MYSQL_CMD} -e "CREATE DATABASE $MYSQL_DB_NAME;" echo "Database loading" cat ${WWWPATH}/sql/schema.sql | mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} echo "Database Successfully loaded" RP_USERNAME=admin RP_PASS="" RP_PASS2="2" RP_NAME_FIRST="" RP_NAME_LAST="" RP_EMAIL="" read -e -p "Admin Username?: " -i ${RP_USERNAME} RP_USERNAME < /dev/tty while [ "$RP_PASS" != "$RP_PASS2" ]; do read -s -e -p "Admin Password?: " RP_PASS < /dev/tty echo read -s -e -p "Re-enter Admin Password?: " RP_PASS2 < /dev/tty if [ "$RP_PASS" != "$RP_PASS2" ] ; then echo echo "Passwords didnt match, please try again" fi done echo read -e -p "Admin First Name?: " RP_NAME_FIRST < /dev/tty read -e -p "Admin Last Name?: " RP_NAME_Last < /dev/tty read -e -p "Admin Email?: " RP_EMAIL < /dev/tty if ! echo "$REPO" | grep -iq "rtlindne" ; then mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -e "INSERT INTO users (username,password,name,email,createdDate,modifiedDate) VALUES ('${RP_USERNAME}',MD5('${RP_PASS}'),CONCAT('${RP_NAME_FIRST}', ' ', '${RP_NAME_LAST}'),'${RP_EMAIL}',NOW(),NOW());"; else mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -e "INSERT INTO users (username,password,nameFirst,nameLast,mugId,email,unTapAccessToken,isAdmin,active,createdDate,modifiedDate) VALUES ('${RP_USERNAME}',MD5('${RP_PASS}'),'${RP_NAME_FIRST}','${RP_NAME_LAST}',NULL,'${RP_EMAIL}',NULL,1,1,NOW(),NOW());"; fi mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -e "INSERT INTO config ( configName, configValue, displayName, showOnPanel, createdDate, modifiedDate ) VALUES ( 'repo', '${REPO_CHOICE}', 'The Repo Option from install', '0', NOW(), NOW() );"; if [ -f "${WWWPATH}/index.html" ]; then rm ${WWWPATH}/index.html fi if promptYN "Load Test Data into RaspberryPints" "Y"; then echo "Loading Test Data" cat ${WWWPATH}/sql/test_data.sql | mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} echo "Test Data Successfully loaded" fi } ############ ### Handle the RPints archive ############ doarchive() { local archname retval REPO_OPTIONS=(1 "RandR+" 2 "Tobor" 3 "Original (May not work After Raspbian Jessie)") REPO_CHOICE=$(dialog --clear \ --backtitle "Repository" \ --title "Repository Options" \ --menu "Choose which version of RaspberryPints to install" \ 20 40 6 \ "${REPO_OPTIONS[@]}" \ 2>&1 >/dev/tty); case ${REPO_CHOICE} in 1 ) REPO=$CUSTOM_REPO ;; 2 ) REPO=$TOBOR_ARCHIVE ;; 3 ) REPO=$DEFAULT_REPO ;; esac clear echo "Installing Source ${REPO}" # copy the old DIRECTORY if it exists if [ -d "${WWWPATH}" ]; then echo "renaming current \"${WWWPATH}\" to \"${WWWPATH}-$(date +"%Y%m%d-%H%M%S")\"" # remove the current contents of the install location mv "${WWWPATH}" ${WWWPATH}-$(date +"%Y%m%d-%H%M%S") fi if [ ${REPO_CHOICE} -ne 2 ] ; then # git clone the RaspberryPints installation git clone -b ${BRANCH} ${REPO} "${WWWPATH}" else if [ ! -d ${WWWPATH} ]; then mkdir ${WWWPATH}; fi archname=${TOBOR_ARCHIVE%.*} echo -e "\nDownloading Raspberry Pints archive from Homebrewtalk thread.\n" wget -P "$HOMEPATH" -O "$TOBOR_ARCHIVE" "$TOBOR_SOURCE" retval="$?" if [ "$retval" -ne 0 ]; then echo -e "\nERROR: Archive download failed." exit 1 fi if [ ! -f "$HOMEPATH/$TOBOR_ARCHIVE" ]; then echo -e "\nERROR: $HOMEPATH/$TOBOR_ARCHIVE not found." exit 1 fi echo -e "\nExtracting $HOMEPATH/$TOBOR_ARCHIVE to $WWWPATH." unzip -q "$HOMEPATH/$TOBOR_ARCHIVE" -d "$WWWPATH"||die retval="$?" if [ "$retval" -ne 0 ]; then echo -e "\nERROR: Archive unzip failed." exit 1 fi shopt -s extglob eval cp -R "$WWWPATH/$archname/*" "$WWWPATH" rm -fr "${WWWPATH:?}/$archname" apt-get install "php-mbstring" -y -q=2 < /dev/tty ||die fi } ############ ### Fix WWW path permissions ############ doperms() { echo -e "\nFixing file permissions for $WWWPATH." # find out who the apache server runs as (APACHE_RUN_USER and APACHE_RUN_GROUP) if [ -f /etc/$WEBSERVER/envvars ]; then . /etc/$WEBSERVER/envvars else APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data fi # ensure the files are owned by the apache user chown -R ${APACHE_RUN_USER}:${APACHE_RUN_GROUP} "${WWWPATH}"||warn find "$WWWPATH" -type d -exec chmod 2770 {} \; || warn find "$WWWPATH" -type f -exec chmod 640 {} \;||warn find "$WWWPATH" -type f -regex ".*\.\(py\|sh\)" -exec chmod 770 {} \;||warn find "$WWWPATH/util" -type f -regex ".*installRaspberryPints.*" -exec chmod 750 {} \;||warn usermod -a -G www-data "$REALUSER" } installFlowmeters(){ FLOWMETER_ENABLED=$(mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -sse "SELECT configValue FROM config WHERE configName='useFlowMeter'") # ask the user if they want to install flowmeters if [ $FLOWMETER_ENABLED -ne 1 ] && promptYN "Do you want to use Flow Meters?" "N"; then echo "Will Install Flow Meters" touch ${WWWPATH}/arduino/raspberrypints/raspberrypints.cpp.hex if echo "$VER_NAME" | grep -iq "^jessie" ; then FLOW_METERS_PACKAGES=$FLOW_METERS_PACKAGES_JESSIE fi # Bullseye uses python3 which MySQLdb import is not supported if echo "$VER_NAME" | grep -iq "^bullseye" ; then pip install pymysql FLOW_METERS_PACKAGES=$FLOW_METERS_PACKAGES_BULLSEYE fi # install necessary packages for pkg in $FLOW_METERS_PACKAGES; do pkgOk=$(dpkg-query -W --showformat='${Status}\n' "$pkg" | \ grep "install ok installed") if [ -z "$pkgOk" ]; then echo -e "\nInstalling '$pkg'." apt-get install "$pkg" -y -q=2 < /dev/tty ||die fi done # enable I2C on Raspberry Pi echo '>>> Enable I2C' if ! grep -q '^\s*i2c-bcm2708' $MODULE_CONFIG_FILE; then echo 'i2c-bcm2708' >> $MODULE_CONFIG_FILE fi if ! grep -q '^\s*i2c-dev' $MODULE_CONFIG_FILE; then echo 'i2c-dev' >> $MODULE_CONFIG_FILE fi if ! grep -q '^\s*dtparam=i2c1=on' $BOOT_CONFIG_FILE; then echo 'dtparam=i2c1=on' >> $BOOT_CONFIG_FILE fi if ! grep -q '^\s*dtparam=i2c_arm=on' $BOOT_CONFIG_FILE; then echo 'dtparam=i2c_arm=on' >> $BOOT_CONFIG_FILE fi if ! grep -q '^\s*dtparam=spi=on' $BOOT_CONFIG_FILE; then echo 'dtparam=spi=on' >> $BOOT_CONFIG_FILE fi if ! grep -q '^\s*enable_uart=1' $BOOT_CONFIG_FILE; then echo 'enable_uart=1' >> $BOOT_CONFIG_FILE fi if [ -f /etc/modprobe.d/raspi-blacklist.conf ]; then sed -i -r 's/^\s*(blacklist\s*spi-bcm2708)/#\1/g' $BLACKLIST_CONFIG_FILE sed -i -r 's/^\s*(blacklist\s*i2c-bcm2708)/#\1/g' $BLACKLIST_CONFIG_FILE fi if [ ! -d ${WWWPATH}/alamode/ ]; then FLOW_METERS_DIRECTORY=${WWWPATH}/alamode/ pushd . if [ ! -d $FLOW_METERS_DIRECTORY ]; then mkdir $FLOW_METERS_DIRECTORY fi cd "${FLOW_METERS_DIRECTORY}" # Get the Alamode files if [ -f "${FLOW_METERS_DIRECTORY}/alamode-setup.tar.gz" ]; then rm "${FLOW_METERS_DIRECTORY}/alamode-setup.tar.gz" fi wget ${FLOW_METERS_REPO} if [ -d "${FLOW_METERS_DIRECTORY}/alamode-setup" ]; then rm "${FLOW_METERS_DIRECTORY}/alamode-setup" -r fi tar -xvzf "alamode-setup.tar.gz" cd "${FLOW_METERS_DIRECTORY}/alamode-setup" if [ ! -f "${FLOW_METERS_DIRECTORY}/alamode-setup/stretch-setup" ]; then wget ${FLOW_METERS_STRETCH_REPO} fi if [ ! -f "${FLOW_METERS_DIRECTORY}/alamode-setup/buster-setup" ]; then wget -O buster-setup ${FLOW_METERS_BUSTER_REPO} fi if [ ! -f "${FLOW_METERS_DIRECTORY}/alamode-setup/bullseye-setup" ]; then wget -O bullseye-setup https://github.com/wyolum/alamode/raw/master/alamode-setup/stretch-setup fi if [ -f "${FLOW_METERS_DIRECTORY}/alamode-setup/80-alamode.rules" ]; then FIND_STR=",MODE:=0666" REPL_STR=",MODE=0666" sed -i "s_${FIND_STR}_${REPL_STR}_" "${FLOW_METERS_DIRECTORY}/alamode-setup/80-alamode.rules" fi # ensure the files are executable by the owner find "${WWWPATH}" -type f -exec chmod o+x {} \; dos2unix ./* ./${VER_NAME}-setup popd fi if [ -f "${WWWPATH}/python/Config.py" ]; then FIND_STR="config\['pints.dir'.*" REPL_STR="config\['pints.dir'\] = '${WWWPATH}/'" sed -i "s_${FIND_STR}_${REPL_STR}_" "${WWWPATH}/python/Config.py" CONNECTION_OPTIONS=(1 "Serial" 2 "USB" 3 "Bluetooth" 4 "MQTT (Photon)") user_choice=$(dialog --clear \ --backtitle "Connection" \ --title "Arduino Communication" \ --menu "Choose how Rpints communicates to the Arduino" \ 20 40 6 \ "${CONNECTION_OPTIONS[@]}" \ 2>&1 >/dev/tty); clear comm_option="/dev/ttyS0" case $user_choice in 1) comm_option="/dev/ttyS0" ;; 2) comm_option="/dev/ttyACM0" ;; 3) comm_option="/dev/rfcomm0" ;; 4) comm_option="MQTT" ;; esac sed -E -i 's/(.*flowmon.port.*)/#\1/' "${WWWPATH}/python/Config.py" echo "config['flowmon.port'] = '$comm_option'" >> "${WWWPATH}/python/Config.py" if [ $user_choice = 4 ]; then setupMQTT fi fi setupFlowMon mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -e "UPDATE config SET configValue='1' WHERE configName='useFlowMeter' OR configName='showKegCol';"; if [ $user_choice != 4 ]; then read -e -p "For alamode set the 5V_link jumper to on (see page 11 of the Alamode Manual). Enter to continue" ANSWER < /dev/tty fi elif promptYN "Do you want to use MQTT?" "N"; then setupFlowMon setupMQTT echo "Will use MQTT" elif promptYN "Do you want to use Load Cells?" "N"; then setupFlowMon echo "To setup Load Cells visit your RaspberryPints Admin - Advanced Hardware - Load Cells page" else echo "Will Not Install Flow Meters" echo fi } installRFID(){ RFID_SPI_DIRECTORY=${WWWPATH}/python/SPI-Py if [ $RECONFIG_PI -ne 0 ] && [ -d ${RFID_SPI_DIRECTORY} ]; then return ; fi # ask the user if they want to install RFID if promptYN "Do you want to use RFID" "N"; then echo "Will Install RFID" setupFlowMon pushd . cd ${RFID_SPI_DIRECTORY} python setup.py install popd read -e -p "What Pi Pin is the RFID Slave Select (SDA) connected to (Blank to skip)?: " ANSWER < /dev/tty if [ "$ANSWER" != "" ]; then mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -e "INSERT INTO rfidReaders (name,type,pin,priority,createdDate,modifiedDate) VALUES ('default',0,'${ANSWER}',0,NOW(),NOW());"; else echo "To setup a RFID Reader visit your RaspberryPints Admin - RFID Reader page" fi else echo "Will Not Install RFID" echo fi } #based off https://www.homebrewtalk.com/forum/threads/initial-release-raspberrypints-digital-taplist-solution.456809/page-20#post-6029665 installMotionSensor(){ PKG_OK=$(dpkg-query -W --showformat='${Status}\n' xscreensaver|grep "install ok installed") if [ "" != "$PKG_OK" ] && [ $RECONFIG_PI -ne 0 ]; then return ; fi # ask the user if they want to install Motion Detection if promptYN "Do you want to use Motion Detection?" "N"; then echo "Will Install Motion Detection" setupFlowMon apt-get install --assume-yes xscreensaver if promptYN "Do you want to use day_trippr's configuration?" "Y"; then cp ${DIRECTORY}/util/.xscreensaver /home/pi/.xscreensaver else echo "Configure Screen Saver" fi echo "Connect the detector to the PI when power is off)" echo "5V: Pin 2, or 4 (pick one)" echo "GND: Pin 6,9,14,20 or 25 (pick one)" echo "Notes:" echo " - Verify that the two pin jumper is positioned on the 2 pins closes to the adjust dials." echo " - Set the Sensitivity Adjust to 50% of travel to start" echo " - Set the Time Delay Adjust full counter-clockwise to start (minimum delay between triggers is roughly 10 seconds)" read -e -p "What Pi Pin is the Motion Sensor output connected to (Blank to skip)?: " ANSWER < /dev/tty if [ "$ANSWER" != "" ] && [[ $ANSWER =~ '^[0-9]+$' ]] ; then mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -e "INSERT INTO motionDetectors (name,pin,createdDate,modifiedDate) VALUES ('default','${ANSWER}',NOW(),NOW());"; else echo "To setup a Motion Detector visit your RaspberryPints Admin - Motion Detector page" fi else echo "Will Not Install Motion Detection" echo fi } installTempProbes(){ if [ $RECONFIG_PI -ne 0 ] && grep -q '^\s*dtoverlay=w1-gpio' $BOOT_CONFIG_FILE; then return ; fi # ask the user if they want to use temp probes if promptYN "Do you want to use Temp Probes?" "N"; then if ! grep -q '^\s*dtoverlay=w1-gpio' $BOOT_CONFIG_FILE; then echo 'dtoverlay=w1-gpio' >> $BOOT_CONFIG_FILE fi mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -e "UPDATE config SET configValue='1' WHERE configName='useTempProbes';"; FLOWMETER_ENABLED=$(mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -sse "SELECT configValue FROM config WHERE configName='useFlowMeter'") if [ $FLOWMETER_ENABLED -ne 1 ]; then setupFlowMon fi else echo "Will Not Setup Temp Probes" echo fi } setupFlowMon(){ if echo "$VER_NAME" | grep -iq "^jessie" ; then FLOW_METERS_PACKAGES=$FLOW_METERS_PACKAGES_JESSIE fi # Bullseye uses python3 which MySQLdb import is not supported if echo "$VER_NAME" | grep -iq "^bullseye" ; then pip install pymysql FLOW_METERS_PACKAGES=$FLOW_METERS_PACKAGES_BULLSEYE fi if [ ! -f "${INIT_DIRECTORY}/flowmon" ]; then # install necessary packages apt-get install --assume-yes ${FLOW_METERS_PACKAGES} if [ -f "${WWWPATH}/python/Config.py" ] ; then FIND_STR="config\['pints.dir'.*" REPL_STR="config\['pints.dir'\] = '${WWWPATH}/'" sed -i "s_${FIND_STR}_${REPL_STR}_" "${WWWPATH}/python/Config.py" fi if [ -f "${WWWPATH}/python/flowmon" ]; then FIND_STR="DIR=.*" REPL_STR="DIR=${WWWPATH}/python" sed -i "s_${FIND_STR}_${REPL_STR}_" "${WWWPATH}/python/flowmon" cp "${WWWPATH}/python/flowmon" "${INIT_DIRECTORY}/flowmon" chmod a+x "${INIT_DIRECTORY}/flowmon" if echo "$VER_NAME" | grep -iq "^jessie" ; then /bin/systemctl daemon-reload /bin/systemctl enable flowmon.service fi "${INIT_DIRECTORY}/flowmon" start if ps aux | grep -iq "flow_monitor.py" ; then echo "Flowmon install successfully" else echo "Unable to install flowmon" fi update-rc.d flowmon defaults fi fi } setupMQTT(){ sed -E -i 's/(.*flowmon.port.*)/#\1/' "${WWWPATH}/python/Config.py" echo "config['flowmon.port'] = 'MQTT'" >> "${WWWPATH}/python/Config.py" for pkg in $MQTTPYTHONPACKAGES; do pkgOk=$(pip show "$pkg" | \ grep "Name: ") if [ -z "$pkgOk" ]; then echo -e "\nInstalling '$pkg'." pip install "$pkg" < /dev/tty ||die fi done mqtt_local="N" if ! promptYN "Will this pi host the MQTT Server" "Y"; then read -e -p "MQTT Server?: " -i ${MQTT_SERVER} MQTT_SERVER < /dev/tty else mqtt_local="Y" # Now install any necessary packages if they are not installed echo -e "\nChecking and installing required dependencies via apt." for pkg in $MQTTPACKAGES; do pkgOk=$(dpkg-query -W --showformat='${Status}\n' "$pkg" | \ grep "install ok installed") if [ -z "$pkgOk" ]; then echo -e "\nInstalling '$pkg'." apt-get install "$pkg" -y -q=2 < /dev/tty ||die fi done read -e -p "MQTT Port?: " -i ${MQTT_PORT} MQTT_PORT < /dev/tty #configure mosquitto for MQTT echo '' > $MQTT_CONFIG_PATH echo 'allow_anonymous false' >> $MQTT_CONFIG_PATH echo 'password_file /etc/mosquitto/pwfile' >> $MQTT_CONFIG_PATH echo "listener $MQTT_PORT" >> $MQTT_CONFIG_PATH fi read -e -p "MQTT Username?: " -i ${MQTT_USERNAME} MQTT_USERNAME < /dev/tty read -s -e -p "MQTT Password for server ${MQTT_SERVER}?: " MQTT_PASSWORD < /dev/tty if [ "$MQTT_PASSWORD" == "" ]; then MQTT_PASSWORD="default" fi echo if [ "${mqtt_local}" = "Y" ]; then if [ ! -f "/etc/mosquitto/pwfile" ]; then echo "" > /etc/mosquitto/pwfile fi mosquitto_passwd -b /etc/mosquitto/pwfile $MQTT_USERNAME $MQTT_PASSWORD /etc/init.d/mosquitto restart fi sed -E -i 's/(.*mqtt.host.*)/#\1/' "${WWWPATH}/python/Config.py" echo "config['mqtt.host'] = '$MQTT_SERVER'" >> "${WWWPATH}/python/Config.py" sed -E -i 's/(.*mqtt.port.*)/#\1/' "${WWWPATH}/python/Config.py" echo "config['mqtt.port'] = '$MQTT_PORT'" >> "${WWWPATH}/python/Config.py" sed -E -i 's/(.*mqtt.user.*)/#\1/' "${WWWPATH}/python/Config.py" echo "config['mqtt.user'] = '$MQTT_USERNAME'" >> "${WWWPATH}/python/Config.py" sed -E -i 's/(.*mqtt.password.*)/#\1/' "${WWWPATH}/python/Config.py" echo "config['mqtt.password'] = '$MQTT_PASSWORD'" >> "${WWWPATH}/python/Config.py" } configureMonitor(){ MONITOR=true MONITOR_OPTIONS=(1 "No Monitor" 2 "1920 x 1080 | 1080p" 3 "1280 x 720 | 720p" 4 "1280 x 1024" 5 "1600 x 1200" 6 "1680 x 1050" 7 "1920 x 1200") HDMI_GROUP=1 HDMI_MODE=16 MONITOR_RESOLUTION=$(dialog --clear \ --backtitle "Monitor" \ --title "Monitor Options" \ --menu "Choose your Monitor Size" \ 20 40 6 \ "${MONITOR_OPTIONS[@]}" \ 2>&1 >/dev/tty); clear case $MONITOR_RESOLUTION in 2) HDMI_GROUP=1 HDMI_MODE=16 ;; 3) HDMI_GROUP=1 HDMI_MODE=4 ;; 4) HDMI_GROUP=2 HDMI_MODE=35 ;; 5) HDMI_GROUP=1 HDMI_MODE=2 ;; 6) HDMI_GROUP=2 HDMI_MODE=51 ;; 7) HDMI_GROUP=2 HDMI_MODE=68 ;; *) MONITOR=false ;; esac if $MONITOR = true ; then if [ -f $BOOT_CONFIG_FILE ]; then sed -i -E 's/^\s*(hdmi_group.*)/#\1/g' $BOOT_CONFIG_FILE sed -i -E 's/^\s*(hdmi_mode.*)/#\1/g' $BOOT_CONFIG_FILE fi echo "hdmi_group=$HDMI_GROUP" >> $BOOT_CONFIG_FILE echo "hdmi_mode=$HDMI_MODE" >> $BOOT_CONFIG_FILE MONITOR_OPTIONS=(1 "No Rotation" 2 "90 Degrees Clockwise" 3 "90 Degrees CounterClockwise" 4 "Upside Down") MONITOR_ROTATION=0 MONITOR_ROTATION=$(dialog --clear \ --backtitle "Monitor" \ --title "Monitor Options" \ --menu "Choose your Monitor Size" \ 20 40 4 \ "${MONITOR_OPTIONS[@]}" \ 2>&1 >/dev/tty); clear case $MONITOR_ROTATION in 1) MONITOR_ROTATION=0 ;; 2) MONITOR_ROTATION=3 ;; 3) MONITOR_ROTATION=1 ;; 4) MONITOR_ROTATION=2 ;; *) MONITOR=false ;; esac if $MONITOR = true ; then if [ -f $BOOT_CONFIG_FILE ]; then sed -i -E 's/^\s*(display_rotate.*)/#\1/g' $BOOT_CONFIG_FILE fi echo "display_rotate=$MONITOR_ROTATION" >> $BOOT_CONFIG_FILE fi if [ ! -f "${START_CONFIG_FILE}" ]; then START_CONFIG_FILE=${GLOBAL_CONFIG_FILE} fi if ! grep -q '^\s*@xset s off' $START_CONFIG_FILE || ! grep -q '^\s*@xset -dpms' $START_CONFIG_FILE || ! grep -q '^\s*@xset s noblank' $START_CONFIG_FILE; then if promptYN "Do you want to turn off Screen Blanking?" "Y"; then if ! grep -q '^\s*@xset s off' $START_CONFIG_FILE; then echo '@xset s off' >> $START_CONFIG_FILE fi if ! grep -q '^\s*@xset -dpms' $START_CONFIG_FILE; then echo '@xset -dpms' >> $START_CONFIG_FILE fi if ! grep -q '^\s*@xset s noblank' $START_CONFIG_FILE; then echo '@xset s noblank' >> $START_CONFIG_FILE fi fi fi sed -i -E 's/^\s*(@chromium.*)/#\1/g' $START_CONFIG_FILE if promptYN "Do you want to start with Chromium in Kiosk Mode?" "Y"; then echo '@chromium --kiosk localhost' >> $START_CONFIG_FILE fi fi } ############ ### Instructions ############ complete() { local IP IP=$(ip -4 addr | grep 'global' | cut -f1 -d'/' | cut -d" " -f6) IPURL="http://$IP" HOSTURL="http://$(hostname).local" #fix up the URLs based on if fermentrack was installed case ${FERMTRACK_INSTALLED} in -1 ) IPURL="${IPURL}:81"; HOSTURL="http://$(hostname).local:81"; ;; 0 ) ;; 1 ) IPURL="${IPURL}$NGINX_SUB"; HOSTURL="http://$(hostname).local$NGINX_SUB"; ;; esac clear cat << EOF ============================================================================= -----=====>>>>> Raspberry Pints Tools Complete <<<<<=====----- ============================================================================= Raspberry Pints has now been installed to $WWWPATH. There's also a very good chance that a large number of packages have been updated. In order to allow thse changes to be effective, please reboot your Pi to ensure a clean start. It may take several minutes for this reboot. Be patient. To continue your Raspberry Pints setup, please use your web browser and navigate to: By IP : $IPURL -or- by host name : $HOSTURL EOF if promptYN "Restarted needed to use alamode. Restart Now?" "Y"; then reboot fi if promptYN "Open RaspberryPints" "Y"; then su pi chromium http://localhost fi if promptYN "Open RaspberryPints Admin?" "Y"; then su pi chromium http://localhost/admin/index.php fi } ############ ### Used to read the database settings from RPints and get the current Repo value (if exists) ############ getExistingSystemVariables(){ if [ -n "$WWWPATH_SET" ] ; then #do nothing we have our path already echo "Updating $WWWPATH from arguments" elif [ -z "$RPINTS_INSTALLED" ]; then getwwwpath # Get WWW path else count=$(echo "$RPINTS_INSTALLED" | wc -l ) if [ $count -eq 1 ]; then WWWPATH=${RPINTS_INSTALLED/"/admin/includes/conn.php"/} else option=0 local Rpints_Options Rpints_Options=() for item in $RPINTS_INSTALLED do option=$((option+1)) Rpints_Options+=(${option} ${item/"/admin/includes/conn.php"/}) done Rpints_Option=0 Rpints_Option=$(dialog --clear \ --backtitle "RPints to Update" \ --title "Installed RPints" \ --menu "Choose RPints to Update" \ 20 40 4 \ "${Rpints_Options[@]}" \ 2>&1 >/dev/tty); clear WWWPATH=${Rpints_Options[$Rpints_Option+($Rpints_Option-1)]#"${Rpints_Option} "} fi fi MYSQL_SERVER=$(grep -oE '\$host=.*;' ${WWWPATH}/admin/includes/conn.php | tail -1 | sed 's/$host="//g;s/";//g') MYSQL_RP_USER=$(grep -oE '\$username=.*;' ${WWWPATH}/admin/includes/conn.php | tail -1 | sed 's/$username="//g;s/";//g') MYSQL_RP_PASS=$(grep -oE '\$password=.*;' ${WWWPATH}/admin/includes/conn.php | tail -1 | sed 's/$password="//g;s/";//g') MYSQL_DB_NAME=$(grep -oE '\$db_name=.*;' ${WWWPATH}/admin/includes/conn.php | tail -1 | sed 's/$db_name="//g;s/";//g') MYSQL_CMD="-h${MYSQL_SERVER}" if [ "${MYSQL_RP_USER}" != "" ]; then MYSQL_CMD="${MYSQL_CMD} -u${MYSQL_RP_USER}" fi if [ "${MYSQL_RP_PASS}" != "" ] ; then MYSQL_CMD="${MYSQL_CMD} -p${MYSQL_RP_PASS}" fi REPO_CHOICE=$(mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -sse "SELECT configValue FROM config WHERE configName='repo'") if [ -z $REPO_CHOICE ]; then if grep -qE '.*\$rpintsversion="1.0.0.279".*' ${WWWPATH}/install/includes/config_files.php; then REPO_CHOICE=3; fi if grep -qE '.*dbRPintsConnect.*' ${WWWPATH}/install/includes/config_files.php; then REPO_CHOICE=2; fi if grep -qE '.*\$rpintsversion="2.0.4.0".*' ${WWWPATH}/install/includes/config_files.php; then REPO_CHOICE=1; fi fi } ############ ### Actually pull the latest and run the update database script ############ updateRpints(){ getExistingSystemVariables if [ -f /etc/init.d/flowmon ]; then # Next, kill the running RPints instance using circus echo -e "Stopping Rpints..." /etc/init.d/flowmon stop &>> "$HOMEPATH/$SCRIPTNAME.log" fi pushd . >/dev/null cd ${WWWPATH} cp -R -f img /tmp/rpints_img cp -R -f python/Config.py /tmp/RPints_Config.py case ${REPO_CHOICE} in 1 ) git config --global user.email "test@test.com"; git config --global user.name "Test Test"; ;; 2 ) git config --global user.email "test@test.com"; git config --global user.name "Test Test"; ;; 3 ) ;; #Not sure how to update this one since its static esac case ${REPO_CHOICE} in 1 ) git stash; git pull; mysql ${MYSQL_CMD} -D ${MYSQL_DB_NAME} -s -L < ${WWWPATH}/sql/update.sql > /dev/null 2>&1; cp -f /tmp/RPints_Config.py ./python/Config.py; if [ -z "$WWWPATH_SET" ]; then git difftool --dir-diff -y stash < /dev/tty; fi; ;; 2 ) git stash; git pull; cp -f /tmp/RPints_Config.py ./python/Config.py; if [ -z "$WWWPATH_SET" ]; then git difftool --dir-diff -y stash < /dev/tty; fi; ;; 3 ) ;; #Not sure how to update this one since its static esac #bring over any images that were undone but do not overwrite except background and logo cp -R -n /tmp/rpints_img/* ./img/ cp -f /tmp/rpints_img/background.jpg ./img/background.jpg cp -f /tmp/rpints_img/logo.png ./img/logo.png #cp -f /tmp/RPints_Config.py ./python/Config.py echo -e "Images updated, old images can be found in /tmp/rpints_img" popd >/dev/null doperms if [ -f /etc/init.d/flowmon ]; then # Finally, relaunch the RPints echo -e "Relaunching RPints..." /etc/init.d/flowmon start &>> "$HOMEPATH/$SCRIPTNAME.log" echo -e "Complete!" fi echo -e "Update Complete!" } ############ ### Main function ############ main() { [[ "$*" == *"-verbose"* ]] && VERBOSE=true # Do not trim logs init "$@" # Get constants arguments "$@" # Check command line arguments checkroot # Make sure we are su into root log "$@" # Start logging checkOS # Check what operating system is being used banner "starting" # Pop starting banner installationPackages detectRPintsInstall if [ $UPDATE_RPINTS -ne 0 ] ; then updateRpints else if [ $RPINTS_INSTALL_DETECTED -eq 0 ] || [ $RECONFIG_PI -eq 1 ] ; then instructions # Show instructions checkpass # Check for default password settime # Set timezone host_name # Change hostname if [ $RPINTS_INSTALL_DETECTED -eq 0 ]; then checkfree # TODO: Figure out size needed packages # Install and update required packages getwwwpath # Get WWW path testapache # Test Apache/PHP doarchive # Handle unzipping archive to WWW path doperms # Fix permissions in WWW path dbauser # Add a new DBA user else #if [ $RECONFIG_PI -eq 1 ] ; then getExistingSystemVariables fi installFlowmeters installRFID installMotionSensor installTempProbes configureMonitor if [ $RPINTS_INSTALL_DETECTED -eq 0 ]; then complete # Final user instructions else echo Reconfiguration Complete fi fi fi } ############ ### Start the script ############ main "$@" && exit 0