configuring tomcat6 for https with cargo

cargo is a nifty tool for launching containers from, say, ant. While it doesn’t contain official support for Tomcat6, the Tomcat5 support works just fine with Tomcat6.

There is a property, cargo.protocol, where you can specify https, however, the resulting server.xml that it generates will not be quite correct. A hack-fix is to edit org/codehaus/cargo/container/internal/resources/tomcat5x/server.xml in the jar file to include «SSLEnabled=”true”». As well, you might want to add the appropriate attributes for the relevant keyfile-path, otherwise, it seemed to use $(HOME)/.keystore, which I was happy to provide.

Champlain Valley water analysis, Spring 2008

As a South Burlington homeowner (water-bill-payer, really), the Champlain Water District sends me a report about how their water is the best water. Of note to me as a homebrewer is the analysis of certain chemical properties of the water. Since a few google searches for this information basically turned up my previous post and not the actual source of the data, here’s the data:

  • aluminum: < 0.06ppm
  • color: 2 units
  • alkalinity: 57-74 ppm as CaCO3
  • calcium hardness: 45-56 ppm as CaCO3
  • total hardness: 61 ppm as CaCO3
  • chloride: 17ppm
  • foaming agents: < 0.1 ppm
  • total organic carbon: 2.04 pm (1.49-2.61)
  • conductivity: 192 micro-S/cm (156-194)
  • pH: 7.62 (7.39-7.79)

  • total disolved solids: 113 ppm

  • iron: < 0.01ppm
  • manganese: .007ppm
  • sodium: 7.5ppm
  • potassium: 1.31 ppm
  • sulfate: 15 ppm
  • silver: < 0.05ppm
  • silica: 1.4ppm
  • silicon: 0.67 ppm
  • bromide: < 0.010 ppm
  • iodide: < 1 ppm
  • flouride: 1.01 ppm (0.74 - 1.28)
  • ammonium ion: 0.15 ppm (0.01 - 0.32)

Champlain Valley water anlysis, 2007

Since the previous water analysis from 2005, I’ve since bought a house, which means the Champlain Water District sends me a report about how their water is the best water. Of note to me as a homebrewer is the analysis of certain chemical properties of the water. Since a few google searches for this information basically turned up my previous post and not the actual source of the data, here’s the data:

  • aluminum: < 0.06ppm
  • color: 2 units
  • alkalinity: 42-56 ppm as CaCO3
  • calcium hardness: 45-56 ppm as CaCO3
  • total hardness: 61 ppm as CaCO3
  • chloride: 17ppm
  • foaming agents: < 0.1 ppm
  • total organic carbon: 2.22 pm (1.60-3.1)
  • conductivity: 189 micro-S/cm (163-208)
  • pH: 7.56 (7.29 - 7.89)
  • total disolved solids: 113 ppm
  • iron: < 0.01ppm
  • manganese: .007ppm
  • sodium: 7.5ppm
  • potassium: 1.31 ppm
  • sulfate: 15 ppm
  • silver: < 0.05ppm
  • silica: 1.4ppm
  • silicon: 0.67 ppm
  • bromide: < 0.010 ppm
  • iodide: < 1 ppm
  • flouride: 0.97 ppm (0.71 - 1.21)
  • ammonium ion: 0.20 ppm (0.04 - 0.048)

java array iteration

Java5 now has language support for iteration of the form:

for (Type var : someIterable) { ... }

As well, there is now an Iterable<t> interface, and Arrays are directly iterable, allowing you to write:

String[] thingys = {"a","b","c"};
for (String thingy : thingys) { ... }

At work, we have a collection of utility iterators, most written before these were available. As such, we have an ArrayIter utility, and a ZipIterator, inspired by Python’s itertools.izip.

I’ve been going through these classes and their usages on a lazy basis to update them to the new syntax. I finally got around to a usage of the ZipIterator, which happened to compose an ArrayIter … it zipped together an array of String names with the results of a test.

So, I changed it to:

String[] names = { "foo", "bar", "baz" };
List results;
for (Object[] pair : new ZipIterator(names, results))
{
// ...

No dice, says Java:

/home/jsled/stuff/work/[...]TestMumble.java:46: cannot find symbol
symbol  : constructor ZipIterator(java.lang.String[],java.util.List)
location: class com.spokesoftware.util.iterator.ZipIterator
for (Object pairObj : new ZipIterator(data, results))

WTF? Okay, let me help you out:

for (Object[] pair : new ZipIterator((Iterable)names, results))
// ...

FUCK YOU, says Java:

/home/jsled/stuff/work/[...]/TestMumble.java:46: inconvertible types
found   : java.lang.String[]
required: java.lang.Iterable
for (Object pairObj : new ZipIterator((Iterable)data, results))

It turns out that the string “iter” isn’t even in the text of the section about Arrays in the Java Language Spec. Array instances aren’t Iterable. They’re a special case in the handling of the for-each loop syntax.

This code ended up as:

for (Object pair : new ZipIterator(Arrays.asList(names), results))

Java is totally shitrude.

rstiki-1.1

Felix Wiemann of docutils was kind enough to write and point out that docutils doesn’t protect against various kinds of malicious markup and content inclusion. He notes that there are a couple of options to prevent such inclusion.

While I don’t intend to use rstiki on a public-facing web server, others might, and docutils makes it very easy to disable such inclusion. So, it does by default, now.

rstiki-1.1 also sports a new link to the rST quickref.

rstiki - minimalist wiki using reStructuredText

I used to use phpwiki for a personal, behind-the-firewall wiki. It was simple, though it was many files, and gentoo packaged it. Then, there was a version upgrade that required a database and lost all my (handful of) content. I switched to pwyky because it was a single file, simple, and SBP wrote it. But its syntax doesn’t support nested lists, and it’s not reStructuredText.

rstiki is a minimalist single-file CGI wiki, in python, which uses docutils to render reStructuredText markup.

wish (x10dev) 2.1.5 ebuild

I got frustrated last week and fixed the wish-2.1.3 ebuild to install the /dev/x10 nodes into /lib/udev/devices/. It was relatively hard to find this out, but when traditional mknod-created nodes are in this directory, they’ll be copied into the otherwise-dynamic /dev tree at boot time. As such, wish finally boots cleanly.

In the course of trying to track down other system lockups, I upgraded to the 2.6.18 kernel, and wish-2.1.3 stopped building for me. A devfs header file that it used was finally deprecated out of the module-building header directory. Luckily, in the mean time, wish-2.1.5 was released without this dependence on devfs. I re-generated the patches, and updated the bug to be an ebuild for wish-2.1.5, a.k.a. x10dev.

Org-mode (vs. planner-mode)

Yesterday I switched from using planner-mode to using Org-Mode, both emacs note-tasking and todo-task management apps. I’ve been using planner-mode for the last year and a half, and rely on it pretty extensively to track upcoming todo items, in both personal and work contexts.

I’ve read in the last couple of months, however, that Org-Mode is already in emacs-cvs, and will be part of the standard distribution of emacs-22. I decided to try it out, was quickly impressed, and transitioned over.

Both support the same basic data model: files of mixed notes and todo-items, where the items are simply specially-formatted lines in the file. Items have an optional due date and an optional priority (ABC). For example, in planner-mode, they appear:

A _ Write up planner-/org-mode post (2006.11.24)

B X Make faux-chicken dinner for Thanksgiving (2006.11.23)

For Org-mode:

** TODO [#A] Write up planner-/org-mode post SCHEDULED: <2006-11-24> ** DONE Make faux-chicken dinner for Thanksgiving SCHEDULED: <2006-11-23> CLOSED: [2006-11-23 Thu]

Both support the same basic execution flow: when requested, the package looks through the special files to find lines that fit the pattern, and constructs another file (planner) or a transient view (Org) over past-due and presently-due items. There are operations for creating items, scheduling them on a particular date, transitioning them closed, jumping from the item to associated notes, &c. As well, both support some form of unidirectional publishing of the content to HTML, ostensibly to serve as some public project-planning status.

Org-mode, I’ve discovered, goes far beyond planner-mode in terms of features.

  • Core
  • It is based on outliner-mode, and its documents are inherently foldable, hierarchical documents.
  • It uses file extension (”.org”) for mode-selection, so planning document can live next-to or within projects.

  • Todo

  • There’s a bit more latitude where items can be placed in the notes documents.
  • It supports — separately from the scheduled to-do time for a task — a deadline, which is brought up differently in the “now” view.
  • Overdue items are indicated more clearly.
  • Items can be scheduled for a range of time.
  • Items can be tagged arbitrarily and searched/viewed by tags (”WORK”, “STORE”, “@LAPTOP”, …)
  • Supports progress logging
  • Supports hierarchical sub-tasks (yay!)

  • Linking

  • Explicit linking rather than CamelCase (though CamelCase is an option), which was the major problem I was having with planner-mode (it starts to become really slow for large documents).
  • Patterned links (”bugs:1234″, “http://bugs/show_bug.cgi?id=%s” → “[…]?id=1234″) are supported.

  • Other

  • Has a table/spreadsheet editor. The table-editing part appears similar to table.el, but the spreadsheet functionality is just pure awesome.

Update Mon 2006-11-27: after being contacted by Carten Dominik, the author of org-mode, I’ve revised the comment at the end about the table/spreadsheet editor.

Oscar handler

Were you the Telepathy project, what would you name your Oscar protocol handler subproject? Why, Wilde, of course. Yuck yuck yuck.

creating many graph instances in cacti

cacti_db.py is a script which will clone an existing data-template and graph-template for multiple (host,rrd_file,template) instances.

In the scenario it was created for, data is (externally) collected into a (directory) tree of RRD files. While there are only a handful of unique RRD file and graph types, there are a large number of instances of those templates. Good examples of this are:

  • cpu load
  • 1,5,15 minute averages
  • 1 per machine
  • disk util
  • avail, used, free
  • ~5 per machine
  • cache stats
  • (hit, miss, size) stats
  • 2 .. 20 caches/”node”, depending type.

This collected data might exist in the following tree of RRD files:

/servers/hostA/cpu.rrd /servers/hostA/disk/root.rrd /servers/hostA/disk/usr.rrd /servers/hostA/disk/data/logs.rrd /node/nodeA/cache/foo.rrd /node/nodeA/cache/bar.rrd […15 more caches…]

Cacti has the following templates manually configured:

/servers//cpu /servers//disk /node/*/_cache

The script, then, knows how to relate RRD files of the regex pattern r'''/servers/([^/]+)/cpu''' to the template(s) “/servers/*/cpu”, using the regexp group 1 as the name of the host; edit the ‘rrd_types‘ global to suit your scenario.

Instances are named as their RRD file name (yes, skipping Cacti’s own |template_formatting|).

The script will delete instances with the same name, allowing you to re-run it pretty liberally to pick up new rrd files, changes in templates, &c.

The process of cloning is as follows; see ‘execute_plan_alpha(...)‘ in the script for the gory details.

  • find the host in table ‘host‘.
  • data template instantiation
  • find the data template id (by name) in ‘data_template‘.
  • if an instance with the name already exists: delete it.
  • insert into data_local, get new (autoinc) id for the instance.
  • get the list of rrd DSes from the template (from ‘data_template_rrd‘)
  • copy each, maintaining the instance -> template id map.
  • instantiate the data_template itself (’data_template_data‘)
  • copy the RRAs as well (’data_template_data_rra‘)
  • graph instantiation
  • get the graph_template_id (by name) from ‘graph_templates
  • insert into ‘graph_local‘, get autoinc id.
  • instantiate graph (’graph_template‘).
  • copy ‘graph_instance_item’s, as this is where the graph-ds/rrd-ds mapping is stored, run the relevant ids through the map retained earlier.

For details on Cacti 0.8’s rather atrocious database schema, see Cacti Forums: Database schema… WTF? and Cacti Forums: Cacti data relationship diagram.