TunnelBroker IPv6 with the Asus RT-N66U

My latest toy is a Asus RT-N66U Dark Knight router. While it’s ever so nice to have a router that’s configurable via telnet and obviously Linux based, IPv6 is a little harder than on an Airport. This is made messier by their having changed the interface at some point, so it’s all a bit of a kerfuffle.

So, without further ado, here’s a quick guide on configuring the RT-N66U with a Hurricane Internet TunnelBroker IPv6 tunnel on the latest firmware (3.0.0.4.270).

On the IPv6 tab:

Connection Type: Tunnel 6rd
DHCP Option: Disable
IPv6 Prefix: The address part of the Routed /48 address of your tunnel, e.g. 2001:123:abcd::
IPv6 Prefix Length: 48
IPv4 Border Router: The Server IPv4 Address address of your tunnel.
IPv4 Router Mask Length: 24
Tunnel MTU: The default, unless you’ve changed it on the Advanced tab for your tunnel. e.g. on BT Infinity this should be 1472 on both ends.
Tunnel TTL: 255
IPv6 DNS Server 1: Your choice, I favour Google: 2001:4860:4860::8888
Enable Router Advertisement: Enable

If you’re on a dynamic WAN IP address (thanks BT) you’ll also need to set up DynDNS.

On the WAN -> DDNS tab:

Server: TUNNELBROKER.NET
Host Name: The ID of your tunnel, e.g. 12345.
User Name or E-mail Address: Your hex user ID (not your username), from the Main Page on TunnelBroker.
Password: Your TunnelBroker password.

Alternately, you can do it manually whenever it changes via:
curl -4 "https://<username>:<password>@ipv4.tunnelbroker.net/nic/update?hostname=<tunnelid>"

Do note, however: the router leaves IPv6 access open, so you’ll want to either configure rules on ip6tables on the router, or to ensure everything on your LAN is firewalled. Caveat emptor.

Hackintopia

I’ve had my 2009 iMac for a couple of years now. It has served me well for both development and gaming, and I can safely say it is the best computer I’ve ever had the pleasure of owning. But it has grown a touch long in the tooth, and the Radeon 4850 really struggles with the newer games¹. Thus, as the year has progressed I’ve found myself more and more desperate to upgrade. WWDC was awaiting with baited breath, only for the desktop line to be utterly ignored. While I can console myself that MacPro users were left even more in the lurch, it was somewhat of a disappointment.

And so, with iMac updates in the ether, I began investigating Hackintoshes. My few dislikes of the iMac – 4 USB ports, SSDs can’t be retrofitted – would be easily solved, and I’d save money as an aside. Future upgrades would be in my hands, with the downside that the mercurial chap[ette]s at Apple could take it all away at a whim. And all this without the dubious joy of having to return to the Windows fold (or the joys of Unity).

A splash of Google revealed the Hackintosh scene has come a long way since the heady days of the Intel transition. With Gigabyte’s entry into UEFI, you could get a build up and running without even looking at a Bash prompt. Being a machoist, however, I decided to go for the bleedy edge and build an Ivy Bridge system. Apple’s first Ivy Bridge machines were the new MacBooks at WWDC, so driver support is currently based on extracts from packages for these machines. As such, life is slighty – very slighty – harder, although such problems should soon be a thing of the past.

All of the hardware suggestions, installation instructions and troubleshooting advice I’ve used came from the community at TonyMacx86. It’s a one stop shop if you’re mad enough to indulge in such pursuits, and I cannot recommend it enough. I’d have been dead in the water on multiple occasions without such help.

I ended up writing up the build (with an abbreviated version of the trials and tribulations involved) on the TonyMaxx86 forums. This includes all the hardware used and a link to the installation guide. Should your hardware tastes differ, there are plenty of other variations in the same forum.

The end result is that I’m very happy that I’ve gone with the Hackintosh route². While I did suffer nightmares that I’d get niggling issues that would suck my will to live, the only real problem was Corsair’s inability to build CPU coolers, which is being sorted with almost no pain by Amazon (no thanks to Corsair). I’d thoroughly recommend it to anyone wanting a Mac who has experience of building their own boxes – all the flexibility, none of the Windows.

¹ CDProjekt, take a bow.
² As is Polly, as she now has possession of the iMac.

Swinging Clojure

Having played with threading, I thought I’d have a go with Java integration. Swing was the obvious target, and a simple quote fetcher was the result.

For simplicity, I stuck with URLConnection, but there are a number of Clojure libraries to solve the HTTP problem. All of them are somewhat nicer to deal with.

I also completely failed to get apply working with addItem on the ComboBoxes – I’m assuming PEBKAC at present, given my limited knowledge of the integration.

Still, the Swing integration was surprisingly easy to do – I had envisioned nightmares here, given the variation in style, but it proved not half as horrid as expected.

(import
  '(java.net URL URLConnection)
  '(java.io BufferedReader InputStreamReader)
  '(javax.swing JFrame JLabel JTextField JButton JComboBox BorderFactory)
  '(java.awt.event ActionListener)
  '(java.awt GridBagLayout GridBagConstraints Insets)
  )

(def currencies ["EUR" "GBP" "JPY" "USD"])

(defn build-url [from-code to-code]
  (str "http://quote.yahoo.com/d/quotes.csv?s="
    from-code to-code "=X&f=sl1d1t1c1ohgv&e=.csv")
  )

(defn read-file [input-stream]
  (loop [line (.readLine input-stream)
         content []]
    (if (= line nil)
      content
      (recur (.readLine input-stream) (concat content [line]))
      )
    )
  )

(defn get-quote [quote-string]
  (nth (.split quote-string ",") 1))

(defn read-url [url]
  (let [connection (.openConnection (URL. url))]
    (read-file (BufferedReader. (InputStreamReader.
      (.getInputStream connection)))))
  )

(defn set-currencies [combo-box]
  (loop [current (first currencies)
         remainder (rest currencies)]
    (if (not (= nil current))
      (do
        (.addItem combo-box (str current))
        (recur (first remainder) (rest remainder))
        )
      )
    )
  )

(defn quote-fetcher []
  (let [frame (JFrame. "Quote Fetcher")
        button (JButton. "Get Quote")
        from-label (JLabel. "From:")
        from-field (JComboBox.)
        to-label (JLabel. "To:")
        to-field (JComboBox.)
        value-label (JLabel. "Result:")
        value-field (JTextField.)]

    (.addActionListener button
      (proxy [ActionListener] []
        (actionPerformed [e]
          (let [from-code (.getSelectedItem from-field)
                to-code (.getSelectedItem to-field)]
            (.setText value-field
              (get-quote (first (read-url
                (build-url from-code to-code)))))
            )
          )
        )
      )

    (.setEditable value-field false)

    (set-currencies from-field)
    (set-currencies to-field)

    (.setBorder (.getContentPane frame)
      (BorderFactory/createEmptyBorder 10 10 10 10))

    (doto frame
      (.setLayout (GridBagLayout.))
      (.add from-label (GridBagConstraints. 0 0 1 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add from-field (GridBagConstraints. 1 0 1 1 1.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/HORIZONTAL) (Insets. 4 4 4 4) 0 0))
      (.add to-label (GridBagConstraints. 0 1 1 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add to-field (GridBagConstraints. 1 1 1 1 1.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/HORIZONTAL) (Insets. 4 4 4 4) 0 0))
      (.add button (GridBagConstraints. 0 2 2 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add value-label (GridBagConstraints. 0 3 1 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add value-field (GridBagConstraints. 1 3 1 1 1.0 1.0
        (GridBagConstraints/EAST) (GridBagConstraints/HORIZONTAL) (Insets. 4 4 4 4) 0 0))
      (.setSize 300 176)
      (.setVisible true)
      )
    )
  )

(quote-fetcher)

Travels in Clojure

I’m currently reading through Pragmatic’s Seven Languages in Seven Weeks. After every chapter it has a series of small ‘self-study’ tasks. For Clojure, the final of these is the Sleeping Barber problem.

So, mostly for my own reference, I present my solution. If anyone who actually knows Clojure ever reads this, I’d welcome any suggestions.

As for Clojure, I’m still endlessly conflicted on whether Lisp is the most elegant language of them all, or if the endless mass of paranthesis is just syntactic pain. What I am sure of is that I wouldn’t trust many of the programmers I’ve run into with a language of its power. Mind, I don’t trust many of those same with the relatively limited power of Java.

(ns barber)

(def seats (ref (clojure.lang.PersistentQueue/EMPTY)))
(def the-barber (agent 0))

(defn barber [b]
    (dosync
        (if (peek @seats)
            (do
                (alter seats pop)
                (Thread/sleep 20)
                (inc b)
            )
            b
        )
    )
)

(defn enter-shop [customer]
    (dosync 
        (if (< (count @seats) 3)
            (alter seats conj customer)
        )
    )
)

(defn run-barber [milliseconds]
    (do 
        (add-watch seats :send-to-barber 
            (fn [_ _ _ _] (send-off the-barber barber))
        )
        
        (def end-time (+ milliseconds (System/currentTimeMillis)))
        
        (while (< (System/currentTimeMillis) end-time)
            (Thread/sleep (+ 10 (rand-int 20)))
            (send (agent :customer) enter-shop)
        )
        (await the-barber)
        @the-barber
    )
)

(run-barber 10000)

Two Datasources, One Rails Application

Rails has a habit of lulling you into a false sense of security. The ease of use for common tasks makes you wonder why you’re wasting your time with Spring or JEE. Then you try to do something off the common path and watch Rails just shrug its shoulders and grin.

I was working on a community project recently and ran into the requirement to access some static data in another database. Multiple datasources, easy enough. Unfortunately, Rails expects you’ll be sticking with just one, and so I had to go hunting for a solution. Thankfully, I wasn’t the first to hit this and so many people had already done the hard work, leaving me with my piecing together the most elegant solution.

The first thing to do is define your datasource, presumably in database.yml.

legacy_datasource:
  adapter: mysql
  database: legacy_database
  timeout: 5000
  encoding: utf8
  host: localhost
  username: readonly
  enable_call: true
  password: readonly	

You’ll then need to introduce a base class for the models which will use this datasource. It’ll need to be abstract, to avoid declaring any columns and establish a connection to the secondary source.

class LegacyObject < ActiveRecord::Base
  establish_connection :legacy_datasource

  self.abstract_class = true

  def self.columns() @columns ||= []; end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end

end	

Now build the model classes you require, making sure to extend from your new base class.

class AnObject < LegacyObject

  column :object_id, :integer

  # and so on...

end	

If you just require read-only access then you're now done. If you require migration support then a bit more work is needed.

Create a new base class for the migrations that redefines the connection.

class LegacyMigration < ActiveRecord::Migration
  def self.connection
    LegacyDatasource.connection
  end
end	

Now, extend from the new base class and write your migration as normal.

class AMigration < LegacyMigration
  def self.up	
    # ...
  end

  def self.down
    # ...
  end
end	

And you now have a complete solution. Despite the lack of official documentation, it's surprisingly easy to do.

CheckStyle-IDEA: Adopt a project!

As any users have probably noticed, little is happening on this at present bar bug-fixes. This is primarily as I am no longer using it at work and therefore have little inclination to work on it, other than the guilt of support.

Therefore, if you are interested in it and would like a try at either contributing or taking over the project, please drop me a line. I’d hate to see something I know people are using die through my neglect.

In the meantime, 3.0.9 has been uploaded to Jetbrains with some synchronisation fixes. Hopefully this will fix the NPE a few have seen.

2009: A Quick & Dirty Recap

As most have probably noticed, my posting has dropped below its normally abysmal rate into new subterranean depths. Nevertheless, I know some friends & family still occasionally read this in the hope of finding out what I’m up to and so here’s a quick & dirty update as I sip wine and ignore the [rather chilly] outside world.

Firstly – why have I not been posting? Two major reasons: firstly, I’m old enough to recognise my essential insignificance and hence unless I’ve something concrete to pose about there seems little point in blogging; secondly, Twitter fulfils those tiny moments where I need to vent or bitch or even occasionally comment constructively – and forces me to be brief in my expression as well.

And now, on to the meat of the dish. On the personal side, life continues as it inevitably must. Polly & I are still happily ensconced near the Oval, drinking tea and [in my case] complaining about the commute to work. We’re still saving for a house, and given the government’s contempt for those who didn’t get themselves into silly amounts of debt it looks like we’ll be saving for a while yet, while the banks profit from the practically absent interest rates. Although I’m not too bitter – given that my most cynical estimates of our politicians, leaders and the general populace seem to become closer to proven every time one of such opens their mouths, I’m merely having my misanthropy confirmed.

Despite air travel becoming more unpleasant every time the authorities see an excuse to extend their grasp a little we did still manage a couple of trips, the major one being Rome. We almost missed that one – miscalculating our departure times and ending up at Heathrow 30 minutes before the plane took off. However, Alitalia took pity on us and upgraded us to business class, bless them. Rome also turned out to be one of the few places we’ve left and still felt there was more to see and do, although a break was required before we saw any more Roman ruins – look upon my works, ye mighty, and despair.

We also resorted to public transport and indulged my inner-boy, visited Duxford at Cambridge. Not only do they have a mass of planes, but a tank hall as well – what better a place to indulge my inner Peter-Pan? Polly then dragged me up to Northumberland for a week, trekking parts of Hadrian’s wall and even touching on the Lake District. I even managed without Internet for an evening, a feat never (or since) before attempted.

Polly also risked life & limb and had me drive us into deepest darkest Somerset for Ben & Tina’s wedding – very traditional and the first time I’ve been in a church for legit reasons for a long time. Congratulations were combined with catching up with some old friends – and, for that matter, crowning four years in which Ben and I have managed to avoid each other through shear uselessness.

On the work side, Amigo suffered from drifting goals and the business decided to kill it, making us redundant. Worse, this happened after a month’s planning on the subject of escaping Hammersmith and moving to the West End. Still, after a two week break where little was accomplished (and much fun was had) I returned to Signature, rejoining their efforts at world domination via online multi-player gaming, and getting work with grid-based systems as well. So, apart from my still being in Hammersmith I cannot really complain on that front.

I’ve also ended up biking more frequently – between the RMT finding any excuse to strike and the conditions on the Tube during summer it has proved a blessing. And besides, it does wonders for my hips.

On the hobby side, I’ve been struggling with the joys of open source – it’s all very fun creating a project, but support (especially when you end up not using it yourself) soon becomes a horrid drag. And so I’ve ended up being much less productive on that front than I should have, although I hope to learn some Cocoa in the new year as a start at remedying this. Whether I dare release it is another matter entirely.

I’ve also played too much World of Warcraft, although that is now firmly under control thanks to Blizzard, who did their best to destroy the game with their 3.2 patch. In return, however, I’ve picked up EVE and even worse got involved with Goonswarm, and so I have other terrible things to waste my time on. Add to this the superb Dragon Age: Origins, and time becomes a scarce resource.

And so that’s a quick, clean summary of my year. Needless to say, I can’t see updates coming much more frequently in the new year – Flickr and Twitter remain better resources to track me. But hope springs eternal.

Happy New Year to you all!

CheckStyle IDEA 3.0 Release

After a long long wait, I’ve finally bit the bullet and released CheckStyle-IDEA 3.0.

What is it? Integrated real-time and static CheckStyle scanning for IntelliJ IDEA 7 and 8.

What’s new in 3.0?

  • CheckStyle 5.0 support (thanks to jicken)
  • Per-module configuration support
  • Severity filtering on result list.

Please note that you will need to reconfigure the plugin, due to changes in how we store configuration information. Annoying, but it was necessary to support multiple configuration files.

As always, you can find it in the IntelliJ Plugin repository. And please throw any bugs you find into the issue tracker.

Linux love for TeamCity

For far too long we’ve been running our TeamCity build agents on Windows 2003 Server. This was, originally, driven by necessity. We were using Selenium, and out client cared only for a single browser: Internet Explorer. As time progressed we decided Selenium was costing us more than we received from it, so we dropped it. And so we ended up using Windows to build for historical reasons only. And, of course, inertia.

So, over the last day or two, I’ve been building up replacements. Our build box is actually a PowerEdge 1950, split into two machines with the aid of VMWare ESXi. So I hacked together a build agent on VMWare Fusion to use as a template, copied it onto ESX, and set it spinning.

This was the point I got a kick in the arse. We were using Ubuntu 8.10 64bit – and ESX didn’t like it one bit. So I dragged a LCD and keyboard up to the server room and had a nose in the BIOS – sure enough, Dell had left VT off. Bloody Dell. I took advantage of the visit to hack SSH on in ESXi and headed downstairs.

No luck. Same error.

An hour later I stumbled on the solution. The VM had paravirtualisation turned on. Paravirtualisation, apparently, only supports 32bit hosts. Off went paravirtualisation and on went the build server. Win!

So, victory, one less Windows server, and once more a severe wish that VMWare would produce Infratructure Client for either Linux or Mac OS X.

That wasn’t all I learnt of value, however. JetBrains are good enough to tell you how to start TeamCity automatically on Windows (via a server) and the Mac (via launchd) and complete omit Linux. So I went and found out about Upstart.

End solution: create the scripts below in /etc/event.d. They’ll run on startup/shutdown, and can also be started manually using:

sudo start [start|stop]-teamcity-buildagent

/etc/event.d/start-teamcity-buildagent

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5

console output

script
	exec su -l buildagent -c '/opt/build-agent/bin/agent.sh start'
end script

/etc/event.d/stop-teamcity-buildagent

start on shutdown

console output
script
	exec su -l buildagent -c '/opt/build-agent/bin/agent.sh stop'
end script

Building Java 7 on Mac OS X

Update 26/5/9: Updated for last night’s source with the JIBX libraries, and note on the version of XCode.

So, I’ve just got my laptop back after a brief separation. What does one do?

Compile the JDK, of course!

For those unfamiliar with the situation, Apple hate Java developers. Well, one suspects they do. Apple being Apple, one never knows. We could get Java 1.6.0_12 with 32bit support tomorrow, or it could never come. You’ll never know until it appears.

Luckily, Landon Fuller loves us. Which Apple play with their iPhones, he beat the OpenJDK into submission on OS X. Only drawback – Swing is X11 based. But still, it’s JDK6 for 10.4, 10.5 and in both 32 and 64bit, and available as SoyLatte.

This work has all found its way back into the trunk, and so JDK7 is buildable on the Mac (usually). The only catch: the instructions are scattered, and often vary slightly. So I’m documenting them here for tonight’s build, mostly for my reference.

Thanks go to Landon Fuller and Stephen Bannasch for putting these together.

1. Get version 3.1 (or above, presumably) of XCode.

2. Download SoyLatte. I found the JDK7 build Landon released in 2008 did not work as a bootstrap.

3. Get Mercurial

sudo port install mercurial +bash_completion

4. Install the Forest extension

hg clone http://bitbucket.org/pmezard/hgforest-crew

You’ll need to point Mercurial at the hgforest-crew directory, by adding the following to ~/.hgrc:

[extensions]
hgext.forest=/opt/hgforest-crew/forest.py

5. Grab Kurt Miller’s BSD binary plugs:

wget http://www.intricatesoftware.com/distfiles/jdk-7-icedtea-plugs-1.6b.tar.gz

6. Get the JIBX libraries (version 1.1.5) from:

http://sourceforge.net/project/showfiles.php?group_id=69358&package_id=68290

7. Check out the OpenJDK:

hg fclone http://hg.openjdk.java.net/bsd-port/bsd-port

8. Place the following in build.sh in the bsd-port directory (modify as appropriate, depending on where you placed downloaded items):

LC_ALL=C
LANG=C
unset CLASSPATH
unset JAVA_HOME
make \
  ALT_BOOTDIR=/opt/soylatte16-i386-1.0.3/ \
  ALT_BINARY_PLUGS_PATH=/opt/jdk-7-icedtea-plugs \
  ALT_FREETYPE_HEADERS_PATH=/usr/X11R6/include \
  ALT_FREETYPE_LIB_PATH=/usr/X11R6/lib \
  ALT_JIBX_LIBS_PATH=/opt/jibx/lib \
  ALT_CUPS_HEADERS_PATH=/usr/include \
  ANT_HOME=/usr/share/ant \
  NO_DOCS=true \
  HOTSPOT_BUILD_JOBS=2

9. Run, and cross your fingers!

10. I ran into a ld error (archive has no table of contents). Should you hit this, try the following and then rerun build.sh:

ranlib build/bsd-i586/tmp/java/fdlibm/obj/*.a

11. Copy bsd-port/build/bsd-i586/j2sdk-image somewhere useful – and you’re done!