Showing posts with label mercurial. Show all posts
Showing posts with label mercurial. Show all posts

20 September 2010

Mercurial on Synology (hg web)



I switched from a single Mercurial repository configuration (cf previous post) to one-per-project-so-multiple-repositories on my Synology.

All my projects would be stored on NAS, located under a specific directory  /volume1/repos , and browsable through internet at http://diskstation/hg

I was using ssh until now but someone suggested an hg web configuration: so, basically we are going to configure the native Apache web server to allow Mercurial transactions *and repositories browsing* via http/https.


This is how i did it, the 'minimal Apache fuss' way, dealing with a dedicated web directory via .htaccess/.htpasswd files: it's far from perfect, security speaking, as it does not follow every Apache recommendations. 
Sorry, but i didn't want to cripple this How-To with too much external considerations.

1) Requirements:
  • being able to telnet into your synology box
  • being able to ipkg packages
  • having mercurial installed
  • having nano installed, or mastering vi
  (cf previous post)

Note:
  • to edit text files, install nano with ipkg install nano
  • if you're editing files into windows through shared directories (using pspad ?) dont forget to save files the unix way (CR). Or Apache will fail @ parsing them.
2) Enable Web Service on Synology:
      Apache web service should now be 'live', and you should have a new 'web' shared directory in /volume1/web or /var/services/web (both paths are identical).

3) Creating a directory of Repositories (with correct credentials):
  • telnet into your diskstation, and type
    mkdir /volume1/repos/hg
    chown -R nobody:users /volume1/repos
  hgweb/apache would have problems to access repos otherwise (Error: abort: HTTP Error 500: Permission denied: .hg/store/lock), as processes are spawned with nobody:users credentials (check this with 'ps', looking at httpd processes group and user).
   could be good to create a shared repos/ directory (via syno control panel).
  • now create a /volume1/repos/hg/test repository, type :
     cd /volume1/repos/hg
     hg init test
     cd test
     nano test.txt (write some and save)
     hg add test.txt
     hg commit -u yourname -m first
  • create a /volume1/web/hg subdirectory
      cd /volume1/web
      mkdir hg
 
4) Time for Script and Config 
  • create a .htaccess file to allow script executions in /volume1/web/hg/.htaccess
    cd /volume1/web/hg (or cd /var/services/web/hg)
    nano .htaccess

    (.htaccess is an Apache config file specifying options for this specific directory
  • insert this:
AddHandler cgi-script .cgi
Options +FollowSymLinks +ExecCGI

AuthUserFile /var/services/web/hg/.htpasswd
AuthName "Protected Access"
AuthType Basic

Require valid-user
  In this directory, Apache is allowed to execute cgi scripts and will protect access with login/passwords. If you don't want a password protected directory, erase all but the two first lines.
  Then, to password access /volume1/web/hg/:
  • create a .htpasswd file in /volume1/web/hg/ to store login info
    cd /volume1/web/hg    

    nano .htpasswd
  now, get and modify the Mercurial web cgi script (into /volume1/web/hg)
  • get mercurial hgweb.cgi from there or via
      cd /volume1/web/hg 
    wget http://www.selenic.com/repo/hg-stable/raw-file/7cf258b2d0cc/hgweb.cgi 
  • rename it into index.cgi
      mv hgweb.cgi index.cgi 
  • flag this python script as executable, and assign credentials (thx anon)
      chmod u+x index.cgi 
      chown -R nobody:users index.cgi
  • create a symbolic link to your favorite python executable: 
      ln /opt/bin/python2.6 /opt/bin/python
  • change /volume1/web/hg/index.cgi first line to: 
     #!/opt/bin/python
  • change in index.cgi (thx Mike):
config = "/var/services/web/hg/hgweb.config"
  • create hgweb config file in /volume1/web/hg/hgweb.config
     nano /volume1/web/hg/hgweb.config
  • write
[collections]
/volume1/repos/hg = /volume1/repos/hg
this config file is parsed by hgweb.cgi (now index.cgi), and will allow it to scan the whole directory to build the repository list. They are other options to play with.
5?) Optionally, error feedbacks from Apache: 
  • edit apache config /usr/syno/apache/conf/httpd.conf-user
      nano /usr/syno/apache/conf/httpd.conf-user
  • to get log informations, change the line
      ErrorLog /dev/null
    into
      ErrorLog /var/log/httpd-error-user.log
  • save and restart apache
      /usr/syno/etc.defaults/rc.d/S97apache-user.sh restart
  • then, to access apache log
     cat /var/log/httpd-error-user.log|more

Final notes: 
  Use the latter two to pull/push changes from/into other repos.
  Mercurial pushes are only allowed through https: it's possible to change this behavior in hgweb.config. Otherwise, dont forget to open your router to port 443 transactions.
  And yes it's working: i'm using it every day :)
  With Redmine. Next post should be totally about RedMine.

References:




25 August 2009

Mercurial on Synology

First telnet, and boostrap to install ipkg, classic (look at this and uses this).

Then ipkg install py26-mercurial (many mercurial flavours in repository btw: one for every major python version).

Now mercurial should be installed somewhere in '/opt/bin' (which redirects to '/volume1/@optware/bin'), type hg -v to check this (or maybe hg-2.6 -v as ipkg apparently let me do the symbolic link: ln /opt/bin/hg /opt/bin/hg-2.6).

You need to have some directory ready to hold a code repository, e.g. '//volume1/repos', executing hg init /volume1/repos/testhg will init/create a mercurial dir with (hidden) management files in it.

We could start working in this, as a shared folder on the network (\\diskstation\repos\testhg), or via http (execute cd /volume1/repos/testhg, and hg serv, it mounts an http server on port 8000, accessible via 'http://192.168.0.X:8000' !), or via ssh (through 'ssh://user@192.168.0.x//volume1/repos/testhg') ! So Nice !

I finally choosed the ssh way, to easily secure transaction.

So, now ssh on synology:

Let's activate the service using the web interface.
Test it using kitty or plink with: plink.exe -ssh -2 root@192.168.0.X "set" should print a lot of variables contents.

But, if we execute plink.exe -ssh -2 root@192.168.0.X "hg": it should fail with ash: hg: not found. When the ssh daemon starts a session, it uses only a subset of the usual user environment, so our PATH variable is missing directories, hence cant find hg.

We might override this by editing (vi) /etc/ssh/sshd_config on the synology, to set PermitUserEnvironment yes.
(to restart the ssh daemon after this, type killall sshd and /usr/syno/etc.defaults/rc.d/S95sshd.sh start)
This script mod triggers the execution of a script $HOME/.ssh/environment for each ssh session creation: let's create such (executable) script with the line PATH=/opt/bin:/opt/sbin:$PATH in it.

Now back to plink: we should now be able to execute hg through ssh.

And... Everything should roll from this point :)

(Once in a while, telnet into your box (putty) and ipkg update and ipkg upgrade)