Install web server

h1. Create servers

We used Debian Lenny virtual servers. We need at least 512 MB RAM.

h1. Install packages

<pre>
apt-get update

apt-get install apache2 php5 libapache2-mod-php5 php5-cli php5-ldap
apt-get install mysql-server mysql-client php5-mysql phpmyadmin php5-memcache php-apc
apt-get install ssh subversion expect lynx imagemagick
</pre>

h1. Apache configuration

h2. .htaccess

 vi /etc/apache2/sites-enabled/000-default
 apache2ctl restart

h2. rewriteEngine

<pre>
ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/
</pre>

The Agilo server can trigger the tests by calling the php script only with the following trick:

mail.toltech.nl:81 redirects to azavista-test:80

You have to ask the system administrators to do that for you in any case. Just tell them: "Please Bas, make mail.toltech.nl:81 route to azavista-test:80 (and include azavista-test in the DNS)".

If you point to azavista-test:81 instead (a cross-port redirection doesn't work always), you also need to open port 81 (and not only *:80 in the virtual name) so that we can also Listen to it:

<pre>
sudo vi /etc/apache2/ports.conf
...
[Name Virtual Host?]] *:80
Listen 80
Listen 81
</pre>

<pre>
sudo vi /etc/apache2/sites-enabled/000-default
...
<Virtual Host? *:80 *:81>
...
</pre>

h2. SSL server

SSL is needed for https secure transactions. Configure your server like this.

Enable ssl in Apache:

<pre>
sudo a2enmod ssl
</pre>

Copy the key and the certificate in a directory /etc/apache2/ssl/ (developers can find a key and certificate at /working_files in the repository).

Install a virtual server in /etc/apache2/sites-enabled/001-ssl

<pre>
Name Virtual Host? *:443
<Virtual Host? *:443>

  Server Admin? webmaster@localhost
# Server Name? ws11
# Server Alias? localhost
  # Uncomment to disable SSL:
# Redirect Match? 302 (.*) http://azavista.com$1
       SSLEngine On
       SSLCertificateFile /etc/apache2/ssl/private_ssl_certificate.crt
SSLCertificateKeyFile /etc/apache2/ssl/private_ssl_certificate.key
Document Root? /var/www/

<Directory />

  Options Follow Sym Links?
Allow Override? None

</Directory>
<Directory /var/www/>

  Options Indexes Follow Sym Links? Multi Views?
Allow Override? all
Order allow,deny
allow from all

</Directory>

  Script Alias? /cgi-bin/ /usr/lib/cgi-bin/

<Directory "/usr/lib/cgi-bin">

  Allow Override? None
Options +ExecCGI -Multi Views? +Sym Links If Owner Match?
Order deny,allow
Allow from 83.160.103.186
Allow from 95.97.75.122

</Directory>

  Error Log? /var/log/apache2/ssl-azavista.com_error.log
Error Log? /var/log/apache2/ssl_error.log
  1. Possible values include: debug, info, notice, warn, error, crit,
  2. alert, emerg.
  Log Level? warn
Custom Log? /var/log/apache2/access_ssl.log combined

</VirtualHost>

</pre>

Make sure [Suhosin Php?]] is configured correctly, not to mess with your sessions.

h1. Suhosin Php?

This is a security extension for php, that makes settings more strict.

Documentation: http://www.hardened-php.net/suhosin/configuration.html

h2. Memory limit

Suhosin by default removes the ability of the php script to change the memory limit settings. To override this you need to edit /etc/php5/conf.d/suhosin.ini:

<pre>
suhosin.memory_limit=256M
</pre>

We increased it a lot, because od the CIC sync and the email campaigns:

suhosin.memory_limit=6G

This means that the script can set the memory limit up to 256Megs, but not more.

h2. Session cookies

This is required to keep cookies between http and https sessions, apart from the CakePHP configurations in azavista_session.php

<pre>
suhosin.session.cryptdocroot = Off
</pre>

See http://stackoverflow.com/a/11657470/653201

h2. other defaults

It also limits the max number of posted variables!

We tuned it to this:

<pre>
; configuration for php suhosin module
; /etc/php5/conf.d/suhosin.ini

extension=suhosin.so
suhosin.executor.include.whitelist="phar"
suhosin.memory_limit=6G
suhosin.post.max_vars = 2048
suhosin.request.max_vars = 2048

</pre>

Restart Apache

<pre>
sudo /etc/init.d/apache2 restart
</pre>

h2. php.ini

Edit /etc/php5/apache2/php.ini.

Increase execution time, at least when importing the CSV files. Make it about five minutes. You can later reduce it for production.

<pre>
max_execution_time = 30
</pre>

Keep an eye on the memory limit, maybe this default is too high for production:

<pre>
memory_limit = 128M
</pre>

Increase the garbage collection time, so that it is not below the time you expect your sessions to last (see http://www.lextech.com/blog/cakephp-and-session-garbage-collection)

<pre>
; six hours
session.gc_maxlifetime = 21600
</pre>

Check also

<pre>
; Maximum size of POST data that PHP will accept.
post_max_size = 8M

; Maximum allowed size for uploaded files.
upload_max_filesize = 8M

</pre>

Make sure you have the correct time zone set (both for apache and cli):

<pre>
date.timezone = 'Europe/Amsterdam'
</pre>

Make sure you configure Suhosin [Suhosin Php?]]

h1. APC

<pre>
sudo apt-get install php-apc
</pre>

And add extension=apc.so to your php.ini

h1. APC

h3. This is how you can install APC and it works out of box

First, we need the pecl command so we can download and install APC from the repositories.

Do to so, we execute the following command:

<pre>
aptitude install php-pear
</pre>

But, this will not run on its own, we need the following package for the phpize command:

<pre>
aptitude install php5-dev
</pre>

We also need the apxs command, which is installed via the following package:

<pre>
aptitude install apache2-dev
</pre>

Now we have all the software we need, so we install apc via the pecl command:

<pre>
pecl install apc
</pre>

Once that finishes, we need to enable apc in Apache's configuration. the following command should do this for us.

<pre>
echo "extension=apc.so" > /etc/php5/apache2/conf.d/apc.ini
</pre>

> That didn't work for me, my PHP doesn't include files in that directory. I added that line directly to php.ini.

Then we restart Apache:

<pre>
/etc/init.d/apache2 restart
</pre>

h3. Production / beta servers

we cannot run make on those so instead of pecl we use:
<pre>
sudo apt-get install php-apc
</pre>

http://azavista.com/site/apc.php login apc, password azavista

h1. Memcache

We use both APC and Memcache, in production.

Memcache in production runs with two instances: one for storing PHP sesions (port 11211) a another one for caching our aplication data (port 11212)

h1. Mem Cache?

h1. restart

 echo -e "flush_all\n\quit\n" | telnet localhost 11211

. command line

http://www.design-ireland.net/?http%3A//www.design-ireland.net/article/Accessing_Memcached_from_the_command_line

 telnet localhost 11211

stats
stats slabs
stats items
stats cachedump 1 0
get testkey
delete testkey
quit

h1. Use memcache to store sessions

http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/

Installation

The first thing is to install the memcached server on your Debian server :

 apt-get install memcached

Then, since the memcache PECL extension now provides its own session handler, it’s easy to plug PHP and memcached servers. Just install the appropriate extension (from Dotdeb) :

 apt-get install php5-memcache

and change some of your PHP settings :

 session.save_handler = files

; session.save_path = "N;/path"

to :

 session.save_handler = memcache
change server
port to fit your needs...

session.save_path="tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

That’s all! After relaunching your Apache2 server, your PHP sessions will be stored on the memcached server.

h2. Use multiple memcached instances to separate 'namespaces'

Memcache doesn't use namespaces, so you cannot flush just a part ot it. But running multiple instances of memcached listening to different ports is very easy, and you can use them for different purposes. One for sessions, and one for the application data, for example.

There are three files that need to be replicated and slightly edited:

<pre>

 /etc/init.d/memcached
/usr/share/memcached/scripts/start-memcached
/etc/memcached.conf

</pre>

Make copies of all of them, append a number to the file names, and edit their contents to refer to each other correctly:

<pre>

  1. editions for /etc/init.d/memcached2
  1. Provides: memcached2

DAEMONBOOTSTRAP=/usr/share/memcached/scripts/start-memcached2
NAME=memcached2
DESC=memcached2

  1. editions for /usr/share/memcached/scripts/start-memcached2

my $etcfile = "/etc/memcached2.conf";
my $pidfile = "/var/run/memcached2.pid"
</pre>

Moreover, edit /etc/memcached2.conf to set the instance options:

<pre>

  1. editions for /etc/memcached2.conf

logfile /var/log/memcached2.log

  1. Default connection port is 11211

-p 11212

  1. This is a new line, required only by newer versions that also listen to udp: default udp port is 11211

-U 11212

  1. Sometimes this option -l is set to 127.0.0.1, preventing listening from other servers. Open it:

-l 0.0.0.0
</pre>

Start the new instance, and confirm they are at different ports:

<pre>
/etc/init.d/memcached2 start
netstat -lnp | grep memcached
</pre>

Set it up so that it starts up automatically on boot:

<pre>
update-rc.d memcached2 defaults
</pre>

See http://code.google.com/p/memcached/wiki/NewConfiguringServer#Multiple_Instances

h1. Memcached pool of servers

Memcached just receives requests, doesn't distribute anything. It is the client library that hashes the query and asks to the right server in the pool. Therefore, all servers must have the same identification in all client instances, so that they get the same hash!

We cannot use 'localhost' in one application instance and a full IP address in another, to refer to the same Memcached server, for example.

Also notice that the CakePHP 'prefix' for the cache configuration must be the same in all instances. Beware of using smart prefixes based on the application path!

h1. Memcached and CakePHP

Cake uses a restricted configuration parameter set for Memcached's addServer(), see cake/libs/cache/memcache.php

I'm not use if it uses failure or failover! See http://code.google.com/p/memcached/wiki/NewConfiguringClient#Failure,_or_Failover

h1. How to make web sites fast ?

You can use a cache to store the results of frequent database queries. Memcache is a tool to store this in memory, so that from cakePHP you can simply use things like

<pre>
Cache::write('recentFive', $recentFive, 86400);
</pre>

to store a DB result array $recentFive, and a structure like

<pre>

 if(!$recentFive = Cache::read('recentFive')) {
// Do the DB query here it not cached
}

</pre>

to read it back.

Basic memcache installation steps, summarized:

Details below.

h2. Caching

Visit ibm tutorial about memcache

        http://www.ibm.com/developerworks/opensource/library/os-php-cake5/

h1. What do you need for memcache ?

 apt-get install memcached

This is a manual installation, maybe outdated:

Prerequisite Install

<pre>

  1. Download & install libevent (memcached dependency)

wget http://www.monkey.org/~provos/libevent-1.4.8-stable.tar.gz
tar xfz libevent-1.4.8-stable.tar.gz
cd libevent-1.4.8-stable
./configure && make && sudo make install

  1. Create a symlink to libevent

sudo ln -s /usr/local/lib/libevent-1.4.so.2 /usr/lib

  1. Download & install memcached

wget http://danga.com/memcached/dist/memcached-1.2.6.tar.gz
tar xfz memcached-1.2.6.tar.gz
cd memcached-1.2.6
./configure && make && sudo make install

  1. Run memcached as a daemon (d = daemon, m = memory, u = user, l = IP to listen to, p = port)

memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211
</pre>



 PHP5-Memcache Install


<pre>

  1. Download the extension module

apt-get install php5-memcache

  1. Edit /etc/php5/conf.d/memcache.ini and uncomment the following line by removing the semi-colon

extension=memcache.so

  1. Restart apache

/etc/init.d/apache2 restart
</pre>

Test Installation

Create a file 'memcache_test.php' in your webroot and paste the following:
<pre>
<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

$version = $memcache->getVersion();
echo "Server's version: ".$version."<br/>\n";

$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;

$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/>\n";

$get_result = $memcache->get('key');
echo "Data from the cache:<br/>\n";

var_dump($get_result);
?>
</pre>
That is how to install memcahe in our system.
Caching is disabled by default so we need to enable it before using it so
we need to configure it for cakephp.
You can do that by uncommenting the following
<pre>

   Configure::write('Cache.check',true)

</pre>

 line in app/config/core.php.

and make sure the value is true. That is for making cache works.

    -to make memcache work we need to uncomment the following lines

<pre>

         Cache::config('default', array(
'engine' => 'Memcache', //required?
'duration'=> 3600, //optional?
'probability'=> 100, //optional?
'prefix' => Inflector::slug(APP_DIR) . '_', //optional? prefix every cache file with this string
'servers' => array(
'127.0.0.1:11211' // localhost, default port 11211
), //optional?
'compress' => false, // optional? compress data in Memcache (slower, but uses less memory)
));

</pre>

and comment out

<pre>

    // Cache::config('default', array('engine' => 'File'));

</pre>

in app/config/core.php

http://www.dirnonline.com/release/memcached-for-cakephp/

http://teknoid.wordpress.com/tag/cakephp-memcached/

http://amiworks.co.in/talk/step-by-step-guide-to-install-memcache-on-linux/

http://www.linuxsa.org.au/pipermail/linuxsa/1999-August/008869.html

http://www.php.net/manual/en/memcache.installation.php

http://code.google.com/p/memcached/wiki/NewConfiguringServer

use memcache also for views: http://andy-gale.com/cakephp-view-memcache.html

h1. email

 apt-get install postfix

Configure for 'Satellite system':

<pre>

  1. Contents of /etc/postfix/main.cf
  1. Debian specific: Specifying a file name will cause the first
  2. line of that file to be used as the name. The Debian default
  3. is /etc/mailname.
  4. myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no

  1. appending .domain is the MUA's job.

append_dot_mydomain = no

  1. Uncomment the next line to generate "delayed mail" warnings
  2. delay_warning_time = 4h

readme_directory = no

  1. TLS parameters

smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

  1. See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
  2. information on enabling SSL in the smtp client.

myhostname = www.azavista.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = azavista-production, localhost, localhost.localdomain, localhost
relayhost = 213.222.2.6
mynetworks = 127.0.0.0/8 ::ffff:127.0.0.0?/104 ::1?/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

</pre>

After modifying main.cf, be sure to run '/etc/init.d/postfix reload'.

Test it:
<pre>
mail jose@toltech.nl
Subject: test azavista-test
hi there!
.
Cc:
</pre>

h1. Configure azavista base url

This goes for cron jobs only, to determine which base url it is using for creating links in emails. To configure it you need to add an entry in the config_app/azavista.php with the name of the server as key:

<pre>
$base_url'www.azavista.com'? = "http://azavista.com";
</pre>

h1. Configure database

If you have two servers, one for the website and another to process the queue, you'll need to let one mysql to listen to the other. Edit configuration in web server, where the database is:

 /etc/mysql/my.cnf

comment out

 # bind-address          = 127.0.0.1

and restart

 /etc/init.d/mysql restart

h1. Create database user

http://azavista-test/phpmyadmin/ (http://10.1.0.188/phpmyadmin/)

Go to Home -> Privileges -> Add a new User

Create this user:
<pre>
user: comodo
host: localhost
password: c0m0d0
no database
</pre>
All data and structure privileges

h1. Create databases

All of type uft8_general_ci. Leave emtpy, let the schema populate them.

h1. GPG

Azavista uses GnuPG to encrypt some things. It must be installed in the server. Moreover, a public key for support@azavista.com must be in Apache's keyring for the application to be able to encrypt.

h1. InstallingGPGpublicKey

Azavista uses GnuPG (gpg) to encrypt some things. It must be installed in the server. Moreover, a public key for support@azavista.com must be in Apache's keyring for the application to be able to encrypt.

For Apache, I'm putting the gpg keyring directory at /mnt/data/azavista/.gnupg/, for user www-data. Change this path in the scripts below.

On my dev machine, I put it in /var/www/.gnupg/.

You can find the public key in the svn repository: just update your code and copy it from app/webroot/azavista-pub.gpg to /tmp, for the following instructions to work.

Create Apache's gpg homedir, and import public key:

<pre>
cp azavista-pub.gpg /tmp/
cd /www/var/
sudo mkdir .gnupg
sudo chown www-data:www-data .gnupg
sudo chmod o-rx .gnupg
sudo chmod g-rx .gnupg
sudo su www-data -c "gpg --homedir /var/www/.gnupg/ --import /tmp/azavista-pub.gpg"
</pre>

(This implies that all gpg commands must have the option --homedir /mnt/data/azavista/.gnupg/)

Trust this key, to prevent warning messages when encrypting later (message: "It is NOT certain that the key belongs to the person named in the user ID.")

<pre>
sudo su www-data -c "gpg --homedir /var/www/.gnupg/ --edit-key support"

Command> trust

  5 = I trust ultimately

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
</pre>

Test it:

<pre>
echo "Hello World" > /tmp/test.txt
sudo su www-data -c "gpg --homedir /var/www/.gnupg/ --recipient support --encrypt /tmp/test.txt"
</pre>

Now, acting as support (with my private key installed locally), I can try to decrypt that:

<pre>
gpg --decrypt /tmp/test.txt.gpg
</pre>

Our private key must be installed for that, BUT NEVER ON THE PRODUCTION SERVER!

The command for importing our private key on your local machine is just

<pre>
gpg --allow-secret-key-import --import secret.key
</pre>

I can also put multiple GPG encrypted files named pay*.asc in a directory /tmp/, and decrypt them all with this:

<pre>

 find /tmp/ -name pay\*.asc -exec gpg --batch --passphrase MY_PASSPHRASE_HERE --decrypt {} >> /tmp/decoded.out \;

</pre>

h1. Install Azavista

When checking out from SVN, you'll be asked for user and password. Use for example "jose" and "sinabmtdA".

<pre>
cd /var/www
mkdir azavista_app
cd azavista_app

svn co http://agilo.toltech.nl/svn/azavista/trunk/
svn co http://agilo.toltech.nl/svn/azavista/build/
cp -R trunk azatest

cd /var/www
ln -s azavista_app/trunk azavista

cd /var/www/azavista_app/build
./test_build.sh
</pre>

In a test server, allow apache to serve files in /var/www/build by editing the file .htaccess there, and commenting out the denial. Otherwise Automatic Build And Test? can't run the build.php script in there.

Let apache own the azavista/app/tmp and azavista/archive directories (also in the test installations) so that apache can write on them. Use

<pre>
chown -R www-data:www-data /var/www/azavista/archive
chown -R www-data:www-data /var/www/azavista/app/tmp
</pre>

Changing that ownership for the whole tree is necessary if YOU (and not SVN, which does it indirectly) intend to upgrade azavista using the build.php script from your browser, something that is not done some much recommended anyway.

Notice that the test server installation gets fully installed (including the database schema) when you run the automatic upgrade, but not so the live installation. For that, use the script at /var/www/azavista_app/build/LAUNCH_ME... . Make a copy of it and call it 'azavista_update_db.sh' or so, edit it to adapt it to the database configuration, and run it with the following option (that installs basic user data, including the sysadmin account):

 ./azavista_update_db.sh --drop 1

With an incomplete database, you'll get the following misleading [Cake Php?]] error:

 Error: The requested address '/users/login' was not found on this server.

See [Upgrade Azavista?]] for more details.

h1. Configure Azavista

The installation scripts copy the config_sql, config_test, or confing_andersen to the right places in app/config. If your installation doesn't use that, or changes something, you'll have to review them.

Also review app/config_app/azavista.php, specially the part about the base_url that is passed to cron, for it to generate the correct direct access links.

h1. Root directory redirection

By using a .htaccess:
<pre>
Deny from all
Allow from 95.97.75.122
Allow from 80.101.102.24
Allow from 82.94.228.216
Allow from 82.169.179.97
Allow from 10.1

  1. Allow servers to see themselves

Allow from 10.1.0.70
Allow from 10.1.0.71
Allow from 127.0.0.1

<If Module? mod_rewrite.c>

   Rewrite Engine? on
Rewrite Rule? ^$ azavista/app/webroot/ L?
Rewrite Rule? (.*) azavista/app/webroot/$1 L?
Rewrite Rule? users/(.*)$ azavista/users/$1 L?
Rewrite Rule? dl/(.*)$ azavista/dl/$1 L?
Rewrite Rule? App(.*)$ azavista/App$1 L?
Rewrite Cond? %{SCRIPT_FILENAME} !^.*\/azavista\/.*$
Rewrite Cond? %{SCRIPT_FILENAME} !^.*\/offline\/.*$
Rewrite Cond? %{SCRIPT_FILENAME} !^.*\/piwik\/.*$
Rewrite Rule? (.*) site/$1 L?

</IfModule>
</pre>

h1. Restrict access

Apart from the .htaccess above to limit access, you can also edit /etc/hosts.allow

<pre>

  1. mail.toltech.nl 80.101.102.24
  2. agilo 82.94.228.216
  3. jose 82.169.179.97

ALL: 80.101.102.24, 82.94.228.216, 82.169.179.97, 195.169.147.106, 82.94.228.211, 127.0.0.1, localhost
</pre>

and /etc/hosts.deny:

<pre>
ALL:ALL
</pre>

h2. Dispatcher

<pre>

  1. m h dom mon dow command

</pre>

These are the cronjobs run by root at queue.azavista.com:

<pre>

  1. restart office server at every hour and, inmediatelly after that, resume the queue.

0 * * * * sudo -E -H -u officeserver /var/www/azavista/app/libs/soffice/oooctl.sh restart >> /var/www/azavista/log/cron.log; /var/www/azavista/app/vendors/cakeshell negotiations_handler -cli /usr/bin -console /var/www/azavista/cake/console/ -app /var/www/azavista/app/ >> /var/www/azavista/log/cron.log

  1. do queue stuff - do not do it while the office server is restarting

1-59 * * * * /var/www/azavista/app/vendors/cakeshell negotiations_handler -cli /usr/bin -console /var/www/azavista/cake/console/ -app /var/www/azavista/app/ >> /var/www/azavista/log/cron.log
1-59 * * * * /var/www/azavista_demo/app/vendors/cakeshell negotiations_handler -cli /usr/bin -console /var/www/azavista_demo/cake/console/ -app /var/www/azavista_demo/app/ >> /var/www/azavista_demo/log/cron.log
</pre>

h2. Automatic test run

You have to connect the server with SVN to this one to update and run the tests. See

Root's crontab at the test server:
<pre>

  1. m h dom mon dow command

30 20 * * * /usr/share/salsa2/backup/dump_mysql

  1. See every few minutes if the test server needs an upgrade,
  2. due to a recent SVN commit:

</pre>

If something goes wrong, see the /tmp/post-commit file both in the SVN server (Agilo) and in the test server.

h1. optional

apt-get install php5-dev

Xdebug: pecl install xdebug

h1. Troubleshooting

from Jose Viña <jose@toltech.nl>
to Marek Robert Lipinski <marek@toltech.nl>, Bas Tichelaar <btichelaar@toltech.nl>
date Wed, Jul 28, 2010 at 11:29 AM
subject mail problem

Hi!

FYI: I installed postfix at azavista-test as we used to. Mailing works
from the command line, no problem.

But when the user www-data via a shell script tries to use it, it gets

<pre>

   r1024 => send-mail: fatal: /etc/mailname: cannot open file:

Permission denied

   r1025 => Can't send mail: sendmail process failed with error code 75

</pre>

WARNING: before fixing this, run 'stat /etc/mailname' to see the date of last change.

Indeed, that /etc/mailname file has permissions 600 for root. Not
something I changed, I think it came like that.

I set it to 644, as it is in my toltech-11. I hope it is OK... Any
idea of why this is different now?

h1. Open Office Server?

h2. Installation

To run openoffice in server mode the following packages are needed:

<pre>
apt-get install openoffice.org xvfb
</pre>

Create a user (password: WsHzJRTp96):

 adduser officeserver

<pre>
chmod -R g+w /var/www/azavista/app/tmp
usermod -G www-data officeserver
</pre>

(if officeuser doesn't have permission to write in the destination directory, the phyton script will cause the ERROR! ErrorCodeIOException 283 reported at #3681). (You still get the error despite granting permissions? Remember that it is openoffice, not phyton, the one that writes on that destination. Maybe you need to restart the openoffice server with the right user, with the command below for 'Run script').

To use it with azavista create a directory for conversion:

<pre>
mkdir /var/www/azavista/app/tmp/convert
chmod og+w /var/www/azavista/app/tmp/convert
</pre>

A directory from that user's home should point to azavista's fonts directory, for the PDF generator to use them:

<pre>
sudo su officeserver
cd
ln -s /var/www/azavista/vendors/fonts .fonts
</pre>

h2. Run script

The attached script can start/stop/restart the open office server (it is also in the azavista svn).
To do it as root you need to become officeserver user (cannot use the script as root):
<pre>
sudo -E -H -u officeserver /var/www/azavista/app/libs/soffice/oooctl.sh restart
</pre>

h1. Call Center

The call center application uses PAMI, included in the repository. This, in turn, requires log4php:

Apache log4php has it's own PEAR channel.

To install from the PEAR channel, execute the following commands:
<pre>
pear channel-discover pear.apache.org/log4php
pear install log4php/Apache_log4php
</pre>

h1. Install developers boxes

Apart from the generic ones at [Install Azavista Servers?]] and [Upgrade Azavista?]], these other instructions are interesting for developers:

h2. SVN configuration

Avoid storing unencrypted SVN passwords. To use gnome's keyring instead, edit your ~/.subversion/servers file and add:

<pre>

 auth?
### Set password stores used by Subversion. They should be
### delimited by spaces or commas. The order of values determines
### the order in which password stores are used.
### Valid password stores:
### gnome-keyring (Unix-like systems)
### kwallet (Unix-like systems)
### keychain (Mac OS X)
### windows-cryptoapi (Windows)
password-stores = gnome-keyring , kwallet

</pre>

Then delete any already stored password you may have unencrypted at ~/.subversion/auth/svn.simple/.

After the next SVN operation you will be asked for a password again, but it should not be readable in files in that directory when stored.

h1. For vim users

h2. Exuberant-ctags

 sudo apt-get install exuberant-ctags

This script creates the tags index in the parent directory of the one given as first argument:

<pre>

  1. !/bin/bash

cd $1
exec ctags-exuberant -f $1/../tags \
-h ".php" -R \
--exclude="\.svn" \
--totals=yes \
--tag-relative=yes \
--PHP-kinds=+cf \
--regex-PHP='/abstract class (^?*)/\1/c/' \
--regex-PHP='/interface (^?*)/\1/c/' \
--regex-PHP='/(public |static |abstract |protected |private )+function
(^ (?*)/\2/f/'
</pre>

It scans for PHP files recursively through the given tree, excluding any files found in a .svn directory. (I run this script every hour from cron).

Once the index file is generated (it takes less than a second), all you need to do in vim is tell it to load it in ~/.vimrc:

 set tags=$PATH_TO_TAGS/tags

At this point, you can do all sorts of
fun stuff. Place the cursor on a class name or method name, anywhere
in it, and hit Ctrl-], and you'll jump to the file and line of its
declaration; Ctrl-T then takes you back. If you change the invocation
to Ctrl-W ], it will split the current window and open the declaration
in the new pane.

http://weierophinney.net/matthew/archives/134-exuberant-ctags-with-PHP-in-Vim.html

h1. X Debug

h1. Installing Xdebug in Ubuntu

Installing xdebug:
<pre>
sudo apt-get install php5-xdebug
</pre>

The config file:

<pre>
gedit /etc/php5/apache2/conf.d/xdebug.ini &
</pre>

h2. For profiling

In the config set the following:
<pre>

  1. profiler is enabled

xdebug.profiler_enable = 1

  1. the profiler will create files for each request in this directory

xdebug.profiler_output_dir = /var/www/profiler

  1. this is the filename for the profiling information: %R: reuquest_uri, %U server_id, %t timestamp, %r random number

xdebug.profiler_output_name = cachegrind.out.%R.%U.%t.%r
</pre>

Convenient: If you configure your php.ini with xdebug.profiler_enable = 0 and xdebug.profiler_enable_trigger = 1, you can enable the profiler temporarily by passing a variable like http://localhost/azavista/pages/plannerStart?XDEBUG_PROFILE=1

To process the profiler files, use cachegrind as explained at [Performance Analysis?]].

h2. For debugging

The config file (xdebug.ini or php.ini) file should be further configured as follows:

<pre>
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_host = localhost
</pre>

h2. Alternative installation

To confirm the installation, you can write a PHP page that calls @phpinfo()@, load it in a browser and look for the info on the Xdebug module.

Now you can test for example "code coverage":http://debuggable.com/posts/cakephp-code-coverage-for-group-tests:483b2b77-c420-47e3-b337-653c4834cda3 from the cake's simple test.

php.ini configuration should be in this section:

<pre>
Zend?
zend_extension = /full/path/to/xdebug.so
</pre>

h2. Debugging from vim

To setup vim to use Xdebug, please read http://tech.blog.box.net/2007/06/20/how-to-debug-php-with-vim-and-xdebug-on-linux/

With vim configured properly, go to http://localhost/azavista/?XDEBUG_SESSION_START=1. This will set a cookie in your browser which expires in one hour which tells the PHP XDebug module to try to make a connection every time a page loads to a debugging client which is listening on port 9000. The cool thing is that if it can’t make a connection, it just keeps loading the page, so there’s no issue just leaving the cookie on.

Now go back to vim and press F5. You should see a message like “waiting for a new connection on port 9000 for 5 seconds…” at the bottom of the screen. You have five seconds to now refresh the PHP page. This will create a connection between the debugger and client. Now you’re debugging. Follow the instructions in the Help window to step into, over and out of code. Press F5 to run the code until a breakpoint (which you can set using :Bp).

To get the value of the variable under the cursor, press F12. To go to next step (step into), use F2.

<pre>
In debugging mode (F5):

<F1> : resizing windows
<F2> : step into
<F3> : step over
<F4> : step out

<F6> : stop debugging

<F11> : shows all variables
<F12> : shows variable on current cursor

,e : evalute expression and display result. cursor is automatically move to watch window. type line and just press enter.

command mode (:)
:Bp : toggle breakpoint on current line
:Up : goto upper level of stack
:Dn : goto lower level of stack
</pre>

F6 exists debugging. Extra help is given in one of the debug panels.

For the differences between 'step into', 'step over' and 'step out' see e.g. http://www.developerfusion.com/article/33/debugging/4/.

To switch between panels, use the standard vim way to "change between windows":http://vimdoc.sourceforge.net/htmldoc/windows.html#window-move-cursor: Control+W and the an arrow key to go in certain direction.

h2. Debugging from Eclipse

To use it from within Eclipse, see e.g. http://devzone.zend.com/article/2930.

Please write your experiences here.

h1. Branches

 svn co http://agilo.toltech.nl/svn/azavista/branches/BRANCH_NUMBER
svn copy http://agilo.toltech.nl/svn/azavista/trunk http://agilo.toltech.nl/svn/azavista/branches/BRANCH_NUMBER

To make a branch from a particular revision in the past, just specify it with the -r option:

 svn copy -r REVISION_NUMBER http://agilo.toltech.nl/svn/azavista/trunk http://agilo.toltech.nl/svn/azavista/branches/BRANCH_NUMBER

h3. Merging

The "SVN book":http://svnbook.red-bean.com/en/1.5/svn.branchmerge.advanced.html says: "The term “merge” somehow denotes that branches are combined together, or that there's some sort of mysterious blending of data going on. That's not the case. A better name for the command might have been svn _diff-and-apply_, because that's all that happens: two repository trees are compared, and the differences are applied to a working copy."

So "merging" goes like this:

h4. In practice: merging a branch back into the trunk

Subversion knows which branch changes you've already replicated to your trunk, so it carefully replicates only those changes you don't yet have. After merging, you'll have to test and svn commit the local modifications to your trunk.

Here's the merging procedure, then:

<pre>

  1. Your trunk working copy must be a clean trunk head, with no pending modifications:

$ cd azavista/trunk/app
$ svn update
At revision 1977.

  1. On the same trunk working copy, apply the branch changes:

$ svn merge http://agilo.toltech.nl/svn/azavista/branches/0.1/app

  1. ...examine the diffs, test, etc...

$ svn status

  1. Commit, with a clear description.

$ svn commit -m "Bring last branch 0.1 changes into the trunk."
...
Transmitting file data ...
Committed revision 1978.
</pre>

We put a script in the build directory in the Azavista repository to do the merge safely, that you can run from your trunk working copy root, just by providing the new branch number as argument:

<pre>
cd azavista/trunk/app
../build/svnmerge BRANCH_NUMBER
</pre>

After that, review the merge, and commit.

You can also manually apply the changes of one single changeset:

<pre>
cd azavista/trunk/app
svn merge -c 1971 http://agilo.toltech.nl/svn/azavista/branches/0.1/app
</pre>

The --dry-run option for merge doesn't actually apply any local changes to the working copy. It only shows status codes that would be printed in a real merge.

  1. Running SCP in batch mode

SCP (Secure Co Py?) and SSH in general can be used in batch mode without asking for passwords. That is very convenient for scripts.

Instructions to do so are a little ambiguous in different places . (See some references below). This worked in my case, using OpenSSH both in the server and the client.

Procedure

1. In these instructions, the user name is the same in both machines. Instructions for different user names could differ from these (but see note below!!!)

2. The user keys will be stored in ~/.ssh in both machines.

3. At the client, run:

 ssh-keygen -t dsa

to generate a key pair. Accept default options by pressing return. Specially, do not enter any passphrase. (Option -d seems to be an alias of -t dsa in some platforms).

4. Change the permissions of the generated .pub file to 600 by commanding chmod 600 id_dsa.pub

5. Copy the public key to the server with

 scp id_dsa.pub user@server:~/.ssh/authorized_keys

(Caution: if that destination file already exists on the server, copy first to a different file foo and then append the contents with cat foo >> authorized_keys executed on the server).

6. Done!!! Verify that now you can connect directly from the client with ssh user@server without being prompted for a password or username.

7. If it doesn't work, verify that in the server your home directory, the ~/.ssh subdirectory, and the authorized_keys file do not have writing permissions to others. If they do, they won't be considered to grant access. You can correct this with something like:

 chmod 755 ~ 0
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

8. If it still doesn't work, try changing the authorized_keys file name to authorized_keys2, or ask your system administrator what file name is ssh actually using.

9. If it worked, you can now run SCP in batch mode with the -B option, as in

 scp -B foofile user@server:~/foodir/

Notes

The name of the server must have been registered in the known_hosts. This can be done with a regular (with password) ssh connection, and accepting the host as known. Then, the host name should be the same as the one accepted!!! If you used user@server first, do not use user@server.domain.tk later on!!!

SSH protocol 2 is assumed in this procedure (it uses dsa keys). If your ssh configuration files (at /etc/ssh/) do not establish this as a default, you may have to force it with the -2 option of the ssh and scp. Moreover, if the default public key is not configured to be "id_dsa.pub" you can specify what key to use for identification with the -i option.

The same procedure worked fine when the username was different in both machines. I simply copied userA's public key at the end of userB's authorized_keys file, then I could login from my client as userA with ssh userB@server.

References
http://www.atmos.albany.edu/facstaff/rmctc/ssh2/brandenb-Ssh.html
OpenSSH manual


EditThis! (edited 2013-01-04 22:39) [info] [diff] ♦ Print [help]
Search. Links to this page.
Recent changes, Wiki Front Page, What is this wiki?