User Tools

Site Tools


doc:appunti:linux:sa:liquidfeedback

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
doc:appunti:linux:sa:liquidfeedback [2012/11/06 23:17]
niccolo [Install a second instance of LiquidFeedback on the same host]
doc:appunti:linux:sa:liquidfeedback [2012/11/11 13:58] (current)
niccolo [LiquidFeedback administration]
Line 105: Line 105:
 <​code>​ <​code>​
 cd /​usr/​local/​share/​liquid_feedback_frontend/​config cd /​usr/​local/​share/​liquid_feedback_frontend/​config
-cp example.lua ​m5scb campibisenzio5stelle.lua+cp example.lua ​campibisenzio5stelle.lua 
 +chgrp www-data campibisenzio5stelle.lua 
 +chmod 640 campibisenzio5stelle.lua
 </​code>​ </​code>​
 +
 +The configuration file must be readable by the web server process, but not readable by others, because it can contains database credentials and other sensitive data.
  
 The configuration name (**''​campibisenzio5stelle''​** in the example) must be referenced by the web server via the **''​WEBMCP_CONFIG_NAME''​** environment variable (see below). The configuration name (**''​campibisenzio5stelle''​** in the example) must be referenced by the web server via the **''​WEBMCP_CONFIG_NAME''​** environment variable (see below).
 +
 +Then you must adjust the configuration of the Frontend, this is an example of values changed from defaults:
 +
 +<​file>​
 +config.instance_name = "​Movimento 5 Stelle Campi Bisenzio"​
 +config.app_service_provider = "​Movimento 5 Stelle Campi Bisenzio<​br/>​Campi Bisenzio<​br/>​Italia"​
 +config.absolute_base_url = "​http://​lqfb.campibisenzio5stelle.it/​lf/"​
 +config.database = { host='​localhost',​ engine='​postgresql',​ dbname='​liquid_feedback',​ user='​liquid_feedback',​ password='​MySecret'​ }
 +  rocketwiki= "/​usr/​local/​lib/​rocketwiki-lqfb/​rocketwiki-lqfb",​
 +  compat = "/​usr/​local/​lib/​rocketwiki-lqfb/​rocketwiki-lqfb-compat"​
 +config.default_lang = "​it"​
 +config.mail_envelope_from = "​lqfb@campibisenzio5stelle.it"​
 +config.mail_from = { name = "​LiquidFeedback",​ address = "​lqfb@campibisenzio5stelle.it"​ }
 +</​file>​
 ==== Database (the Core) ==== ==== Database (the Core) ====
  
Line 156: Line 174:
 INSERT INTO member (login, name, admin, invite_code) VALUES ('​admin',​ '​Administrator',​ TRUE, '​vieniqua'​);​ INSERT INTO member (login, name, admin, invite_code) VALUES ('​admin',​ '​Administrator',​ TRUE, '​vieniqua'​);​
 </​code>​ </​code>​
-===== Cronjob ​=====+===== lf_update daemon ​===== 
 + 
 +The **''​lf_update''​** core program must be run regulary:
  
 <​code>​ <​code>​
Line 163: Line 183:
 </​code>​ </​code>​
  
 +We must prepare a script that runs in an endless loop, **''/​usr/​local/​sbin/​lf_updated''​**:​
 +
 +<code bash>
 +#!/bin/sh
 +
 +PIDFILE="/​var/​run/​lf_updated.pid"​
 +PID=$$
 +
 +if [ -f "​${PIDFILE}"​ ] && kill -CONT $( cat "​${PIDFILE}"​ ); then
 +  echo "​lf_updated is already running."​
 +  exit 1
 +fi
 +
 +echo "​${PID}"​ > "​${PIDFILE}"​
 +
 +while true; do
 +  nice /​usr/​local/​lib/​liquid_feedback_core/​lf_update \
 +      "​host=localhost dbname=liquid_feedback user=liquid_feedback password=MySecret"​ 2>&1 \
 +      | logger -t "​lf_updated"​
 +  sleep 5
 +done
 +</​code>​
 +
 +The script contains database credentials,​ so protect it:
 +
 +<​code>​
 +chown root:root /​usr/​local/​sbin/​lf_updated
 +chmod 750 /​usr/​local/​sbin/​lf_updated
 +</​code>​
 +
 +Then preare a script that start/stop the daemon, **''/​etc/​init.d/​lf_updated''​**:​
 +
 +<code bash>
 +#! /bin/sh
 +### BEGIN INIT INFO
 +# Provides: ​         lf_updated
 +# Required-Start: ​   $syslog
 +# Required-Stop: ​    ​$syslog
 +# Default-Start: ​    2 3 4 5
 +# Default-Stop: ​     0 1 6
 +# Short-Description:​ lf_updated
 +# Description: ​      Calls LiquidFeedback lf_update regulary
 +### END INIT INFO
 +
 +# PATH should only include /usr/* if it runs after the mountnfs.sh script
 +PATH=/​sbin:/​usr/​sbin:/​bin:/​usr/​bin
 +DESC="​lf_updated"​
 +NAME=lf_updated
 +DAEMON=/​usr/​local/​sbin/​lf_updated
 +DAEMON_ARGS=""​
 +PIDFILE=/​var/​run/​$NAME.pid
 +SCRIPTNAME=/​etc/​init.d/​$NAME
 +
 +. /​lib/​lsb/​init-functions
 +
 +do_start()
 +{
 +        start-stop-daemon -b --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1
 +        start-stop-daemon -b --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS || return 2
 +}
 +
 +do_stop()
 +{
 +        start-stop-daemon --stop --quiet --retry=TERM/​30/​KILL/​5 --pidfile $PIDFILE --name $NAME
 +        RETVAL="​$?"​
 +        [ "​$RETVAL"​ = 2 ] && return 2
 +        start-stop-daemon --stop --quiet --oknodo --retry=0/​30/​KILL/​5 --exec $DAEMON
 +        [ "​$?"​ = 2 ] && return 2
 +        rm -f $PIDFILE
 +        return "​$RETVAL"​
 +}
 +
 +case "​$1"​ in
 +  start)
 +        [ "​$VERBOSE"​ != no ] && log_daemon_msg "​Starting $DESC" "​$NAME"​
 +        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" "​$NAME"​
 +        do_stop
 +        case "​$?"​ in
 +                0|1) [ "​$VERBOSE"​ != no ] && log_end_msg 0 ;;
 +                2) [ "​$VERBOSE"​ != no ] && log_end_msg 1 ;;
 +        esac
 +        ;;
 +  status)
 +       ​status_of_proc "​$DAEMON"​ "​$NAME"​ && exit 0 || exit $?
 +       ;;
 +  restart|force-reload)
 +        log_daemon_msg "​Restarting $DESC" "​$NAME"​
 +        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
 +        ;;
 +  *)
 +        echo "​Usage:​ $SCRIPTNAME {start|stop|status|restart|force-reload}"​ >&2
 +        exit 3
 +        ;;
 +esac
 +
 +:
 +</​code>​
 +
 +Activate the start/stop script at bootstrap:
 +
 +<​code>​
 +chmod 755 /​etc/​init.d/​lf_updated
 +insserv lf_updated
 +</​code>​
 +
 +The daemon logs to syslog with the **''​lf_updated''​** tag.
 ===== Configuring Apache ===== ===== Configuring Apache =====
  
Line 172: Line 319:
 </​code>​ </​code>​
  
 +Create an Apache configuration snippet, e.g. in **''/​etc/​lqfb/​apache.conf''​**:​
 +
 +<​file>​
 +Alias       /​lf/​static ​  /​usr/​local/​share/​liquid_feedback_frontend/​static
 +Alias       /​lf/​fastpath /​usr/​local/​share/​liquid_feedback_frontend/​fastpath
 +ScriptAlias /lf/         /​usr/​local/​lib/​webmcp/​cgi-bin/​
 +
 +RewriteEngine on
 +#RewriteLog /​var/​log/​apache2/​rewrite.log
 +#​RewriteLogLevel 3
 +
 +RewriteRule ^/$ /lf/ [R]
 +RewriteRule ^/​lf/​static/​(.*)$ /​lf/​static/​$1 [L,PT]
 +
 +RewriteCond %{QUERY_STRING} (.*)?
 +RewriteRule ^/lf/$ \
 +    /​lf/​webmcp-wrapper.lua?​_webmcp_urldepth=0&​_webmcp_module=index&​_webmcp_view=index&​%1 [PT]
 +
 +RewriteCond %{QUERY_STRING} (.*)?
 +RewriteRule ^/​lf/​([^/​]+)/​$ \
 +    /​lf/​webmcp-wrapper.lua?​_webmcp_urldepth=1&​_webmcp_module=$1&​_webmcp_view=index&​%1 [PT]
 +
 +RewriteCond %{QUERY_STRING} (.*)?
 +RewriteRule ^/​lf/​([^/​]+)/​([^/​\.]+)$ \
 +    /​lf/​webmcp-wrapper.lua?​_webmcp_urldepth=1&​_webmcp_module=$1&​_webmcp_action=$2&​%1 [PT]
 +
 +RewriteCond %{QUERY_STRING} (.*)?
 +RewriteRule ^/​lf/​([^/​]+)/​([^/​\.]+)\.([^/​]+)$ \
 +    /​lf/​webmcp-wrapper.lua?​_webmcp_urldepth=1&​_webmcp_module=$1&​_webmcp_view=$2&​_webmcp_suffix=$3&​%1 [PT]
 +
 +RewriteCond %{QUERY_STRING} (.*)?
 +RewriteRule ^/​lf/​([^/​]+)/​([^/​]+)/​([^/​\.]+)\.([^/​]+)$ \
 +    /​lf/​webmcp-wrapper.lua?​_webmcp_urldepth=2&​_webmcp_module=$1&​_webmcp_view=$2&​_webmcp_id=$3&​_webmcp_suffix=$4&​%1 [PT]
 +
 +# Allow CGI execution for the webmcp CGI interface
 +<​Directory "/​usr/​local/​lib/​webmcp/​cgi-bin">​
 +    AllowOverride None
 +    Options ExecCGI -MultiViews
 +    Order allow,deny
 +   Allow from all
 +</​Directory>​
 +</​file>​
 +
 +Any Apache VirtualHost can include that configuration:​
 +
 +<​file>​
 +<​VirtualHost *:443>
 +    SSLEngine on
 +    SSLCertificateFile ssl/​lqfb.campibisenzio5stelle.it.pem
 +    ServerName lqfb.campibisenzio5stelle.it
 +    ServerAlias lqfb1.campibisenzio5stelle.it
 +    DocumentRoot /var/www/
 +    ErrorLog ${APACHE_LOG_DIR}/​lqfb.campibisenzio5stelle.it/​error.log
 +    CustomLog ${APACHE_LOG_DIR}/​lqfb.campibisenzio5stelle.it/​access.log combined
 +
 +    # Configure environment for LiquidFeedback application
 +    Include /​etc/​lqfb/​apache.conf
 +    <​Location />
 +        SetEnv LANG '​it_IT.UTF-8'​
 +        SetEnv WEBMCP_APP_BASEPATH '/​usr/​local/​share/​liquid_feedback_frontend/'​
 +        SetEnv WEBMCP_CONFIG_NAME '​campibisenzio5stelle'​
 +    </​Location>​
 +
 +</​VirtualHost>​
 +</​file>​
 ===== Configure the mail subsystem ===== ===== Configure the mail subsystem =====
  
 Install an MTA software like Exim4 or Postfix and configure it so that the system can send mail to the internet. This is required to send the invite code to new members. Install an MTA software like Exim4 or Postfix and configure it so that the system can send mail to the internet. This is required to send the invite code to new members.
  
 +Mail messages generated by LiquidFeedback will have **''​www-data@mailname''​** as sender address, where //​mailname//​ is the content of **''/​etc/​mailname''​**.
 +
 +You can change the LiquidFeedback frontend configuration **''/​usr/​local/​share/​liquid_feedback_frontend/​config/​campibisenzio5stelle.lua''​**:​
 +
 +<​file>​
 +config.mail_envelope_from = "​lqfb@campibisenzio5stelle.it"​
 +config.mail_from = { name = "​LiquidFeedback",​ address = "​lqfb@campibisenzio5stelle.it"​ }
 +</​file>​
 +
 +Another way to map the sender to another address is by configuring the MTA. With Postfix you can add into **''/​etc/​postfix/​main.cf''​**:​
 +
 +<​file>​
 +# Rewrite some sender addresses.
 +sender_canonical_maps = hash:/​etc/​postfix/​sender_canonical_maps
 +</​file>​
 +
 +Then create the **''/​etc/​postfix/​sender_canonical_maps''​** and compile it with **''​postmap''​**:​
 +
 +<​file>​
 +www-data ​       lqfb@campibisenzio5stelle.it
 +</​file>​
 ===== Install a second instance of LiquidFeedback on the same host ===== ===== Install a second instance of LiquidFeedback on the same host =====
  
 FIXME Verify if this checklist is complete. FIXME Verify if this checklist is complete.
  
-  - Create another database. +  - Create another ​**database**
-  - Create another Apache VirtualHost and declare the configuration filename in **''​WEBMCP_CONFIG_NAME''​**.+  - Create another ​**Apache VirtualHost** and declare the configuration filename in **''​WEBMCP_CONFIG_NAME''​**.
   - Create another config file in ''/​usr/​local/​share/​liquid_feedback_frontend/​config/''​ configuring at least **''​absolute_base_url''​** and **''​database''​** credentials.   - Create another config file in ''/​usr/​local/​share/​liquid_feedback_frontend/​config/''​ configuring at least **''​absolute_base_url''​** and **''​database''​** credentials.
 +  - Add or update the **''​lf_updated''​** daemon to run on each database instance.
 ===== LiquidFeedback administration ===== ===== LiquidFeedback administration =====
  
-^ unit    | Administrators allow each user partecipate (or not) to the existing units. ​ | +^ Eng     ^ Ita      ^ Note  ^ 
-^ area    | An unit can contain one or more areas. An user can partecipate to an area and he can delegate the entire area to someone else.  | +^ unit    ​^ sezione  ​| Administrators allow each user partecipate (or not) to the existing units. ​ | 
-^ issue   ​| ​ | +^ area    ​^ area     | An unit can contain one or more areas. An user can partecipate to an area and he can delegate the entire area to someone else.  | 
-^ policy ​ |  |+^ issue   ^          ​|  | 
 +^ policy  ​^          ​|  | 
 + 
 +An user with the admin right can login and click on the **//​admin//​** link. 
 + 
 +The first task for an administrator is to create some **units** containing some **areas**, where users can partecipate. From //Admin// -> //Units// -> //Create new unit// or //Edit areas//. 
 + 
 +Then the administrator create invite codes for new users. When creating a new user the admin define the login name (the identification),​ an email address, the admin right and the **units** where he can partecipate.
  
-An user with the admin right can login and click on the **//​admin//​** link. The first task for an administrator is to create invite codes for new users. When creating a new user the admin define the login name (the identification),​ an email address, the admin right and the **units** where he can partecipate. 
doc/appunti/linux/sa/liquidfeedback.1352240232.txt.gz · Last modified: 2012/11/06 23:17 by niccolo