Blog

Blog

python virtualenv / global site-packages

If you’re switching from Ubuntu Oneiric to Ubuntu Precise and you’re using python-virtualenv, you might be in for a surprise: The default access to the global site-packages modules is reversed between virtualenv 1.6.x and 1.7. When you were used to finding your apt-get installed python modules like python-mysqldb and python-psycopg2 in your new virtualenv environment, now they’re suddenly unavailable. The culprit: --no-site-packages Ignored (the default). Don´t give access to the global site-packages modules to the virtual environment.

Read more

mysql / replicating repair table

From the MySQL 5.1 manual: 15.4.1.16. Replication and REPAIR TABLE When used on a corrupted or otherwise damaged table, it is possible for the REPAIR TABLE statement to delete rows that cannot be recovered. However, any such modifications of table data performed by this statement are not replicated, which can cause master and slave to lose synchronization. For this reason, in the event that a table on the master becomes damaged and you use REPAIR TABLE to repair it, you should first stop replication (if it is still running) before using REPAIR TABLE, then afterward compare the master’s and slave’s copies of the table and be prepared to correct any discrepancies manually, before restarting replication.

Read more

indirect scp / bypass remote firewall rules

Suppose I’m on machine DESKTOP and I want to copy files from server APPLE to server BANANA. DESKTOP has access to both, but firewalls and/or missing ssh keys prevent direct access between APPLE and BANANA. Regular scp(1) will now fail. It will attempt to do a direct copy and then give up. This is where this indirect scp wrapper (view) comes in: First, it tries to do the direct copy.

Read more

mysql replication / relay log pos

So, hardware trouble caused a VPS to go down. This VPS was running a MySQL server in a slave setup. Not surprisingly, the unclean shutdown broke succesful slaving. There are several possibly causes for slave setup breakage. This time it was the local relay log file (mysqld-relay-bin.xxxx) that was out of sync. SHOW SLAVE STATUS\G looked like this: ... Master_Log_File: mysql-bin.001814 <-- remote/master file (IO thread) Read_Master_Log_Pos: 33453535 <-- remote/master pos (IO thread) Relay_Log_File: mysqld-relay-bin.

Read more

mysql slow / queries / sample

Sometimes you’re in a situation where you know that a database is more heavily loaded than it should be. Time to figure out which queries are stressing it the most. The standard thing to do with a MySQL database would be to enable query logging with general_log_file. Or, to get only slow queries and those not using indexes, the log_slow_queries. But, if this is a mission critical and heavily loaded database, adding expensive logging may be just enough to give it that final push to become overloaded.

Read more

postgres / alter column / look closer

Just now, I tried to convert an integer column in a PostgreSQL database to one of type VARCHAR. I knew you had to do an explicit cast, so I was a bit stumped that I still wasn’t allowed to perform the ALTER TABLE. mydb=> ALTER TABLE mytable ALTER COLUMN mycolumn TYPE VARCHAR(31) USING mycolumn::text; ERROR: operator does not exist: character varying >= integer HINT: No operator matches the given name and argument type(s).

Read more

fixing symptoms / not problems

Some people seem to think that fixing the symptom is fixing the problem. import random def return_one_of(list): return list[random.randint(0, len(list))] def say_something(): try: print return_one_of(["Hello World!", "Hi!", "How you doin'?"]) except: return say_something() say_something() Gah! This is obviously an example, but there are people who do this and claim to have “fixed the problem”. Let me reiterate: the fact that your code does not raise any exceptions does NOT mean that it is not broken code!

Read more

django / mongodb / manage dbshell

The current django-mongodb-engine doesn’t seem to ship with a working manage dbshell command yet. Right now it returns this: $ ./manage.py dbshell ... File "/home/walter/.virtualenvs/myproject/lib/python2.6/site-packages/django/core/management/commands/dbshell.py", line 21, in handle connection.client.runshell() File "/home/walter/.virtualenvs/myproject/lib/python2.6/site-packages/django_mongodb_engine/base.py", line 108, in __getattr__ raise AttributeError(attr) AttributeError: client The fix is simple, patch your django_mongodb_engine with this: --- django_mongodb_engine/base.py.orig 2011-11-15 11:53:47.000000000 +0100 +++ django_mongodb_engine/base.py 2011-11-15 11:54:07.000000000 +0100 @@ -7,6 +7,7 @@ from pymongo.connection import Connection from pymongo.collection import Collection +from .

Read more

certificate verify fail / crt / bundle

So. SSL certificates are still black magic to me. Especially when they cause trouble. Like when one of the sysadmins has forgotten to add the certificate bundle to the apache2 config. Then you get stuff like this: $ hg pull -u abort: error: _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed Most web browsers do not notice this as they already have the intermediate CA files, but /etc/ssl/certs/ca-certificates.crt seemingly doesn’t. The problem in this case was not that I was missing any certificates locally.

Read more

backtrace / without debugger

You may not always have gdb(1) at hand. Here are a couple of other options at your disposal. #1 Use addr2line to get the crash location $ cat badmem.c void function_c() { int *i = (int*)0xdeadbeef; *i = 123; } // <-- line 1 void function_b() { function_c(); } void function_a() { function_b(); } int main() { function_a(); return 0; } $ gcc -g badmem.c -o badmem $ ./badmem Segmentation fault No core dump?

Read more

gdb / backtrace / running process

Sometimes you want a backtrace or a core dump from a process that you do not want to stall. This could concern a multithreaded application of which some threads are still doing important work (like handling customer calls). Firing up gdb would halt the process for as long as you’re getting info, and raising a SIGABRT to get a core dump has the negative side-effect of killing the process. Neither is acceptable in a production environment.

Read more

sip / six digit port number / invalid

While looking through opensips logs of a customer, sometimes we would see the following: ERROR:core:parse_via: invalid port number <110900> ERROR:core:parse_via: <SIP/2.0/UDP 1.2.3.4:110900;branch=z9hG4bKabcdef... ERROR:core:parse_via: parsed so far:<SIP/2.0/UDP 1.2.3.4:110900;branch=z9hG4bKabcdef... ERROR:core:get_hdr_field: bad via As you can see, that 6-digit port number is invalid. Furthermore, when sniffing this traffic, we could see that the port number is almost right. The traffic came from port 11090 (one less zero at the end). Not only the Via header, the Contact header too had the extra appended zero.

Read more

openswan klips install / modules

If you want to be able to sniff your IPsec traffic with OpenSwan, you’ll need to get KLIPS instead of the default NETKEY IPsec protocol stack. Installing that on Ubuntu/Karmic should be a matter of: ~# apt-get install openswan-modules-source ~# cd /usr/src /usr/src# tar jxvf openswan-modules.tar.bz2 /usr/src# cd modules/openswan /usr/src/modules/openswan# make KERNELSRC=/lib/modules/`uname -r`/build module module_install But it’s not. Right now, we’re running the default Linux kernel 2.6.31-23-server on this Karmic machine.

Read more

mocp / random / enqueue

After disk failure on our company music server, I lost my enqueue-some-random-music-script. That shan’t happen again. So here, for my own enjoyment: autoenq.sh #!/bin/sh enqueue_app="mocp -a" music_glob="*.mp3" music_path="`dirname "$0"`" list_path="$music_path/.autoenq.list" if [ "$*" = "-c" ]; then # Create list of all files find . -type f -iname "$music_glob" > "$list_path.tmp" 2>/dev/null # no lost+found # Create list of all dirs that have files cat "$list_path.tmp" | sed -e 's/\/[^\/]*$//' | sort | uniq > "$list_path" exit 0 fi args="`echo "$*" | sed -e "s/['\\\\]//g"`" # no backslashes and single quotes please args="`echo "$args" | sed -e 's/[[:blank:]]\+/.

Read more

asterisk dialplan peculiarities / regex with eqtilde

In the Asterisk PBX dialplan, expressions can be formed using the $[...] syntax. Addition, subtraction, comparison and so on are defined. As is a regex operator: =~ Unfortunately, the documentation about the details of the implementation is hard to find. Here, a breakdown of my findings: static struct val * op_eqtilde is defined in main/ast_expr2.y It uses the REG_EXTENDED flag when calling regcomp: so extended regular expression syntax is used.

Read more

executing remote command / ssh / extra escaping

If you use ssh to run commands remotely, you may have run into the problem that you need an extra layer of escaping. Let’s say you have application myapp that for some reason only runs on host myserver. If you have functional ssh keys to log onto myserver it can be helpful to create a myapp wrapper on your desktop. After all, this: $ myapp myargs … is far more convenient than doing this:

Read more

django / query expression / negate

Suppose you have an is_enabled boolean in your Django model. class Rule(models.Model): is_enabled = models.BooleanField(blank=True) # other exciting fields here And now imagine you want to negate the is_enabled values. Something you would easily do in SQL, with: UPDATE myapp_rule SET is_enabled = NOT is_enabled; The Django F-syntax is nice, and looks like it should be up for the task. Let’s sum up a couple of attempts: Rule.objects.update(is_enabled=(not F('is_enabled'))) No! You get this:

Read more

mysql issue warnings / cron

I’ve previously written about MySQL pain in the behind issues involving views with SECURITY DEFINER and bad client collation selection. For the former problem, I wrote a script that you could call periodically to warn you of potential problems with your views. Now I’ve extended it to warn you about collation issues as well. Put warn-mysql-issues.sh (view) in your cron tab and run it periodically. It’ll save you from production-time errors that you get when attempting to compare a string of one collation with another.

Read more

linux / canon mf8350 / printer driver

Getting printer drivers for the Canon MF8350 to work under Ubuntu is a big pain in the behind. (Installation using custom scripts that abuse both /usr/lib and /usr/local/lib and ultimately fail to compile for obscure reasons.) My colleague found that the easiest way to get it to work, was converting the RPM to DEB using alien(1). For your enjoyment, here are the two debian packages needed for Ubuntu 10.04 (amd64):

Read more

diff / memory exhausted / udiff

Sometimes when I’m unsure what a button in a database-driven application does, I simply click it and check the differences in the database before and after the click. If the database dumped is (somewhat) sorted and with one line per row (for MySQL use –skip-extended-insert), this can be an easy method of verifying that your application action does exactly what you expect and nothing more. Create a pre.sql before the click, click the button and watch the action happen.

Read more

pcap / capture fragments / udp

When dealing with internet protocols that operate on top of UDP, fragmenting suddenly becomes a lot less uncommon. Normally, you would only encounter fragments on TCP connections when the MTU on the sending host is larger then the MTU in any of the next hops. Hosts usually attempt to avoid fragmentation for obvious reasons. (Inefficiëncy, extra reassembly work.) For connectionless UDP packets this is a different matter. Protocols over UDP expect packets to be single entities.

Read more

no sql security definer / please

Have you ever had it happen that you removed a MySQL user and suddently parts of your application stopped working? Not because you removed the user that was connecting, but because you removed the user that defined the particular view or function that you were using. I have, and it was quite stressful ;-) We moved a slave machine to a different IP, I updated the mysql.user host column, and BAM, the application running on the master mysql stopped working.

Read more

build error / unixodbc / debian-squeeze

Building unixodbc-2.2.14p2 on debian/squeeze which you just fetched through apt-get source unixodbc. ~/src/unixodbc-2.2.14p2$ ./configure ... works fine ... ~/src/unixodbc-2.2.14p2$ make ... make[1]: Entering directory `/home/walter/src/unixodbc-2.2.14p2/odbcinst' make[1]: *** No rule to make target `libltdl/libltdlc.la', needed by `libodbcinst.la'. Stop. make[1]: Leaving directory `/home/walter/src/unixodbc-2.2.14p2/odbcinst' make: *** [install-recursive] Error 1 The fix: add top_build_prefix to the environment. ~/src/unixodbc-2.2.14p2$ top_build_prefix=`pwd`/ make ... success!

Read more

asterisk / nat keepalive / round robin dns

Current Asterisk (telephony software) version 1.6.2.x (and probably 1.4 and 1.8), has an odd quirk with the qualify option. The qualify option enables a function that checks the response times of the SIP peer. By default, it sends an OPTIONS SIP packet every 60 seconds. The quirk here, is that it sends the packet to the first A-record resolved for this peers hostname at startup (or sip reload). This works fine in most cases when the host has only one A-record.

Read more

pruning old data / mysql / csv

It is not uncommon to have a database with records that just accumulate and accumulate over time. Think of log files, telephony billing records, traffic data and so forth. The chances that you’ll ever need this data again are very slim. And letting your database grow indefinitely is not particularly smart. Time to prune! Two things you need to worry about while pruning your data: Throwing it all away without a backup doesn’t feel right.

Read more