#!/bin/bash SCRIPTVERSION="$Id:2.1$" # Author: Adimarantis # License: GPL #Install script for FHEM including signal-cli FHEMVERSION=6.0 FHEMUSER=fhem FHEMGROUP=fhem SIGNALVAR=/var/lib/signal-cli SIGNALBOTSOURCE=https://github.com/bublath/FHEM-Signalbot LOG=/tmp/docker_install.log TMPFILE=/tmp/signal$$.tmp OPERATION=$1 BUILDDIR=$HOME/fhem #Space separated list of additional packages, installed with apt (linux), cpan (perl) or npm (node.js) APT="usbutils libimage-librsvg-perl perl libcpan-changes-perl liburi-perl" CPAN="local::lib" NPM= #for signal-cli APT="$APT wget default-jre zip base-files libdbus-1-dev zip build-essential" #APT="$APT wget haveged default-jre qrencode pkg-config gcc zip libexpat1-dev libxml-parser-perl libtemplate-perl libxml-xpath-perl build-essential xml-twig-tools base-files" CPAN="$CPAN Protocol::DBus" #for DBLOG APT="$APT default-mysql-client libdbd-mysql libdbd-mysql-perl" #for FRITZBOX #APT="$APT libjson-perl libwww-perl libsoap-lite-perl libjson-xs-perl libnet-telnet-perl" #for GoogleCast #APT="$APT python3 python3-pip python3-dev libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libglib2.0-dev libdbus-1-dev bluez libbluetooth-dev" #CPAN="$PERL Protocol::WebSocket" #for Alexa #APT="$APT nodejs npm" #NPM="$NPM alexa-fhem" #gassistent #APT="$APT nodejs npm libjson-perl" #NPM="$NPM gassistant-fhem" #Get OS data if [ -e /etc/os-release ]; then source /etc/os-release cat /etc/os-release >$LOG else echo "Could not find OS release data - are you on Linux?" exit fi if grep -q docker /proc/1/cgroup; then echo "Cannot install Docker inside Docker" exit fi USER=`id | grep root` if [ -z "$USER" ]; then echo "Docker Installation needs to run under root" exit fi FHEM_UID=`id -u $FHEMUSER` FHEM_GID=`id -g $FHEMGROUP` echo "Will create a Docker FHEM instance including signal-cli for Signalbot usage" echo echo "Please verify that these settigns are correct:" echo "FHEM-Version: $FHEMVERSION" echo "SIGNALBOT Repository $SIGNALBOTSOURCE" echo "BUILD directory $BUILDDIR" echo "User $FHEMUSER ($FHEM_UID)" echo "Group $FHEMGROUP ($FHEM_GID)" # install_and_check() { #Check availability of tools and install via apt if missing TOOL=$1 PACKAGE=$2 echo -n "Checking for $TOOL..." WHICH=`which $TOOL` if [ -z "$WHICH" ]; then echo -n "installing ($PACKAGE)" apt-get -q -y install $PACKAGE >>$LOG WHICH=`which $TOOL` if [ -z "$TOOL" ]; then echo "Failed to install $TOOL" exit else echo "done" fi else echo "available" fi } install_by_file() { #Check availability of tools and install via apt if missing FILE=$1 PACKAGE=$2 echo -n "Checking for $FILE..." if ! [ -e "$FILE" ]; then echo -n "installing ($PACKAGE)" apt-get -q -y install $PACKAGE >>$LOG if ! [ -e "$FILE" ]; then echo "Failed to install $FILE" exit else echo "done" fi else echo "available" fi } check_and_create_path() { #Check if path is available and create of not CHECK=$1 echo -n "Checking for $CHECK..." if ! [ -d $CHECK ]; then mkdir $1 if ! [ -d $CHECK ]; then echo "Failed to create $CHECK - did you run on sudo?" exit else echo "created" fi else echo "found" fi if ! [ -w $CHECK ]; then echo "Cannot write to $CHECK - did you start this script with sudo?" exit fi } check_and_compare_file() { #Check if a file exists and compare if its the same as our internal reference file CHECK=$1 COMPARE=$2 echo -n "Checking for $CHECK..." if [ -e $CHECK ]; then echo "found" diff $CHECK $COMPARE DIFF=`diff -q $CHECK $COMPARE` if ! [ -z "$DIFF" ]; then echo "$CHECK differs, update (Y/n)? " read REPLY if [ "$REPLY" = "y" ]; then cp $COMPARE $CHECK echo "$CHECK updated" else echo "$CHECK left untouched" fi fi else cp $COMPARE $CHECK echo "$CHECK installed" fi } #Main part - do always, check basic system requirements like OS, packages etc - does not install any signal specific stuff ARCH=`arch` OSNAME=`uname` RASPI="" if [ $OSNAME != "Linux" ]; then echo "Only Linux systems are supported (you: $OSNAME), quitting" exit fi if [ "$ID" = "raspbian" ] || [ "$ID" = "Raspian" ] || [ "$ARCH" = "armv7l" ]; then echo "You seem to be on a Raspberry pi with $ARCH" RASPI=1 else if [ "$ID" = "ubuntu" ] || [ "$ID" = "Ubuntu" ]; then echo "You seem to run Ubuntu on $ARCH" else echo "Your configuration" uname -a echo "has not been tested, continue at own risk" fi fi check_and_update() { APTCMD=`which apt` if [ -z "$APTCMD" ]; then echo "Can't find apt command - are you on a supported system?" exit fi check_and_create_path $BUILDDIR install_and_check docker docker.io install_and_check wget wget cd $BUILDDIR cat >docker-compose.yml <<EOF version: '2' services: fhem: hostname: fhemsignal build: . image: fhem/signal container_name: fhem_signal stdin_open: true tty: true volumes: - "./fhem-$FHEMVERSION/:/opt/fhem/" - "./signal/:/var/lib/signal-cli" ports: - "8083:8083" - "7072:7072" networks: - fhem-network #devices: # - "/dev/ttyUSB0:/dev/ttyUSB0" environment: FHEM_UID: $FHEM_UID FHEM_GID: $FHEM_GID FHEMUSER: $FHEMUSER FHEMGROUP: $FHEMGROUP TIMEOUT: 10 RESTART: 1 TELNETPORT: 7072 TZ: Europe/Berlin networks: fhem-network: driver: bridge EOF cat >Dockerfile <<EOF ARG BASE_IMAGE="ubuntu" ARG BASE_IMAGE_TAG="latest" FROM \${BASE_IMAGE}:\${BASE_IMAGE_TAG} RUN addgroup --gid $FHEM_GID fhem RUN useradd -r -u $FHEM_UID -g fhem fhem RUN mkdir /run/dbus # Install base environment RUN DEBIAN_FRONTEND=noninteractive apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y base-files locales apt-utils sudo RUN dpkg --configure -a RUN DEBIAN_FRONTEND=noninteractive apt-get upgrade -y RUN DEBIAN_FRONTEND=noninteractive apt-get install -y $APT RUN cpan install -f $CPAN RUN if [ -n "$NPM" ]; then npm install $NPM ; fi COPY org.asamk.Signal.conf /etc/dbus-1/system.d/org.asamk.Signal.conf COPY org.asamk.Signal.service /usr/share/dbus-1/system-services/org.asamk.Signal.service WORKDIR "/opt/fhem" ENTRYPOINT [ "./entry.sh" ] CMD [ "start" ] EOF cat >entry.sh <<EOF #!/bin/bash cd /opt/fhem if [ -e /tmp/signal_install.log ]; then export FHEMUSER ./signal_install.sh start >/tmp/start.log 2>/tmp/start.err fi sudo -u $FHEMUSER perl fhem.pl fhem.cfg echo -n "Waiting for fhem to terminate." WAIT="runs" while [ -n "\$WAIT" ] do WAIT=\`ps -eo pid,command | grep fhem.pl | grep -v grep\` echo -n "." sleep 1 done echo "stopped" EOF cat >org.asamk.Signal.conf <<EOF <?xml version="1.0"?> <!--*-nxml-*--> <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy user="$FHEMUSER"> <allow own="org.asamk.Signal"/> <allow send_destination="org.asamk.Signal"/> <allow receive_sender="org.asamk.Signal"/> </policy> <policy context="default"> <allow send_destination="org.asamk.Signal"/> <allow receive_sender="org.asamk.Signal"/> </policy> </busconfig> EOF cat >org.asamk.Signal.service <<EOF [D-BUS Service] Name=org.asamk.Signal Exec=/bin/false User=$FHEMUSER SystemdService=dbus-org.asamk.Signal.service EOF } create_docker() { REINST=0 cd $BUILDDIR if [ -d fhem-$FHEMVERSION ]; then echo "FHEM $FHEMVERSION directory already exists" echo "delete and reinstall (y/N)?" read REPLY if [ "$REPLY" = "y" ]; then REINST=1 fi fi if [ $REINST = 1 ]; then echo -n "Downloading fhem $FHEMVERSION..." wget -qN http://fhem.de/fhem-$FHEMVERSION.tar.gz if ! [ -e fhem-$FHEMVERSION.tar.gz ]; then echo "failed" exit else echo "done" echo "Unpacking ..." tar xf $BUILDDIR/fhem-$FHEMVERSION.tar.gz fi cd $BUILDDIR chown -R $FHEMUSER: fhem-$FHEMVERSION fi check_and_create_path $BUILDDIR/signal chown -R $FHEMUSER: $BUILDDIR/signal if ! [ -d $BUILDDIR/signal/data ]; then echo "Can't find any signal-cli registration data. You will need to do this later or register a new device" echo "Or just copy it to $BUILDDIR/signal now" echo -n "Press return to continue" read REPLY fi #Get latest scripts anyway echo -n "Downloading/Updating Signalbot..." cd $BUILDDIR/fhem-$FHEMVERSION wget -qN wget https://svn.fhem.de/fhem/trunk/fhem/contrib/signal/signal_install.sh chmod a+rx signal_install.sh echo "done" echo -n "Adjusting permissions..." chown -R $FHEMUSER: $BUILDDIR/fhem-$FHEMVERSION chown -R $FHEMUSER: $SIGNALVAR echo "done" cd $BUILDDIR cp entry.sh fhem-$FHEMVERSION docker-compose up -d docker exec -ti fhem_signal /opt/fhem/signal_install.sh docker # Restart container now that everything is set docker-compose down docker-compose up -d } remove_all() { #just in case paths are wrong to not accidentially remove wrong things cd /tmp echo "Warning. This will the container environment including images previously created by this script" echo echo -n "Continue (y/N)? " read REPLY if ! [ "$REPLY" = "y" ]; then echo "Abort" exit fi docker stop fhem_signal docker rm fhem_signal docker rmi fhem/signal docker system prune } if [ -z $OPERATION ]; then echo "This will create a container environment for fhem and signal-cli" echo echo "To do this rather step by step use the command line arguments or just proceed to do system,install,register:" echo "system : prepare required system packages (docker, script files" echo "docker : Create the docker and run the installation/configuration" echo "remove : Docker container and image" echo echo "!!! Everything needs to run with sudo !!!" else echo "Your chose the following option: $OPERATION" fi echo echo -n "Proceed (Y/n)? " read REPLY if [ "$REPLY" = "n" ]; then echo "Aborting..." exit fi # Main flow without option: intall, register if [ -z "$OPERATION" ] || [ $1 = "system" ]; then check_and_update fi if [ -z "$OPERATION" ] || [ $1 = "docker" ]; then create_docker fi rm -f $TMPFILE if [ -z "$OPERATION" ]; then exit fi # Other options if [ $OPERATION = "remove" ]; then remove_all fi rm -f $TMPFILE exit