wiki:installation
Last modified 3 months ago Last modified on 07/13/2014 09:56:53 PM

How to install LiquidFeedback on a Debian squeeze system with lighttpd

This guideline is outdated! Please refer to the ‚Äčinstallation instruction included in the LiquidFeedback Frontend distribution.

Install debian security updates:

apt-get update
apt-get upgrade

Install the neccessary debian packages:

apt-get install lua5.1 postgresql build-essential libpq-dev liblua5.1-0-dev lighttpd ghc libghc6-parsec3-dev imagemagick exim4

Create a database role for www-data:

su - postgres
createuser
Enter name of role to add: www-data
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) n
exit

Create a directory for unpacking source tarballs:

cd /root
mkdir install

Install and configure LiquidFeedback Core v2.2.1:

cd /root/install
wget http://www.public-software-group.org/pub/projects/liquid_feedback/backend/v2.2.1/liquid_feedback_core-v2.2.1.tar.gz
tar -xvzf liquid_feedback_core-v2.2.1.tar.gz
cd liquid_feedback_core-v2.2.1
make
mkdir /opt/liquid_feedback_core
cp core.sql lf_update /opt/liquid_feedback_core/
su - www-data
cd /opt/liquid_feedback_core
createdb liquid_feedback
createlang plpgsql liquid_feedback
psql -v ON_ERROR_STOP=1 -f core.sql liquid_feedback
psql liquid_feedback
psql (8.4.13)
Type "help" for help.

liquid_feedback=> SELECT * FROM liquid_feedback_version;
 string | major | minor | revision 
--------+-------+-------+----------
 2.2.1  |     2 |     2 |        1
(1 row)

liquid_feedback=> SELECT * FROM system_setting;
 member_ttl 
------------
(0 rows)

liquid_feedback=> INSERT INTO system_setting (member_ttl) VALUES ('1 year');
INSERT 0 1
liquid_feedback=> SELECT * FROM contingent;
 polling | time_frame | text_entry_limit | initiative_limit 
---------+------------+------------------+------------------
(0 rows)

liquid_feedback=> INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 hour', 20, 6);
INSERT 0 1
liquid_feedback=> INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 day', 80, 12);
INSERT 0 1
liquid_feedback=> INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 hour', 200, 60);
INSERT 0 1
liquid_feedback=> INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 day', 800, 120);
INSERT 0 1
liquid_feedback=> SELECT * FROM policy;
 id | index | active | name | description | polling | admission_time | discussion_time | verification_time | voting_time | issue_quorum_num | issue_quorum_den | initiative_quorum_num | initiative_quorum_den | direct_majority_num | direct_majority_den | direct_majority_strict | direct_majority_positive | direct_majority_non_negative | indirect_majority_num | indirect_majority_den | indirect_majority_strict | indirect_majority_positive | indirect_majority_non_negative | no_reverse_beat_path | no_multistage_majority 
----+-------+--------+------+-------------+---------+----------------+-----------------+-------------------+-------------+------------------+------------------+-----------------------+-----------------------+---------------------+---------------------+------------------------+--------------------------+------------------------------+-----------------------+-----------------------+--------------------------+----------------------------+--------------------------------+----------------------+------------------------
(0 rows)

liquid_feedback=> INSERT INTO policy (index, name, admission_time, discussion_time, verification_time, voting_time, issue_quorum_num, issue_quorum_den, initiative_quorum_num, initiative_quorum_den) VALUES (1, 'Default policy', '8 days', '15 days', '8 days', '15 days', 10, 100, 10, 100);
INSERT 0 1
liquid_feedback=> SELECT * FROM policy;
 id | index | active |      name      | description | polling | admission_time | discussion_time | verification_time | voting_time | issue_quorum_num | issue_quorum_den | initiative_quorum_num | initiative_quorum_den | direct_majority_num | direct_majority_den | direct_majority_strict | direct_majority_positive | direct_majority_non_negative | indirect_majority_num | indirect_majority_den | indirect_majority_strict | indirect_majority_positive | indirect_majority_non_negative | no_reverse_beat_path | no_multistage_majority 
----+-------+--------+----------------+-------------+---------+----------------+-----------------+-------------------+-------------+------------------+------------------+-----------------------+-----------------------+---------------------+---------------------+------------------------+--------------------------+------------------------------+-----------------------+-----------------------+--------------------------+----------------------------+--------------------------------+----------------------+------------------------
  1 |     1 | t      | Default policy |             | f       | 8 days         | 15 days         | 8 days            | 15 days     |               10 |              100 |                    10 |                   100 |                   1 |                   2 | t                      |                        0 |                            0 |                     1 |                     2 | t                        |                          0 |                              0 | t                    | f
(1 row)

liquid_feedback=> SELECT * FROM unit;
 id | parent_id | active | name | description | member_count | text_search_data 
----+-----------+--------+------+-------------+--------------+------------------
(0 rows)

liquid_feedback=> INSERT INTO unit (name) VALUES ('Our organization');
INSERT 0 1
liquid_feedback=> SELECT * FROM unit;
 id | parent_id | active |       name       | description | member_count |     text_search_data     
----+-----------+--------+------------------+-------------+--------------+--------------------------
  1 |           | t      | Our organization |             |              | 'organization':2 'our':1
(1 row)

liquid_feedback=> SELECT * FROM area;
 id | unit_id | active | name | description | direct_member_count | member_weight | text_search_data 
----+---------+--------+------+-------------+---------------------+---------------+------------------
(0 rows)

liquid_feedback=> INSERT INTO area (unit_id, name) VALUES (1, 'Default area');
INSERT 0 1
liquid_feedback=> SELECT * FROM area;
 id | unit_id | active |     name     | description | direct_member_count | member_weight |   text_search_data   
----+---------+--------+--------------+-------------+---------------------+---------------+----------------------
  1 |       1 | t      | Default area |             |                     |               | 'area':2 'default':1
(1 row)

liquid_feedback=> SELECT * FROM allowed_policy;
 area_id | policy_id | default_policy 
---------+-----------+----------------
(0 rows)

liquid_feedback=> INSERT INTO allowed_policy (area_id, policy_id, default_policy) VALUES (1, 1, TRUE);
INSERT 0 1
liquid_feedback=> \q
could not save history to file "/var/www/.psql_history": Permission denied
exit

Install WebMCP:

cd /root/install
wget http://www.public-software-group.org/pub/projects/webmcp/v1.2.5/webmcp-v1.2.5.tar.gz
tar -xvzf webmcp-v1.2.5.tar.gz
cd webmcp-v1.2.5
vi Makefile.options  # append  -I /usr/include/lua5.1  at end of CFLAGS line
make
mkdir /opt/webmcp
cp -RL framework/* /opt/webmcp/

Install RocketWiki LqFb-Edition:

cd /root/install
wget http://www.public-software-group.org/pub/projects/rocketwiki/liquid_feedback_edition/v0.4/rocketwiki-lqfb-v0.4.tar.gz
tar -xvzf rocketwiki-lqfb-v0.4.tar.gz
cd rocketwiki-lqfb-v0.4
make
mkdir /opt/rocketwiki-lqfb
cp rocketwiki-lqfb rocketwiki-lqfb-compat /opt/rocketwiki-lqfb/

Install LiquidFeedback-Frontend v2.2.1:

cd /root/install
wget http://www.public-software-group.org/pub/projects/liquid_feedback/frontend/v2.2.1/liquid_feedback_frontend-v2.2.1.tar.gz
tar -xvzf liquid_feedback_frontend-v2.2.1.tar.gz
mv liquid_feedback_frontend-v2.2.1 /opt/liquid_feedback_frontend

Create HTML code for help texts:

cd /opt/liquid_feedback_frontend/locale
PATH=/opt/rocketwiki-lqfb:$PATH make

Make tmp directory of LiquidFeedback-Frontend writable for webserver:

chown www-data /opt/liquid_feedback_frontend/tmp

Compile binary for fast delivery of member images:

cd /opt/liquid_feedback_frontend/fastpath
vi getpic.c
check    #define GETPIC_CONNINFO "dbname=liquid_feedback"
and
replace  #define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_testing/app/static/avatar.jpg"
with     #define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_frontend/static/avatar.jpg"
make

Configure mail system:

dpkg-reconfigure exim4-config

Create webserver configuration for LiquidFeedback:

cd /etc/lighttpd
vi conf-available/60-liquidfeedback.conf
server.modules += ("mod_cgi", "mod_rewrite", "mod_redirect", "mod_setenv")

# Enable CGI-Execution of *.lua files through lua binary
cgi.assign += ( ".lua" => "/usr/bin/lua5.1" )

alias.url += ( "/lf/fastpath/" => "/opt/liquid_feedback_frontend/fastpath/",
               "/lf/static"    => "/opt/liquid_feedback_frontend/static",
               "/lf"           => "/opt/webmcp/cgi-bin" )

# Configure environment for demo application
$HTTP["url"] =~ "^/lf" {
  setenv.add-environment += (
    "LANG" => "en_US.UTF-8",
    "WEBMCP_APP_BASEPATH" => "/opt/liquid_feedback_frontend/",
    "WEBMCP_CONFIG_NAME"  => "myconfig")
}

# URL beautification
url.rewrite-once += (
  # do not rewrite static URLs
      "^/lf/fastpath/(.*)$" => "/lf/fastpath/$1",
      "^/lf/static/(.*)$"   => "/lf/static/$1",

  # dynamic URLs
      "^/lf/([^\?]*)(\?(.*))?$" => "/lf/webmcp-wrapper.lua?_webmcp_path=$1&$3",

)

$HTTP["url"] =~ "^/lf/fastpath/" {
  cgi.assign = ( "" => "" )
  setenv.add-response-header = ( "Cache-Control" => "private; max-age=86400" )
}
cd /etc/lighttpd/conf-enabled
ln -s ../conf-available/60-liquidfeedback.conf .

Configure LiquidFeedback-Frontend:

cd /opt/liquid_feedback_frontend/config
cp example.lua myconfig.lua
vi myconfig.lua

While configuring the LiquidFeedback-Frontend, use the following option to enable fast image loading:

config.fastpath_url_func = function(member_id, image_type)
  return request.get_absolute_baseurl() .. "fastpath/getpic?" .. tostring(member_id) .. "+" .. tostring(image_type)
end

Execute lf_update once:

su - www-data
cd /opt/liquid_feedback_core
./lf_update dbname=liquid_feedback && echo OK
exit

The commands "lf_update dbname=liquid_feedback" and "lf_update_suggestion_order dbname=liquid_feedback" have to be executed regulary. Create the following shell script to call this command in an endless loop:

vi /opt/liquid_feedback_core/lf_updated
#!/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
  su - www-data -c 'nice /opt/liquid_feedback_core/lf_update dbname=liquid_feedback 2>&1 | logger -t "lf_updated"'
  su - www-data -c 'nice /opt/liquid_feedback_core/lf_update_suggestion_order dbname=liquid_feedback 2>&1 | logger -t "lf_updated"'
  sleep 5
done
chmod +x /opt/liquid_feedback_core/lf_updated

Create the following init-script for lf_updated...

vi /etc/init.d/lf_updated
#! /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=/opt/liquid_feedback_core/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

:

... and make the init script executable and let it start automatically at boot time

chmod +x /etc/init.d/lf_updated
update-rc.d-insserv lf_updated defaults

Start sending of event notifications: (TODO: daemonize)

su - www-data
cd /opt/liquid_feedback_frontend/
echo "Event:send_notifications_loop()" | ../webmcp/bin/webmcp_shell myconfig

Restart the webserver:

/etc/init.d/lighttpd restart

Create an administrator account:

su - www-data
cd /opt/liquid_feedback_core
psql liquid_feedback
psql (8.4.13)
Type "help" for help.

liquid_feedback=> INSERT INTO member (login, name, admin, invite_code) VALUES ('admin', 'Administrator', TRUE, _INSERT_ADMIN_INVITE_CODE_IN_SINGLE_QUOTES_HERE_);
INSERT 0 1
liquid_feedback=> \q
could not save history to file "/var/www/.psql_history": No such file or directory
exit