Setting up Windows 2003 as an NTP Client

Published on Tuesday, April 29, 2008

I have had to search for the commands to setup a Windows 2003 box as an ntp client a few times now, so have decided to finally write them down here for my own good measure. Funny thing is, I'm pretty sure there are three ways to setup a 2003 box as an ntp client.

1) Via the CLI



Open up the cmd prompt and type in:

w32tm /config /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" 
/syncfromflags:MANUAL /reliable:YES /update


2) Via the CLI, option 2



net time setsntp: "0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org"


3) Via GUI



Type in gpedit.msc and your local GPO editor will pop up. Go to the folder as indicated in the below screenshot and Enable the "Enable Windows NTP Client" option. Next set the "Configure Windows NTP Client" option to whatever time servers you so choose. As always, make sure to keep the 0x1 at the end.

Event vs. DOM Driven Parsing of XML

Published on

I recently have been playing with parsing GPX files and spitting out the results into a special KML file. I initially wrote a parser using minidom, yet after running this the first time -- and my Core2Duo laptop reaching 100% utilization for 10 seconds -- I realized I needed to re-write it using something else.

I spent a little time reading the different parsers for XML and eventually read more about cElementTree. And it is included with Python2.5, sweet.

I quickly rewrote the code and did some tests. First, the two bits of code for parsing my GPX file:

minidom-speed.py

#!/usr/bin/python

from xml.dom import minidom
from genshi.template import TemplateLoader

def collect_info():
dom = minidom.parse('airport.gpx')
for node in dom.getElementsByTagName('trkpt'):
lat = node.getAttribute('lat')
lon = node.getAttribute('lon')
speed = node.getElementsByTagName('speed')[0].firstChild.data
speed = float(speed) * 10
coords = '%s,%s' % (lon, lat)
coords_speed = '%s,%s' % (coords, speed)
yield {
'coordinates': coords_speed
}

loader = TemplateLoader(['.'])
template = loader.load('template-speed.kml')
stream = template.generate(collection=collect_info())

f = open('minidom.kml', 'w')
f.write(stream.render())


cet-speed.py

#!/usr/bin/python

import sys,os
import xml.etree.cElementTree as ET
import string
from genshi.template import TemplateLoader

def collect_info():
mainNS=string.Template("{http://www.topografix.com/GPX/1/0}$tag")

wptTag=mainNS.substitute(tag="trkpt")
nameTag=mainNS.substitute(tag="speed")

et=ET.parse(open("airport.gpx"))
for wpt in et.findall("//"+wptTag):
wptinfo=[]
wptinfo.append(wpt.get("lon"))
wptinfo.append(wpt.get("lat"))
wptinfo.append(str(float(wpt.findtext(nameTag)) * 10))
coords_speed = ",".join(wptinfo)
yield {
'coordinates': coords_speed,
}

loader = TemplateLoader(['.'])
template = loader.load('template-speed.kml')
stream = template.generate(collection=collect_info())

f = open('cet.kml', 'w')
f.write(stream.render())


The speed difference is not just noticeable, but very noticeable.

minidom-speed.py

$ python -m cProfile minidom-speed.py
4405376 function calls (3787047 primitive calls) in 32.142 CPU seconds


cet-speed.py

$ python -m cProfile cet-speed.py
1082061 function calls (904167 primitive calls) in 6.736 CPU seconds


A quarter as many calls and almost 5x faster -- at least that's how I interpret the results. Much better!

Another Baby Step

Published on

I showed a few of my co-workers my graph and one replied -- oh! that's really cool. (I think only two of my co-workers are actually interested in my geekyness). He then emailed me tonight a .kmz file containing a colorized file of his speed. I looked at the kml and noticed it appeared to be dynamically allocated judging by the top speed. Well, as you could guess, I surely had to modify my code to include colors.

Within an hour I had a semi-working example, and within two hours will easily be done with this blog post. The code might not be perfect, but it first parses the xml and returns the max speed for the trip. Next, it colorizes the speeds based on a scale of 0-255, with 0 being blue for fast and 255 for being yellow, or slow. I was going to study for the CCNA tonight, but it looks like writing Python is just too much fun.





So what, you might ask, are those dips? Good question. They are huge speed bumps (and the tall blue mound in the middle is a really steep hill).



Setting up a Mapnik Server on Ubuntu

Published on Sunday, April 27, 2008

First, we go ahead and install the needed packages. I've tried to include "my" list of packages that were needed to get a vanilla 7.10 image up to steam.

apt-get install build-essential libltdl3-dev autoconf libtool automake \
postgresql postgresql-8.2-postgis postgresql-server-dev-8.2 \
wget subversion libboost-python1.34.1 libboost-thread-dev \
libboost-program-options-dev libboost-regex-dev \
libboost-python-dev libboost-serialization-dev \
libboost-filesystem-dev libpng12-dev libjpeg62-dev \
libtiff4-dev zlib1g-dev libfreetype6-dev libgeos-dev \
unzip apache2-prefork-dev


Next we start to download a few components. I did this in my home directory, /home/kelvin

mod_tile - this is the apache module and rendering daemon that uses mapnik to render the maps.

svn co http://svn.openstreetmap.org/applications/utils/mod_tile

Mapnik - this will help us create the maps.

wget http://download.berlios.de/mapnik/mapnik_src-0.5.1.tar.gz


Now we start to install things.

tar -xpzf mapnik_src-0.5.1.tar.gz
cd mapnik-0.5.1


Build mapnik as per: http://wiki.openstreetmap.org/index.php/Mapnik -- make sure to use scons as follows:

python scons/scons.py PYTHON=/usr/bin/python \
PGSQL_INCLUDES=/usr/include/postgresql \
PGSQL_LIBS=/usr/lib/postgresql BOOST_INCLUDES=/usr/include/boost BOOST_LIBS=/usr/lib


Now, I'm temporarily serving/rendering my tiles from an old Thinkpad "server" (PIII with 512MB RAM, of which only 128MB goes to the Xen instance that hosts all of this). So, I am using osm2pgsql on my laptop (a new Thinkpad), and pushing it into the postgres database on my "server". So, I built osm2pgsql on my new Thinkpad, and setup postgres on the "server" to accept connections from my new Thinkpad.

pg_hba.conf -- Set these lines should be added, assuming your computer is 192.168.10.100:

host    all     all     192.168.10.100/32  trust

Then I do the actual import, assuming my "server" has an IP of 192.168.10.10:

./osm2pgsql -H 192.168.10.10 -U username -l -m -d gis -W /home/location/to/osm/australia.osm


Make sure generate_image works before installing mod_tile!

Install mod_tile as per the modifications needed: http://www.kelvinism.com/howtos/notes-installing-mod_tile-mapnik/

And the end result? http://tiles.kelvinism.com (remember, on a seven year old Thinkpad!)

Baby Steps at Graphing Traffic

Published on

You can likely tell that I've been having some fun with graphing and mapping recently. I was reading a few articles about GIS and stumbled upon a pretty darn cool project at Webopticon, which included cool pictures. I showed it to my girlfriend thinking she would find it interesting, and then realized: oh! KML has an altitude attribute. That could be interesting.
One of my projects is to create maps of Sydney's traffic, so I have been experimenting heavily with Mapnik and OSM. I figured I could have some fun and finally parse some gps tracks and display the data.


I first started off trying to play around with the KML files my gps logger natively stores. After a while I realized it shouldn't be this hard to parse the XML, and realized it also stores data in gpx format. I opened up one of the gpx files and immediately saw how much easier it would be to work with. I quickly created a parser for the xml in Python (using the dom method, yet I think I'm going to rewrite it using sax), and then with the aid of an article by Sean Gillies, converted the needed objects into KML. I used the speed attribute (with some magnification) as the altitude, and voila, a pretty picture.
This picture is as Victoria Road crosses James Rouse Drive -- a spot that is always congested in the morning.
I'll likely post some code shortly, I would like to rewrite the parsing section to use something event-driven -- hopefully it will be a little faster.

Redirecting Fun with Lightty

Published on Wednesday, April 23, 2008

Two of my colleagues were having just a little bit too much fun with my blog, so I decided to have some fun back. Over a period of 10 minutes, they managed to leave 10+ comments. Luckily I have full control over my server, and was able to quickly create my practical joke.

$HTTP["remoteip"] == "123.45.678.910" {
url.redirect = (
"^/(.*)" => "http://www.urbandictionary.com/define.php?term=annoying+fuck",
"" => "http://www.urbandictionary.com/define.php?term=annoying+fuck",
"/" => "http://www.urbandictionary.com/define.php?term=annoying+fuck"
)
}

Notes on Installing mod_tile for Mapnik

Published on Tuesday, April 22, 2008

I have no idea if these notes on how to install mod_tile will be useful for anybody. The current readme states that you need to edit the source code, but never actually where. Well, this is where, at least until the code can either take switches or can auto-configure itself. This is quite brief, so if you need more details, shoot me an email or leave a comment. I have repeated this process on two Ubuntu 7.10 machines.

1) Install mapnik as per normal -- you may also need to do a...

$ ./bootstrap
$ ./autogen.sh
$ ./configure
$ make
# make install


2) Install libagg (apt-get install libagg-dev)

3) Make sure the mapnik library files are /usr/local/lib (libmapnik.*)

4) Make sure to copy/install fonts and input folders into /usr/local/lib/mapnik

5) Edit Makefile, change line 27 to where your include files are located

RENDER_CPPFLAGS += -I/usr/local/include/mapnik


6) Edit Makefile, change line 33 to where your mapnik libraries are (libmapnik.*)

RENDER_LDFLAGS += -lmapnik -L/usr/local/lib


7) Edit Line 40 of gen_tile.cpp to point to your osm.xml file (that you can verify works with generate_image.py)

static const char *mapfile = "/home/kelvin/mapnik-osm/osm.xml";


8) Edit line 219 of gen_tile.cpp to point to the correct location of the datasource input.

datasource_cache::instance()->register_datasources("/usr/local/lib/mapnik/input");


9) Edit line 221 of gen_tile.cpp to point to the correct location of your fonts directory.

load_fonts("/usr/local/lib/mapnik/fonts", 0);

10) The module will install in /usr/lib/apache2/modules, so mod_tile.conf should read:

LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so

Final note: I think it would be possible to just symlink the lib directory to lib64, although I would expect that could have some undesirable outcomes down the road. However, despite being pretty new code, how do I find mod_tile? Pretty good, actually. I expected more difficulties setting it up, but overall the procedure hasn't been too bad. I like the approach of creating a module vs. using several middle-layers. So once again, hats off to the OSM crew.

ethX Issues with Xen and Ubuntu

Published on Sunday, April 20, 2008

My new guest VMs under Xen seem to be having issues where upon each reboot, the network interface gets incremented by 1. For instance, it starts at eth0, then goes to eth1, then eth2, and eventually ethX. There are two issues to fix: 1) get the count back to 0, and 2) stop it from counting again.

I was able to get them to decrease by looking in the /etc/udev/rules.d/70-persistent-net.rules file and removing all entries.

Next, I was able to prevent this by simply inserting a MAC address to the interface in the configuration. For instance, one of my domU's has this entry:

vif         = [ 'mac=00:D0:59:83:DC:B5,bridge=xenbr0' ]


Lastly, I made sure (as I would with any server) to create an entry in the /etc/network/interfaces file.

auto eth0
iface eth0 inet static
address 192.168.1.16
gateway 192.168.1.1
netmask 255.255.255.0


Works like a charm.

Installing Mapnik on Ubuntu 7.10

Published on Saturday, April 19, 2008

I have managed to install mapnik 0.4, 0.5, 0.5.1 and various SVN releases in-between on Ubuntu. While this isn't in itself exciting, I think I manage to stumble at every installation. I typically forget to add the flags when building, so, to prevent myself from stumbling again, I'm going to write them out here.

Build mapnik

$ python scons/scons.py PYTHON=/usr/bin/python \ 

PGSQL_INCLUDES=/usr/include/postgresql \

PGSQL_LIBS=/usr/lib/postgresql BOOST_INCLUDES=/usr/include/boost BOOST_LIBS=/usr/lib





Then install it
$ sudo python scons/scons.py install PYTHON=/usr/bin/python \ 

PGSQL_INCLUDES=/usr/include/postgresql \

PGSQL_LIBS=/usr/lib/postgresql BOOST_INCLUDES=/usr/include/boost BOOST_LIBS=/usr/lib


Then proceed as normal.