Friday, April 13, 2012

Running SQL commands on Sybase from Hudson

This post means to describe the several problems i found when trying to run SQL commands on Sybase from Hudson.

Problem 1: Host key verification failed”
Problem: When trying to SSH to the server which holds the Sybase database I got "Host key verification failed" even thought they keys were correct.
Solution: The missing piece of the puzzle was a row in the ~/.ssh/known_hosts file.
By using another user, which uses the same private/public key, I could run a ssh to the sybase server and get a row in that users known_hosts file. Then I just copied that row to
/var/lib/hudson/.ssh/known_hosts and voila everything worked.
Learn more:
http://amath.colorado.edu/computing/unix/sshknownhosts.html

Problem 2: Shell profile not loaded when running one-line ssh
Problem: The script we need to run on the server needed a lot of magic that was set up by the shell profile scripts. When ssh:ing to the server the profiles scripts are run and everything is dandy. But from Jenkins I need to use one-line ssh commands like this.
ssh user@server "isql < lots_of_stuff.sql" But when running one-line ssh the profile is NOT loaded and and I get a lot of errors since the magic is not set up. Solution: Load the profile in the ssh one-liner before running the real command. ssh user@server ". ./.profile; isql < lots_of_stuff.sql"

Problem 3: Incorrect Locale
After solving the two problems above I was sure everything would work fine, but no, of course it didn't.
Instead of the expected SQL response I got:
The context allocation routine failed when it tried to load localization files!!
One or more following problems may caused the failure

Your sybase home directory is /opt/sybase. Check the environment variable SYBASE if it is not the one you want!
Using locale name "POSIX" defined in environment variable LC_ALL
An error occurred when attempting to allocate localization-related structures.
Locale name "POSIX" doesn't exist in your /opt/sybase/locales/locales.dat file

POSIX? It could make a grown man cry :~(
Solution: Adding -v, for verbose, to the ssh command I could quickly see the difference between what Hudson was doing and what happened when running it from my own machine.
Hudson:
...
debug1: Sending environment.
debug1: Sending env LC_ALL = POSIX
debug1: Sending command: . ./.profile; isql < lots_of_stuff.sql


Locally:
...
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: . ./.profile; isql < lots_of_stuff.sql

No locale is sent from my local machine so I tried overriding it before sending the command in Hudson and it worked.
export LC_ALL=;
ssh sybase@inttestsbn.its.sec.intra '. ./.profile;isql < lots_of_stuff.sql'

And it works!