tail -f findings.out

Checking options with optparse callbacks

optparse is a flexible and powerful module for processing command line options in Python programs. I’ve used it for a while, but I didn’t have much occasion to get into callbacks until recently. A callback here is a user-defined function optparse calls when its associated option is encountered. They can help you keep your script’s logic clear within a forest of options by providing arbitrary checks when particular options are passed.

When I first began using them, I ran into a critical point of confusion that wasn’t clearly illuminated in the assorted guides I found for optparse. In response, here is a short overview of how to use callbacks to perform checks and validations against passed options.

First, a very basic script using optparse for option parsing:

1
2
3
4
5
6
7
import optparse
parser = optparse.OptionParser()
parser.add_option("-f", "--input-file", dest="inputfile",
                  help="The file with input")
(options, arguments) = parser.parse_args()

print options

Which outputs:

1
2
python test.py -f test.txt
{'inputfile': 'test.txt'}

For a more detailed coverage of the basics, review Doug Hellman’s PyMOTW article on optparse. It would be best to verify that this input file exists so that we might inform the user and exit early. Adding that functionality to our example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import optparse
import os

def check_file(option, opt, value, parser):
    if not os.path.exists(value):
        raise optparse.OptionValueError("%s doesn't seem to exist." % value)
    parser.values.inputfile = value

parser = optparse.OptionParser()
parser.add_option("-f", "--input-file", dest="inputfile",
                  action="callback", callback=check_file,
                  type="string", help="The file with input")
(options, arguments) = parser.parse_args()

print options

We’ve added a check_file() function to perform our check and also added the callback specification to the associated option. The arguments a callback function is passed are described in the module documentation. optparse.OptionValueError provides an elegant way to send an error message about the problem and quit the program in one step.

So what’s the problem? When I first wrote a callback, I didn’t catch the line in the tutorial examples that set the value of the option. I still don’t understand why this is necessary, but without the “parser.values.inputfile = value” line above, you’d find the inputfile variable to have None for its value. Strange, but true. I could understand the callback function having to return the option value if all was well, but why would the option’s value get unset in the first place?

Additionally, it turns out you have to set the option’s type even if the desired value is supposed to be default. In the above example, without ‘type=”string”‘, the callback function would have thrown an error, complaining that we were claiming to use a string and weren’t.

So watch out for these details, and clean up your scripts with callbacks.

Tags: , ,
August 16, 2009 - 12:44 AM No Comments

Using a Juniper SSL VPN on Ubuntu

Juniper’s SSL-based VPNs are wonderfully easy to use. Windows and OS X users simply sign into the VPN website, click Connect, install the Java-based app (if it’s the first time) and are good to go. On the Linux side, it seems Juniper didn’t quite expend the effort to make it so easy. I’ve heard it works fine on RPM-based distros, but it doesn’t work on Ubuntu without some preparation. The steps below are what I needed to do to get it working. This tutorial got me part of the way, so if you run into issues you might want to check it out.

Here’s what I had to do the first time:

  • Set up the Sun Java Runtime Environment and configure the system to use it. This guide explains how to do this.
  • Set up the Firefox Java plugin. You’ve probably already done this, but check this page if not.
  • Ubuntu doesn’t have a password on the root account or enable it by default. However, the install will ask for root’s password. Your sudo password will not work, as the install script dumbly switches to the root user. So set it beforehand (”sudo passwd root”) and remember it.

At this point I was able to login to the VPN site, click Connect, and complete the install. After the app installs, if all goes well, you should see something like this:

vpn

[EDIT, 2010-01-23: Commenter Jld9za helpfully reports that on Ubuntu 9.10 the following DNS and continual re-install issues aren't encountered. If you are on 9.10 or later you should be good at this point. If not, keep reading.]

Once I was connected, I could sign into things over the VPN by IP but not by name. This was due to the VPN install adding an entry to /etc/resolv.conf after my current nameserver entry. This was /etc/resolv.conf before connecting to the VPN:

1
2
3
4
# Generated by NetworkManager
domain home
search home
nameserver 192.168.1.1

And after:

1
2
3
search home MYCOOLDOMAIN.loc
nameserver 192.168.1.1
nameserver 10.175.211.10

Once I switched the VPN entry to be first, all worked fine:

1
2
3
search home MYCOOLDOMAIN.loc
nameserver 10.175.211.10
nameserver 192.168.1.1

You have to remember to switch the nameserver order in /etc/resolv.conf every time you connect. This is fairly annoying, but haven’t I found a way around it yet.

There one other problem with this setup. You have to put in the root password every time you connect, because it claims it has to reinstall a service each time. This is the popup that appears after hitting connect every time after the initial install:

vpn-reinstall

Taking a look inside the script referenced (~/.juniper_networks/network_connect/installNC.sh):

1
2
3
4
5
6
if [ -e "$1/ncsvc" ]
then
    echo "Service needs to be reinstalled."
else
    echo "Service needs to be installed for the first time."
fi

After I installed the client for the first time, ~/.juniper_networks/network_connect/ncsvc did exist. This is what prompts the re-install each time. I’m not sure why they have to initialize this every single time. I thought I could get around it by changing installNC.sh, but it gets recreated every time you click Connect. So currently you have to type in your root password for each connection.

Tags: , , ,
August 2, 2009 - 11:41 AM Comments (3)

Twitter links powered by Tweet This v1.6.1, a WordPress plugin for Twitter.