Search Results: "cas"

2 January 2009

Michael Casadevall: Notes from Underground, Part 1

For those following d-devel, you may notice that I've recently been working on improving one of the cornerstones of Debian infrastructure; the Debian Archive Kit, or dak for short. Most DDs and DMs don't notice dak exists expect when trying to determine why their latest upload was rejected, and then yelling at the powers that be. I'm here to shead some light on this mythicial beast.

First off, a quick history lesson:

dak (also known as projectb) is a replacement for Debian's original archive software, known simply as dinstall. dinstall itself was a fairly large perl script that does what dak process-unchecked/process-accepted does today. James Troup did a fairly decent summary of dinstall, and its issues

James Troup's README.new-incoming (from dak's git repo):

The old system:
---------------
o incoming was a world writable directory

o incoming was available to everyone through http://incoming.debian.org/

o incoming was processed once a day by dinstall

o uploads in incoming had to have been there > 24 hours before they
were REJECTed. If they were processed before that and had
problems they were SKIPped (with no notification to the maintainer
and/or uploader).

dak's first commits were in 2000, and rolled out onto ftp-master.d.o sometime in 2001 or 2002 (I can't find an exact date for this). Since then, dak is also used on security.d.o, and on backports.org (fun fact for bpo people; the dak installation there is now up to date, and tracking git's tip).

So now that you know the history lesson, what specificially does dak do is the next question. Simply put, dak is the glue that binds the rest of the Debian's backends together; both britney and wanna-build/buildd depend on it. It handles management of uploads to the archive, handles stable release updates, as so forth. It is also the only Debian archive software that uses an actual database backend, and scales fairly well handling over 10,000 packages, and 12 architectures. Unfortunately, there are also a lot of issues with dak as it stands.

Sections of the code base have bitrotted over the years; legacy and legacy-mixed support have died, the import-archive function is shot (more so now than ever, see below), the test suite is non-functional (never a good sign), the docs are out of date, and in many places non-existant, doing a release (both point and full) requires editing the database and so forth.

In addition, dak, while written in python, is written in a fairly procedural style, and and some very ugly code in some places. For instance, the original Debian Maintainer code was handled by having the uid's in the database prefixed by dm: vs having a flag somewhere, and had some hardcoded variables like checking for "unstable", as well as quite a few bugs which caused interesting behavior when uploading to a non-unstable suite such as experimental or one of the proposed queues. (for those of curious, I recommend checking the dak git tree to see what the old DM code looked like, and then aside from the design, find the two major bugs which caused a lot of the weirdness with DMs). It should be stated that the last merge from redid the DM code and design sanely using the new update framework.

These issues have lead to the genesis of the dak v2 project, which is an attempt to replace dak with a module, rewritten from the ground up to be more secure and modular, although its not gotten very far as of writing. I personally don't believe that the current iteration of dak is so bad as scrapping and rewritting is necessary. Instead, I've been working to implement v2 features in dak by aggressive refactoring and cleanup, with the hope of negating the need for a rewrite.

So now thats out of the way, I bet you probably are interested in my .plan for dak. Well, lets go over I've implemented so far.

* An update database framework for dak, which will allow for easy database upgrade and migration, vs the "does it work yet?" approach to applying schema updates. Simply type dak update-db, and your done!

* 822 formatted output for queues (http://ftp-master.debian.org/new.822); this information is now used on DDPO pages

* Rewriting DM management code to have more of a brain than the previous implementation.

What's next on the TODO list

* Content file generation from the database (part of removal of apt-ftparchive, but thats another blog post ;-)).

Oh, as a side note to my current readers, my blog has changed names to "Notes from Underground", after one of my favorite novels, and futher in reference to exploring the mysterious underground that is Debian's backend code. We're also now on Planet Debian :-).

1 January 2009

Jeff Bailey: Launchpad email noise finally crushed!

Launchpad's email handling is awful. Truly awful. I left a pile of teams I was on to reduce the noise, and vaguely considered leaving the core-dev team so that I would never have to see another "merge request" come through that I couldn't possibly ever care about.

But I have solved the problem!

I remembered that my email can cope with jbailey+FOO@raspberryginger.com and still delivery it, giving me something to filter on. So effectively immediately, all mail from launchpad now skips my inbox is tagged in case I do actually need it. The only thing I need to improve this is a feature to auto-delete emails after 30 days labeled with a certain tag.

What a lovely start to 2009.

Biella Coleman: 2008

When I return to PR, my blog tends to lie fallow. Between taking care of the house, outdoor distractions (like the very overgrown garden and the very enticing beach), and most especially visiting my mother, I turn away from the computer, from my analytical mind, from writing. But since we have edged into a new year, I thought I would spend a little bit of time ruminating on 2008, which was one of the most unforgettable for me. With each passing year, it seems that 12 months bleed right into the next 12 months. But within this swirl, there are a handful of years that retain their sharp edges (1992, 1996, 2005, 2005-2006 are the most memorable). 2008 now sits among those as it is the the year that a tube was placed into my mother s stomach and soon after she was taken from the hospital into a nursing home without even the chance to say goodbye to the dog who was her steadfast companion and the house, which was her home for over 20 years. Over the last 6 years while I have not written much about my mother and her Alzheimer s, I did so fairly consistently with at least 3 entries per year, that is until March 2008 when she was put in the nursing home. Soon after being admitted, I wrote one entry and since then have not had the heart to commit much to words, something of which I am ashamed of and have sworn I would write about at least once before another years passes us by. I don t have the desire to constantly write about my experiences with her but it seems to be that Alzheimer s is erased far too often from public view and I would rather not contribute to that type of very pervasive silencing either. The recipe for my silence has been made up of various ingredients. One was I was just really really busy. Last semester was frenetic so I often did not have an ounce of room/time to think, much less blog about such a difficult situation (and I spent a lot of time going back and forth to PR as well). Another is that I was trying to avoid the heartache that arises when you focus in, with some detail, care and attention, on something that is unavoidably painful. Each time I tried, I ultimately failed and told myself, I would do so later. Finally I was blogging less and less about these types of subjects so it just seemed a little out of place every time I tried to commit something to words. For me, one of the hardest things to accept and this probably fed into my silence is that I played a part in prolonging her life when I know she wanted out (with a capital O U and T). But at the time the feeding tube was placed in her, she was walking and talking and it did not seem right to refuse her food (and I hoped that with some food, she would then start to eat on her own as she can swallow just fine) not to mention that her caretaker (a devout Catholic) and my sister would have never at the time been ready to refuse the feeding tube and I was not exactly quite ready either. Well, what we did not foresee was that 5 days in the hospital did her in and when she left, she could no longer walk, she could barely talk, and yet due to the feeding tube, she gained back the dramatic weight that she had shed over a year so that her body at least looked far more alive than it had been for years thanks to the steady stream of nutrition being slowly pumped into her body. I just know she would not want to be alive under these conditions and yet at this point, there is not much I can do legally except refuse certain classes of treatments if she gets sick (such as respirator) or wait until she becomes completely vegetative and then go through the legal hoops, that ultimately may not be successful, to remove the feeding tube. It has been so hard for so many months that as I late I have been trying to approach the whole thing with at least one dash of Zen-like detachment (by which I mean an embrace/acceptance of suffering in this world) and just spend as much time as I can with my mother, which I did a lot over the summer and I am now doing this winter. I am most probably moving back over the summer as well as my sister is not faring all that well after being with her for so many years. Even though she no longer knows my name, or who I am, I can tell she notices my presence and there are days she even seems to be happy. In fact, over the summer, she had some pretty lively days when we could manage to joke about almost nothing. Those days were rare and precious and today they don t seem to happen at all (she did seem a bit excited that it was a New Year though I could not tell if she really knew what I was saying). Over the summer, generally I would climb into her bed and we would co-nap for a couple of hours. And then the worst were the days she was hysterical and crying, and the absolutely worst was when she was crying, pleading for her parents. Those were days that did not break my heart but my soul. Thankfully those days of hysterics seem to be happen less and less and my mother just seems to sleep a lot. I sometimes like to think she is like those really old cats or dogs who seem to spend interminable hours sleeping and resting and don t seem to be suffering all that much though I can still tell she is still in a bad mood from time to time. She also has a wonderful roommate, Ana, who also pretty advanced Alzheimer s though certainly not as bad as my mom. Unlike my mother, she is happy as a clam, so much so she is always saying things like Isn t this a great day? How wonderful the day is, etc. etc, which is a nice counterbalance to my mom! I sort of like that my mom s roommate is, personality wise, the polar opposite of my mother, who is not a fundamentally unhappy soul, but she was emotionally erratic one with quite a few peaks and valleys and this is still very much the case. Having Ana around (and her family) has transformed the way I have seen this illness and my mother s condition. I am certainly not thrilled that she is alive and in fact think how we end (or don t end) life is something we as a society should be ashamed of. I clearly want to see her released, freed like a bird from the cage of this world (my mother loved loved birds I think because they symbolized freedom), but spending time with Ana, who again seems quite content, made me realize how part of the Alzheimer s experience is rooted in one s personality. My mom has always been difficult and when she was sick but still quite functional, her personality made the illness difficult for her and those around her. She never really had much luck changing her karmic personality and it sure is not going to change now. But as I said she does seem to rest a lot. I just hope her last few months, possibly years, are if nothing else peaceful and tranquil.

Biella Coleman: 2008

When I return to PR, my blog tends to lie fallow. Between taking care of the house, outdoor distractions (like the very overgrown garden and the very enticing beach), and most especially visiting my mother, I turn away from the computer, from my analytical mind, from writing. But since we have edged into a new year, I thought I would spend a little bit of time ruminating on 2008, which was one of the most unforgettable for me. With each passing year, it seems that 12 months bleed right into the next 12 months. But within this swirl, there are a handful of years that retain their sharp edges (1992, 1996, 2005, 2005-2006 are the most memorable). 2008 now sits among those as it is the the year that a tube was placed into my mother s stomach and soon after she was taken from the hospital into a nursing home without even the chance to say goodbye to the dog who was her steadfast companion and the house, which was her home for over 20 years. Over the last 6 years while I have not written much about my mother and her Alzheimer s, I did so fairly consistently with at least 3 entries per year, that is until March 2008 when she was put in the nursing home. Soon after being admitted, I wrote one entry and since then have not had the heart to commit much to words, something of which I am ashamed of and have sworn I would write about at least once before another years passes us by. I don t have the desire to constantly write about my experiences with her but it seems to be that Alzheimer s is erased far too often from public view and I would rather not contribute to that type of very pervasive silencing either. The recipe for my silence has been made up of various ingredients. One was I was just really really busy. Last semester was frenetic so I often did not have an ounce of room/time to think, much less blog about such a difficult situation (and I spent a lot of time going back and forth to PR as well). Another is that I was trying to avoid the heartache that arises when you focus in, with some detail, care and attention, on something that is unavoidably painful. Each time I tried, I ultimately failed and told myself, I would do so later. Finally I was blogging less and less about these types of subjects so it just seemed a little out of place every time I tried to commit something to words. For me, one of the hardest things to accept???and this probably fed into my silence is that I played a part in prolonging her life when I know she wanted out (with a capital O U and T). But at the time the feeding tube was placed in her, she was walking and talking and it did not seem right to refuse her food (and I hoped that with some food, she would then start to eat on her own as she can swallow just fine) not to mention that her caretaker (a devout Catholic) and my sister would have never at the time been ready to refuse the feeding tube and I was not exactly quite ready either. Well, what we did not foresee was that 5 days in the hospital did her in and when she left, she could no longer walk, she could barely talk, and yet due to the feeding tube, she gained back the dramatic weight that she had shed over a year so that her body at least looked far more alive than it had been for years thanks to the steady stream of nutrition being slowly pumped into her body. I just know she would not want to be alive under these conditions and yet at this point, there is not much I can do legally except refuse certain classes of treatments if she gets sick (such as respirator) or wait until she becomes completely vegetative and then go through the legal hoops, that ultimately may not be successful, to remove the feeding tube. It has been so hard for so many months that as I late I have been trying to approach the whole thing with at least one dash of Zen-like detachment (by which I mean an embrace/acceptance of suffering in this world) and just spend as much time as I can with my mother, which I did a lot over the summer and I am now doing this winter. I am most probably moving back over the summer as well as my sister is not faring all that well after being with her for so many years. Even though she no longer knows my name, or who I am, I can tell she notices my presence and there are days she even seems to be happy. In fact, over the summer, she had some pretty lively days when we could manage to joke about almost nothing. Those days were rare and precious and today they don t seem to happen at all (she did seem a bit excited that it was a New Year though I could not tell if she really knew what I was saying). Over the summer, generally I would climb into her bed and we would co-nap for a couple of hours. And then the worst were the days she was hysterical and crying, and the absolutely worst was when she was crying, pleading for her parents. Those were days that did not break my heart but my soul. Thankfully those days of hysterics seem to be happen less and less and my mother just seems to sleep a lot. I sometimes like to think she is like those really old cats or dogs who seem to spend interminable hours sleeping and resting and don t seem to be suffering all that much though I can still tell she is still in a bad mood from time to time. She also has a wonderful roommate, Ana, who also pretty advanced Alzheimer s though certainly not as bad as my mom. Unlike my mother, she is happy as a clam, so much so she is always saying things like ???Isn t this a great day???? ???How wonderful the day is,??? etc. etc, which is a nice counterbalance to my mom! I sort of like that my mom s roommate is, personality wise, the polar opposite of my mother, who is not a fundamentally unhappy soul, but she was emotionally erratic one with quite a few peaks and valleys and this is still very much the case. Having Ana around (and her family) has transformed the way I have seen this illness and my mother s condition. I am certainly not thrilled that she is alive and in fact think how we end (or don t end) life is something we as a society should be ashamed of. I clearly want to see her released, freed like a bird from the cage of this world (my mother loved loved birds I think because they symbolized freedom), but spending time with Ana, who again seems quite content, made me realize how part of the Alzheimer s experience is rooted in one s personality. My mom has always been difficult and when she was sick but still quite functional, her personality made the illness difficult for her and those around her. She never really had much luck changing her karmic personality and it sure is not going to change now. But as I said she does seem to rest a lot. I just hope her last few months, possibly years, are if nothing else peaceful and tranquil.

Kees Cook: happy new year, RIP md5

Welcome to 2009! Really, seriously, everyone can stop using MD5 now. However, be sure not to overreact. The forged CA research is a great read, but there s no need to break existing certs. For a calm reaction, please read this.

Ingo Juergensmann: Good old and trusty hardware

Today Spice, one of my m68k buildds, made the 400 days uptime:

15:00:32 up 400 days, 2:28, 6 users, load average: 1.39, 1.65, 1.23


And uprecords shows:

spice:/home/ij$ uprecords
# Uptime System Boot up
----------------------------+---------------------------------------------------
-> 1 400 days, 02:29:00 Linux 2.6.23-m68k Wed Nov 28 11:56:41 2007
2 349 days, 23:37:09 Linux 2.6.14-m68k-amiga Tue Dec 5 19:06:28 2006
3 66 days, 07:29:56 Linux 2.6.14-m68k-amiga Fri Feb 3 01:14:11 2006


Spice is an Amiga 3000 with 68040 accel card. The Amiga 3000 hit the market in 1990, Spice was bought in 1991 or 1992 and is running since then more than less non-stop. That's roughly 16 years of continuous operation and still being useful.

:-)

Sadly I' going to temporarily shutdown Spice in order for the annual dedusting of the case and PSU in some days.

31 December 2008

Russell Coker: Tidal River

Tim (a member of my local LUG) writes about some observations he has made of a nearby river and speculates on a tidal bore-like phenomenon [1]. One thing that surprised me was how short the list was on the Tidal Bore Wikipedia page [2], and the fact that is it missing an entry for Tidal River at Wilson s Promontory [3] (where my family often spent the Christmas holidays when I was young). Some of the tidal bores are described as having a wave as high as two meters, Tidal River is not so impressive, my observation was that during the 80 s it was about 40cm near the mouth of the river. The area near the river mouth had many bends when I last saw it which absorbed some of the energy of the wave (but I expect that the river changes course constantly so it might be straight from time to time). On one occasion I River Surfed [4] about 500 meters upstream at Tidal River on a surf-mat (an inflatable surf-board). I have searched for research into this issue, the Tidal Bore Research Society [5] seems to just maintain a list of tidal bores and not do any real research. Pierre Lubin, Stephane Glockner, and Hubert Chanson published a paper titled Numerical simulation of turbulence generated by a tidal bore [6]. Hubert Chanson at the University of Queensland has written an interesting paper titled Physical Modelling of the Flow Field in an Undular Tidal Bore [7]. Hubert seems to have published more papers related to tidal bores than anyone else (or at least more papers that are publicly accessible).

Andrew Pollock: [tech] Goodbye Vonage, hello T-Mobile@Home

When we first moved to the US, I wanted to try and do the telecoms and Internet stuff as cheaply as possible, while still trying to be technologically "fun" as well. I elected to get the cheapest home phone line (local calls only) I could get with AT&T (then SBC) (which is still remarkably expensive) so that I could get DSL (which, while three times faster than what I'd had previously in Australia, was still not that fast). (I went for DSL over cable because I'd heard horror stories about Comcast's reliability, and also they weren't cool with running servers or inbound services, Sonic is, and is a great ISP). I chose Vonage for US long-distance, I think because I'd heard of them previously, and was interested in trying out VoIP. We initially used Vonage for calling Australia as well, until I played around with Engin, and then deployed Asterisk. Anyway, I've been a loyal Vonage customer for exactly three years. The truth is, we hardly make any US long distance calls. We've got friends in Phoenix (hi Craig and Sarah!) that we call infrequently. I guess there might be the odd cell phone that isn't considered a local call, but we tend to use our cell phones more than the home phone anyway... So we were a very cheap $14.99 a month for Vonage. So when I called T-Mobile to purchase a SIM card for the Android Dev Phone 1 I'd been recently given, the opportunity to have their T-Mobile @Home in place of Vonage, for an extra $9.99 on top of what I was paying for the cell phone line seemed like worthwhile cost saving. I have no attachment to the incoming number for the Vonage line, we give out the AT&T land line number to people as our "primary" home number. Later that day, Vonage announced they were increasing their monthly fee from $14.99 to $17.99, which made the decision seem all the more prodigious. I did a spot of research while I was waiting for the @Home box to ship to me, and it turns out that they have a wireless router and non-wireless router option. They hadn't specified what I was getting at order time, and I was hoping I'd get the non-wireless router, since I already had an access point I was perfectly happy with it. As luck would have it, I received the wireless router model (a Linksys WRTU54G-TM). I'd mentally prepared myself to be receiving just another Linksys RTP300, like what Vonage used, and so I was quite surprised by the differences in technology used. It's been a while since I tried to do any reverse-engineering of the Vonage ATA, but I think from memory, it was essentially that: an ATA. It talked SIP back to Vonage. My DSL provider gave me a few static IP addresses, so when I got it, I just allocated one for Vonage, and did a static NAT through my firewall to for it, and everything just worked. It was fairly apparent that the WRTU54G-TM was nothing at all like this (given it was also an access point). It takes a GSM SIM card (up to two in fact), which I presume has all of the provisioning information on it. I was initially worried that I was going to need to completely rejig my network to accommodate it. I guess the SIM card approach means there's no customer specific provisioning that presumably otherwise needs to be done to the device itself, and they can just ship vanilla devices. I presume the Vonage RTP300 had some sort of customer-specific configuration, because I never had to do anything. I briefly toyed with the idea of running two access points, and having a "guest" wireless network, but I am interested in reducing heat and power consumption in my linen cupboard, so I decided to try and just swap over to using the WRTU54G-TM as my access point, retiring my Linksys WAP54G. So that's exactly what I sat down to do last night. Sometimes in their efforts to make these things "simple", they end up making things more complicated. What I wanted to do was just plug the "Internet" side of the device into my internal network, have it get an IP address with DHCP, and then let me get on with configuring it. The "advanced" setup instructions talked about the box having a default IP address of 192.168.0.1 ("or try 192.168.24.1 if that doesn't work"). I figured the DHCP IP address would override that, so I was trying to hit the IP address I could see the unit had picked up from my DHCP server. No response from the HTTP server. I could see it replying to ARP requests, and I could see what appeared to be an IPsec NAT-T connection. After some fiddling around, I twigged that I was trying to manage it over the Internet port, and any device worth its salt was going to be very hardened out of the box on what it expected to be the raw Internet-facing side, so I plugged my laptop directly into one of the four Ethernet ports that it also had, and then I could hit the 192.168.0.1 IP address and access the management interface. It never occurred to me prior to fighting with getting the WRTU54G-TM configured, that the RTP300 might have been more than a black box, as I'd never tried plugging anything into the "inside" ports on it, mainly because I'd never intended to use it as a router or a switch. Out of the box, the WRTU54G-TM was configured to be a router, which I didn't need, and it was configured to be a DHCP server for 192.168.0.0/24, which I definitely didn't want. An interesting side-effect of putting it into bridging mode was the MAC address changed (to the one that was printed on the unit, which was not how out of the box it presented itself). I have no need or intention of plugging anything into the "inside" Ethernet ports on the WRTU54G-TM, as I have a separate switch for that, and indeed I run my wireless network on a different interface of my firewall to my wired network. Fortunately I was able to enable the management interface via the "Internet" interface. The added benefit of the device doing NAT-T is I don't need to allocate an IP address to it for the VoIP stuff it work, it all just works fine without it, so I've freed up an IP address, removed two devices from my linen cupboard, added one new one, and saved some money. Woot! Next, just because I can, I'm going to try and break into the RTP300 and see if I can reconfigure it as a general purpose ATA to talk to Asterisk. There's evidence it's possible. It's otherwise of no further use to me. Even if I get it working with Asterisk, it's not of a lot of use to me. Maybe I can send it to a family member, and they can call us over the Internet for free instead of for the cost of a call to Brisbane...

Joachim Breitner: Handling explicit and implicit recusion in Haskell data

For a while I have been pondering over a problem that arises when your functionally written program has some state with cross references for example a list of users, each of which uses a number of computers, and a list of computers, each having an owner. Implicit referencing For doing queries on such data, it would be convenient if every reference is just the referenced object itself. Although we would visualize this as a graph, semantically, it is more like an infinite tree. This is possible in Haskell, due to laziness, and if you create the data structure cleverly, it even uses constant memory, no matter how deep you enter this infinite tree (a recent post of mine talks about this). A possible data definition would be:
data User = User  
userName :: String,
uses :: [Computer]

data Computer = Computer
computerName :: String,
owner :: User -- references the Users

data State = State [User] [Computer]

testState = let user = User "Conrad" [computer]
computer = Computer "Z3" user
in State [user] [computer]
Explicit referencing But such a representation is very unsuitable for updates (at least I can t think if a nice way of updating such a graph without breaking the internal cross-references) and serialization, which is a must for a HAppS based application. So what one would probably start with is this data structure:
data User = User  
userId :: Int,
userName :: String,
uses :: [Int] -- references the Computers

data Computer = Computer
computerId :: Int,
computerName :: String,
owner :: Int -- references the Users

data State = State [User] [Computer]

testState = State
[User 0 "Conrad" [1]]
[Computer 1 "Z3" 0]
I think the semantics of this are clear. Note that the referencing is currently not type-safe, but this can be provided by phantom types. Maybe I ll write more about that later. Now imaging you want to display the information about the first computer with your web application. You extract the information with let State _ cs = testState in head cs and pass that to your templating engine. But what if your template wants to display the name of the owner? It only has access to his userId. You would either need to know what information the template will ever need, extract that from the state beforehand and pass it along, or give the template access to the whole state. In that case, though, there has to be lookup-logic in your output code, which is also not nice. Woudln t it be nice if you could, in your application logic, work with the explicit references, which are easy to modify and store, but somehow turn that into the implicit referencing? Duplicated representation One way would be to have two unrelated sets of data structures, ExplicitState, ExplicitUser, ExplicitComputer, which use explicit identifiers to reference each other, and ImplicitState,... which are defined as the first representation of our state. It is then mostly trivial to write a function that converts ExplicitState to ImplicitState. The big disadvantage of this is that you have to maintain these two different hierarchies. It also means that every function on the state has to be defined twice, which often almost identical code. Clearly, this is not desirable. Annotated representation It would be more elegant if the state is stored in one data type that, controlled by a type parameter, comes in the one or the other representation. To do that, we need two types: One that contains a value, and one that contains just a reference:
newtype Id v = Id v deriving (Show, Typeable, Data)
newtype Ref v = Ref Int deriving (Show, Typeable, Data)
Then we need to adjust our data definitions, to make use of these. (I ll leave out the names, to keep the code smaller)
data User ref = User  
userId :: Int,
uses :: [ref (Computer ref)]

data Computer ref = Computer
computerId :: Int,
owner :: ref (User ref)

data State ref = State [User ref] [Computer ref]
Here we introduce a type parameter ref , which will later be either Id or Ref. Note that now a reference also states the object it is a reference for, which greatly increases type safety. Functions on these data types that don t work with the references will be polymorphic in the ref type parameter, so only need to be written once. A User Id is a complete user with all related data, while User Ref is a user with only references. And a Ref (User Ref) is reference to a user, which contains references... Not so kind kinds Did you notice the lack of a deriving clause? Our data structures have the relatively peculiar kind ((* -> *) -> *), which makes it hard for the compiler to derive instances for things like Show. But we already know that we will only use Id or Ref for the type variable, so we can use ghc s StandaloneDeriving language extension and have these instances created:
deriving instance Show (User Id)
deriving instance Show (User Ref)
deriving instance Show (Computer Id)
deriving instance Show (Computer Ref)
deriving instance Show (State Id)
deriving instance Show (State Ref)
Toggling a type parameter The next step is to write the conversion function. It will have type
unrefState :: State Ref -> State Id
For that, and for later, we need lookup functions:
unrefUserRef :: State Id -> Ref (User Ref) -> Id (User Id)
unrefUserRef (State l _) (Ref i) = Id $ fromJust $
find (\u@(User i' _) -> i == i') l
unrefComputerRef :: State Id -> Ref (Computer Ref) -> Id (Computer Id)
unrefComputerRef (State _ l) (Ref i) = Id $ fromJust $
find (\u@(Computer i' _) -> i == i') l
These expect a State (with implicit referencing) and a reference, and look up this reference. The function unrefState then looks like this:
unrefState :: State Ref -> State Id
unrefState (State us cs) =
let unrefState = State (map (unrefUser unrefState) us)
(map (unrefComp unrefState) cs)
in unrefState
where unrefUser :: State Id -> User Ref -> User Id
unrefUser s (User i refs) = User i (map (unrefComputerRef s) refs)

unrefComp :: State Id -> Computer Ref -> Computer Id
unrefComp s (Computer i ref) = Computer i (unrefUserRef s ref)
Note how we tie the knot in the let expression. This is the trick that ensures constant memory consumption, because every reference points back to the same place in memory. Satisfied already? So what do we have? We have no duplication of data types, we can write general functions, and we can resolve the explicit referencing. We can also easily write functions like unrefUser :: State Ref -> User Ref -> User Id, which transform just a part of the state. But writing unrefState is very tedious when the State becomes more complex. Each of the other unrefSomething functions are very similar, but need to be written anyways. This is unsatisfactory. What we want, is a generic function, something like
gunref :: State Ref -> a Ref -> a Id
which, given a state with explicit references, replaces all explicit references in the first argument (which could be State Ref or User Ref or anything like that) with implicit ones. This function can not exist, because we would not know anything about a and b. But maybe we can do this:
gunref :: (Data (a Id), Data (a Ref)) =>  State Ref -> a Ref -> a Id
Typeable and Data Before being able to do so, we need to derive Data for our types. We can start with
deriving instance Data (User Id)
deriving instance Data (User Ref)
deriving instance Data (Computer Id)
deriving instance Data (Computer Ref)
deriving instance Data (State Id)
deriving instance Data (State Ref
but that will complain about missing Typeable instances. Unfortunately, ghc s deriver for Typeable (even the stand-alone-one), does not handle our peculiar kind, so we need to do it by hand. With some help from quicksilver on #haskell, I got it to work:
instance Typeable1 ref => Typeable (User ref) where
typeOf _ = mkTyConApp (mkTyCon "User") [typeOf1 (undefined :: ref ())]
instance Typeable1 ref => Typeable (Computer ref) where
typeOf _ = mkTyConApp (mkTyCon "Computer") [typeOf1 (undefined :: ref ())]
instance Typeable1 ref => Typeable (State ref) where
typeOf _ = mkTyConApp (mkTyCon "State") [typeOf1 (undefined :: ref ())]
everywhere is not enough Turning to the documentation of Data.Generics, I notice with some disappointment that there is no function that is able to change a type they all seem to replace a value by another value of the same type. But the functions gfoldl and gunfold sounded like they could be used for this. Warning: What comes now is a very non-haskellish hack that subverts the type system, just to get the job done. Please read it with a healthy portion of distrust. If you know of a cleaner way of doing that, please tell me! Wrapped Data I want to do some heavy type hackery, so I need to disable haskell s type system. There is Data.Dynamic, but not even that is enough, as we need to carry a type s Data instance around as well. So let s wrap that up:
data AData where AData :: Data a => a -> AData
instance Show AData where show (AData a) = "<" ++ show (typeOf a) ++ ">"

fromADataE :: forall b. Data b => AData -> b
fromADataE (AData d) = case cast d of
Just v -> v
Nothing -> error $ "Type error, trying to convert " ++
show (typeOf d) ++ " to " ++
show (typeOf (undefined :: b)) ++ "."
There is also a function that converts an AData back to a normal type, if possible. If it s not possible, then there is a bug in our code, so we give an informative error message. AData transformers Similar to everywhere, we want to have transformers that combinable. They need to have the change to convert an arbitrary value, but also signal that they could not convert something (and this something has to be recursed into). I came up with this:
type ADataT = AData -> Maybe AData

extADT :: forall a b. (Data a, Data b) => ADataT -> (a -> b) -> ADataT
extADT at t a@(AData v) = case cast v of
Just x -> Just (AData (t x))
Nothing -> at a

doNothing :: ADataT
doNothing = const Nothing
ADataT is the type for such a transformer. doNothing will not transform anything, and extADT can be used to add any function to the list of tried transformers, in the spirit of extT. The ugly part To apply such a transformer, I want to use this function, which I ll describe in the code comments:
everywhereADT :: forall a b. (Data a, Data b) => ADataT -> a -> b

-- first check if we can transform this value already
everywhereADT f v = case f (AData v) of
-- if so, coerce it to the users requested type, which hopefully goes well
Just r -> fromADataE r
-- if not, we need to recurse into the data structure
Nothing -> recursed

-- for that, we first need to figure out the arguments to the
-- constructor. We store them in the untyped list
where args :: [AData]
(Const args) = gfoldl k z v
-- gfoldl lets us have a look at each argument. We wrap it in AData
-- and append it to the list
k (Const args) arg = Const (AData arg : args)
z start = Const []

-- We need the data constructor of the input data type. If the user did not want
-- it to be transformed, it will be the same
c = toConstr v

-- To give better error messages, we make sure that the outmost type constructor
-- of the requested type actually has the data constructor we were given. Otherwise
-- gunfold will complain in a non-helpful way
input_type = dataTypeRep (constrType c)
output_type = dataTypeRep (dataTypeOf (undefined :: b))

recursed = if input_type /= output_type
then error $ "Can not convert <" ++ show input_type ++ ">"++
" to <" ++ show output_type ++ ">."
-- the types match, so we assemble the output type, using gunfold
else snd (gunfold k' z' c)
k' :: forall b r . Data b => ([AData], b -> r) -> ([AData],r)

-- we start by reversing the input list
z' start = (reverse args,start)

-- then we call us recursively on the argument and feed the result
-- to the output constructor
k' ((AData a) : args, append) = (args, append (everywhereADT f a))

-- Used for folding (we don t need to retain the original constructor)
data Const a b = Const a
What a beast! But surprisingly, it works. Here are some examples. Note that I always have to specify the requested output type:
bool2Int :: Bool -> Int
bool2Int False = 0
bool2Int True = 1

*Main> everywhereADT (doNothing extADT bool2Int) True :: Int
1
*Main> everywhereADT (doNothing extADT bool2Int) True :: ()
*** Exception: Type error, trying to convert Int to ().
*Main> everywhereADT (doNothing extADT bool2Int) (True,False) :: (Int,Int)
(1,0)
*Main> everywhereADT (doNothing extADT bool2Int) ([True,False],True,()) :: ([Int],Int,())
([1,0],1,())
*Main> everywhereADT (doNothing extADT bool2Int) ([True,False],True,()) :: [()]
*** Exception: Can not convert to .
*Main> everywhereADT (doNothing extADT bool2Int) [True] :: [Bool]
[*** Exception: Type error, trying to convert Int to Bool.
I hope this code does not inflict too much pain on any Haskell-loving reader. I know I violated the language, but I didn t know how to do it better (at least not without using Template Haskell). I also know that this is not very good performance wide: Every single value in the input will be deconstructed, type-compared several times and re-assembled. If that is an issue, then this function should only be used for prototyping. Almost done To apply this to our state, we only need to glue it to our lookup functions from above:
gunref :: (Data (a Id), Data (a Ref)) =>  State Ref -> a Ref -> a Id
gunref s w = let unrefState = gunref' unrefState s
in gunref' unrefState w

gunref' :: (Data (a Id), Data (a Ref)) => State Id -> a Ref -> a Id
gunref' unrefState = everywhereADT unref'
where unref' = doNothing extADT
unrefUserRef unrefState extADT
unrefComputerRef unrefState
Now we have a generic unreferencer. I set the type a bit more specific than necessary, to make it safe to use (under the assumption that the list of lookup functions is complete and will not leave any Ref in the output).
*Main> testState 
State [User userId = 0, uses = [Ref 1] ] [Computer computerId = 1, owner = Ref 0 ]
*Main> gunref testState testState
State [User userId = 0, uses = [Id (Computer computerId = 1, owner = Id (User userId = 0,
uses = [Id (Computer computerId = 1, owner = Id (User userId = 0, uses = ..
Oh, and by the way, if you want to test this code, you ll need at least:
 -# LANGUAGE DeriveDataTypeable, FlexibleInstances, GADTs,
FlexibleContexts, StandaloneDeriving, ScopedTypeVariables #-

Russell Coker: Links December 2008

A teacher in Arizona steals Linux CDs from a student and then accuses a Linux distributor of being a criminal [1]. Even though she had used Linux in the past she didn t believe that software was free. Of course that implies that in the past she had performed actions that she believed were criminal. Neat Little Mac Apps interviews Marshall Kirk McKusick - he describes how the BSD Daemon logo was designed and one of his most significant bugs [2]. OurDelta.org offers MySQL builds with some extra features and support [3]. I was recommended to use their builds by Arjen Lentz of Open Query [4], as one of my clients is going to use the services of Open Query it seems best to use the Our Delta builds if only to get better support from Open Query. The extra features in the Our Delta builds seem interesting, but I m not sure that my client needs any of them at this time. The Global Guerilla blog reports on a man who single-handedly invaded the most heavily guarded power station in Britain and shut it down to protest against new coal power stations [5]. The entire blog is worth reading, the author has a lot of interesting ideas. PhpMyVisites is a free web site analytics system that competes with Google Analytics [6]. I haven t implemented it yet, but it looks promising. It seems that PhpMyVisites is not being updated any more (not even security updates) and the replacement is Piwik [11]. Andrew Lahde was a fund manager who made significant amounts of money by betting on the inability of US mortgagees to repay their debts, he wrote an interesting goodbye letter (Telegraph.co.uk) [7]. He now has a Wikipedia page which gives some interesting background to his career [8]. An Employee of the Financial Times is famous for flaming Andrew [9], I have submitted a comment pointing out that being famous for flaming someone who is more successful than yourself is nothing to be proud of and suggesting that he advocate his own political views when criticising those of others - I doubt that it will get through moderation. It s a pity that Andrew doesn t have a blog, I would like to read more from him. At CCC a paper by Alexander Sotirov, Marc Stevens, Jacob Appelbaum, Arjen Lenstra, David Molnar, Dag Arne Osvik, and Benne de Weger on how to crack the PKI infrastructure used for SSL signing was presented [10]. The root cause is some CAs still using MD5 even though it was broken a long time ago. Updated to note that Piwik is the replacement for PhpMyVisites.

Neil Williams: OpenID.com https FAIL

*.myopenid.com - page security information.
Equifax Secure Global eBusiness CA-1
PKCS #1 MD5 With RSA Encryption

Same for https://www.myopenid.com/signin_password and the same for the myOpenID.com SSL certificates that you actually use with myOpenID.com - all now known to be vulnerable to spoofing. I don't think I'll be using those any more.

SSL spoofing via MD5 certification

CA's using only MD5 to sign the certificate

Oops.

It depends on how you use OpenID I suppose, but if known weak certificates are removed from browsers in order to protect users from possible SSL spoofing, current myOpenID.com certificates will simply stop working.

Not really a surprise considering how Canonical came to exist but, Launchpad OpenID has got it right. Launchpad itself doesn't use a CA that relies solely on the weak MD5. Maybe I'll start using the Launchpad OpenID instead. (Launchpad OpenID still works with the Alioth OpenID support). However, it would be nice if the Launchpad OpenID could provide SSL certificates for users to import into browsers and then I could log into various sites directly. I did like that functionality with myopenid.com but those certificates have had to be revoked now.

Gold stars for Ubuntu and the Alioth admins. A pile of stinky brown stuff for the myopenid.com team.

Update:
Maybe it's time for Alioth to support OpenID more fully? Or there again, maybe not. After a little reading up on the multiple failings of openid in general, I'm going to leave openid as it is (mostly disabled in my case) and use it only for stuff that really doesn't matter much. Using openid for important stuff just doesn't make any sense.

30 December 2008

Mike Hommey: Another threat to the internet

Some people presented a rogue Certificate Authority at this year s CCC. What is surprising is not so much that they could create such a rogue CA, but the fact that MD5, despite having been broken for several years, is still in use by some important CAs to sign SSL certificates. Amazing.

Joerg Jaspert: Fuck it! What could possibly go wrong?

Time for another ftpmaster blog. It s not like we stopped doing things. :) It seems we, somehow, got a pretty active coder (yay), Michael Casadevall. In the last few days I merged multiple code changes from him. The first was a different output format for our NEW queue overview page. It is now also available in 822 Format for all those people that want to use the data in their tools. Like QA for example. Today got a second change touching this, we now not only list NEW/BYHAND in there, but also our incoming (accepted) and Proposed-Updates queue. There is also a patch waiting to fix up the pretty weird code thats around the DM stuff. Will fix some of the many bugs and weirdnesses in the current implementation. And it seems he is right now trying to get rid of apt-ftparchive, the beast that makes our dinstall run take so long. Oh we will be so happy when we got rid of it. :) Also, we do have two new people as trainees for ftpteam. If that works out, we will have yet another 2 new members in our team. Yay.

Julien Danjou: Rants about Lua

I've started using Lua some months ago, while looking for a more powerful way to configure awesome. At this time, around March 2008, Lua seemed to be the best language to integrate inside the core system of awesome. I still think that Lua was a good choice, but after 8 months, it shows some important drawbacks. I'll try to keep my explanation simple and to make you understand everything, even if you do not know Lua. I refer here to Lua 5.1 Design flaws Length operator Lua has a length operator on its objects, known as #. It can be used to get the size of various objects.
return #"lol" 3
This operator works for table, string, etc It's possible to define this operator by setting a __len meta-method on a userdata value. The problem is that you cannot redefine it on string or table objects, see:
> a =   "hello", "world"  
> return #a
2
> setmetatable(a,   __len = function () return 18 end  )
> return #a
2
Indeed, looking at the Lua core code:
     case OP_LEN:   
       const TValue *rb = RB(i); 
       switch (ttype(rb))   
         case LUA_TTABLE:   
           setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); 
           break; 
             
         case LUA_TSTRING:   
           setnvalue(ra, cast_num(tsvalue(rb)->len)); 
           break; 
             
         default:    /* try metamethod */ 
           Protect( 
             if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) 
               luaG_typeerror(L, rb, "get length of"); 
           )   
             
           
       continue; 
      
You clearly see that tables and strings always use the internal length operator, never the __len meta-method. That's for me a design problem, which will cause more trouble. We'll see later. __index and __newindex metamethods Lua defines two useful metamethods, which are __index and __newindex. Both can be set on a table or any other object. __index will be called upon each read access to an undefined key on an object, and __newindex upon each write access. Example
> a =  
> setmetatable(a,   __index = myindexfunction, __newindex = mynewindexfunction  ) -- function are not defined, this is just an example
> a[1] = "hello" -- This will call __newindex metamethod
> return a[2] -- This will call __index metamethods
> return a[1] -- This will NOT call __index
The last line does not call __index meta-method because a[1] does exists. This is a problem when you want to use table as object, because sometimes you want to monitor access to the table elements. This can be easily worked around using a proxy system: you don't store things in the table you manipulate, but in another table.
> a =  
> realtable =  
> setmetatable(a,   __index = myindexfunction, __newindex = mynewindexfunction  ) -- function are not defined, this is just an example
Where meta-methods are something like:
function myindexfunction(table, key)
   return realtable[key]
end
function mynewindexfunction(table, key, value)
   realtable[key] = value
end
This way, our a table will always be empty, and realtable will have the data. At every read or write access to a, the meta-methods will be called. This is very convenient and widely used hack. But this has serious drawbacks: as we saw before, the length operator (#) cannot be redefined on a table. That means #a will always be 0, and you cannot get the table length anymore, except by defining another method or a special attribute. Also, Lua has several functions in the table library that are used to manipulate table in a easy way. The problem is that standard functions like table.insert or table.remove do raw accesses to the table. Meaning that if you do table.insert(a, 1, 1) it will insert the value 1 at the key 1 into a, without calling the __newindex meta-methods, breaking all your beautiful object-oriented model. Another solution is to use a userdata object, like done in the Lua newproxy function (which is under-documented). The problem is that it breaks all the other functions that are waiting for a table as argument, because they see a userdata, not a table. So this time table.insert is now more usable, which somehow fixes the problem, but not in the right way IMHO. However, this allows to use the __len meta-method. Development model The development model of Lua is, from my point of view, non-existent. There is no public version control system repository available, so there's no chance to really contribute to Lua. It seems only a defined set of people work on it and therefore, the development system is very closed to my eyes, in comparison of usual projects. Conclusion I still think Lua is a good choice, because it is very easy to integrate into any C program, and to expand to fulfill your needs. However, some bad design choices were made, and the poor and closed development model chosen does not allow to have a good overview of the future of Lua. This has been well stated by the authors themselves.

29 December 2008

John Goerzen: A Day with Jacob

Old train! Smoke inside. That s what Jacob said today when he saw an old steam locomotive at the old Union Station in Wichita, KS. Never mind that it s been sitting there for decades he s got that concept of smoke coming out of steam engines down, and apparently realizes that for smoke to come out of them, it must start out inside them. But I don t think I ve ever heard anyone talk about a steam engine in a more cute way. Two is a fun age. Today I needed to return a power supply to Circuit City, so Jacob and I made a day of it. He came with me to town (yes, us country folk go to town ). We returned the power supply, then ate lunch at a Mexican place. Jacob would call it a chips and salsa place. Today he drank from a straw for the first time, and loved it so much that I think he got more liquid than food in him over lunch. Oh well. After that, we went to the eye cream (ice cream) store - Cold Stone Creamery. Whenever Jacob hears talk of Wichita, he comments with something like Go ichita. Eat eye cream. Go town. Jacob ate his entire kid-sized chocolate ice cream with sprinkles. He loves sprinkles. While we were eating ice cream, I asked him, After you are done, would you like to see skyscrapers or trains? NO! Eat eye cream! I don t think he quite got the after bit, so I asked him again in the car after we were done eating. His eyes lit up. SEE KYCRAPER!! So we drove to downtown Wichita and saw the skyscrapers. (Yes, I am aware that other cities have much taller buildings. It doesn t matter when you re 2.) We got out of the car and he got to touch a few of them. In fact, the only way I got him back into the car without a meltdown was by pointing out the train crossing above the road on a bridge, and the fact that he d still be able to see it from in the car. That, of course, led to us needing to see trains. I drove him up the ramp to be trackside by the old Wichita Union Station. There weren t any trains going past right then, but he did get to see the locomotives at the Great Plains Transportation Museum through the fence. We started to head home, but he really wanted to see the train again. So we stopped at the park in Newton to see the old ATSF locomotive there. By that point, it was waaaay past naptime and we narrowly averted a fit when I informed him that no, we could not go inside the adjacent grain elevators. So all told, I think Jacob had a fun day with his dad. Now, in case there is any doubt out there about what kind of child Jacob is, I should point out the things he notices in church lately. First off, when we get into the sanctuary, we sit in the back. But first thing he said lately when we walked in was TWO THERMOSTATS! Yes, he saw two thermostats at opposite ends of the room up front, pointed right at them, and was very excited. He also notices the organ speakers ( oran peaker ), big cross , ceiling fans, and now furnace vents . Yes, furnace vents. At the Christmas Eve service, there was a candlelight part. He loved it. Daddy hold fire! A few people nearby smiled. While we sang Silent Night, he really wanted to blow out the candle. When it was time, I said OK Jacob, now you can blow it out. A very excited Fffffffffffffffff followed, and several people nearby were chuckling by then. I also let Jacob put the candle in the box on our way out. He said, I put fire in box. I did it!

Neil Williams: When firmware is not software

So the failings of the GR result in just what everyone didn't need - a restarted discussion about the firmware issue without first releasing Lenny. Come on people, leave it alone and get Lenny done. Anthony, Thomas and Theodore (also in his blog) all seem to be missing the point(s):



To me, it's more like data for the chips - it's saying "this is who you are, this is what you do and this is how to understand all subsequent instructions". Software is what follows - the instructions themselves.

We have a very good understanding of the separation between software and data in userspace - we all recognise that unless the output of a program consists to a large extent of modified versions of already licensed code (e.g. code generators), then the data created by your free software GPL-3+ text editor (or blogging client) cannot be deemed to be under the GPL-3+ or any other licence until such a statement is made by the copyright holder and that the copyright holder is the user of the software, not the author of the software. I could quite easily put this blog under a Microsoft-style EULA or even NDA if I wanted to be obtuse, despite it being created using a free software stack. The point remains - I am the copyright holder of the content created using the free software on my machines and I am free to publish that data as I see fit. The authors of the software itself have no rights to dictate what I do with the content I create using the software, just as I - as a user - cannot dictate whether the authors of my editor choose to migrate from GPL-2+ to GPL-3+ or even BSD.

Where firmware can have source code, let it have source code - we have such packages in Debian already. Even then, much of the code may be simply calculations or conditionals to select the right combination of binary flags for specific situations. This isn't about Nvidia kernel drivers that do real runtime calculations during the entire runtime of the machine, this is about tiny bits of initialisation data that are set once and not touched again. Can we not accept that some firmware is derived from a process that does not involve source code? How about experimentation and calculation? We know the voltage on pins 5 and 19, we know the state of register A and that for this specific case, it needs to be toggled to match the state of register E because otherwise another chip on the same board gets confused, so setup the chip to do that by setting a firmware datum point to initialise A? Where's the source code in that process? There is none - it is a piece of data, an item in the design notes (or more likely the errata). Yes, maybe the chip should know how to set this datum itself but for whatever reason (probably financial), it doesn't.

Source code could be used to calculate the datum point for a range of chips and chipsets according to a range of data inputs but the creative effort is then in the calculation not the data. The chip doesn't want the calculation, it cannot perform a calculation in this uninitialised state, it needs the datum point. Once it has the registers set, it can then understand subsequent instructions - the software itself. The datum point itself is just a raw piece of initialisation junk for the chip, it has no source code, it is determined by a physical process. It is a reference point - a fixed value that is determined during the design of the chip and/or chipset.

It's like saying you want the source code that determines whether there are one hundred cents in a Euro so that you could modify it to create a thousand or just ten or maybe turn the Euro into a hexadecimal currency. Weird. The fact that the Euro has one hundred sub-divisions is not up for negotiation, it isn't a modifiable value - changing the value unilaterally is not going to magically make everyone use the new value. It is a fixed reference point - a single datum point that initialises all subsequent behaviour of all software utilising such a currency. Even if there was source code (gee, what could that be, do you think? "%.2i" ?) it would be meaningless to insist on being able to modify it.

Few people can make the judgement about whether particular firmware can or cannot have source code - in most cases it comes down to the hardware design of either just the chip or how the chip is utilised for a particular board.

At some point, Debian has to accept that we cannot know if source code was used to create a particular blob. We simply have to ensure that maintainers ask upstream, elucidate as much information as possible about how the firmware was created and document that in debian/copyright. If that information is proved to be incorrect, then we have to deal with it as best we can - on a package-by-package basis. The assumption has to be that firmware does not necessarily have any source code.

In the end, I think the GR came up with the right result, despite all the failings - Option 5, assume that firmware is compliant with the GPL unless there is evidence to the contrary.

Sometimes, there simply is no source code - sometimes all you have is data.

Debian cannot insist on source code for data that is not generated from source code and it is the difficulty in deciding whether one set of figures is initialisation data or a set of compiled instructions that will defeat all debate on a general solution for the firmware debate. It is comparing apples and oranges - we can insist on source code where source code was used but we also have to accept that some firmware is identified, not programmed. In the end, Debian will have to trust the maintainer and the maintainer will have to trust upstream. Documenting that in debian/copyright seems to be the only sane option.

Now can we all just shut up and release Lenny? Please?

MJ Ray: Looking Back: 2008 Part 3

This is the final part of my review of popular articles on my news websites during 2008. It follows part 1 and part 2, but it can be enjoyed on its own, like an nice ripe cheese. Unlike one friend, I do not like cheese for breakfast.
September
  • Are Your Free Software T-Shirts Ethical? This question got a lot of views, but no answers yet. Again, those statistics surprised me.
  • Away From Keyboard was a listing of events I attended in early September, with some links to summaries in the article and the comments. (I can t find my Bristol Knowledge Unconference report just now. Did I post it to another site?)
October
  • The Trouble With Big Webmail built on my past comments about Yahoo and broadens them to Hotmail/Live and GoogleMail. I m still convinced those sites remain popular because they are good at marketing, rather than being good at email. In fact, they re so bad at email, almost no-one should use them.
  • Pulling One File From a Plesk Backup - It seems I wasn t the only person not to know about that.
  • Nestle Boycott 20th Anniversary seems to be the only time I wrote about boycotts this year, surprisingly (I know I m pretty militant and direct-action-y), but what more deserving target?
November
  • Which Social Bookmarking? was by far the most popular article in November and it also got lots of helpful comments. I posted my review and choices (such as they are) a few days ago.
December
  • Bristol Alternative Christmas Quiz. Everyone loves a good seasonal quiz, it seems. I didn t get to it (arrrrrrrrrgh busy!) but I hope it went well for BWCC.
  • Smart Tricks with ssh was only the second meme-like post to make the most popular list this year.
  • and it s still a bit early to evaluate articles from late December! I may add a few to this list later.
Happy New Year 2009, in case I don t see you before then!

28 December 2008

Andrew Pollock: [life/americania] The Civic Musical Road and Other Adventures

It's not a holiday without a road trip, especially with petrol prices being lower now than they were three years ago when we arrived here. So we headed off on Christmas Day for San Simeon, with the general plan to tour Hearst Castle on Boxing Day (which isn't a public holiday in the US, but is a company holiday), and then head to Thousand Oaks, to visit a friend of Sarah's who also had heart surgery this year, and then head home. We'd hatched this plan a few months ago, and afterwards, saw a news piece on the "Civic Musical Road", and when we discovered it wasn't too far from Thousand Oaks in the grand scheme of things, we decided to throw that on the itinerary as well. I found a five-part "making of" documentary on YouTube, along with what I presume is the original commercial, and of course, we had to record the experience. Making of, part 1 Making of, part 2 Making of, part 3 Making of, part 4 Making of, part 5 Presumably the final commercial Our experience (on the relocated version)

Theodore Ts'o: Debian, Philosophy, and People

Given the recent brouhaha in Debian, and General Resolution regarding Lenny s Release policy as it relates to Firmware and Debian s Social Contract, which has led to the resignation of Manoj Srivastava from the position of Secretary for the Debian Project, I m reminded of the following passage from Gordon Dickson s Tactics of Mistakes (part of Dickson s Childe Cycle, in which he tells the story of the rise of the Dorsai):
No, said Cletus. I m trying to explain to you why I d never make an Exotic. In your calmness in the face of possible torture and the need to kill yourself, you were showing a particular form of ruthlessness. It was ruthlessness toward yourself but that s only the back side of the coin. You Exotics are essentially ruthless toward all men, because you re philosophers, and by and large, philosophers are ruthless people. Cletus! Mondar shook his head. Do you realize what you re saying? Of course, said Cletus, quietly. And you realize it as well as I do. The immediate teaching of philosophers may be gentle, but the theory behind their teaching is without compunction and that s why so much bloodshed and misery has always attended the paths of their followers, who claim to live by those teachings. More blood s been spilled by the militant adherents of prophets of change than by any other group of people down through the history of man.
The conflict between idealism and pragmatism is a very old one in the Free and Open Source Software Movement. At one end of the spectrum stands Richard Stallman, who has never compromised on issues regarding his vision of Software Freedom. Standing at various distances from this idealistic pole are various members of the Open Source Community. For example, in the mid-1990 s, I used to give presentations about Linux using Microsoft Powerpoint. There were those in the audience that would give me grief about using a non-free program such as MS Powerpoint, but my response was that I saw no difference between driving a car which had non-free firmware and using a non-free slide presentation program. I would prefer to use free office suite, but at the time, nothing approached the usability of Powerpoint, and while dual-booting into Windows was a pain, I could do a better job using Powerpoint than other tools, and I refused to handcap myself just to salve the sensibilities of those who felt very strongly about Free Software and who viewed the use of all non-Free Software as an ultimate evil that must be stamped out at all costs. It is the notion of Free Software as a philosophy, with no compromises, which has been the source of many of the disputes inside Debian. Consider, if you will, the first clause of the Debian Social Contract:
Debian will remain 100% free We provide the guidelines that we use to determine if a work is free in the document entitled The Debian Free Software Guidelines. We promise that the Debian system and all its components will be free according to these guidelines. We will support people who create or use both free and non-free works on Debian. We will never make the system require the use of a non-free component.
This clause has in it no room for compromise. Note the use of words such as 100% free and never make the system require the use of a non-free component (emphasis mine). In addition, the Debian Social Contract tends to be interpreted by Computer Programmers, who view such imperatives as constraints that must never be violated, under any circumstances. Unfortunately, the real world is rarely so cut-and-dried. Even the most basic injunctions, such as Thou shalt not kill have exceptions. Few people might agree with claims made by the U.S. Republican Party that the war in Iraq qualified as a Just War as defined by Thomas Aquinas, but rather more people might agree that the July 20, 1944 plot to assassinate Hitler would be considered justifiable. And most people would probably agree most of the actions undertaken by the Allied Soldiers on World War II battlefields that involved killing other soldiers would be considered a valid exception to the moral (and for those in the Judeo-Christian tradition, biblical) injunction, Thou shalt not kill . As another example, consider the novel and musical Les Mis rables, by Victor Hugo. One of the key themes of this story is whether or not Thou shalt not steal is an absolute or not. Ultimately, the police inspector Javert, who lived his whole life asserting that law (untempered by mercy, or any other human considerations) was more important than all else, drowns himself in the Seine when he realizes that his life s fundamental organizing principle was at odds with what was ultimately the Right Thing To Do. So if even the sixth and eighth commandments admit to exceptions, why is it that some Debian developers approach the first clause of the Debian Social Contract with a take-no-prisoners, no-exceptions policy? Especially given the fourth clause of the Debian Social contract:
Our priorities are our users and free software We will be guided by the needs of our users and the free software community. We will place their interests first in our priorities. We will support the needs of our users for operation in many different kinds of computing environments. We will not object to non-free works that are intended to be used on Debian systems, or attempt to charge a fee to people who create or use such works. We will allow others to create distributions containing both the Debian system and other works, without any fee from us. In furtherance of these goals, we will provide an integrated system of high-quality materials with no legal restrictions that would prevent such uses of the system.
This clause does not have the same sort of absolutist words as the first clause, so many Debian Developers have held that the needs of the users is defined by 100% free software . Others have not agreed with this interpretation but regardless of how needs of the users should be interpreted, the fact of the matter is, injuctions such as Thou shalt not kill are just as absolute and yet in the real world, we recognize that there are exceptions to such absolutes, apparently unyielding claims on our behavior. I personally believe that 100% free software is a wonderful aspirational goal, but in particular with regards to standards documents and firmware, there are other considerations that should be taken into account. People of good will may disagree about what those exceptions should be, but I think one thing that we should consider as even higher priority and with a greater claim on how we behave is the needs of our users and fellow developers as people. For those who claim Christianity as their religious tradition, Jesus once stated,
Thou shalt love the Lord thy God with all thy heart, and with all thy soul, and with all thy mind. This is the first and great commandment. And the second is like unto it: Thou shalt love thy neighbour as thyself. On these two commandments hang all the law and the prophets.
Even for those who do not claim Christianity as their religious tradition, most moral and ethical frameworks have some variant on the Golden Rule: Do unto others as you would have them do unto you . I would consider, for example, that the Golden Rule is at least a high priority claim on my behavior as the notion of free speech, and in many cases, it would be a higher priority claim. The recent controversy surrounding Josselin Mouette was started precisely because Joss has taken a something which is a good thing, namely Free Speech, and relegated it to a principle more important than all else, and claiming that any restraint on such a notion was equivalent to censorship. I think the same thing is true for free software, although it is a subtler trap. Philosophical claims than 100% free software as most important consideration is dangerously close to treating Free Software as the Object of Ultimate Concern or in religious terms, idolotry. For those who are religious, it s clear why this is a bad thing; for those who aren t if you are unwilling to worship a supernatural being, you may want to very carefully consider whether you are willing to take a philosophical construct and raise it to a position of commanding your highest allegiance to all else, including how you treat other people. Ultimately, I consider people to be more important than computers, hardware or software. So over time, while I may have had some disagreements with how Mark Shuttleworth has run Canonical Software and Ubuntu (but hey, he s the multimillionaire, and I m not), I have to give him props for Ubuntu s Code of Conduct. If Debian Developer took the some kind of Code of Conduct at least as seriously as the Social Contract, I think interactions between Debian Developers would be far more efficient, and in the end the project would be far more successful. This may, however, require lessening the importance of philosophical constructs such as Free Speech and Free Software, and perhaps becoming more pragmatic and more considerate towards one another.

Joey Hess: Southern borscht

I was asked for my borscht recipe. This is loosely derived from a recipe that is really weird -- it says to throw away the beets! Both that recipe and mine are probably very unauthentic. But good. 6 cups water
3 medium size beets
2 medium size potatoes, quartered
1/2 cup chopped carrots
1 stalk celery, chopped -- optional
1/2 a bell pepper, chopped (red or green) -- optional
1/3 cup butter
1/2 to 1 cup chopped onion
1/2 cup tomatoes (fresh are best, canned or tomato paste + water is ok)
1/4 cup milk
2 cups finely chopped cabbage
1 tablespoon vinegar
1 teaspoon dried dill weed
sour cream Put water in a large pot on high heat. Add beets, potatoes, carrots, celery, and bell pepper. Cover and boil until potatoes are tender. Meanwhile, melt butter in a skillet. Saute onion in butter until tender, about 5 minutes. Stir in tomatoes, reduce heat to medium low, cover, and simmer for 15 minutes. Remove half of sauce from skillet into a medium size bowl. Add cabbage to remainder of sauce in skillet and cook coverted on medium low heat, stirring occasionally for ten minutes, or until tender. Reduce heat on pot to a simmer. Remove beets from pot and set aside to cool. Remove quartered potatoes and add to bowl with sauce. Mash potatoes, adding milk, until creamy. Stir mashed potato mixture into soup in pot. Grate beets, removing skin if desired, or grating it in. Combine grated beets and cabbage into pot. Add vinegar to taste (optional but recommended with sweet beets). Add salt and pepper to taste. Stir in a teaspoon of dill. Cover and cook for at least another 5 minutes on low heat, then let it cook in its residual heat for as long as desired. Serve hot, garnished with sour cream and dill.

Next.

Previous.