diff --git a/.gitignore b/.gitignore index cdecf3f..2ddc203 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ node_modules .idea/ *.swp config.json +*~ diff --git a/README.md b/README.md index 20bb5f6..ed0d1dc 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,74 @@ -npm install -npm install -g grunt-cli bower -gem install compass +####\# dependencies developer-mashine + sudo aptitude install npm nodejs-legacy ruby-dev + npm install + sudo npm install -g grunt-cli bower + sudo gem install compass +####\# dependencies server + sudo aptitude install npm nodejs-legacy -ggf.: +####\# where applicable + bower prune + bower install + +####\# generate the `dist` folder + grunt + +####\# on the server the form should run as user fastdform + useradd -m -U fastdform + cp -a dist/ /home/fastdform/ffffng + chown fastdform:fastdform -Rf /home/fastdform/ffffng/ + sudo su - fastdform + cd ~/ffffng + npm install + cd ~ + vim config.json + cd ffffng/ + ln -s ../config.json + cd ~ + mkdir keys + mkdir bin + cp ~/ffffng/assest/autoupdate.sh ~/bin/ + chmod +x ~/bin/autoupdate.sh + +####\# Keys repository + mkdir /home/fastdform/keys + cd /home/fastdform/keys + git init + git config user.email "formular@gothamcity.freifunk.net" + git config user.name "Knotenformular" + +####\# add this to your users crontab + + crontab -e + + */1 * * * * sleep 20 && /home/fastdform/bin/autoupdate.sh > /dev/null 2>&1 + */1 * * * * /home/fastdform/ffffng/bin/fix_key_file_names.py /home/fastdform/keys > /dev/null 2>&1 + +####\# create the init script to start the form as deamon + su - + cp /home/fastdform/ffffng/assets/init.d.fastdform /etc/init.d/fastdform + update-rc.d fastdform defaults + service fastdform start + +####\# start the server on http://localhost:8080/ + node server/main.js + +####\# example apache config + cat > /etc/apache2/sites-available/formular.conf < + ServerName formular.localhost + + ProxyRequests Off + ProxyVia Off + + ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + + EOF + + cd /etc/apache2/sites-enabled + ln -s ../sites-available/formular.conf 002-formular.conf + + apache2ctl restart -bower prune -bower install diff --git a/assets/autoupdate.sh b/assets/autoupdate.sh new file mode 100644 index 0000000..8ea587f --- /dev/null +++ b/assets/autoupdate.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Simple script to update fastd peers from git upstream +# and only send HUP to fastd when changes happend. + +# CONFIGURE THIS TO YOUR PEER DIRECTORY +FASTD_PEERS=/home/fastdform/keys +FASTD_BACKBONE=/etc/fastd/ffffng-mesh-vpn/backbone + +# CONFIGURE THIS TO THE USER TO RUN THE GIT COMMANDS AS +USER=fastdform + +function getCurrentVersion() { + # Get hash from latest revision + su -c "git log --format=format:%H -1" $USER +} + +cd $FASTD_PEERS + +# Get current version hash +GIT_REVISION=$(getCurrentVersion) + +# Automagically commit local changes +# This preserves local changes +su -c "git add -A ." $USER +su -c "git commit -m \"CRON: auto commit\"" $USER + +# Pull latest changes from upstream +su -c "git fetch" $USER +su -c "git merge origin/master -m \"Auto Merge\"" $USER + +# Get new version hash +GIT_NEW_REVISION=$(getCurrentVersion) + +# Push changes +su -c "git push" $USER + +if [ $GIT_REVISION != $GIT_NEW_REVISION ] +then + # ATTENTION: Specific handling to sync backbone keys to own directory + mkdir -p $FASTD_BACKBONE + rm -f $FASTD_BACKBONE/* + cp $FASTD_PEERS/srv[0-9][0-9]* $FASTD_PEERS/gateway[0-9][0-9]* $FASTD_BACKBONE/ + + # Version has changed we need to update + echo "Reload fastd peers" + kill -HUP $(pidof fastd) +fi diff --git a/assets/init.d.fastdform b/assets/init.d.fastdform new file mode 100644 index 0000000..7a00ae0 --- /dev/null +++ b/assets/init.d.fastdform @@ -0,0 +1,241 @@ +#!/bin/bash +# created from /etc/init.d/skeleton +### BEGIN INIT INFO +# Provides: fastdform +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: fastdform initscript +# Description: deamon for the freifunk formular ffffng +### END INIT INFO + +# Author: Freifunk Hamburg + +# ______________________________________________________________________________ +# +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin # modify if you need + +DAEMON_ARGS="/home/fastdform/ffffng/server/main.js" # path to your node.js server/app + # NB: don't use ~/ in path + +DESC="Form for registering nodes and their fastd keys." # whatever fancy description you like + +NODEUSER=fastdform:fastdform # USER who OWNS the daemon process (no matter whoever runs the init script) + # user:group (if no group is specified, the primary GID for that user is used) + +LOCAL_VAR_RUN=/usr/local/var/run # in case the init script is run by non-root user, you need to + # indicate a directory writeable by $NODEUSER to store the PID file + # NB : 1) /usr/local/var/run does not exist by DEFAULT. Either create it + # or choose one of your own liking. + # 2) node, npm,... are best NOT installed/run as ROOT. + # (see here: https://github.com/isaacs/npm/blob/master/README.md) + +NAME=node # name of the node.js executable +DAEMON=/usr/bin/$NAME # this SHOULD POINT TO where your node executable is +# +# # +# END # +# (Nothing else to modify from this point on...) # +# ------------------------------------------------------------------------------ + + + + + +# Do NOT "set -e" + +[ $UID -eq "0" ] && LOCAL_VAR_RUN=/var/run # in case this script is run by root, override user setting +THIS_ARG=$0 +INIT_SCRIPT_NAME=`basename $THIS_ARG` +[ -h $THIS_ARG ] && INIT_SCRIPT_NAME=`basename $(readlink $THIS_ARG)` # in case of symlink +INIT_SCRIPT_NAME_NOEXT=${INIT_SCRIPT_NAME%.*} +PIDFILE="$LOCAL_VAR_RUN/$INIT_SCRIPT_NAME_NOEXT.pid" +SCRIPTNAME=/etc/init.d/$INIT_SCRIPT_NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || { echo "can't find Node.js ($DAEMON)" >&2; exit 0; } + +# Exit if the 'run' folder is not present +[ -d "$LOCAL_VAR_RUN" ] || { echo "Directory $LOCAL_VAR_RUN does not exist. Modify the '$INIT_SCRIPT_NAME_NOEXT' init.d script ($THIS_ARG) accordingly" >&2; exit 0; } + +# Read configuration variable file if it is present +[ -r /etc/default/$INIT_SCRIPT_NAME ] && . /etc/default/$INIT_SCRIPT_NAME + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# uncomment to override system setting +# VERBOSE=yes + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $NODEUSER --background --exec $DAEMON --test > /dev/null \ + || { [ "$VERBOSE" != no ] && log_daemon_msg " ---> Daemon already running $DESC" "$INIT_SCRIPT_NAME_NOEXT"; return 1; } + start-stop-daemon --start --quiet --chuid $NODEUSER --make-pidfile --pidfile $PIDFILE --background --exec $DAEMON -- \ + $DAEMON_ARGS \ + || { [ "$VERBOSE" != no ] && log_daemon_msg " ---> could not be start $DESC" "$INIT_SCRIPT_NAME_NOEXT"; return 2; } + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. + [ "$VERBOSE" != no ] && log_daemon_msg " ---> started $DESC" "$INIT_SCRIPT_NAME_NOEXT" +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --chuid $NODEUSER --name $DAEMON + RETVAL="$?" + #[ "$VERBOSE" != no ] && [ "$RETVAL" = 1 ] && log_daemon_msg " ---> SIGKILL failed => hardkill $DESC" "$INIT_SCRIPT_NAME_NOEXT" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/3/KILL/5 --pidfile $PIDFILE --chuid $NODEUSER --exec $DAEMON -- $DAEMON_ARGS + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + [ "$VERBOSE" != no ] && [ "$RETVAL" = 1 ] && log_daemon_msg " ---> $DESC not running" "$INIT_SCRIPT_NAME_NOEXT" + [ "$VERBOSE" != no -a "$RETVAL" = 0 ] && log_daemon_msg " ---> $DESC stopped" "$INIT_SCRIPT_NAME_NOEXT" + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --quiet --signal 1 --pidfile $PIDFILE --chuid $NODEUSER --name $NAME + return 0 +} + +# +# Function that returns the daemon +# +do_status() { + # + # http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html + # 0 program is running or service is OK + # 1 program is dead and /var/run pid file exists + # (2 program is dead and /var/lock lock file exists) (not used here) + # 3 program is not running + # 4 program or service status is unknown + RUNNING=$(running) + + # $PIDFILE corresponds to a live $NAME process + ispidactive=$(pidof $NAME | grep `cat $PIDFILE 2>&1` >/dev/null 2>&1) + ISPIDACTIVE=$? + + if [ -n "$RUNNING" ]; then + if [ $ISPIDACTIVE ]; then + log_success_msg "$INIT_SCRIPT_NAME_NOEXT (launched by $USER) (--chuid $NODEUSER) is running" + exit 0 + fi + else + if [ -f $PIDFILE ]; then + log_success_msg "$INIT_SCRIPT_NAME_NOEXT (launched by $USER) (--chuid $NODEUSER) is not running, phantom pidfile $PIDFILE" + exit 1 + else + log_success_msg "no instance launched by $USER, of $INIT_SCRIPT_NAME_NOEXT (--chuid $NODEUSER) found" + exit 3 + fi + fi + +} + +running() { + RUNSTAT=$(start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $NODEUSER --background --exec $DAEMON --test > /dev/null) + if [ "$?" = 1 ]; then + echo y + fi + +} + + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$INIT_SCRIPT_NAME_NOEXT" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$INIT_SCRIPT_NAME_NOEXT" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + #reload|force-reload) + # + # If do_reload() is not implemented then leave this commented out + # and leave 'force-reload' as an alias for 'restart'. + # + #log_daemon_msg "Reloading $DESC" "$NAME" + #do_reload + #log_end_msg $? + #;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$INIT_SCRIPT_NAME_NOEXT" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + status) + do_status + ;; + *) + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 3 + ;; +esac + +exit 0 + +