Search Results: "xam"

12 April 2006

Matt Brown: Loading GPG / SSH Keys from a USB Key, Round 2

Back in January I talked about setting up some scripts to automatically load ssh/gpg keys into the appropriate agents when you plugged in a UBS key. I had quite a number of people ask me for my scripts, but they just weren’t quite ready. I’m still not entirely happy with the solution that I’ve come up with, but I figure its working well enough to get some feedback now. It’s based very heavily on the usb-storage script originally written by Sean Finney, so I think that means I owe him Pizza now. However while its based on the usb-storage script it has changed in a few major ways: The mounting of the partition is the key change and I’m still tossing up whether the way I’m doing it is best or whether I should return to having it handled by the script. The primary reason for changing it was to allow the partition to be mounted in a stable location (as opposed to a random directory under /var/tmp) so that I could symlink from appropriate places in my home directory to the partition on the key. The symlinking is needed to keep GPG happy as the gpg-agent seems to store only the passphrase and requires access to the private key whenever you need to sign/encrypt something. The way ssh-agent works is much nicer in this respect, in that once you’ve loaded a key into the agent it doesn’t need to refer to it on disk again. Currently I’m using autofs to mount the partition as needed and this seems to be working well. It’s probably possible to go back to mounting the partition at a stable location from within the script without too much hassle. You can grab the script from http://www.mattb.net.nz/debian/misc/manage-keys The remaining details for my configuration are below: First, setup udev to rename the key partitions to a static name and then fire the script at the appropriate times
/etc/udev/rules.d/usbkey.rules

ACTION=="add", KERNEL=="sd?2", SYSFS serial ="A0494386139B005B", NAME="%k", SYMLINK="usbkeys", RUN+="/usr/local/bin/manage-keys"
ACTION=="remove", KERNEL=="sd?2", RUN+="/usr/local/bin/manage-keys"
Then setup autofs to mount the partition on demand
/etc/auto.master

/media/usb /etc/auto.usbkey --timeout=10

/etc/auto.usbkey

keys -fstype=ext3,ro,noatime,nosuid,nodev :/dev/usbkeys
I keep only id_dsa and secring.gpg on the key and symlink from the appropriate places in my homedir to /media/usb/keys/

matt@argon:~$ ls -l .ssh/
total 76
-rw------- 1 matt matt 612 2006-04-12 22:45 authorized_keys
-rw-r--r-- 1 matt matt 2694 2006-04-12 22:46 config
lrwxrwxrwx 1 matt matt 22 2006-04-13 01:08 id_dsa -> /media/usb/keys/id_dsa
-rw-r--r-- 1 matt matt 612 2006-04-12 22:46 id_dsa.pub
-rw-r--r-- 1 matt matt 58851 2006-04-12 23:10 known_hosts
matt@argon:~$ ls -l .gnupg/
total 2336
-rw-r--r-- 1 matt matt 126 2006-04-12 22:56 gpg.conf
drwx------ 2 matt matt 4096 2006-04-12 23:07 private-keys-v1.d
-rw------- 1 matt matt 1175737 2006-04-12 23:29 pubring.gpg
-rw------- 1 matt matt 600 2006-04-13 01:51 random_seed
lrwxrwxrwx 1 matt matt 27 2006-04-13 01:08 secring.gpg -> /media/usb/keys/secring.gpg
-rw------- 1 matt matt 10560 2006-04-12 23:27 trustdb.gpg
And that’s basically it. The script takes care of the rest. The main problem I’m having with the script at the moment is that it doesn’t autolock the screen when you remove the key because gnome-screensaver-command is lacking the necessary environment variables to find the DBUS socket it needs to talk to its backend. Need to read up on DBUS/gnome-screensaver and sort out how to fix that tommorrow. Update: Updated example udev config so it doesn’t run a script out of /home

Lars Wirzenius: Random hacks: doc-get

I often want to save interesting web pages on my own disk, so that I have a copy even off-line, or in case the page goes away. Occasionally a bit of a pack-rat I am, yes. Web browsers can do this, but not in a perfect manner. For example, Epiphany does not save all embedded objects (images), so viewing the saved page can result in images being loaded from the net. Another problem is that I'd like to record the URL of the page that was saved, in case I want to go back some day. And finally, I would like to be able to get an entire multi-page document (say, a manual) in one go. The other day I played around with wget options, and came up with this set:
wget -N -nd -k -p -H -P "$dir" "$url"
This seems to work fairly well so far. I've wrapped it in a little shell script I call doc-get. It doesn't do the multi-page document thing yet, but I'll look at that later. More things that doc-get might do, but that I'm probably too lazy to implement in the near future: updating an already saved document; better heuristics for the name of the directory (currently it's date + MD5 of URL); having a central registry of saved documents, so that you can do "doc-get --update-all" and refresh everything; inventing something to make it easy for publishers of free documents (say, much of the Creative Commons stuff) easily downloadable by doc-get, even if their directory structure is complicated.

Erich Schubert: Python pitfall of the day: <tt>def function(var= )</tt>

I was hunting an odd bug in a python program of mine. Here's a condensed code snippet for explanation:
class odd:
        def __init__(self, a, b= ):
                self.b = b
                self.b["a"]=a
one = odd(1)
two = odd(2)
print one.b["a"]
That code looks reasonable, doesn't it? The parameter "a" is required, but other parameters can be given in a hash. So what output would you expect? The output is 2. The reason is as follows: Python creates an empty hash, and b is a reference to this hash per default. To the same hash each time. So the code is basically equivalent to
class odd2:
        default_for_b_in_init =  
        def __init__(self, a, b=default_for_b_in_init):
                self.b = b
                self.b["a"]=a
and not (as I had expected):
class odd3:
        def __init__(self, a, b=None):
                if not b: b =  
                self.b = b
                self.b["a"]=a
Obviously, both behaviours make sense, and the python way is somewhat consequenter. So be careful when using default values in functions! Non-reference types such as integers are fine, so is None, and of course any outside objects you want to be the same for each call. Don't assume the def statement will create any new object. Even shorter example:
def test(a, b= ):
        print b
        b["a"]=a
test(1)
test(2)
will result in the output
 
 'a': 1 
again there is only a single hash b.

11 April 2006

Riku Voipio: planet techsupport

Ross, use

debuild --preserve-env

Now that we are aware of it, we might fix the default for the next release. Of course, if I guess correctly where you need scratchbox, you can't use a new version anyway anytime soon... Crappy Crap..

Speaking of new versions, Scratchbox 1.0.3 AKA Scratchbox Apophis (looks like our new developer is Starg te fan..) is out. Most important change is:

* easier support for "foreign" toolchains and host binaries.

In older versions toolchains and other host had to be built with scratchbox's own HOST toolchain using a gar-based build system. While making your own toolchain using scratchboxes build system is really not hard, it seems to scare people away. With foreign toolchain support, you can for example take CodeSourcery's excellent prebuild Gcc 3.4 2005q3-2 arm EABI crosscompiling toolchain and just drop it in. OTOH copying, setting up the symlinks, support files etc is a bit tedious, so that particular example is available Prepackaged too ;)

10 April 2006

Enrico Zini: What package is eating up my disk space?

My 5Gb /usr partition is full. What do I have installed that's eating up all the space? Let's see:
#!/usr/bin/ruby
# pkgsizestat - Display the installed size of packages in a filesystem
#
# Copyright (C) 2006  Enrico Zini <enrico@debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# Display the installed size of packages in the given filesystem
# Defaults to /usr if non specified
#
# Usually used as "./pkgsizestat /usr   sort -nr   less" to see what packages
# are filling up your /usr partition
dev = File.stat(ARGV[0]   "/usr").dev
def pkgsize(name, dev)
      size = 0
      IO.foreach(name)    line 
              begin
                      st = File.stat(line.chomp)
                      if (st.file? && st.dev == dev)
                              size += st.size
                      end
              rescue
              end
       
      return size
end
Dir.glob("/var/lib/dpkg/info/*.list").each    file 
      puts "%d %s" % [pkgsize(file, dev), file.gsub(/.+?\/([^\/]+)\.list/, '\1')]
 
Neat little useful ruby script. Ruby is nice in making scripts short clean and compact. Now I need a shorter version of the GPL :) Update: Florian Ragwitz suggests to use dpigs(1) from debian-goodies instead. What my script does that dpigs doesn't do, however, is counting only those files provided by the packages that reside in the given partition. I could for example use my script to see what's filling up the root ('/') partition when /usr is mounted elsewhere, and I find out that the top package is not openclipart-svg, but linux-image-2.6.15-1-686. Update: htom sent an updated version to sum all sizes and show only up to a certain size:
dev = File.stat(ARGV[0]   "/usr").dev
def pkgsize(name, dev)
      size = 0
      IO.foreach(name)    line 
              begin
                      st = File.stat(line.chomp)
                      if (st.file? && st.dev == dev)
                              size += st.size
                      end
              rescue
              end
       
      return size
end
pkgs =  
Dir.glob("/var/lib/dpkg/info/*.list").each    file 
  pkgs[pkgsize(file, dev)] = file.gsub(/.+?\/([^\/]+)\.list/, '\1')
 
pkgs = pkgs.sort
pkgs.reverse!
to_size = 1024**3 # show up to 1 GB
size = 0
pkgs.each do  a 
  size += a[0]
  puts "%d %d %s" % [a[0], size, a[1]]
  break if size >= to_size
end
Ralph Amissah posted a different variant:
# [License part omitted]
dev=File.stat(ARGV[0]   "/usr").dev
def pkgsize(name, dev)
  size=0
  IO.foreach(name) do  line 
    begin
      st=File.stat(line.chomp)
      if (st.file? && st.dev == dev)
        size += st.size
      end
    rescue
    end
  end
  return size
end
def space(file,dev)
  "%d %s" % [pkgsize(file,dev),file.gsub(/.+?\/([^\/]+)\.list/,'\1')]
end
@used=Array.new
Dir.glob("/var/lib/dpkg/info/*.list").sort.each do  file 
  x=Array.new
  x << space(file,dev).split(/\s+/)
  p [x[0][0].to_i,x[0][1]]
  @used << [x[0][0].to_i,x[0][1]]
end
#p @used.sort.each    x  p x  
@used.sort.each    x  puts "# x[0]  # x[1] "  
#redirect to file?
Thank you everyone for the nice feedback!

8 April 2006

Lars Wirzenius: Random thought: Simplicity in web browsers

I like simplicity. I want things to be as simple as is sensible, but no more, and because of this, I tend not to particularly like web browsers. Web browsers are extremely complicated beasts, and to a large degree this is for stupid reasons, like having to support any kind of broken markup. I think the world would be better if web browsers would simply not display pages with broken markup. However, web browsers also have other things that irritate me, even if ever so slightly. For example, there's way too many buttons and other elements in their tool bars. Compare the following four screenshots of Mozilla, Firefox, and Epiphany, with their default configurations in Debian, with the version of Epiphany that I have configured myself.
Mozilla screenshot Mozilla: six real buttons, URL box, throbber, four bookmark buttons, plus widgets for rearranging or otherwise manipulating the toolbars themselves.
Firefox screenshot Firefox: six real buttons, URL box, Google search box, throbber, two bookmark buttons.
Epiphany screenshot Epiphany: nine buttons, throbber, and URL box on a separate line.
Epihany   la liw screenshot Epiphany la liw: four buttons, URL box, throbber.
Now, I admit that I'm a bit of a power user, and don't need quite as much hand-holding as a novice, but still, does anyone need a bookmarks button in the toolbar? People who make bookmarks often will quickly learn to type control-D, and those who do it only rarely don't need a toolbar button, they're happy enough with a menu entry. And why do Firefox and Mozilla need a button called "Latest Builds"? How is that interesting to anyone except Mozilla developers? Me, I prefer my setup. Four buttons plus the URL box. All buttons are easy to hit with the mouse, no need to hunt and seek the right location. Besides simplicity, my configuration saves on vertical space, which is pretty important for us laptop users.

Julien Danjou: New TuxFamily web site

TuxFamily.org has just launched his new web site. It now supports english, spanish and, of course, french. For whose who don't know TuxFamily yet, it's a non-profit organization aiming to provide hosting services for free software projects. It's like SourceForge somehow, except that we don't use gforce but vhffs, our own hosting system. I would say that the main difference is that we don't provide a lot of preinstalled tools like bugtracking system, release publishing infrastructure, forums, etc.
We "only" give web spaces (with PHP support), MySQL or PostgreSQL databases, Subversion and/or CVS repositories, DNS servers hosting, mail hosting, mailing-lists, etc. For free, and for all projects which are free as in free speech. And not only free software projects, we also host some free art stuffs. For example, we host the prism54 project. Although the organization is french, our goal is to be open to other countries, so we began to internationalize all of our web interfaces. It is almost complete now, so maybe you could give it a try if you need hosting for your next project!

6 April 2006

Mike Beattie: Planarity

Seriously, I'm not just responding to only you Erich.. Anyway, that's an evil thing to post on a Friday (for me). I can see I'll get no work done now. *sigh*. Oh, I found an example of your solution: Planarity Solution

Enrico Zini: Converging to a solution

Sustain a discussion towards solving a problem is sometimes more important than solving the problem. I can't decide if this is trivial or counterintuitive. Anyway it's been quite enlightening when it came out. I once took this note:
I found that with my projects, when someone posted a mail about a problem I would work maybe some days to find a solution, and just post the solution at the end. However, now I realised it's more costructive to have the problem-solving process itself happen online. This way, instead of keeping people waiting in silence for a few days they can get quicker feedback and extra informations, and they also have a chance to participate to solving the problem before I manage to. For example, when I have to interrupt to go home or sleep, someone else can pick it up and do another step. Plus, the entire problem-solving process remains documented, which will provide more written information for future readers.
This note was from a few months ago; however, I still fail to do it. Bad habits are sometimes hard to change. Please kick me about it :)

Mike Beattie: A solution for blocking ssh probers/scanners.

Erich, There's a much easier solution to blocking those ssh scanning bastards... some nice friendly iptables rules! (I forward ssh to an internal system, so this is in the FORWARD chain.. use the INPUT chain otherwise)
### Catch SSH probes
iptables -A FORWARD -p tcp --dport 22 -d <local net> -o eth0 -s 0/0 -i ppp0
         -m state --state NEW
         -m recent --rcheck --hitcount 3 --seconds 60 --name SSH_PROBERS
         -j LOG --log-prefix "Adaptive-FW SSH Prober: "
iptables -A FORWARD -p tcp --dport 22 -d <local net> -o eth0 -s 0/0 -i ppp0
         -m state --state NEW
         -m recent --update --hitcount 3 --seconds 60 --name SSH_PROBERS
         -j DROP
iptables -A FORWARD -p tcp --dport 22 -d <local net> -o eth0 -s 0/0 -i ppp0
         -m state --state NEW
         -m recent --set --name SSH_PROBERS
         -j ACCEPT
So, in the INPUT chain, you wouldn't use -o, and -d would be the IP on your external link.. in this example, ppp0. What it does, is uses the ipt_recent module, tracking connections from a given IP. 3 incoming connections in 60 seconds will cause the remote host to be blocked. Of course, this affects normal logins too, so for known hosts, it pays to insert a rule beforehand that does a -j ACCEPT. I'm enjoyng the very short log entries for a given ssh scanning host in my logcheck mail :).UPDATE 2006/04/07: Whoops...
Sorry Erich, didn't notice that :)

Martin F. Krafft: Sawasdee, Thailand!

The day of our departure to Thailand was remarkably stressless, I even found the time for lunch and coffee with one of my dearest friends. We had plenty of time catching the flight to Vienna, and if it wasn't for the filthy Danish sex tourist who kept burping, snorting, and generally being a bother next to me on the fliught from Vienna to Bangkok, I would have said the trip was perfect. We got in to the city in the afternoon, found a fair hotel next to Sukhumvit Road and headed off to run errands, cashing traveller cheques, drinking juices, and walking around. Just ready for sunset, we got up to the 59th floor of the amazing Banyan Tree Hotel, and two further flights of stairs led us to the roof-top bar. That evening, we went through Patphong and Soi Cowboy, the two centres of the infamous Thai ladyboys, and after a beer or two, we headed for the hotel and drifted away almost immediately. Our plans to head for Lumphini Park in the morning to participate in the Tai Chi sessions were foiled by oversleeping, but we can do Tai Chi on other days. Rested, we headed for the train station to send off the bag with clothing via train cargo to Chiang Mai, where it will (hopefully) be waiting when we arrive in two weeks' time. This message reaches you from Chinatown, we're catching something to eat before going 3rd class to Ayuthaya. Tourists usually take a taxi for 1000 Baht (about 20 EUR), we pay 15 Baht each and will be in touch with the locals. This being my first post on my trip towards Myanmar, so there's nothing much to write. One thing I found noteworthy is the change in the way taxis work these days. Two years ago, I learnt to insist on taxis starting their meters rather than quoting a price up front. Last year, my cousin and I made first experiences with taxi drivers refusing to go with the meter. This years it's nearly impossible; apparently too many tourists didn't think enough and now the drivers are unwilling to give up the profit from ripping them off. Example: Sukhumvit to Hua Lamphong station was 69 Baht in a taxi (our hotel told the driver to behave), and I sure we would have been quoted 200 Baht with a possibility to bargain the driver down to 140 or so. Anyway, that's it form today. I'll write again from Ayuthaya or Khorat.

5 April 2006

Adeodato Sim : grep-dctrl -s Source:Package

I just wanted to say thanks to Antti-Juhani Kaijanaho, the author of grep-dctrl, for implementing a fix for my wishlist bug #355960. Now it is possible to obtain the value for a field (eg. Source) from some other field (eg. Package), when the former is not present. For example, to obtain a list of source packages that need to be rebuilt in a MusicBrainz transition: grep-dctrl -FDepends musicbrainz -ns Source:Package. Formerly, one would have to list binary packages, and do some juggling to get the list of sources. I think regular grep-dctrl users will surely appreciate this capability. NP: Almod var & McNamara, Suck it to me

Erich Schubert: Programming languages that need to die.

We have way to many programming languages. So I'm putting together a list of languages that need to die. ;-) Honorable mentions that didn't make it into the "must die" list: Languages that I think have issues, but couldn't put on this list: So let the flamewars begin. I'll try to keep track which language zealots are the worst. Without having started, I bet it'll be the Lisp zealots.

Rapha&#235;l Hertzog: Leader election: last chance to vote

Given the low participation, it looks like the choice of a DPL is difficult this year. It probably means that the platform of the candidates do no suit everybody… however with DPL teams, there’s more than just the DPL and in theory each member should have their own platform. That’s not the case for me because writing a platform is a big job… which I can avoid since I’m not candidate. :-) However I now do feel the need to tell what I would like to propose (and do) if I’m part of a team so that you know better what to expect if you vote for a team where I’m involved. I’d just like to give a warning, those items are quick notes and are in no way full- and flesched out solutions, they will need to be discussed and refined in all cases, and somes ideas may be dropped of course. This list is neither complete nor definitive. Not all items will be achieved but each of them is a real progress IMO and I’d like to be able to work on them. For people who are concerned by those changes, I’m sorry if you discover my ideas by this post even before I had the opportunity to talk to you… I’m posting those ideas now because they may be considered by people who are currently voting, but it does not mean that I’m not interested to discuss them with you. It’s also true that some of those ideas can be implemented without being part of the DPL team and I’ll certainly try to implement some whatever the outcome of the election, but I really believe that being part of a DPL team helps greatly because you have access to some important informations, and you can effectively discuss with core teams which are otherwise difficult to approach for non-technical discussions when you’re a random DD. And last but not least, the trust of the developers is a big motivation (at least for me) to work effectively on those problems. See this post for my personal vote recommandation and see you in 3 days for the result of the election !

4 April 2006

Lars Wirzenius: Random thought: I've finally touched OS X

I played around with a friend's Apple Powerbook for a while today. It is nice, weird, confusing, and intriguing all at the same time. This was my first real experience with Mac OS X, but it was clear that the user experience is quite different from what I'm used to with GNOME and Linux. Some things were clearly better, others clearly worse. For example, Safari's "back" button and the window close button are right next to each other so it was easy for me to repeatedly accidentally close a window when I wanted to go back. It would be quite interesting to see what it would be like to use OS X as my primary computer for real, for a month or three. I don't think I it would be quite interesting enough to buy an Apple laptop just for that, though.

Matthew Palmer: Rewriting in Rails -- A Practical Examination

[Note: this article was mostly written some weeks ago; I left it in my "to be edited" box and then promptly forgot about it. So any and all temporal references are way out of whack. Since originally writing this article, I have commenced an incremental rewrite of an in-house business management application from crazy-PHP (a common -- some may say overwhelmingly so -- dialect of the language noted for it's complete lack of any sort of good software development practices, such as the creation and use of functions (!)) into Rails. Articles on this effort will be appearing presently.] Almost immediately after I'd finished writing my previous discussion on why rewriting software is evil, I decided to make a little experiment. What I did was take a fairly well factored PHP application, and rewite (a portion of) it in Rails. My intent in this was not to produce a production-quality rewrite. I have no interest in proliferating yet more functionally equivalent clones on the world. Instead, I undertook the work simply to get a feel for (a) writing a whole, traditional, Rails app in a short space of time, (b) how quick Rails really was to produce an application, and (c) whether wholesale rewrites really are as boring and life-sucking as I imagined them to be. My methodology was this: with a small amount of knowledge of the target application (SysCP), the existing database schema and templates, and a weekend, rewrite as much of SysCP as I could in a close-as-possible reproduction of critical SysCP functionality. My summary results are: rewrites are as boring as I thought they would be, Rails is powerful but fairly complex and slightly buggy when you get down into it (especially if you're working from an existing -- possibly suboptimal -- database schema), but overall, Rails is Way Good Stuff. On the boredom aspect -- I had two days to write code. I had some domestic duties to attend to (walk the dog, visit the hardware store, help my wife with attaching a new bag rack to her bike, mow the lawn, etc) but on the whole, it was dedicated to programming. I've spent whole days (hell, 40 hour marathon stretches) cutting code before. I knew this wasn't a six-month deathmarch, but only a weekend experiment. Despite that, I feel that my motivation levels were lower than they normally are when coding. I can only imagine what it must feel like, two weeks into several months of hard core coding, knowing that you'll end up with what you had before, functionally speaking. If you are going to do the rewrite thing (and may the Flying Spaghetti Monster have mercy on your soul if you do), then pick the right project. SysCP is large masses of tangled PHP (is there any other kind?) but it has a fair amount of local and global structure once you get down to it -- for instance, it's quite well factored into business logic and display, and the code is broken down fairly logically by action handler, so you get entire source files that look like this:
  if ($action == 'edit')
   
    // 150 lines of twisty passage PHP
   
  else if ($action == 'new')
   
    // Another 150 lines
   
  // repeat for another few actions
and so on. The nice thing about this is that, if you have to look for how something works, you can almost certainly find it in one place in the source. Deciphering it might be another matter, but at least you've got something to start from. As I mentioned, the display in SysCP is pretty nicely split off from the logic -- a large number of templates, with common header/footer files, with some small parts in common templatettes. Some HTML is still generated within the actions, but due to the above action-based structure, it's usually fairly easy to identify all of the HTML that will be associated with a particular action and turn it into a coherent Rails template. I would dread doing a rewrite of the presentation layer of, say, IRM. It's idea of well-factored presentation is to separate print statements from logic by a blank line. To my great shame, I've had the reins of IRM for a year, and it's still this bad. I claim it's because I hate HTML coding with a vengeance, but I think I'm actually just scared to try and tame that particular monster. (Update: Martin Stevens has been doing some good work turning IRM's HTML into Savant templates. The only downside is that I can hear his manic laughter -- caused by IRM's insanity slowly infecting him -- all the way from England, and it's keeping me awake at night). I also had to re-learn that most hated but most important of lessons -- that, no matter how much reading you may have done, until you've cut chunks of code in a language or environment, you have no idea how it actually behaves in your brain. Specifically, I spent a fair amount of my alloted rewrite time learning a few little lessons in how Rails actually behaves, and all of it's cool little features. Of course, everyone is going to have this pain, and I've suffered it in every language that I've done any appreciable amount of programming in, but it's always a shock to the system that -- after all this time programming -- a new language still makes my brane tingle curiously for a while. Luckily, I'd read and digested all of both the Pickaxe (Programming Ruby) and AWDWR (Agile Web Development with Rails) so I knew what was possible, I just usually wasn't sure how exactly, so I spent a lot of time with my head in the books. Rails' little foibles also bit me in the bum more than once. For example, I spent over an hour (a no foolin' hour) trying to hunt down what I was doing stupid in my code to make Rails completely forget about the value of a couple of my fields. The answer turned out to be to restart Webrick (Rails' internal webserver for development testing), and the problem cleared right up. You could hear my screams of anguish from the moon (even through the vacuum of space -- it was a lot of anguish). Rails isn't the Final And Ultimate Solution To The Webapp Problem, but it's a good start. There is near-zero administrative bumf when you're writing a Rails app. Rails is fairly intelligent about working out what you want done from the world around it. Code generators (which produces sensible, minimalist templates -- not the ugly, unmaintainable behemoths produced by Visigoth Studio, which has given the whole code generation world a bad name) handle a lot of the low-level "oh bugger, I have to add a new file" feeling. It's very, very anal about project structure, but (in contrast to many other bondage-and-discipline frameworks I've looked at in the past) this structure seems almost comforting (maybe I'm just getting old and turning into a satisficer). What all this means is that you (a) don't write much code unless it moves you toward your goal, and (b) Common structure means that any Rails app will be fairly familiar to an incoming programmer. Unfortunately it also means that cunning wankers will, sooner or later, work out a whole pile of ugly tricks and contortions to get themselves out of Rails' comfortable-but-no-doubt-incompatible-with-many-people's-ways-of-thinking straitjacket, which I will (sooner or later) end up maintaining. Like many of Rails' (and Ruby's) features, though, I don't see them being any more abusable than most features of any programming language or environment -- and at least they're powerful and useful (unlike, say, register_globals, magic_quotes_gpc, magic single-character variables, mandatory indenting, or banning tabs as indent characters -- I thought I'd spread the slagging amongst lots of languages). Productivity-wise, although I was only just kicking off my Rails webapp knowledge, I felt I was doing fairly well. From experience, what I produced in my weekend was roughly on par with what I could produce in PHP in the same amount of time, had the situation been reversed. Considering that I have about 3 weeks of Ruby/Rails knowledge, and about 5 years of PHP experience, I think that's a big win. (Update: I've since produced a DNS management applet for work in about 6 hours billable time, and a virtual mail account application in about 12 hours, both using Rails. There isn't a hope in hell that I could have performed a similar feat in PHP, especially with the same amount of inherent flexibility that the Rails solutions contain). Overall, my impression of wholesale rewrites as being soul-sucking experiences stands. I suggest they be approached with the greatest of care, and only be permitted after an appropriate period of psychological counselling. There is plenty of code that needs rewriting (but why do I always have to find it?) but replacing it by doing an rm -rf on the source tree and starting again is not the answer.

Erich Schubert: Windows fileservers suck

... give me samba, please! I've recently been fighting windows file servers. They run on totally oversized hardware (P4-HT, 8 SATA drives in a 7-active-1-hotspare RAID-5 set) but still don't perform reasonably. (2.5 MB/s write performance is really bad, read performance is somewhat okay, though) And then it's so easy to confuse windows... seems like Windows can't handle directories ending with a dot. But you can easily create such folders over the network with SMB... name a folder "foo." and windows can't handle it any more. Or "...". Windows can't delete or rename it. And I'm talking NTFS, not plain old legacy FAT. So if you're going to hide data on a windows box, just store it using SMB in such a folder. And if you want to be really evil, write a script that autodiscovers writeable network shares around you and creates "You suck." folders there. Windows users will start running around screaming, but obviously you can't be the culprit, since you can't access Windows shares, can you? I've also been porting a python app to Windows. Python is so nice, and PyGTK works like a charm on windows. Now if Windows just wouldn't suck as much... for example, it doesn't have os.fork(). And it's I/O charset semantics are a complete mess. Once you don't use only 7-bit ASCII you're likely to go crazy. Seems like the console on Windows always uses codepage 437. The filesystem probably cp 1252. Windows internally claims to use 16-bit unicode. So if you want a python script to run on windows: I can recommend python for cross-platform coding however. The PyGTK GUIs are really nice, much nicer than all that java stuff out there. And these "issues" with windows aren't really Pythons fault, but Windows.

2 April 2006

Barry Hawkins: If your Debian menu in GNOME ever disappears

I recently had my Debian menu in GNOME disappear for reasons I could not explain. Since this is where the launcher for many of the applications one installs are typically housed, it was quite the inconvenience. I posted to the debian-user mailing list, and asked around on IRC in #debian and #debian-devel, but the most I ever received was a suggestion to run 'update-menus' from a command line. Having done that within the first 30 minutes of the issue’s appearance to no avail, I resigned myself to making do without the menu for the time being. Uninstalling and reinstalling the menu package was of no help. Reinstalling the gnome package yielded no joy, either. I could examine the contents of /var/lib/gnome and see that the menu structure was being built, it just wasn’t making into the menu. Through some poking around and talking with some folks who emailed me off-list to admit that they, too, had experienced this and were at a loss, the mystery has been solved. Apparently during some upgrade to packages, the menu-xdg package had been removed. Reinstalling it restored the menu to its formerly visible and altogether handy state. I posted a follow-up reply to debian-user in hopes of it helping posterity. This issue must seem like such a stupid or neophyte question that some people refrain from replying to a mailing list post about it. For those who knew the answer (I assume someone did), the question must have somehow seemed unworthy of reply. However, looking at the menu package, I don’t even see a Suggests entry for menu-xdg. It would be a shame if there are other people facing this issue with no resolution, so I am openly admitting that I had this problem in the hopes that it helps someone else out. Perhaps I should file some sort of wishlist bug, but my knowledge of the menu system is still narrow; maybe I will. I find myself periodically expanding the Debian menu on my desktop just to look at it and enjoy that warm, cozy feeling I get from having it back. 8^)

Barry Hawkins: Why make a free runtime for Java?

I was at my monthly Java ™ user group meeting tonight, and during the pre-meeting discussion our president Burr Sutter asked a question he usually asks: “So, anybody working on anything exciting?” This typically is taken as “does anyone have a really cool Java ™ project that they are working on right now that would be neat for us to hear about?” I usually sit there, not saying anything. But tonight, nobody had anything much, and I finally spoke up about free runtimes for Java ™. I told them that great progress is being made in the free runtimes for Java ™ arena, particularly in GNU Classpath and Kaffe. After my update, Burr asked a very good question: “Why would you work on a free, open runtime for Java ™ programming language?” My answer follows. You would work on it in order to have a free alternative to a platform governed by the SCSL. You work on a free runtime for Java ™ because a free alternative would be better than what we have now; a closely-guarded and largely ingrown platform. You work on improving a free alternative because you are free to participate without that project demanding (via a legally-binding license) that you can only work with them from here on out, and that nothing you learn while devoting your time and energy to them (without compensation) can be used elsewhere. If you do share it elsewhere, and that project finds out, their legal team will make an example out of your ass. You prefer a free alternative runtime for the same reason that you prefer the free alternatives to the non-free frameworks and platforms available for use on Java(TM). Why is Hibernate so popular? Why is Spring so popular? Why is EJB not? Because innovation by committee, while better than a ruthless, unaccountable corporate entity concerned solely with its own betterment, is still not as good as free, open cooperation and collaboration. Is this idea so new? Don’t we try to teach kids that sharing and honesty is the Right Thing ™ to do? I will probably flesh this out as an article at some point, but I wanted to get something written down tonight, while it’s still fresh in my mind.

Erich Schubert: Read Feeders

... or feed readers, whatever. I'm currently using Liferea, and I've previously been using Straw for a long time. While both are okay, I consider liferea a bit more polished than straw (and it definitely has some functions like Extensions (aka filters) I really like. For example Heise only has a rather crippled feed (which doesn't even contain the teaser part of the article), so I grab the front page and convert it to a feed myself. And liferea allows you to group feeds together into one folder and read them like they were one feed. Very nice if you have a couple of comic strips which are each updated once a day, saves a couple of clicks. Straw also didn't have proper threading IMHO, so every now and then it was unresponsive while updating the feeds, especially at startup. However, straw at least did some caching of "attachments", which is very nice when you're using it to e.g. read some comic strips via RSS. Liferea doesn't cache any images, and this totally sucks. For example the Technorati icon it has for each entry is loaded again and again (or at least it always takes a second to be drawn... Oh, and depending on the rendering engine you use in liferea (gtkhtml or mozilla, I'd recommend the first) some keys may or may not function. Oh, and please don't suggest I try "blam". From what I've read it's rather minimalistic so far, and I don't like C#/Mono stuff.

Next.

Previous.