Showing posts with label technical. Show all posts
Showing posts with label technical. Show all posts

Thursday, August 23, 2012

A NewConfigParser Module for Python


Python standard library contains an excellent ConfigParser module. It allows one to directly read the configuration variables from an INI file, without much ado and overhead. Simple and beautiful. Here is Doug Hellman's PyMOTW blog about the module, for more info.

Now so far as you have a simple requirement of independent configuration variables, you are good to go right away. But if you are used to shell scripting, and are spoilt by variable resolution there (one variable resolving from another previously defined variable, like this - $URL=$PROTOCOL://$DOMAIN:$PORT/), you sure are not satisfied. And if you are spoilt by python's opulence, you sure cannot just let it go and do with whatever is available.

I couldn't either. I had a complex configuration file, and I just couldn't think doing without variable resolution. Here is a subset of what I wanted. I had a common configuration section about a server and different set of URLs which I wanted to fire HTTP requests at (get/post/any such), on the server. Now these domains would be listed in a different 'urls' section, while server details will be listed in the 'server' section. Something like this -
[server]
domain = www.pyarabola.in
port = 80

[request-config]
protocol = http
type = get

[urls]
konkan = ${request-config.protocol}://${sever.domain}:${server.port}/coastal-konkan-day01.html
apple = ${request-config.protocol}://${sever.domain}:${server.port}/applyhypepotatopoteto.html

[requests]
get_konkan = GET ${urls.konkan}
get_apple = GET ${urls.apple}

Note: I know there will be other (better) ways to get the URLs constructed, but this is a made-up example just to make the use-case clear.

The requirement is quite straight-forward - if I want to change the server or port number or the type of request I am making, I dont want to end up changing all [requests].

As you can see, the parameters are constructed by back-referencing other parameters. And the back-referencing is multi-level - one parameter referencing another, which in turn is referencing yet another, and so on, as can be seen for the get_konkan parameter in [requests] section.

As far as I know, the current ConfigParser module (or its ConfigParser.SafeConfigParser class) doesn't allow such referencing in the INI file it parses. Enter NewConfigParser.


NewConfigParser

So I ended up extending the ConfigParser.SafeConfigParser class and overriding its get(...) method to make space for such back-referencing.

Features -
  1. Define-anywhere-use-anywhere freedom, while defining dependent options
  2. This means even if the [requests] section in the above example, is defined at the top of the INI file, before any other parameter definition, it will not complain. This is contrary to the way linux shell variables are resolved. There the used variable must have been defined apriori.

  3. Caching of resolved parameters
  4. A small optimization. It caches any resolved parameters. As a result, if get_konkan request, from above example, is resolved before get_apple request, the NewSafeConfigParser.get("requests", "get_apple") call wont again resolve the same protocol, domain or port. It would directly use it from cache.

  5. Any amount of depth in dependancies (*only limited by global recursion limit)
  6. The parameters' dependancies are resolved recursively. So the depth of dependancies is only limited by python's global recursion limit.

  7. Detection of circular dependancies
  8. All circular dependancies are detected and they result into a CircularDependancyException. It also prints the dependancy graph for you to make hay. Take a look at the circular dependacy example in the Examples section below.

  9. Same usage semantics as SafeConfigParser, i.e. variable resolution is transparant to the user
  10. Since NewSafeConfigParser is extended from SafeConfigParser, the usage semantics are same as SafeConfigParser. You would call a NewSafeConfigParser.get(...) method in the same way you would call a SafeConfigParser.get(...) method. All the referencing and parameter resolution and caching and circular dependancy detection happens behind the closed curtains. User No Bother.

  11. No section means current section
  12. Back-references are to be specified in ${section.parameter} manner for resolution. If no section is specified, e.g. new_param = ${param}, then current section (same as the new_param) is assumed, and the back referenced parameter - param - is resolved in the same section as that of new_param.


Check the Examples section below for more details.


Limitations
  1. Works only for strings as of now
  2. Only SafeConfigParser class extended as of now. Not implemented for ConfigParser.


Code: Where and How

The code is available on GitHub - https://github.com/shreyas/NewConfigParser
I was too lazy to pack it into a legitimate module and post it on PyPI for pip install (it's only a smal tweak really). So it's just a single file (as of now). You might want to copy it into you tools folder and import it as a module to start using it.


License

This was done quite long back, only to realise that I need it quite often. So thought it might be useful to someone else as well. One shouldn't just consume open-source, but contribute to it too. So am releasing it in the public domain under Apache Software License version 2.0.

Do what you want with it, just maintain that copyright notice at the top, despite the (obvious) disclaimer that I wont be responsible if your rocket hits someone's ass instead of the moon just because you resolved its controller config using this parser.


Examples
shreyas@tochukasui:~/devel/python$ python
Python 2.7.3 (default, Aug 1 2012, 05:16:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from NewConfigParser import SafeConfigParser as NewSafeConfigParser
>>> from ConfigParser import SafeConfigParser
>>> newparser = NewSafeConfigParser()
>>> origparser = SafeConfigParser()
>>> newparser.read("config.ini")
['config.ini']
>>> origparser.read("config.ini")
['config.ini']

>>> newparser.get("request", "request_type")
'get'
>>> origparser.get("request", "request_type")
'get'

>>> newparser.get("request", "request");
'get http://pyarabola.blogspot.in'
>>> origparser.get("request", "request");
'${request_type} ${server.url}'

>>> newparser.get("server", "url");
'http://pyarabola.blogspot.in'
>>> origparser.get("server", "url");
'${protocol}://${website}'

>>> origparser.get("server", "protocol");
'http'

>>> origparser.get("server", "website");
'${subdomain}.${host}.${tld}'
>>> newparser.get("server", "website");
'pyarabola.blogspot.in'
>>>


Circular Dependancy Detection
shreyas@tochukasui:~/devel/python$ cat circdep.ini
[humans]
drinking_water = ${govt.pipeline}

[animals]
drinking_water = ${natural.reservoire}

[govt]
pipeline = ${natural.reservoire}

[natural]
reservoire = ${river}
river = ${heavens.rains}

[heavens]
rains = ${clouds}
clouds = ${vapor}
vapor = ${natural.reservoire}

shreyas@tochukasui:~/devel/python$ cat cdep.py
#!/usr/bin/python

import NewConfigParser

p = NewConfigParser.SafeConfigParser()
p.read("circdep.ini")

try:
p.get("humans", "drinking_water")
except Exception as e:
print e

shreyas@tochukasui:~/devel/python$ ./cdep.py
Cicrular dependancy detected while resolving parameter 'natural.reservoire': natural.reservoire -> natural.river -> heavens.rains -> heavens.clouds -> heavens.vapor -> natural.reservoire
shreyas@tochukasui:~/devel/python$

Monday, July 9, 2012

Why People Choose Java over Python



I love Python for the freedom it gives to a developer, and for the way it allows one to concentrate purely on the business logic part of the solution, rather than on the nitty-gritties of the language. Coming over from C/C++ world, it's a breath of fresh air, no matter how much you love C/C++.

Despite all this coolness, this awesomeness of Python, and this black-magic-like problem solving ability that it offers, it's heart-breaking to see the adaptability of this superb language staying much lower than it deserves to be. The industry is still banking on Java for addressing its requirements.

Over some time recently, I have been trying to understand what makes people prefer Java over Python for new development, despite Python being such an excellent choice.

So from whatever little I have understood about the technological landscape so far, here are some points (without any priority as such) that I could put together, as to why java might still be a go-to rather than Python -
  • Java is compiled while Python is interpreted. When you want to deploy a webapp on a third-party web host, with Python you have to deploy all your source on the server, while in case of Java, you deploy compiled bytecode (classes and jars). And though bytecode reverse engineering may not be impossible or uncommon, it just makes access to source-code much more difficult, as compared to Python where you have to deploy production source-code as it is. People are paranoid about exposing their source code.

    CPython / Jython / IronPython might offset this shortcoming to a certain extent, but then this is an added layer, and it might come with its own set of drawbacks, limitations and bugs.

  • A Java webapp, when deployed under an app server like Tomcat, allows request pooling and hence will possibly be more responsive. For a WSGI/mod-python/FCGI hosted Python web-app on the other hand, all requests result in a new fresh invocation of the interpreter and it will be, I suspect, much slower in comparison with a request-pooled instance which can maintain its state.

  • The biggest thing, in my opinion, that goes in favor of java, is the huge ecosystem, of proven tools (development, debugging, profiling, build-management, documentation etc) and frameworks, that has been developed around it over the last decade or so. And 'proven' is really the keyword here.

  • When it comes to language constructs, Python doesnt enfoce anything. It's a come-all-do-all language where even following OOP paradigm is *voluntary*. for exmaple, encapsulation, which is a very important OOP building block, is not enforced. It's voluntary. You can use _underscores_ and __double_underscores__ if you will to specify class variable accesses, but then there is no restriction on their being accessed from outside the class definition - private/protected/public notwithstanding. So chances of a developer making a subtle but critical mistake are much more than say in java.

    Managers, product owners, and anybody for that matter, want to have the peace of mind that the software development process they are overlooking, will have stringent checks in place at the grass root level itself, so that a subtle mistake from an inexperienced developer wont go on wreaking havoc on production.

    Java to a large extent has those checks.Pointers, or rather lack of it, was one of the reasons why it gained acceptance above C++ after all. Java enforces OOP paradigms. It has static typing as opposed to duck-typing or dynamic-typing in Python. Due to enforcement of OOP, it opens up large possibilities for development methodologies, like interfaces and contracts, which, though possible in Python, will be bypass-able, due to its weak OOP support.

Again, to reiterate, I have jotted this down as per my understanding of the technological landscape. I am nowhere near being an expert in either Java or Python, and I do not claim to be one either. So there might be some errors in the way I perceive these things, and if you spot one, please point it out.

With that, I open it up to you guys. I am sure there will be lots of viewpoints as to why Java clicks, since we have such a large experienced Java population here. And there will be counter-points as to why Python clicks despite these points or why some of these points I mentioned aren't valid anymore. So let those viewpoints flow.

Monday, September 21, 2009

Choosing Instant Messaging client for Windows Mobile

Since I have baught my HTC Touch Pro, it's awesome keyboard has opened up a lot of doors for me. Staying online 24x7 through GTalk has been one of them. It's very exciting to be online and accessible always. It helps you keep in touch with your friends. The choice for an appropriate IM client for Windows Mobile, is not a straight-forward one though. You have to first be clear about what to expect from such a client - whether it's chatting or voice calls or file sharing or something else. Then you can go on and select a client. Everyone of available free IM clients on WinMo, has it's own set of shortcomings; so it helps to have your priorities defined in advance.

Anayway, here I present a few (or rather most of the available) winmo IM clients, that I have used recently and the factors that set them apart from each other. I have listed pros and cons of each of them alongwith my personal rating.

I have used/tested these IM apps on my HTC Touch Pro running Windows Mobile 6.1. Though it's a shipped ROM and not a customized one, I have done some performance tweaking using Advanced Config Tool.


Palringo

Website: http://www.palringo.com/en/gb/
Download Link: http://www.palringo.com/en/gb/download/
License Type: Free

Supported Protocols:
MSN Messenger, AIM, Yahoo!, GTalk, ICQ, Jabber, iChat / MobileMe, QQ, Gadu-Gadu, Facebook Chat (Alpha)

Pros
  1. Clean and simple interface
  2. Works in power and data save mode
  3. Location reporting in status (can be disabled if required)
Cons
  1. Requires registration with Palringo
  2. Weird notification - when an instant message arrives, there is sound played, and an icon is displayed in the start bar. but the pop up awkwardly contains two buttons - Open Palringo, Dismiss Message. Instead the message could directly have been reported in the pop up itself.
  3. After opening Palringo following an IM notification, the user is not led to the IM session itself, rather he has to click on Chat to open it. Not very intuitive.
  4. Gtalk voice-calling is not supported. only voice messages can be sent. Real time call is not allowed.
  5. The default sound notification for incoming IM, is very lame. If you want to change it, only a WAV file is supported. It turns out to be a nightmare to find an alert of choice in WAV format. WMA format would have been much nicer to have as all pre-installed windows alerts are in WMA format.
  6. If google or yahoo are the accounts you want to keep logged in, you will compulsory need to stay logged into the Palringo registered account. If you log out of Palringo, you logout of all other configured services. It means at least two IM services need to stay connected, which, I suspect, will result in higher data usage. It will also result in draining the battery.
  7. HTML links sent in IM are not clickable in chat window. You cannot copy them either. Very frustrating.
  8. Uninstallation is not clean. A link remains in startup, which keeps bugging you for missing Palringo executable, on each reboot. The registry entry is not cleaned up either. you have to do it yourself, which is not something that every end user will know how to.
Rating: 5/10


Fring


Website: http://www.fring.com/default.asp
Download Link:
http://www.fring.com/download/
Licence Type: Free

Supported Services:
Skype, MSN Messenger, GTalk, ICQ, SIP, Twitter, Yahoo!, AIM, Facebook

Pros

  1. Supports calling google talk contacts through VoIP
Cons
  1. Major: Fring appends its advertisements below every IM that u send. That's very bad in my opinion.
  2. There is no way to update ur status on fring. Fring 'hardcodes' it to something like 'Online through www.fring.com'. That's bad too.
  3. The interface is very amaturish and crude and contains a lot of annoyances. Hence not ideal for regular use, in my opinion.
Rating: 3/10


Nimbuzz


Website: http://www.nimbuzz.com/en/
Download Link: http://www.nimbuzz.com/en/mobile/download
Licence Type: Free

Supported Protocals:
Skype, MSN, Yahoo!, ICQ, AIM, GTalk and more

Pros

  1. Has a good clean interface.
  2. Supports file/photo transfers.
  3. Supports VoIP chat with google contacts.
  4. Has an interesting Buzz feature. More details here.
Cons
  1. Major: DOESN'T HAVE NOTIFICATIONS!! You are notified only if the application is in the foreground! I totally fail to understand how come the designers/devlopers of Nimbuzz failed to understand the importance of proper notifications. It's like building a Ferrari and not putting in a dashboard inside - just the driving wheel. You can still drive using the driving wheel, but you cannot go and check the petrol every 10-20 mins. It's nasty.
  2. With Nimbuzz, if my Touch Pro's screen is turned off, there is absolutely no notification, neither audio nor visual. Both, IM pings as well as IM voice calls, are not communicated. Frankly speaking, this shortcoming makes this powerful app utterly useless. I cannot stress its importance more. notifications are must-haves not nice-to-haves.
  3. Major: Sometimes you may find that you are logged out without any reason. You never know for how long. It's very irritating.
  4. Requires account registration with Nimbuzz.
  5. HTML link is neither clickable nor the text is selectable in the chat windows.
Rating: 6/10


BeejiveIM

Website: http://www.beejive.com/
Download Link: http://www.beejive.com/download/winmo
Licence Type: Free (beta)

Supported Protocols
:
AIM, iChat / MobileMe, MSN Messenger, Yahoo!, MySpace, GTalk, ICQ, Jabber

Pros
  1. No account registration required.
  2. HTML links are clickable in chat window
  3. Status bar notifications and sound notifs are available for incoming pings and they are good.
  4. Clean interface
  5. Easy to set Status quickly
Cons
  • Doesnt support voice calling
  • Doesnt support file/photo sharing
  • Leaks memory big time.
  • Sometime it can go down and simply refuse to connect. Happened twice to me; out of which, once, I believe, was due to memory leak, and it started working after a soft reboot. The other occasion was this error. But I am back up now after few days of inactivity.
Rating: 8/10


Octrotalk

Website: http://www.octro.com/
Download Link: No direct link, as you have to accept a EULA before the download.
Licence Type
: Paid
Price: $29.95

Supported Services:
GTalk, Jabber, MSN Messenger, AIM, ICQ, Yahoo!

Description

This is one IM app that I used to use on my O2 XDA Orbit, sometime ago. It was in beta that time, and I pretty much liked the functionality it offered, with very good notifications support. Now the IM client app has become paid, and is priced at a steep $30 (keeping in mind the presence of free IM clients).

Features
  1. Supports majority of the protocols
  2. Supports VoIP calls
  3. Support file/photo transfer
  4. Claims to support video calling
  5. Clean and very minimalistic interface
  6. Encrypted IM messaging for Google Talk (using TLS/SSL)

Agile Messenger

Website: http://www.agilemobile.com/
Download Link: http://www.agilemobile.com/download.html
Licence Type: Paid
Price: $44.95

Supported Services:
MSN, Yahoo!, ICQ, AIM, GTalk

Description

While I found this IM client while searching on google, I didn't even give it a thought of testing, when I found out the ghastly price tag of $45!! And still no support for voice calls it seems. It only mentions voice messaging (which is not equivalent to voice calls).

Features
  1. Voice/Video messaging
  2. Photo transfer

A few Others

Below are two more free winmo IM clients that I came across, but found the interface very bad and non-intuitive. I wouldn't like to use them in their current state, hence I haven't reviewed them. The links are included here just in case they turn out to be useful to somebody.

Talkonaut

Website: http://www.talkonaut.com/
Download link: http://www.talkonaut.com/download.shtml
Type: Free

Slick

Website: http://www.lonelycatgames.com/?app=slick
Download Link: http://www.lonelycatgames.com/?app=slick&page=download&platform=windowsmobile
Type: Free


Conclusion


I have tried to capture the plus points and annoyances of each of the IM clients I used. After sometime of use, I have found BeejiveIM to fit my bill, even though it doesnt offer file/photo sharing or voice calling. Everybody has their own needs and expects different features. I hope this comparison helps people find their desired IM client app.

I have tried to be as correct as possible. In case you find any of the above information wrong/mis-interpreted, please let me know; I will verify it and will update this blogpost accordingly.

Technorati Tags: , , , , ,

Friday, April 24, 2009

Connecting to Internet on Ubuntu using GPRS on HTC PDAs

I own an awesome O2 XDA Orbit (base model - HTC P3350) PDA which has kept me satisfied with its features for almost last 2 years. Coupled with a fantastic GPRS plan from Idea (with really good connection speeds, I admit), it was very easy for me to remain connected  24x7. When my laptop had Windows (OEM version that came with my Dell Vostro), the internet connection sharing feature on the PDA allowed me to use GPRS internet on my laptop whenever I visited Sangli. Windows used to automatically configure itself to use this GPRS internet (I didn't like it though, as these things were happening without me knowing any details).

Then came a day when I got frustrated enough with Windows, and destroyed windows (with all its partitions) once and for all, from my laptop, and installed 3-4 different linux flavours instead. That (golden) day was Sunday 8 March 2009.

Since then, I have never missed windows again, but for some exceptions like iTunes, which is just not available on windows (see my previous post about this - iTunes for Ubuntu) or configuring different networking interfaces (like autoconnecting to wireless networks). Connecting to GPRS internet connection provided by my PDA to Ubuntu, had been one such problem that I didn't have a clue about.

The solution, though, turned out to be pretty simple. There are two ways to share Internet Connection from a windows mobile 6 device, like my O2 XDA Orbit -
  1. USB
  2. Bluetooth PAN

USB Connection (RNDIS)


What is needed is an RNDIS (Remove Network Device Interface Specification) driver on Ubuntu.
So get the sources of one such driver, build it and install the kernel module -

shreyas@ghatotkatch:~$ svn co https://synce.svn.sourceforge.net/svnroot/synce/trunk/usb-rndis-lite
shreyas@ghatotkatch:~$ cd usb-rndis-lite
shreyas@ghatotkatch:~/usb-rndis-lite$ make
shreyas@ghatotkatch:~/usb-rndis-lite$ sudo ./clean.sh
shreyas@ghatotkatch:~/usb-rndis-lite$ sudo make install


Then edit the network interface file -

shreyas@ghatotkatch:~/usb-rndis-lite$ sudo emacs /etc/network/interfaces

Add following entries to the interfaces file -

auto rndis0
iface rndis0 inet dhcp


Save the file and restart your network interfaces -

shreyas@ghatotkatch:~/usb-rndis-lite$ sudo /etc/init.d/networking stop
shreyas@ghatotkatch:~/usb-rndis-lite$ sudo /etc/init.d/networking start


That's it. Now on your WM6 PDA, select Start>Programs>Internet Connection Sharing.
I assume you have already configured GPRS on your PDA. So in the Internet Connection Sharing app, select USB as PC-Connection type, and click Connect. Now connect your PDA to the USB port.

The RNDIS connection should be automatically configured and the rndis0 interface should have got an IP address. To check this, run /sbin/ifconfig command, and verify the rndis0 interface.

Reference - http://forums.opensuse.org/1579065-post1.html


Bluetooth PAN

It has been my experience that Bluetooth PAN (Personal Area Network) slows down the internet connection a bit (as compared to connecting to USB) and also eats into the device battery.

Anyway, to configure a Bluetooth PAN on Hardy Heron (8.04), you need to install atleast following packages -

shreyas@ghatotkatch:~$ sudo apt-get install bluez bluez-compat

The network interfaces file will need to be edited -

shreyas@ghatotkatch:~$ sudo emacs /etc/network/interfaces

Add a new interface for our Bluetooth PAN -

auto benp0
iface benp0 inet dhcp


Then add the bnep module to the kernel. This module takes care of the Bluetooth PAN interface. By the way, BNEP stands for Bluetooth Network Encapsulation Protocol.

shreyas@ghatotkatch:~$
sudo modprobe bnep

Now select Bluetooth PAN as PC Connection type in internet connection sharing app on your PDA, and try to find the PDA from your laptop / PC - 

shreyas@ghatotkatch:~$ hcitool scan
Scanning ...
    00:17:E5:3F:BE:E8    hexaM!ner


Use the hex string to connect to the PAN network -

shreyas@ghatotkatch:~$ sudo pand --connect 00:17:E5:3F:BE:E8


That's it. You should be connected, and your bnep0 interface should have got a brand new IP address. You can verify it using /sbin/ifconfig.

Reference: This article on samiux.wordpress.com


Technorati Tags: , , , ,

Sunday, April 12, 2009

VirtualBox VM with Host Interface Setup on Debian Lenny

For sometime now I had been wishing for a debian virtual machine which can talk to the host - another debian or a ubuntu. If you have used VirtualBox on debian/ubuntu before, I am sure you know NAT is the easiest type you can setup in VirtualBox OSE; while Host Interface configuration is probably the toughest to figure out on your own, especially if you are not used to setting up bridges and stuff. But necessity is mother of reasearch, for engineers. So after a day of struggle I have finally got what I wanted. Here I share with you not only the installation of virtualbox ose in a trouble free manner, but also the simplest way host interface can be configured.

Installing virtualbox on ubuntu turned out to be a breeze for me, as I used the VirtualBox package directly from the virtualbox website. On my Debian Lenny 5.0 though, the DVDs installed VirtualBox-OSE v1.6x which is the open-source-edition; and totally inline with the debian tradition and philosophy. Since I am becoming more and more inclined towards this total-GPL thingy, I decided to set up this GPLed virtualbox only, come what may. I hear Virtualbox v2.1 makes things a lot easier though, just in case you wanna try.

To start with, first I installed the virtualbox-ose packages.
mrutyunjay:~$ sudo apt-get install virtualbox-ose virtualbox-ose-modules module-assistant

module-assistant is required for setting up 'vboxdrv' module required by virtualbox.

Once the installation is through, auto-install the vboxdrv module using module-assistant.
mrutyunjay:~$ sudo m-a prepare
mrutyunjay:~$ sudo m-a -f get virtualbox-ose
mrutyunjay:~$ sudo m-a a-i virtualbox-ose
mrutyunjay:~$ sudo modprobe vboxdrv


Add yourself to the 'vboxusers' group (so that virtualbox can access vboxdrv)
mrutyunjay:~$ sudo adduser username vboxusers

Check your 'kernel' argument list in /boot/grub/menu.lst. Just in case it has something like nmi-watchdog in it, remove that portion. (Mine didnt have this). This is to avoid one of the most commonly observed troubles while setting up virtualbox.
Check if 'vboxdrv' module was loaded successfully -
mrutyunjay:~$ dmesg | grep vboxdrv

You should see a success message, like the one below -
[ 1883.765045] vboxdrv: Successfully loaded version 1.6.6_OSE (interface 0x00080000).

If you get the above message, you are done with the first part. Now reboot your system (relogin should do as well).

Host Interface Configuration

For setting up Host Interface, we will need to install bridge-utils package.
mrutyunjay:~$ sudo apt-get install bridge-utils

There are at least two ways to setup the bridge which will enable the host to talk to guest, and vice versa. One is to set a simple bridge definition in /etc/network/interface file. The other is to write setup and cleanup scripts for bridge and TAP interfaces (using VBoxTunctl and brctl); and then run these scripts before and after start-stop of the virtual machine. Out of these, the first approach of modifying the  /etc/network/interface file, is easiest one and gets the job done in short time.

To setup the bridge, first you need to create a permanent TAP interface for virtualbox. Open the /etc/vbox/interfaces file -
mrutyunjay:~$ sudo emacs /etc/vbox/interfaces

Add following definition to it -

vbox0 username br0

Goes without saying that you should replace 'username' with your user name in the above definition.
Here br0 is the name of the bridge that we are going to setup now.

Open the /etc/network/interfaces file for editing.
mrutyunjay:~$ sudo emacs /etc/network/interface

Add following bridge definition to the file -

auto br0
iface br0 inet static
      address 10.0.0.1
      netmask 255.255.255.0
      bridge_ports vbox0


You can customize the IP address and netmask. I have set it up to be static, for simplicity.

Now that we are done with network interface settings, time to restart both the networking interfaces -
mrutyunjay:~$ sudo /etc/init.d/networking restart
mrutyunjay:~$ sudo /etc/init.d/virtualbox-ose restart


Our 'vbox0' TAP interface requires bridge 'br0' defined before it gets attached to the bridge. So make sure you dont alter the order above.
After restarting network interfaces, ensure that our TAP and bridge interfaces are up and running, using /sbin/ifconfig. It should show 'br0' with above entered IP address and 'vbox0' without any IP address.
We enter this TAP interface name (vbox0) in virtualbox network configuration. Set the network to Host Interface and enter vbox0 as interface name and start the virtual machine.

Guest VM Setting (linux flavour)


I had lightweight text-mode debian lenny 5 as my guest VM. So I will explain the network setting accordingly. But for any other linux flavours, network setting should be on these lines only.

Here in the guest VM, you need to setup the networking interface eth0 to be aware of 10.0.0.1 bridge. The bridge is your host machine.
So add following information to your /etc/network/intertface file -

shaunak:~$ sudo emacs /etc/network/interface

iface eth0 inet static
    address 10.0.0.2
    netmask 255.255.255.0
    network 10.0.0.0
    broadcast 10.0.0.255
    gateway 10.0.0.1



And finally, restart networking -
shaunak:~$ sudo /etc/init.d/networking restart

That's it! Now try pinging your bridge 10.0.0.1 from VM and vice versa -

shaunak:~$ ping -c3 10.0.0.1

mrutyunjay:~$ ping -c3 10.0.0.2

If both the pings are successful, YO!, your network is up and running.


Saturday, March 14, 2009

Skype / Ekiga on Ubuntu 8.04 Hardy Heron

As GTalk doesn't support Linux for VoIP communication, I needed some alternative VoIP software, that works well on Ubuntu. There were couple of them Ekiga and Skype.

Ekiga comes pre-installed in Hardy. So I started with Ekiga and registered for a SIP address on ekiga.net. But unfortunately, ekiga failed to communicate with sound hardware on my Dell Vostro 1500 laptop. So I downloaded Skype for Ubuntu. Same story.


So I searched the net, and finally got it working. It turned out that the pulseaudio package was the culprit. Skype and Ekiga both don't work with pulseaudio. They work with esound package. So I decided to remove pulseaudio and install esound instead. Before removing pulseaudio, I disabled PusleAudio Session Management from System->Preferences->Sessions.




And then -

killall pulseaudio
sudo apt-get remove pulseaudio
sudo apt-get install esound

On some setups (probably on intrepid), it might be required to remove a file from /etc/X11/Xsession.d so that the Ubuntu login process doesn’t break.

sudo rm /etc/X11/Xsession.d/70pulseaudio

This is not required on Hardy though; there is no such file in Hardy. I think disabling of PulseAudio Session Management, does the trick instead.

After installing esound, and restarting both skype and Ekiga, though I could hear Ringing, and Sound Outs from Skype, the mic was still not working in test call. Then after playing with the system for sometime I realised that the mic was muted. I had to enable mic boost control from Volumn Control->Edit->Preferences and tick Capture and Capture-1.



And then, when I un-muted the mic, skype worked flawlessly. And after skype, Ekiga also started working when I set Audio In and Audio Out devices to HDA Intel.


Interesting Part

Now, here is the interesting part. After playing around with skype and ekiga for a lot of time, I came to know that I had an uninterruptible process (elisa media player) parented by a python zombie process. I rebooted the system, since there is no other effective way to get rid of these zombies, and elisa was consuming 100% of my CPU2 (at least that's what the system monitor reported).

Ubuntu got stuck during reboot, I am not sure for what reason. So I had to power the system off. When I powered it back up again, I could login and there were no error messages related to pulseaudio. But the UI was totally unresponsive, as if it has hanged. iThen I switched back to command line mode using CTRL-ALT-F5, logged in, removed esound and reinstalled pulseaudio.

sudo apt-get remove esound
sudo apt-get install pulseaudio
sudo reboot


And after reboot, the UI was back to life again. So it was the pulseaudio which caused this freeze. Out of curiosity, I started Skype and made a test call. And to my surprise, both mic and audio playback worked!!! Now this was not expected, as skype initially refused to work with pulseaudio. So did ekiga.

I started the PulseAudio Session Management as well, still Skype and Ekiga worked perfectly.


Conclusion

It seems that, on Hardy, Skype and Ekiga, both work with pulseaudio, and it was probably due to  the zombie process of elisa media player hogging the sound device that caused problems with audio playback and mi, in Skype/Ekiga.

So finally, it seems that, on Ubuntu 8.04 Hardy Heron, you don't need to remove anything or install anything, to get Skype and Ekiga working!!! And this whole post of mine turns out to be a pure waste of time and energy!!!! :(


An Update -

Just in case somebody is interested, there is a very informative post about pulseaudio and how to get it working, on ubuntuforums.org - HOWTO: PulseAudio Fixes & System-wide Equalizer Support


Technorati Tags: , , , , ,

Sunday, March 1, 2009

Setting up Debian APT behind Proxy Server

Setting APT to run behind a proxy server is a pretty easy and quick procedure. Login as root user, and then All you need to do is set http_proxy environment variable in http://username:password@proxy.server.com:port_no/ format.

debian:~# export http_proxy='http://shreyas:myPassword@myproxyserver.co.in:8080/'
debian:~# echo $http_proxy
http://shreyas:myPassword@myproxyserver.co.in:8080/
debian:~# cat /etc/apt/sources.list
#
deb http://ftp.us.debian.org/debian/ etch main
debian:~# apt-get update
Err http://ftp.us.debian.org etch Release.gpg
Could not resolve myproxyserver.co.in
Ign http://ftp.us.debian.org etch Release
Ign http://ftp.us.debian.org etch/main Packages/DiffIndex
Err http://ftp.us.debian.org etch/main Packages
Could not resolve myproxyserver.co.in
Failed to fetch http://ftp.us.debian.org/debian/dists/etch/Release.gpg Could not resolve myproxyserver.co.in
Failed to fetch http://ftp.us.debian.org/debian/dists/etch/main/binary-i386/Packages.gz Could not resolve myproxyserver.co.in
Reading package lists... Done
E: Some index files failed to download, they have been ignored, or old ones used instead.
debian:~#

Here as the proxy server address is fictitious, apt reports an error. But that's not the point really. The point is, if you observe, what apt does with the http_proxy URL is, it separates out the host (in this case, myproxyserver.co.in) from the URL. And how does it do that? Simply by finding '@' sign in the http_proxy URL and then taking the part from '@' to ':'.

This is fine, but only as long as our password is plain alpha-numeric. The moment password contains a special character, like an '@', this whole thing goes for a toss.

debian:~# export http_proxy='http://shreyas:my@Password@myproxyserver.co.in:8080/'
debian:~# echo $http_proxy
http://shreyas:my@Password@myproxyserver.co.in:8080/
debian:~# apt-get update
Err http://ftp.us.debian.org etch Release.gpg
Could not resolve Password@myproxyserver.co.in
Ign http://ftp.us.debian.org etch Release
Ign http://ftp.us.debian.org etch/main Packages/DiffIndex
Err http://ftp.us.debian.org etch/main Packages
Could not resolve Password@myproxyserver.co.in
Failed to fetch http://ftp.us.debian.org/debian/dists/etch/Release.gpg Could not resolve Password@myproxyserver.co.in
Failed to fetch http://ftp.us.debian.org/debian/dists/etch/main/binary-i386/Packages.gz Could not resolve Password@myproxyserver.co.in
Reading package lists... Done
E: Some index files failed to download, they have been ignored, or old ones used instead.
debian:~#

Now if you observe, because of the '@' in password, apt thinks the username is 'shreyas', password is 'my' and the host is 'Password@myproxyserver.co.in'!! Try using escaping the '@' with a '\' and you will still get the same result.

This is the problem I had been facing since last couple of days. Few of the other guys have also reported this problem in other debian and ubuntu forums, and it's around for almost an year now. It has also been filed in Debian Bug Tracking System (BTS) as bug #500560.

Though this might seem as a rare occurrence, passwords with special characters are a norm in password policies of several organizations, as it is with mine. So I had no option but to either say goodbye to Debian, or fix it myself. And given the regard and love I have towards Debian, I had to at least have a go at fixing the bug. Saying goodbye to such a fantastic distro just because of this minor problem would have been very painful.

Bugfix for APT Bug #500560

And the bug is fixed! As I said, what APT used to do was to look for '@' and a ':' just after that to resolve the Host from http_proxy URL.

After the bugfix, now APT supports escape character '\' before '@'s and ':'s, formulates the correct password. For example, if your password contains an '@' character, all you need to do is prefix the '@' with a '\' while exporting the http_proxy environment variable.

debian:~# export http_proxy='http://shreyas:my\@Password@myproxyserver.co.in:8080/'
debian:~# echo $http_proxy
http://shreyas:my\@Password@myproxyserver.co.in:8080/
debian:~#

I have prepared this bugfix patches for both Lenny and Etch distributions. And they are available at my bugfix post.

For ready reference, here are the cross links to the patch files – 

  1. Debian Lenny - Bug #500560 Patch for APT v0.7.20.2

  2. Debian Etch - Bug #500560 Patch for APT v0.6.46.4.1

These patches have been tested on a Debian 'etch' 4.0 r4a distro running on a Dell Vostro 1500 latop (core 2 duo, 2GB).

Please report if you face any issues with the patches.







Thursday, October 2, 2008

The Py-t(h)onic

Few weeks ago, out of sheer curiosity, I started to have a look at this new scripting-cum-object-oriented language capable of doing almost everything that C++ can do, and more. And I can't tell how mesmerized I am with this fantastic language. Thank god, I thought about giving Python a go. A whole new world has opened up for me. Because of the virtuosity of Python, now I am feeling very confident and capable of actually leveraging various ideas that I keep thinking about. Previously, with C++ it was a bit difficult because its core set of functionality is limited, and it's a pain to go searching for good third-party libraries for each and every aspect of desired functionality, may it be text processing, regexes, web-development, xml processing, or simply, connecting to - say - a mySQL database. Count the overhead of typing and thinking so much just for some small (maybe a PoC) snippet, and you subtly lose the all-important enthu to get it going.

With Python, it all becomes very much palpable. The language itself comes with tones of important 'batteries' of functionality, already included. You can do almost everything conceivable with Python, in a very small amount of time, and that too in a concise and goody-goody way in all aspects. Because of this, you tend to spend almost all your time on solutioning, rather than wasting it in that unnecessary wrestling-with-finer-aspects of the base language. If you are a C++ programmer, and have developed a huge liking for the language (like I have), and hence are adamant enough to even think about any other language (like I was), I would strongly recommend you to spend some time with Python. You won't regret it.

Here I don't intend to project Python as an alternative for C++ (haah!) as there will always remain a performance penalty in an interpreted language as compared to a compiled language (which happens to be closer to the system). But it also depends upon how many of our ideas are actually performance-centric. If you think a little performance gain (think quad-core) can be squandered in favor of an impressive line-up of features, Python is for you. Few of the features offered by Python are – very clean syntax, loads of functionality already included in the language, strong support for OOP paradigm, better portability. Python offers an all-in-one development platform which can be used to develop everything right from the lower-level database persistence mechanism to the web-based GUI. All this, in a very graceful way. That's one of its biggest advantages.

As you might already be aware, the new C++0x standard is coming up with a host of 'new' features for C++, like lambda functions, tuples, regex processing, multi-threading support etc. But if one has to compare, for Python, this is not new at all, it is already present in there, and is very easy to put to work. That is again one more advantage in using Python – no overhead involved for using heavy-duty functionality, with minimal error handling requirement. For example, if you want to use a dictionary in Python, all you have to do is –

Mydict = {<key1>:<value1>, <key2>:<value2>}

That's it. As simple as that. Now you can access the dictionary like a dynamic array in C/C++.

What is more, you can pack the punch in you code in a very concise manner, by clubbing a lot of functionality together. Take a look at following code –

While most of the code is easy to read and understand, for those finding it difficult to understand, let me state my intention behind writing this small snippet of code. Generally, in the unix world, most of the utilities expose their (powerful) functionality through command-line-arguments. Hence, processing these command-line-arguments is one of the most basic requirements, we can say, for a unix utility. Now neither C nor C++ offer any help in getting this done quickly. So what entails this requirement, is the head-ache of string processing, multilevel switches, and a lot of error handling. If you have worked in such a situation before, I am sure, you would empathize with me.

Now in that context, have a look at the python code snippet above. The program defines couple of functions to handle different command line args. Then it defines a dictionary with the command-line-arg and its corresponding handler as the key-value pair. After that, there is no switch, no string processing, nothing. All it does is, pass the 1st argument as a key to the dictionary, get the corresponding handler function, and call it. If required, pass on the remaining command-line-args (if any) to the handler function. All of this in one single statement! It is not only quick, it is elegant too, as you can see. If you come back to your code even after few months, you won't get lost in the quagmire of huge amount code that has very little to do with the actual intention of writing that program.

It is this utter simplicity and elegance offered by Python, that hooks you to this language.

I can tell you about one practical example at my workplace, where I could leverage Python to do an important job of analyzing a log file, very effectively, and that too very quickly.

I wanted to analyze a log file, generated by a time-profiler class which I had written to keep a watch on performance gain achieved through various tuning activities. The time-profiler utility logged method-name, number of records processed and the time taken for it all. Now since the number of calls were in the range of around 40K, visual analysis was not on the cards. So I had to write an utility which would find out the first five calls taking maximum amount of time and corresponding number of records processed, for a given method-name.

For this, I required to process the command line to understand which method is to be analyzed. Then I needed to read the log file, find out all the logs from the logfile which correspond to the given method-name and store the records-processed and time-taken figures with a one-to-one relationship. After that, one sort operation would be required to get the first five records, with maximum time-taken figures. After this sort, the one-to-one relation between the number-of-records-processed and time-taken shouldn't be lost at any cost.

Had I have implemented this in C++, I would have wasted a lot of time in writing a lot of code dealing with the nitty-gritty's of above mentioned things. Instead, I decided to give Python a try, even though I wasn't very much familiar with Python back then.

I came up with a working utility in almost half an hour doing everything mentioned above!!!

This became possible because, as I have been stating again and again, Python offers an impressive set of inbuilt functions and modules, which can effectively do away with the need to spend time on the basic needs. For example, I needn't spend much time on things like –

  1. Processing the command-line
  2. File reading and string processing to find out which lines belong to given method name
  3. Storing the time-taken and number-of-records-processed as key-value pairs in a dictionary (didn't require any STL manipulation overheads)
  4. Sorting the keys (time-taken) in descending order (didn't require any operator overloading)
  5. A LOT of error handling at every stage

Everything was intuitive and hence I was able to find out references for desired functionality, very quickly. I didn't need to spend a lot of time into reading the manuals to find the right method for the job, then check for type-compatibility (due to dynamic typing, another 'controversial' feature of Python) etc etc

That was when I realized, how productive one can get with this powerful language. Allowing the user to focus on the solution, rather than the underlying language, is the most celebrated feature of Python. And I would strongly suggest you taste (and test) it once.