logo

 
Cycling Routes
 
 
blog.rob.sh
Django
Since I've got a few moments, and I've decided to actually write down some rants rather than deciding that I can't be bothered to - I'm going to use some space to single the praises of Django.

I've been using Django for a couple of years now - since around the autumn of 2005, and as such, feel that I've got a pretty good grasp of how the framework works. I haven't really hacked around that much with the innards of Django (although I did propose a patch), however, what I really like about this framework isn't particularly the internals, but just the whole philosophy that there seems to be in terms of building a web application.

Let's face it, when you sit down to write a web application, especially as a sysadmin or a network engineer - your primary motivation isn't to write a web application, your motivation is to get some data out in a very easily readable format to some audience. So, you start looking at how your database should be designed (or retrofitting your code around an existing database), and you start writing code for updating one table, or grabbing data from another. Stop. This is where Django comes in. With Django, you just rapidly develop your data into a set of models, which can be related in a number of different ways - almost everything that you want to do (for generic data handling) can then be done straight from a generic Django view - without you having to go around writing a lot of code for really generic things. It really speeds up web application development.

I love the fact that Django has things like overloadable save(), and delete() methods for each model - it sounds fairly trivial, but it's great to be able to have the application create the ports on a switch when it saves it into the database the first time - and remove them when the user removes the switch. I've found myself able to work on really quite complicated model layouts without getting too tied up in it, because it's just a case of breaking it down simply into models.

I've got a couple of Django based projects that I'm maintaining (hint: you're reading one of them). The other is a portal system for Catalyst2. I've been working on this system for almost 2 years now - it started out as a PHP application, and then morphed into Django when I discovered it. As a PHP app it was just unmanageable, because of the amount of code that I was having to write. Django's inbuilt admin application has let me just worry about actually presenting data to users - and keeping the boring stuff (like adding data to simple database tables) out of the way of the application. It's become a pretty complicated application.

The system tracks ISP assets, things like racks, servers, switches, routers, cabling...the list goes on. For servers it can control APC MasterSwitches via SNMP, it integrates into cacti for network graphs, it can access RANCID SVN repositories to obtain device configurations...I built an SNMP poller that collects traffic data, and produces billing data as both HTML and PDF. I've integrated it with our automated DNS and MX secondary system. The list is pretty huge (hence why this project is almost two years old!).

Before it sounds like I'm just trying to give a list of features that I've written into an application - I'll get to the point. Django and python's flexibility means that I've been able to sit down and write features, I haven't had to sit down and write a lot of generic type functions that add entries to a database, allow them to be updated, and then save them, I haven't had to handle how my site is going to be templated - I've written features. This is the massive difference for me using Django.

Sure, I could get this functionality with just about any framework out there - BUT, Django does this really well - there are very, very few things that you come across and say "Oh, I don't like that" that you can't change. I didn't really like the authentication system that it uses by default - no worries, I can just replace it with an LDAP authentication system for our users, and use the Django one to provide application-specific privileges. Django does things easily, in a sane manner, that you can just code for. What's even better, is it fits in with people like me - who just want to get an application out - but also it fits in with those guys who want to produce just the frontend part of the system - the templating language allows really simple creation of complex pages, without a steep learning curve.

I didn't really plan this entry before I started, but I hope I've got across what I actually wanted to say, Django is a really great framework that's very, very flexible. It's also getting better, they're carefully considering what's added to it, and keeping it so that its very database neutral, and can fit into many, many development styles.

I've written >5,000 lines of just python code in my Django applications, and I'm still finding new and cool things that the framework can do - I really do recommend it for web application RAD!
Tagged in: Code, Tech, Geek, Work
Handy vim tip
I've been working on a number of bits of code recently, and have found that it's not entirely practical to check into RCS or SVN for every change that I've made. I really like to work by committing when I've finished adding a feature to a script, or a project. Hence, I've been using the vim "set backup" option. However, this has some limitations, and hence I decided to have a look at what .vimrc could do for me.

  set backupdir=~/.vimbackup/
  let d = strftime("-%d%m%y-%H%M")
  let d = "set backupext=".d
  execute d
  set backup            
Now I have backup files in ~/.vimbackup/ that reflect the time I started editing the file. This is quite handy if you, like me, :wq! and execute when testing. I'll probably need to write a script to cleanup ~/.vimbackup at some point though!
Tagged in: Geek, Work
Building the RIPEDB server
It took me a few hours over the course of this week to build the RIPE whois server for some internal projects -- given that there seems to be a very limited amount of documentation for the build process, and threads on mailing lists, I'm going to post this here. I hope that it gets picked up by Google.

The first problem that is encountered is that the libtool that is included with the whois server does not support 'modern' tags, such as --tag=CC. This looks to be because the included libtool is somewhat dated. This can be easily fixed by using the system libtool:

[rjs@dbhost whoisserver-nightly]$ mv libtool libtool.old
[rjs@dbhost whoisserver-nightly]$ ln -s `which libtool` .
(NB: after doing this, you should specify --no-all --setup-db --setup-config --install --setup-tests, and _NOT_ --configure, otherwise the existing libtool will just replace the symlink that you've created)

The next problem is that there are a large number of definitions of yywrap() that conflict when they are being linked. On examination, these seem to be of the form:
int yywrap(){
    return 1;
}
There are definitions in:
  • src/modules/rpsl/syntax.c
  • src/modules/rpsl/mnt_routes.lex.c
  • src/modules/rpsl/mnt_routes6.lex.c
  • src/modules/rpsl/mnt_routes_an.lex.c
that conflict with each other. Simply removing the yywrap function that only returns 1 from each of these files resolves this linker issue.

The next problem is that there is a multiple definition of a 'set_dynamic' function -- I believe that this is a function that's used both in the src/modules/pc/pc_commands.c files, and in the MySQL headers.
/usr/lib/mysql/libmysqlclient_r.a(array.o): In function `set_dynamic':
/home/mysqldev/rpm/BUILD/mysql-4.1.22/libmysql_r/array.c:175: multiple definition of `set_dynamic'
/home/rjs/tmp/whoisserver-nightly/src/.././src/librip.a(pc_commands.o):
/home/rjs/tmp/whoisserver-nightly/src/modules/pc/pc_commands.c:509: first defined here
/usr/bin/ld: Warning: size of symbol `set_dynamic' changed from 366 in
/home/rjs/tmp/whoisserver-nightly/src/.././src/librip.a(pc_commands.o) to 203 in
/usr/lib/mysql/libmysqlclient_r.a(array.o)
The first definition (/home/mysqldev/rpm/BUILD/...) is from the RPM package of the shared MySQL libraries. I've tried the compatibility libraries, as well as versions from MySQL 4.1, and MySQL 4.0. The only way I can find to correct this is to change where the include path is from the files that are provided by the MySQL development libraries, to the shared libraries provided by MySQL:
[rjs@dbhost whoisserver-nightly]$ diff Makefile Makefile.orig 
214c214
< MYSQL_LIBS = -L/usr/lib/ -lmysqlclient_r -lz -lcrypt -lnsl -lm
---
> MYSQL_LIBS = -L/usr/lib/mysql -lmysqlclient_r -lz -lcrypt -lnsl -lm
[rjs@dbhost whoisserver-nightly]$ diff src/Makefile src/Makefile.orig 
378c378
< MYSQL_LIBS = -L/usr/lib/ -lmysqlclient_r -lz -lcrypt -lnsl -lm
---
> MYSQL_LIBS = -L/usr/lib/mysql -lmysqlclient_r -lz -lcrypt -lnsl -lm
This then allows the whoisd to compile.

However, when starting the server a number of segmentation faults are experienced:
[rjs@dbhost bin]$ ./whoisd_start --config=rip.config --crashes=1
Starting whois-server daemon with configuration
/home/rjs/whoistmp//conf/rip.config from /home/rjs/whoistmp//bin
./whoisd_start: line 165: 23118 Segmentation fault      (core dumped) $NOHUP_NICENESS $WHOISRIP -p $pid_file -c ${CONFIG} >> $err_log 2>&1
mv: cannot stat `core': No such file or directory
./whoisd_start: line 165: 23145 Segmentation fault      (core dumped) $NOHUP_NICENESS $WHOISRIP -p $pid_file -c ${CONFIG} >> $err_log 2>&1
mv: cannot stat `core': No such file or directory
081008 11:24:36  $WHOISD ended
This is because the MySQL connections do not work correctly out of the box -- what you will need to do is to go to src/SQL/ and create the DB manually:
[rjs@dbhost SQL]$ mysql -utest_db -pPASSWORD test_db < create.tables.sql
[rjs@dbhost SQL]$ mysql -utest_db -pPASSWORD test_db < main.index.1
As long as your $PREFIX/conf/sources.config is correct (correct U/P for the object database, not the admin db), and the rip.conf has the admin DB specified correctly -- then the server should then start.

This was originally going to be an e-mail to ripe-dbm, but I seem to have fixed it during the course of writing the mail!

Tagged in: Tech, Work, ISP, RIPE
I had a bit of a weird problem last night -- when trying to remove BGP from a VRF on a 7600 running 12.2(33)SRC2, I tried:

ar01.tn5(config)#router bgp 65302
ar01.tn5(config-router)#no address-family ipv4 vrf SRC2-TEST
ar01.tn5(config-router)#exit
ar01.tn5(config)#exit

One would expect that this would stop BGP redistributing the VRF routes for the VRF SRC2-TEST. In fact, what happens is that the VRF starts reporting 'debugging-style' messages:
ar01.tn5#sh run vrf SRC2-TEST
Building configuration...

% Topology SRC2-TEST::VPNv4 Unicast::base is currently being deconfigured.
% Topology SRC2-TEST::VPNv4 Unicast::base is currently being deconfigured.
% Topology SRC2-TEST::VPNv4 Unicast::base is currently being deconfigured.
% BGP context has not been initialized properly.
% Topology SRC2-TEST::VPNv4 Unicast::base is currently being deconfigured.
% BGP context not been initialized properly.
% Topology SRC2-TEST::VPNv4 Unicast::base is currently being deconfigured.
% Topology SRC2-TEST::VPNv4 Unicast::base is currently being deconfigured.
Current configuration : 340 bytes
ip vrf SRC2-TEST
 description :c=CORE:x=rjs test for ar01.tn5 issues:
 rd 5413:1020
 export map EXPORT-MAP-SRC2-TEST
 route-target export 5413:1020
 route-target import 5413:1022
!
!
ip route vrf SRC2-TEST 10.0.0.0 255.255.255.0 Null0
!
router bgp 65302
 !
 address-family ipv4 vrf SRC2-TEST
  redistribute static
 exit-address-family
end

And you then can't get rid of the BGP from the VRF. It turns out the fix for this is to remove the VRF itself -- or, rather than removing the address-family itself, remove the contents of the address family. I'm not entirely sure that this is designed behaviour -- and I couldn't seem to find any further results for it. I guess it needs to be put into TAC as another Cisco weird.
Tagged in: Work, Cisco
LINX 65 Presentation
Further to my previous post - I presented this issue at LINX65 - video and slides can be found below.

Video
Fixed Slides - LINX's PowerPoint install seems to have corrupted my slides on the day.




Comments and feedback are most welcome.
A quick personal post to break the silence here!

I'm currently very interested in hearing about any UK or EU-based network engineering or architecture opportunities that are out there, especially in SP networks that run MPLS with TE. If anyone has some such opportunity, or knows of something that they think might suit me -- please drop me a mail to rjs@rob.sh for a copy of my CV.

An outline of my CV is available on LinkedIn.

I'm hoping to find some time to put some technical articles together that can be posted here in the near future.
Tagged in: Tech, Work, ISP
CV Update
I am currently actively interested in new opportunities due to changing circumstances with my current role. I've therefore uploaded a current curriculum vitae to this site.
Tagged in: Work, Me
Error Handling in BGP (Again!)

It looks like, once again, there's another attribute flying around the global BGP table causing Quagga instances to crash (if based on 0.99.9 - I believe the bug is fixed in 0.99.10). This relates to the 2007 draft that introduced AS_PATHLIMIT - see ietf.org - draft-ietf-idr-as-pathlimit. This attribute is actually relatively interesting, from an operator's point of view, where control that is more granular than setting the common no-export or no-advertise communities does not suffice.

As far as I could see, there's only one BGPd that supports this draft (which does appear to have fallen by the wayside in the IDR WG), which is quagga. Whilst looking for this, I found the patch in which this was introduced. Looking at the code, it really reminded me why John Scudder's optional-transitive draft is very useful. If we look at the code in the patch mentioned above:

+  if (flag != BGP_ATTR_FLAG_TRANS)
+    {
+      zlog (peer->log, LOG_ERR, 
+	    "AS-Pathlimit attribute flag isn't transitive %d", flag);
+      bgp_notify_send_with_data (peer, 
+				 BGP_NOTIFY_UPDATE_ERR, 
+				 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
+				 startp, total);
+      return -1;
+    }
+  
+  if (length != 5)
+    {
+      zlog (peer->log, LOG_ERR, 
+	    "AS-Pathlimit length, %u, is not 5", length);
+      bgp_notify_send_with_data (peer, 
+				 BGP_NOTIFY_UPDATE_ERR, 
+				 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
+				 startp, total);
+      return -1;
+    }
Note here that in both these cases, we're checking for errors in AS_PATHLIMIT, that's an optional transitive. This is another "routing metadata" element, or really just a protocol enhancement, but - when an error is found - we're sending a NOTIFICATION message to the other side. Once again, a bug, or incorrect population of this element is going to affect a whole session (which may carry multiple AFIs). I understand that there's no standard, other than NOTIFICATION, available to implementers right now, but this really does seem quite harmful.

I hope that this will be solved as it's pushed through the IDR WG, as usual, operator support for this is useful, as it ensures that vendors, and the WG is well aware of the importance of such a draft!

Tagged in: Code, Work, BGP
UKNOF 16: "Enhancing BGP"
After a late programme committee request, I presented on "Enhancing BGP" at UKNOF 16. The presentation was intended to be an update on the current drafts in the IDR working group, and give some encouragement to operators to get involved, and contribute.

I'll put the video up when the Tom at PortFast and Brandon of Bogons have done their excellent job on it. For the meantime, the slides are linked below.

There's also a good add-paths presentation that John Scudder and Dave Ward gave at NANOG here

Leaving AS5413

For information, and because it means that I have revoked a bunch of UIDs from my GPG Key I am no longer working at AS5413 (Vialtus, Daisy, GX Networks etc.) as of June 18th, 2010. It's been a good two years, but the company direction no longer co-incides with the direction in which I would like to go. I've enjoyed the projects I've worked on, been in contact with a lot of great people, and learnt a lot!

As of Monday, I'll be taking on a IP and Data Network Design Role at Cable & Wireless.

Tagged in: Work, Me, ISP

Tom Bird of PortFast and Brandon Butterworth of Bogons do a great job of webcasting, and recording UKNOF video. Thanks to them, the video of the presentation I gave at UKNOF16 can be watched here. Or you can download it by clicking the image below!

As always, thoughts/comments/corrections most welcome!

This is also probably a good time to mention that my new work mail address is rob.shakir (at) cw.com


rjs@rob.sh sip:rjs@rob.sh
previous posts
contact details
gps logs
 
Fran Buckland [people]
hippy [people]
Andy Davidson [people]
Gem Atkinson [people]
rjs ssh key [tech]
rjs pgp key [tech]
londonfgss [cycling]
Rollapaluza [cycling]
CS Grupetto [cycling]
atom [rob.sh]
notebooks [rob.sh]
admin [rob.sh]
rss [rob.sh]
Stolen Bikes [london]
inhabitat [green]
core77 [design]