Advertisement
Guest User

Untitled

a guest
Jan 20th, 2020
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 16.72 KB | None | 0 0
  1. #!/usr/bin/env bash
  2. # Domoticz: Open Source Home Automation System
  3. # (c) 2012, 2016 by GizMoCuz
  4. # Big thanks to Jacob Salmela! (Sorry i modified your domoticz install script ;)
  5. # http://www.domoticz.com
  6. # Installs Domoticz
  7. #
  8. # Domoticz is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation, either version 2 of the License, or
  11. # (at your option) any later version.
  12.  
  13. # Donations are welcome via the website or application
  14. #
  15. # Install with this command (from your Pi):
  16. #
  17. # curl -L install.domoticz.com | bash
  18.  
  19. set -e
  20. ######## VARIABLES #########
  21. setupVars=/etc/domoticz/setupVars.conf
  22.  
  23. useUpdateVars=false
  24.  
  25. Dest_folder=""
  26. IPv4_address=""
  27. Enable_http=true
  28. Enable_https=true
  29. HTTP_port="8080"
  30. HTTPS_port="443"
  31. Current_user=""
  32.  
  33. lowercase(){
  34.     echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
  35. }
  36.  
  37. OS=`lowercase \`uname -s\``
  38. MACH=`uname -m`
  39. if [ ${MACH} = "armv6l" ]
  40. then
  41.  MACH="armv7l"
  42. fi
  43.  
  44. # Find the rows and columns will default to 80x24 is it can not be detected
  45. screen_size=$(stty size 2>/dev/null || echo 24 80)
  46. rows=$(echo $screen_size | awk '{print $1}')
  47. columns=$(echo $screen_size | awk '{print $2}')
  48.  
  49. # Divide by two so the dialogs take up half of the screen, which looks nice.
  50. r=$(( rows / 2 ))
  51. c=$(( columns / 2 ))
  52. # Unless the screen is tiny
  53. r=$(( r < 20 ? 20 : r ))
  54. c=$(( c < 70 ? 70 : c ))
  55.  
  56. ######## Undocumented Flags. Shhh ########
  57. skipSpaceCheck=false
  58. reconfigure=false
  59.  
  60. ######## FIRST CHECK ########
  61. # Must be root to install
  62. echo ":::"
  63. if [[ ${EUID} -eq 0 ]]; then
  64.     echo "::: You are root."
  65. else
  66.     echo "::: Script called with non-root privileges. The Domoticz installs server packages and configures"
  67.     echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
  68.     echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
  69.     echo ":::"
  70.     echo "::: Detecting the presence of the sudo utility for continuation of this install..."
  71.  
  72.     if [ -x "$(command -v sudo)" ]; then
  73.         echo "::: Utility sudo located."
  74.         exec curl -sSL https://install.domoticz.com | sudo bash "$@"
  75.         exit $?
  76.     else
  77.         echo "::: sudo is needed for the Web interface to run domoticz commands.  Please run this script as root and it will be automatically installed."
  78.         exit 1
  79.     fi
  80. fi
  81.  
  82. # Compatibility
  83.  
  84. if [ -x "$(command -v apt-get)" ]; then
  85.     #Debian Family
  86.     #############################################
  87.     PKG_MANAGER="apt-get"
  88.     PKG_CACHE="/var/lib/apt/lists/"
  89.     UPDATE_PKG_CACHE="${PKG_MANAGER} update"
  90.     PKG_UPDATE="${PKG_MANAGER} upgrade"
  91.     PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
  92.     # grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
  93.     PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
  94.     INSTALLER_DEPS=( apt-utils whiptail git)
  95.     domoticz_DEPS=( curl unzip wget sudo cron libudev-dev)
  96.  
  97.         DEBIAN_ID=$(grep -oP '(?<=^ID=).+' /etc/*-release | tr -d '"')
  98.         DEBIAN_VERSION=$(grep -oP '(?<=^VERSION_ID=).+' /etc/*-release | tr -d '"')
  99.  
  100.     if test ${DEBIAN_VERSION} -lt 10
  101.     then
  102.         domoticz_DEPS=( ${domoticz_DEPS[@]} libcurl3 )
  103.     else
  104.         domoticz_DEPS=( ${domoticz_DEPS[@]} libcurl4 libusb-0.1)
  105.     fi;
  106.  
  107.     package_check_install() {
  108.         dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
  109.     }
  110. elif [ -x "$(command -v rpm)" ]; then
  111.     # Fedora Family
  112.     if [ -x "$(command -v dnf)" ]; then
  113.         PKG_MANAGER="dnf"
  114.     else
  115.         PKG_MANAGER="yum"
  116.     fi
  117.     PKG_CACHE="/var/cache/${PKG_MANAGER}"
  118.     UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
  119.     PKG_UPDATE="${PKG_MANAGER} update -y"
  120.     PKG_INSTALL="${PKG_MANAGER} install -y"
  121.     PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
  122.     INSTALLER_DEPS=( procps-ng newt git )
  123.     domoticz_DEPS=( curl libcurl4 unzip wget findutils cronie sudo domoticz_DEP)
  124.     if grep -q 'Fedora' /etc/redhat-release; then
  125.         remove_deps=(epel-release);
  126.         domoticz_DEPS=( ${domoticz_DEPS[@]/$remove_deps} );
  127.     fi
  128.     package_check_install() {
  129.         rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
  130.     }
  131. else
  132.     echo "OS distribution not supported"
  133.     exit
  134. fi
  135.  
  136. ####### FUNCTIONS ##########
  137. spinner() {
  138.     local pid=$1
  139.     local delay=0.50
  140.     local spinstr='/-\|'
  141.     while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
  142.         local temp=${spinstr#?}
  143.         printf " [%c]  " "${spinstr}"
  144.         local spinstr=${temp}${spinstr%"$temp"}
  145.         sleep ${delay}
  146.         printf "\b\b\b\b\b\b"
  147.     done
  148.     printf "    \b\b\b\b"
  149. }
  150.  
  151. find_current_user() {
  152.     # Find current user
  153.     Current_user=${SUDO_USER:-$USER}
  154.     echo "::: Current User: ${Current_user}"
  155. }
  156.  
  157. find_IPv4_information() {
  158.     # Find IP used to route to outside world
  159.     IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
  160.     IPv4_address=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
  161.     IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
  162. }
  163.  
  164. welcomeDialogs() {
  165.     # Display the welcome dialog
  166.     whiptail --msgbox --backtitle "Welcome" --title "Domoticz automated installer" "\n\nThis installer will transform your device into a Home Automation System!\n\n
  167. Domoticz is free, but powered by your donations at:  http://www.domoticz.com\n\n
  168. Domoticz is a SERVER so it needs a STATIC IP ADDRESS to function properly.
  169.     " ${r} ${c}
  170. }
  171.  
  172. displayFinalMessage() {
  173.     # Final completion message to user
  174.     whiptail --msgbox --backtitle "Ready..." --title "Installation Complete!" "Point your browser to either:
  175.  
  176. HTTP:   ${IPv4_address%/*}:${HTTP_port%/*}
  177. HTPS:   ${IPv4_address%/*}:${HTTPS_port}
  178.  
  179. Wiki:  https://www.domoticz.com/wiki
  180. Forum: https://www.domoticz.com/forum
  181.  
  182. The install log is in /etc/domoticz." ${r} ${c}
  183. }
  184.  
  185. verifyFreeDiskSpace() {
  186.  
  187.     # 50MB is the minimum space needed
  188.     # - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
  189.     echo "::: Verifying free disk space..."
  190.     local required_free_kilobytes=51200
  191.     local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
  192.  
  193.     # - Unknown free disk space , not a integer
  194.     if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
  195.         echo "::: Unknown free disk space!"
  196.         echo "::: We were unable to determine available free disk space on this system."
  197.         echo "::: You may override this check and force the installation, however, it is not recommended"
  198.         echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
  199.         echo "::: eg. curl -L https://install.domoticz.com | bash /dev/stdin --i_do_not_follow_recommendations"
  200.         exit 1
  201.     # - Insufficient free disk space
  202.     elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
  203.         echo "::: Insufficient Disk Space!"
  204.         echo "::: Your system appears to be low on disk space. Domoticz recommends a minimum of $required_free_kilobytes KiloBytes."
  205.         echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
  206.         echo "::: If this is a new install you may need to expand your disk."
  207.         echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
  208.         echo "::: After rebooting, run this installation again. (curl -L https://install.domoticz.com | bash)"
  209.  
  210.         echo "Insufficient free space, exiting..."
  211.         exit 1
  212.  
  213.     fi
  214.  
  215. }
  216.  
  217. chooseServices() {
  218.     Enable_http=false;
  219.     Enable_https=false;
  220.     # Let use enable HTTP and/or HTTPS
  221.     cmd=(whiptail --separate-output --checklist "Select Services (press space to select)" ${r} ${c} 2)
  222.     options=(HTTP "Enables HTTP access" on
  223.     HTTPS "Enabled HTTPS access" on)
  224.     choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
  225.     if [[ $? = 0 ]];then
  226.         for choice in ${choices}
  227.         do
  228.             case ${choice} in
  229.             HTTP  )   Enable_http=true;;
  230.             HTTPS  )   Enable_https=true;;
  231.             esac
  232.         done
  233.         if [ ! ${Enable_http} ] && [ ! ${Enable_https} ]; then
  234.             echo "::: Cannot continue, neither HTTP or HTTPS selected"
  235.             echo "::: Exiting"
  236.             exit 1
  237.         fi
  238.     else
  239.         echo "::: Cancel selected. Exiting..."
  240.         exit 1
  241.     fi
  242.     # Configure the port(s)
  243.     if [ "$Enable_http" = true ] ; then
  244.         HTTP_port=$(whiptail --inputbox "HTTP Port number:" ${r} ${c} ${HTTP_port} --title "Configure HTTP" 3>&1 1>&2 2>&3)
  245.         exitstatus=$?
  246.         if [ $exitstatus = 0 ]; then
  247.             echo "HTTP Port: " $HTTP_port
  248.         else
  249.             echo "::: Cancel selected. Exiting..."
  250.             exit 1
  251.         fi 
  252.     fi    
  253.     if [ "$Enable_https" = true ] ; then
  254.         HTTPS_port=$(whiptail --inputbox "HTTPS Port number:" ${r} ${c} ${HTTPS_port} --title "Configure HTTPS" 3>&1 1>&2 2>&3)
  255.         exitstatus=$?
  256.         if [ $exitstatus = 0 ]; then
  257.             echo "HTTPS Port: " $HTTPS_port
  258.         else
  259.             echo "::: Cancel selected. Exiting..."
  260.             exit 1
  261.         fi 
  262.     fi
  263. }
  264.  
  265. chooseDestinationFolder() {
  266.     Dest_folder=$(whiptail --inputbox "Installation Folder:" ${r} ${c} ${Dest_folder} --title "Destination" 3>&1 1>&2 2>&3)
  267.     exitstatus=$?
  268.     if [ $exitstatus = 0 ]; then
  269.         echo ":::"
  270.     else
  271.         echo "::: Cancel selected. Exiting..."
  272.         exit 1
  273.     fi 
  274. }
  275.  
  276. stop_service() {
  277.     # Stop service passed in as argument.
  278.     echo ":::"
  279.     echo -n "::: Stopping ${1} service..."
  280.     if [ -x "$(command -v service)" ]; then
  281.         service "${1}" stop &> /dev/null & spinner $! || true
  282.     fi
  283.     echo " done."
  284. }
  285.  
  286. start_service() {
  287.     # Start/Restart service passed in as argument
  288.     # This should not fail, it's an error if it does
  289.     echo ":::"
  290.     echo -n "::: Starting ${1} service..."
  291.     if [ -x "$(command -v service)" ]; then
  292.         service "${1}" restart &> /dev/null  & spinner $!
  293.     fi
  294.     echo " done."
  295. }
  296.  
  297. enable_service() {
  298.     # Enable service so that it will start with next reboot
  299.     echo ":::"
  300.     echo -n "::: Enabling ${1} service to start on reboot..."
  301.     if [ -x "$(command -v service)" ]; then
  302.         update-rc.d "${1}" defaults &> /dev/null  & spinner $!
  303.     fi
  304.     echo " done."
  305. }
  306.  
  307. update_package_cache() {
  308.     #Running apt-get update/upgrade with minimal output can cause some issues with
  309.     #requiring user input (e.g password for phpmyadmin see #218)
  310.  
  311.     #Check to see if apt-get update has already been run today
  312.     #it needs to have been run at least once on new installs!
  313.     timestamp=$(stat -c %Y ${PKG_CACHE})
  314.     timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
  315.     today=$(date "+%b %e")
  316.  
  317.     if [ ! "${today}" == "${timestampAsDate}" ]; then
  318.         #update package lists
  319.         echo ":::"
  320.         echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
  321.         ${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
  322.         echo " done!"
  323.     fi
  324. }
  325.  
  326. notify_package_updates_available() {
  327.   # Let user know if they have outdated packages on their system and
  328.   # advise them to run a package update at soonest possible.
  329.     echo ":::"
  330.     echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
  331.     updatesToInstall=$(eval "${PKG_COUNT}")
  332.     echo " done!"
  333.     echo ":::"
  334.     if [[ ${updatesToInstall} -eq "0" ]]; then
  335.         echo "::: Your system is up to date! Continuing with Domoticz installation..."
  336.     else
  337.         echo "::: There are ${updatesToInstall} updates available for your system!"
  338.         echo "::: We recommend you run '${PKG_UPDATE}' after installing Domoticz! "
  339.         echo ":::"
  340.     fi
  341. }
  342.  
  343. install_dependent_packages() {
  344.     # Install packages passed in via argument array
  345.     # No spinner - conflicts with set -e
  346.     declare -a argArray1=("${!1}")
  347.  
  348.     for i in "${argArray1[@]}"; do
  349.         echo -n ":::    Checking for $i..."
  350.         package_check_install "${i}" &> /dev/null
  351.         echo " installed!"
  352.     done
  353. }
  354.  
  355. finalExports() {
  356.     #If it already exists, lets overwrite it with the new values.
  357.     if [[ -f ${setupVars} ]]; then
  358.         rm ${setupVars}
  359.     fi
  360.     {
  361.     echo "Dest_folder=${Dest_folder}"
  362.     echo "Enable_http=${Enable_http}"
  363.     echo "HTTP_port=${HTTP_port}"
  364.     echo "Enable_https=${Enable_https}"
  365.     echo "HTTPS_port=${HTTPS_port}"
  366.     }>> "${setupVars}"
  367. }
  368.  
  369. downloadDomoticzWeb() {
  370.     echo "::: Destination folder=${Dest_folder}"
  371.     if [[ ! -e $Dest_folder ]]; then
  372.         echo "::: Creating ${Dest_folder}"
  373.         mkdir $Dest_folder
  374.         chown "${Current_user}":"${Current_user}" $Dest_folder
  375.     fi
  376.     cd $Dest_folder
  377.     wget -O domoticz_release.tgz "http://www.domoticz.com/download.php?channel=release&type=release&system=${OS}&machine=${MACH}"
  378.     echo "::: Unpacking Domoticz..."
  379.     tar xvfz domoticz_release.tgz
  380.     rm domoticz_release.tgz
  381.     Database_file="${Dest_folder}/domoticz.db"
  382.     if [ ! -f $Database_file ]; then
  383.         echo "Creating database..."
  384.         touch $Database_file
  385.         chmod 644 $Database_file
  386.         chown "${Current_user}":"${Current_user}" $Database_file
  387.     fi
  388. }
  389.  
  390. makeStartupScript() {
  391.     cp "${Dest_folder}/domoticz.sh" /tmp/domoticz_tmp_ss1
  392.  
  393.     #configure the script
  394.     cat /tmp/domoticz_tmp_ss1 | sed -e "s/USERNAME=pi/USERNAME=${Current_user}/" > /tmp/domoticz_tmp_ss2
  395.     rm /tmp/domoticz_tmp_ss1
  396.    
  397.     local http_port="${HTTP_port}"
  398.     local https_port="${HTTPS_port}"
  399.     if [ "$Enable_http" = false ] ; then
  400.         http_port="0"
  401.     fi    
  402.     if [ "$Enable_https" = false ] ; then
  403.         https_port="0"
  404.     fi    
  405.    
  406.     cat /tmp/domoticz_tmp_ss2 | sed -e "s/-www 8080/-www ${http_port}/" > /tmp/domoticz_tmp_ss1
  407.     rm /tmp/domoticz_tmp_ss2
  408.     cat /tmp/domoticz_tmp_ss1 | sed -e "s/-sslwww 443/-sslwww ${https_port}/" > /tmp/domoticz_tmp_ss2
  409.     rm /tmp/domoticz_tmp_ss1
  410.     cat /tmp/domoticz_tmp_ss2 | sed -e "s%/home/\$USERNAME/domoticz%${Dest_folder}%" > /tmp/domoticz_tmp_ss1
  411.     rm /tmp/domoticz_tmp_ss2
  412.    
  413.     mv /tmp/domoticz_tmp_ss1 /etc/init.d/domoticz.sh
  414.     chmod +x /etc/init.d/domoticz.sh
  415.     update-rc.d domoticz.sh defaults
  416. }
  417.  
  418. installdomoticz() {
  419.     # Install base files
  420.     downloadDomoticzWeb
  421.     makeStartupScript
  422.     finalExports
  423. }
  424.  
  425. updatedomoticz() {
  426.     # Source ${setupVars} for use in the rest of the functions.
  427.     . ${setupVars}
  428.     # Install base files
  429.     downloadDomoticzWeb
  430. }
  431.  
  432. update_dialogs() {
  433.     # reconfigure
  434.     if [ "${reconfigure}" = true ]; then
  435.         opt1a="Repair"
  436.         opt1b="This will retain existing settings"
  437.         strAdd="You will remain on the same version"
  438.     else
  439.         opt1a="Update"
  440.         opt1b="This will retain existing settings."
  441.         strAdd="You will be updated to the latest version."
  442.     fi
  443.     opt2a="Reconfigure"
  444.     opt2b="This will allow you to enter new settings"
  445.  
  446.     UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
  447.     "${opt1a}"  "${opt1b}" \
  448.     "${opt2a}"  "${opt2b}" 3>&2 2>&1 1>&3)
  449.  
  450.     if [[ $? = 0 ]];then
  451.         case ${UpdateCmd} in
  452.             ${opt1a})
  453.                 echo "::: ${opt1a} option selected."
  454.                 useUpdateVars=true
  455.                 ;;
  456.             ${opt2a})
  457.                 echo "::: ${opt2a} option selected"
  458.                 useUpdateVars=false
  459.                 ;;
  460.         esac
  461.     else
  462.         echo "::: Cancel selected. Exiting..."
  463.         exit 1
  464.     fi
  465.  
  466. }
  467.  
  468. install_packages() {
  469.     # Update package cache
  470.     update_package_cache
  471.  
  472.     # Notify user of package availability
  473.     notify_package_updates_available
  474.  
  475.     # Install packages used by this installation script
  476.     install_dependent_packages INSTALLER_DEPS[@]
  477.  
  478.     # Install packages used by the Domoticz
  479.     install_dependent_packages domoticz_DEPS[@]
  480. }
  481.  
  482. main() {
  483. # Check arguments for the undocumented flags
  484.     for var in "$@"; do
  485.         case "$var" in
  486.             "--reconfigure"  ) reconfigure=true;;
  487.             "--i_do_not_follow_recommendations"   ) skipSpaceCheck=false;;
  488.             "--unattended"     ) runUnattended=true;;
  489.         esac
  490.     done
  491.  
  492.     if [[ -f ${setupVars} ]]; then
  493.         if [[ "${runUnattended}" == true ]]; then
  494.             echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
  495.             useUpdateVars=true
  496.         else
  497.             update_dialogs
  498.         fi
  499.     fi
  500.  
  501.     # Start the installer
  502.     # Verify there is enough disk space for the install
  503.     if [[ "${skipSpaceCheck}" == true ]]; then
  504.         echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
  505.     else
  506.         verifyFreeDiskSpace
  507.     fi
  508.  
  509.     install_packages
  510.  
  511.     if [[ "${reconfigure}" == true ]]; then
  512.         echo "::: --reconfigure passed to install script. Not downloading/updating local installation"
  513.     else
  514.         echo "::: Downloading Domoticz"
  515.     fi
  516.    
  517.     find_current_user
  518.    
  519.     Dest_folder="/home/${Current_user}/domoticz"
  520.    
  521.     find_IPv4_information
  522.  
  523.     if [[ ${useUpdateVars} == false ]]; then
  524.         # Display welcome dialogs
  525.         welcomeDialogs
  526.         # Create directory for Domoticz storage
  527.         mkdir -p /etc/domoticz/
  528.         # Install and log everything to a file
  529.         chooseServices
  530.         chooseDestinationFolder
  531.         installdomoticz
  532.     else
  533.         updatedomoticz
  534.     fi
  535.  
  536.     if [[ "${useUpdateVars}" == false ]]; then
  537.         displayFinalMessage
  538.     fi
  539.  
  540.     echo "::: Restarting services..."
  541.     # Start services
  542.     enable_service domoticz.sh
  543.     start_service domoticz.sh
  544.     echo "::: done."
  545.  
  546.     echo ":::"
  547.     if [[ "${useUpdateVars}" == false ]]; then
  548.         echo "::: Installation Complete! Configure your browser to use the Domoticz using:"
  549.         echo ":::     ${IPv4_address%/*}:${HTTP_port}"
  550.         echo ":::     ${IPv4_address%/*}:${HTTPS_port}"
  551.     else
  552.         echo "::: Update complete!"
  553.     fi
  554. }
  555.  
  556. main "$@"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement