Search Results: "xam"

10 November 2008

David Welton: Generating Rails Fixtures From Large Datasets

I've been working with Tomaso Minelli doing some Rails work, and one thing we needed to do was set up some tests. The situation we are in is that we already have a large set of data to work with in our development environment, but getting that data into .yml files is no easy task. Since we have a fairly large number of interdependent tables, dumping one of them alone is pretty useless, unless you manage to get the other tables it links to, and so on and so forth. Dumping all the data would make testing quite slow, and really is too much to be useful. Here's the rough solution we arrived at:

@fixtures =  
@seen =  
# Do something with a fixture.  In this case, we store it for later.
def handle_fixture(record)
  @fixtures[record.class.table_name]  = []
  @fixtures[record.class.table_name] << record
end
# Get some sort of unique way of identifiying a record - class name and id.
def unique_record(record)
  return record.class.to_s + " " + record.id.to_s
end
# Grab all the relations of a class and add them to the queue.
def add_fixture(record)
  ur = unique_record(record)
  if @seen[ur]
    puts "LOOP!"
    return
  end
  @seen[ur] = true
  puts "Fixture for # record.class.name  - ID # record.id "
  handle_fixture(record)
  record.class.reflections.each do  k, r 
    begin
      if r.macro == :has_many  
          r.macro == :has_and_belongs_to_many
        related = record.send(r.name).send('find', :all, :limit => STARTING_LIMIT)
      else
        related = record.send(r.name)
      end
      related = [related] unless related.is_a?(Array)
      related.each do  related_record 
        if related_record
          puts "    New Record # related_record.class.name  # related_record.id "
          @todo << related_record
        end
      end
    rescue => e
      puts "    ERROR: # e :\n# e.backtrace.inspect "
    end
  end
end
@todo = []
namespace :db do
  namespace :fixtures do
    desc 'Create YAML test fixtures starting from a single model using reflections'
    task :modelbase => :environment do
      STARTING_CLASS = Foobar
      STARTING_FIND  = :all
      STARTING_LIMIT = 1
      tmp = 0
      totale = STARTING_CLASS.find(STARTING_FIND, :limit => STARTING_LIMIT).size
      STARTING_CLASS.find(STARTING_FIND, :limit => STARTING_LIMIT).each do  m 
        tmp += 1
        puts "# tmp  su # totale : # m.id "
        @todo << m
      end
      while true
        if @todo.length == 0
          break
        end
        add_fixture(@todo.pop)
      end
      puts "\n\n# '='*80 \nScan Finished\n# '='*80 \n\n"
      @fixtures.each do  name, fixture 
        if fixture.size > 0
          i = "000"
          filename = "# RAILS_ROOT /test/fixtures/# name .yml"
          puts "Create # filename  for class # fixture.class.name "
          FileUtils.mkdir(File.dirname(filename)) unless Dir[File.dirname(filename)].size > 0
          File.open("# RAILS_ROOT /test/fixtures/# name .yml", 'w') do  file 
            file.write fixture.inject( )    hash, record 
              hash["# record.class.table_name _# i.succ! "] = record.attributes
              hash
             .to_yaml
          end
        else
          puts "Fixture for # name  is EMPTY"
        end
      end
    end
  end
end
It's written in a somewhat quick and dirty way, but it gets the job done. What it does: It takes a single class - hopefully a well connected one - fetches a few of them, and goes from there, exploring all the other objects that the initial ones are connected to, and then dumping them in .yml files in the fixtures/ directory. It could certainly use more work:
  • Additional starter classes, for ones that aren't connected to others.
  • Intelligent examination of data and data sets...
  • For example you could check to see what classes aren't connected to the others and use them as starter classes.
  • If you wanted to waste a lot of cycles, you could also try and aim for a representative set of examples. For an object that has_many something elses, you could try and find one with zero, one with one, and one with a lot, to cover various cases. That could quickly get out of hand for largish data sets though.
  • I'm sure there are various other tweaks, knobs, and levers that could be added to work more efficiently. I'd love to see them!

9 November 2008

Simon McVittie: Implementing D-Bus services with telepathy-glib

(Part 1 of an ongoing series: shiny things in telepathy-glib)
16:46 < epmf> tp-glib is made of magic

—#telepathy, 2008-04-15

Rob pointed out today that I'd been promising to blog about telepathy-glib for several months and still haven't done so. I think there's too much to cover in one blog post, so I'll start with the oldest part - implementing a service (typically a Telepathy connection manager).

While telepathy-glib is (obviously) intended for Telepathy implementors, I think the ideas we've been implementing are likely to be useful for any D-Bus API, particularly flexible/complex APIs where an object implements many interfaces.

Introduction to telepathy-glib telepathy-glib started out as a collection of code extracted from our XMPP connection manager, telepathy-gabble, but at some point it grew beyond that into a wrapper around/partial replacement for dbus-glib. We've been quite pleased with it, really :-) My first major round of work on telepathy-glib, during the first half of 2007, was to split it out from telepathy-gabble (versions up to 0.5.9 were released as part of Gabble 0.5.x tarballs, in fact), leading to the release of the 0.6.x stable branch in late September. This was very helpful for implementing connection managers - Salut, Idle and telepathy-sofiasip (our connection managers for link-local XMPP, IRC and SIP) all started off by forking/cargo-culting from Gabble, and achieved huge code reductions by porting to telepathy-glib. Also, Will Thompson used it in his Summer of Code project, telepathy-haze, to go from nothing to a working and useful Telepathy implementation based on libpurple in a matter of a few months. The second major round of work, which I'll discuss in a later article, added client code to telepathy-glib, obsoleting the older/worse libtelepathy and allowing client programs like Empathy and telepathy-stream-engine to be written using telepathy-glib. In the process, I accidentally reinvented DBusGProxy :-) More details to come later!
Some background: service-side code generation
The secret Collabora code-generation process

(credit: daf)

Supporting D-Bus in the GObject world has always involved quite a lot of code generation. The core API of dbus-glib is heavily reliant on varargs functions, which aren't type-safe and are easy to get wrong. dbus-glib contains a program called dbus-binding-tool, which is meant to generate reasonably sane GObject APIs for D-Bus objects. Unfortunately, it seems to be intended to generate a whole GObject at a time. Early versions of telepathy-gabble used dbus-binding-tool plus a script called gengobject.py to generate API stubs for the exported objects; developers then filled in the blanks, and hey presto, we had a GObject on D-Bus. This was fine up to a point, but had a couple of major drawbacks. Whenever we changed the D-Bus API (quite common during the early development of Telepathy), there was a very laborious and error-prone merging process. We ended up with the following process:
  • copy the D-Bus introspection XML from the telepathy-spec repository into a directory xml/pristine (actually, the canonical form for the spec was Python for a while, and we had a script that exported a contrived object onto D-Bus and introspected itself to get the XML - but that's another story!)
  • preprocess the introspection XML to add the dbus-glib CFunctionName annotation, resulting in a directory xml/modified
  • run dbus-binding-tool and a Python script gengobject.py to generate C source in xml/src
  • three-way-diff the old version of xml/src, the new version of xml/src, and the real C code in src to create a new version of src
  • pray that the diff process hadn't randomly exchanged functions' implementations
  • update the resulting code in src so it worked
  • check the whole mess back into darcs
  • hope that nobody else had made changes that would result in darcs conflicts
If you haven't yet gathered, this was a bit of a nightmare. Also, it was very easy to return the wrong thing from a method without noticing - because all the APIs were varargs, the compiler didn't notice, and the first we'd know about it was a mysterious segfault under certain circumstances.
How telepathy-glib fixes code generation telepathy-glib improves on this by taking advantage of this innocuous-looking feature in dbus-glib:
commit 355ef78d98d6fc65715845d56232199162cab12a
Author: Steve Fr cinaux <steve istique net>
Date:   Thu Aug 17 11:48:20 2006 +0200
    Interface support for bindings.
Instead of running dbus-binding-tool or creating GObjects with D-Bus interfaces, we put the entire Telepathy spec through glib-ginterface-gen.py, a distant descendant of Gabble's gengobject.py. For each interface in the spec, we generate a GInterface that mirrors the D-Bus interface. Any GObject that implements the GInterface automatically gets the D-Bus interface if it's exported onto D-Bus. There are a few non-obvious refinements, though:
  • The signature of the method implementation is always in the mode that dbus-glib calls "asynchronous", where the method implementation can either send a reply message before or after it returns. For "slow" methods, this is the only thing you can do. For instance, many Telepathy D-Bus methods can't return anything until some TCP round-trips to the server have happened. This is also the only thing you can do if you want to extract extra information, like the sender's unique name, from the method-call message (dbus-glib's "synchronous" API doesn't allow this to be done). For "fast" methods, sending a reply message before returning is just as easy as using the "synchronous" API (it's just a difference of syntax), and has an API consistent with that of the "slow" methods, making it easier for service authors.

  • The layout of the GInterface vtable is private, and (auto-generated) accessor functions are used to fill in implementations. This means our ABI doesn't change just because we re-ordered functions in the spec.

  • If no implementation is provided for a method, we just raise an appropriate error (org.freedesktop.Telepathy.Errors.NotImplemented), rather than suffering an assertion failure. This means we can safely add methods to an interface.

  • While we're generating code anyway, we generate some static inline wrapper functions which wrap dbus_g_method_return(), to have type-safe method returns. You can easily check that a method replies with correct types, by checking that the implementation of Foo() replies by calling tp_svc_some_interface_return_from_foo().

  • Similarly, we generate wrapper functions to emit signals, to get type-safe signal emission.

Not all interfaces are stable enough to be included in telepathy-glib's stable API and ABI, so some of our other projects include a copy of the telepathy-glib code-generation tools, and generate their own "mini-telepathy-glib" (traditionally in a /extensions/ directory) for their implementation-specific (drafts of) interfaces. This isn't yet as polished as it ought to be (mainly because we don't want to freeze the augmented-introspection-XML format that we write the Telepathy spec in, because it's rather ad-hoc and hackish in places) but it works quite well in practice. To see what this looks like in practice, have a look at the examples in telepathy-glib, or at a Telepathy connection manager like telepathy-gabble.
Mixins and base classes Another feature of telepathy-glib which makes life easier for connection manager authors is that it provides "mixins" and base classes which implement some of the GInterfaces. There's absolutely nothing magic about the base classes - they don't have any access to private implementation details of the GInterfaces, they just implement them like everyone else does. The "mixins" are only slightly more magical - they store some extra state inside the structures representing GObjects and their classes, and use it to provide default implementations of some or all of the methods on a particular interface (or two interfaces, in the case of the new TpMessageMixin). I'll leave it up to Rob to explain those in greater detail, since I seem to remember that he invented them :-P The examples and regression tests in telepathy-glib are quite good examples of how these work in practice.

7 November 2008

Axel Beckert: e-mail.is-not-s.ms

When I first read http://two.sentenc.es/ in (if I remember correctly) madduck’s signature, I thought something like “This can’t be! Why are people castrating themself?” Although I really understand that the inventor has good reasons for such a personal policy, I notice how much time I waste by trying to fit all the information I want to transmit in the 160 characters a short messages allows — or, even worse, into the 140 characters microblogging services like identi.ca or Twitter allow. So I had to oppose something to this, but even to only reach the coolness level of the domain “sentenc.es” is hard, you probably can’t top it at all. For luck, I’m not alone and Venty had the right idea for a hostname which has at least some geeky niveau. So here it is, our pleading for e-mails as long and detailed as necessary:

http://e-mail.is-not-s.ms/ A German version will be available soon at http://e-mail.ist-nicht-s.ms/. Feel free to add either URL to your e-mail signature. :-) Oh, and thanks to the Government of Montserrat which allows strangers to register .ms domains without any hassles. :-) Update / FAQ Seems to be necessary to make a few things clear…

  1. No, I do not think that everyone using two.sentenc.es has neither style nor knows anything about grammar or punctuation. What I say is that the site two.sentenc.es itself with its comparision to short messages (and especially without reading the author’s blog post about the site’s background) indirectly suggests to drop grammar, punctuation and style by cramming all information into a limit number of characters as often done with short messages or microblogging. And the limitation in senctences leads to tapeworm sentences which I try to avoid since they’re considered bad style, too.
  2. And yes, it’s consciously written and designed to be the opposite of two.sentenc.es — even the colors and the font — and therefore is of course very close to the original. See it as it parody or satire if the closeness makes you angry.
  3. And no, I currently don’t care if the site makes less sense if you don’t know two.sentenc.es — people usually can follow hyperlinks on websites.
  4. We weren’t the first ones who noticed that e-mail is not SMS. An example of the problem described above from 2001.

Martin Michlmayr: Please test debian-installer rc1 images on ARM and MIPS

debian-installer rc1 is going to be officially announced next week. However, the netboot images are already available. I'm now looking for people who are interested in testing these installer images on ARM and MIPS based machines. If you have a spare ARM or MIPS machine or want to reinstall your machine for some reason (for example to move from arm to armel), please see my messages on debian-arm and debian-mips for more information. I've used this opportunity to update all my installation instructions to lenny. See here for Debian on Linksys NSLU2, Thecus N2100, QNAP Turbo Station, HP mv2120 and Cobalt.

6 November 2008

Pablo Lorenzzoni: Bash prompts: the essential

Bash is probably the most common command-line shell in the GNU/Linux world. Although a lot of people use alternate shells (such as Zsh), Bash is still shipped with most mainstream distros as the default. Once you have a lot of different remote machines, all running Bash as the shell, it becomes increasingly difficult to pay attention to the prompt, and typing reboot in a machine different from the one you wanted becomes more likely. I deal with that problem by changing Bash prompts First of all, the basics: Bash prompts are just environment variables with special characters you can set and export. Bash has four of these variables: PS1 to PS4, but usually only the first two matters (actually, just PS1 for a reference on the others, check the manpage). The most common PS1 string is:

spectra@home:~$ echo $PS1
\u@\h:\w\$
spectra@home:~$
This has 4 special characters, escaped with a backslash: \u informing us the username; \h informing us the hostname; \w, informing us the working directory; and \$, which gives us the $ in the end of the prompt (more on this later). So, essentially, one can change that string to anything else

spectra@home:~$ PS1="my_shell_prompt\$ " 
my_shell_prompt$
Pretty easy. You can check a complete reference of the special characters at the section PROMPTING of bash manpage, but the most useful IMHO are the following: Also, as part of the prompt string, one can use ANSI Colors enclosed as non-printing characters (that is between \[ and \]). ANSI sequences always begin with an ESC[ and end with an m . (Yes Really arbitrary but that s the way it is ). ESC can be represented as \e Here is a list of the most common colors in ANSI sequences: Now, notice that there are two numbers separated by a semi-colon the first is always 0 (zero) in the colors I pointed above, but it actually refers to an ANSI attribute called Select Graphic Rendition You can use 0 (zero) to normal colors, 1 for bold, 2 to faint, etc. So \e[0;30m refers to BLACK, \e[1;30m refers to DARK GREY. The Wikipedia has a good article on these escape sequences. Once you re satisfied with something printed in a color, to go back to the default (to reset), you issue the \e[0m escape sequence. So, back to my problem Each different machine gets a different color for the hostname. On hospital machine, for instance, my PS1 looks like:

spectra@hospital:~$ PS1="\[\e[1;33m\]\u\[\e[0m\]@\[\e[0;35m\]\h\[\e[0m\]:\[\e[0;32m\]\w\[\e[0m\]\$ " 
spectra@hospital:~$
With \e[0;35m (Purple) for the hostname. On home machine, it may be \e[0;34m (Blue)... On server , it may be \e[0;36m (Cyan), and so on After a while, you get used to the color and end up linking the color to the machine so that typing reboot on a machine with the wrong color gets harder than before. To make the changes permanent, put export PS1 in one of the config script of bash (.bashrc, .bash_profile, etc). On some systems, /etc/environment holds lots of environment variables definitions. I just scratched the surface That s just what works for me The Bash-Prompt-HOWTO has some interesting examples, and I actually have a friend who uses more esoterical stuff, such as fancybash or bashish, but I ll leave this up to you

Mike Hommey: Emptying a deleted file

Yesterday, at work, we had the typical case where df would say there is (almost) no space left on some device, while du doesn’t see as much data present as you would expect from this situation. This happens when you delete a file that another process has opened (and, obviously, not yet closed). In typical UNIX filesystems, files are actually only entries in a directory, pointing (linking) to the real information about the content, the inode. The inode contains the information about how many such links exist on the filesystem, the link count. When you create a hard link (ln without -s), you create another file entry in some directory, linking to the same inode as the “original” file. You also increase the link count for the inode. Likewise, when removing a file, the entry in the directory is removed (though most of the time, really only skipped, but that’s another story), and the link count decreased. When the link count is zero, usually, the inode is marked as deleted. Except when the usage count is not zero. When a process opens a file, the kernel keeps a usage count for the corresponding inode in memory. When some process is reading from a file, it doesn’t really expect it to disappear suddenly. So, as long as the usage count is not null, even when the link count in the inode is zero, the content is kept on the disk and still takes space on the filesystem. On the other hand, since there is no entry left in any directory linking to the inode, the size for this content can’t be added to du’s total. Back to our problem, the origin was that someone had to free some space on a 1GB filesystem, and thought a good idea would be to delete that 860MB log file that nobody cares about. Except that it didn’t really remove it, but he didn’t really check. Later, the “filesystem full” problem came back at someone else, who came to ask me what files from a small list he could remove. But the files were pretty small, and that wouldn’t have freed enough space. That gave me the feeling that we probably were in this typical case I introduced this post with, which du -sk confirmed: 970MB used on the filesystem according to df, but only 110MB worth of data… Just in case you would need to find the pid of the process having the deleted file still opened, or even better, get access to the file itself, you can use the following command:
find -L /proc/*/fd -type f -links 0
(this works on Linux ; remove -L on recent Solaris ; on other OSes, you can find the pid with lsof) Each path this command returns can be opened and its content accessed with a program, such as cat. That will give access to the deleted content. I already adressed how to re-link such a file, which somehow works under Linux, but in my case, all that mattered was to really remove the file, this time. But we didn’t know if it was safe to stop the process still holding the file, nor how to properly restart it. We were left without a possible resolution, but still needed to come up with something before the filesystem gets really full while waiting to be able to deal with the root of the problem. The first crazy idea I had was to attach a debugger to the process, and use it to close the file descriptor and open a new file instead (I think you can find some examples with google). But there was no debugger installed. So, I had this other crazy idea: would truncate() work on these /proc/$pid/fd files? You know what? It does work. So I bought us some time by running:
perl -e 'truncate("/proc/$pid/fd/$fd", 0);'
(somehow, there is no standard executable to do a truncate(), so I always resort to perl) Afterwards, I also verified the same works under Linux (where you wouldn’t really know what it’d do with these files that are symbolic links to somewhere that doesn’t exist). The even simpler following command works, too.
> /proc/$pid/fd/$fd
It doesn’t truncate() but open() with O_WRONLY O_CREAT O_TRUNC, and close() right after (to simplify), which has the same effect. Good to know, isn’t it?

Martin Michlmayr: European Commission publishes guidelines on the procurement of FOSS

The Open Source Repository and Observatory (OSOR), a new site sponsored by the European Commission to foster the exchange of FOSS related information and software among European public administrations, recently published guidelines on the procurement of open source software. Public administrations in Europe have to follow public tender procedures and the new guidelines give practical and legal advice on how open source software and related services can be incorporated into the procurement process. Rishab Ghosh, who presented the guidelines at the Open Source World Conference in Malaga, argued that the procurement guidelines were needed because of two reasons. First, they studied recent tenders and found that many explicitly mentioned proprietary applications. 16% of 3615 software tenders explicitly asked for products from top 10 software vendors, such as Microsoft, SAP and Oracle. This practice may be illegal because public tenders generally have to describe functional requirements in a general way instead of specifying specific products. Second, many public administrations don't have any experience with the procurement of FOSS. In fact, they often don't know whether or under which circumstances they are allowed to adopt and ask for FOSS solutions. The guidelines are specifically designed in order to clearly and simply explain how public administrations can acquire open source and they don't assume that a country has adopted a specific policy regarding open source. The guidelines include a long section about open standards, open source and how they relate. Both open standards and open source align very well with the needs of public administrations who have an "obligation to support interoperability, transparency and flexibility, as well as economical use of public funds". The guidelines argue that the exit cost, i.e. the cost incurred in moving to another IT system, is also an important consideration but one that is often neglected. The adoption of a proprietary solution without open standards may limit the future choice, thereby increasing the long-time costs and giving the proprietary vendor an unfair advantage in future tenders. The procurement guidelines describe two ways of acquiring FOSS: it is possible to go the usual route of publishing a tender for the supply of software (possibly with related services). However, in the case of FOSS, it is also possible to download the software directly from the Internet. This is possible because the software is not only free of charge but comes with no contractual obligations. If there were any obligations involved with the download (such as fees, the agreement to an EULA or the requirement to purchase services in the future), software download is not an allowed method. What I like about the guidelines is that they explicitly say that downloading software has to be part of the formal procurement process. You have to think about your requirements, look at various alternatives, and so on, and not just blindly download something from the Internet. When it comes to the procurement of FOSS, the guidelines don't suggest that tenders should explicitly ask for FOSS. Instead, they should describe the functional requirements of the software as well as certain properties. For example, a tender could specify that the public administration as well as third parties must have the right to study, distribute and modify the software. In a sense, the guidelines suggest that tenders should include the principles of the Free Software Definition along with justifications for these requirements. Personally, I think there is a great need for these procurement guidelines. There are many public administrations that don't know how to acquire FOSS and these guidelines offer clear advice. Furthermore, I find the guidelines very balanced. They don't recommend that you should always ask for FOSS but incorporate FOSS principles into tenders where it makes sense. It remains to be seen whether the procurement guidelines will have an impact on the FOSS adoption in Europe, but I surely hope so. (Originally published on FOSSBazaar)

5 November 2008

Brandon Holtsclaw: sudo apt-get install Barack-Obama

Change is upon us, lets unite and embrace it. Maybe we can make this country a better place and once again be a Role Model to the world of a young ( yes, 221 years young ) Democracy taking its place in the international community for the betterment of all as an Example Nation, not a unnecessarily forceful and arrogant one. Change is here, and tonight I will sleep well for the first time in ages dreaming of this change. 13 comments so far.
© Brandon Holtsclaw for http://www.imbrandon.com/, 2008. This Post and Originating RSS feed is released under CC-BY-NC-SA license.

4 November 2008

MJ Ray: Tasty New Microblog Flavour

I’ve flirted with it in the past and resisted it for a while, but you can now follow me on Identi.ca and Twitter if you are so inclined. Seems like I might have picked a good time to try this because TwiTip just soft-launched. There’s some overlap between my accounts, but they’re not identical because different third-party sites connect to each one. Both will get told when a new article appears on this website, but Twitter is likely to see more links to other sites and Identi.ca will get more status updates. Other than that, usage will be determined by popularity at events or with communities - or by suggestions here. How would you use them? At first glance, the two services are similar but different. Both sites seem to be “cooperative deserts” (not many cooperative members on them), both sites seem to be running on non-free software (I consider AGPL non-free until its big questions are resolved) and neither site seems to have an easy way to backup one’s data or participate without registration. Identi.ca seems to have some SEO-spammer problems, while Twitter’s interface has some silly needless javascript uses. Identi.ca supports OpenMicroBlogging (OMB) but I don’t understand that yet - it seems a terrible specification. It opens with references (but not web links) to three other things I’ve never heard of, then continues into a dictionary where terms like “listener” are redefined (ouch!) and doesn’t contain an examples section. New article announcements are done by a Wordpress plugin I’ll publish soon. Because of the above problems with OMB and that I can’t find whether Twitter supports it, the plugin uses the simpler status HTTP POST interface. Does anything other than Twitter and Identi.ca support that? I tried a few sites and got bored with them requiring me to apply for an API key before they’d tell me much.

MJ Ray: Tasty New Microblog Flavour

I’ve flirted with it in the past and resisted it for a while, but you can now follow me on Identi.ca and Twitter if you are so inclined. Seems like I might have picked a good time to try this because TwiTip just soft-launched. There’s some overlap between my accounts, but they’re not identical because different third-party sites connect to each one. Both will get told when a new article appears on this website, but Twitter is likely to see more links to other sites and Identi.ca will get more status updates. Other than that, usage will be determined by popularity at events or with communities - or by suggestions here. How would you use them? At first glance, the two services are similar but different. Both sites seem to be “cooperative deserts” (not many cooperative members on them), both sites seem to be running on non-free software (I consider AGPL non-free until its big questions are resolved) and neither site seems to have an easy way to backup one’s data or participate without registration. Identi.ca seems to have some SEO-spammer problems, while Twitter’s interface has some silly needless javascript uses. Identi.ca supports OpenMicroBlogging (OMB) but I don’t understand that yet - it seems a terrible specification. It opens with references (but not web links) to three other things I’ve never heard of, then continues into a dictionary where terms like “listener” are redefined (ouch!) and doesn’t contain an examples section. New article announcements are done by a Wordpress plugin I’ll publish soon. Because of the above problems with OMB and that I can’t find whether Twitter supports it, the plugin uses the simpler status HTTP POST interface. Does anything other than Twitter and Identi.ca support that? I tried a few sites and got bored with them requiring me to apply for an API key before they’d tell me much.

3 November 2008

Russell Coker: Christian Principles in an Election Year

The National Council of Churches in the US [1] has produced some advice for Christian voters titled Christian Principles in an Election Year [2]. It starts by saying “Your church, your communion, and the National Council of Churches USA do not endorse any political party or any candidate” (which is in bold in their text) and then lists 10 issues that Christians should consider when voting. Here are the 10 section headings, the full article has a sentence or two explaining each one. I think that most good people (regardless of religion) will agree with all of this - maybe substitute “God” with the name of some other entity that has not been proven to exist or with “humanity”.

  1. War is contrary to the will of God.

  2. God calls us to live in communities shaped by peace and cooperation.

  3. God created us for each other, and thus our security depends on the well being of our global neighbors.

  4. God calls us to be advocates for those who are most vulnerable in our society.

  5. Each human being is created in the image of God and is of infinite worth.

  6. The earth belongs to God and is intrinsically good.

  7. Christians have a biblical mandate to welcome strangers.

  8. Those who follow Christ are called to heal the sick.

  9. Because of the transforming power of God s grace, all humans are called to be in right relationship with each other.

  10. Providing enriched learning environments for all of God s children is a moral imperative.

The Blogger Joy Reid [3] often uses the term “Matthew Christian” to refer to Christians who follow the book of Matthew and act in ways that would be considered to be good by most people regardless of belief. This is in stark contrast to some of the nasty people who call themselves Christian and who promote hatred, inequality, and war - such people give all Christians a bad reputation (see the comment section of any blog post concerning religion for examples). John Goerzen’s post titled Politics and the Church (which references the NCCUSA article [4]) is also worth reading. Interestingly his blog post had a Google advert for “Christian Masturbation” when I viewed it. John also has a good post explaning why he is voting for Obama - based on his Christian beliefs and “Traditional Values” [5].

Russell Coker: Types of Cloud Computing

The term Cloud Computing seems to be poorly defined at the moment, as an example the Wikipedia page about it is rather incoherent [1]. The one area in which all definitions of the term agree is that a service is provided by a varying number of servers of which the details are unknown to the people who use the services - including the people who program them. There seem to be four main definitions of cloud computing. The first one is Distributed Computing [2] (multiple machines in different administrative domains being used to perform a single task or several tasks), this definition does not seem to be well accepted and will probably disappear. The next one is Software As A Service [3] which is usually based on the concept of outsourcing the ownership and management of some software and accessing it over the Internet. An example is the companies that offer outsourced management of mail servers that are compatible with MS Exchange (a notoriously difficult system to manage). For an annual fee per email address you can have someone else run an Exchange compatible mail server which can talk to Blackberries etc. The main benefit of SAAS is that it saves the risk and expense of managing the software, having the software deployed at a central location is merely a way of providing further cost reductions (some companies that offer SAAS services will also install the software on your servers at greater expense). The last two definitions are the ones that I consider the most interesting, that is virtual machines (also known as Cloud Infrastructure [4]) and virtual hosting of applications (also known as Cloud Platforms [5]). The Amazon EC2 (Elastic Cloud Computing) service [6] seems to be the leading virtual machine cloud service at the moment. Google App Engine [7] seems to be the leading cloud application hosting service at the moment. It is also claimed that “Cloud Storage” is part of cloud computing. It seems to me that storing data on servers all over the world is something that was done long before the term “Cloud Computing” was invented, so I don’t think it’s deserving of the term.

Adrian von Bidder: Out of Office Reply

I am not in the office at the moment.
On a traffic sign in Wales: the welsh text reads “I am not in the office at the moment. Please send any work to be translated.” and was received by the responsible agency in reply to their emailed request to translate the english text. (Reported widely, I've read it in the dead tree variant of my daily newspaper, the Neue Z rcher Zeitung; on the net, for example, here or on BBC.)

2 November 2008

Joerg Jaspert: archive.debian.org, old bugs and list archives

sarge archived As already written a few days ago I was going to archive Sarge on archive.debian.org. That is done, you can get sarge from there now. The dists/sarge directory also already disappeared from the regular mirrors a few days ago. Im not simply deleting all source and binary packages from Sarge. Instead I am doing a removal of 1000 packages every second day, which ends up in batches of about 10000 removed files every other day. While that is a little more work on the archive side I think it pays off - many mirrors, including Debians own ones, limit the amount of files they delete in one mirror run and it is much less work than asking every mirror admin to make sure it will work on their system. Oh, just in case you mirror archive.debian.org somewhere: Make sure to use -H in your rsync call, will save about 30G of disk space.
Sarge AMD64, volatile and backports Now, while I was already working on archive.debian.org I thought it could do a little more than it did in the past. So I also went and put the Sarge AMD64 release on it, in a seperate directory. And as it would have felt lonely I put sarge-backports and sagre-volatile right beside it.
security and non-us non-us.debian.org is a service thats dead since the sarge release. Finally it also got archived on archive.debian.org (it helps that this service is, since a long time, no longer on a host in the US). security.debian.org now also appears on archive.debian.org, and the security archive will soon lose the files of old releases like slink, potato, woody and also sarge.
0.93R6, Rex and Buzz I got a few responses to my post about old releases and now we also provide 0.93R6. And to make it even better we now also have the binary packages for Rex and Buzz again. I still would like to see even older releases, including alpha and beta versions, so if you have such old things somewhere - tell me. Just make sure they somehow include the source too. I do have 0.91 for example, but it is missing any kind of source except for one package and one patchset. :(
Old list archives, old bugs On one of the CD images I thankfully got from J.H.M. Dassen I found another nice thing - old mailinglist archives from 1995 and 1996 as well as old bugs, #350 - #1626. The list- and bugpeople both got a tarball and just need to import them to make them available again. (Well, Don will kill me for that just, the bugs are html and textfile dumps, so he needs to parse them to get them in the right format for debbugs. But I’m sure he will manage. :) ). Comments: 2

Decklin Foster: Tap that class

And now, something entirely impractical. I picked up Beginning Ruby by Peter Cooper the other day to look for some teaching material. Flipping through, I came across a basic feature that had heretofore escaped my notice: the Struct class. If you want to use a class for nothing more than bundling together a few values, you can create a Struct instead of writing out initialize and attr_accessor yourself. The idiom is like this:
class Server < Struct.new(:host, :port, :password)
  def to_s
    port == 6600 ? host : "# host :# port "
  end
end
That particular one's from Njiiri (which may clue you in that it took me several months to get around to writing this post). For educational purposes, it's nice: you can point out how we give a name to a class (I've also tried to explain assignment as "naming" rather than "storing"), that there's an unnamed class (classes are also objects!), and overriding a method (which uses the dynamically defined stuff), without any boilerplate to get in the way. So it's tempting to use this in a lesson. Unfortunately, Ruby is a little bit weird here, and you run into those distracting "practical" issues about the particular language you're working in. Your classes can't subclass Class, and thus you can't say Foo.new like you can Struct.new. Struct is actually implemented in C (or Java, or whatever's native). So you have to do some handwaving. This is because the "metaclasses" we have in Ruby are implemented, so to speak, as singleton classes of objects (including class objects). I do not mean this as a criticism of Matz at all, but they seem like more of a serendipitous thing than an intentional design -- "hey, if we implement classes in this particular way, we get this sort of metaclassing automatically [1]." (The clearest explanation of why this is that I've found is in the first chapter of Advanced Rails by Brad Ediger.) I wanted to be able to just subclass Class, rather than have all that fun power that we normally get to abuse in Ruby, only because I think this is the clearest way to explain the abstraction. Even I still have trouble describing singletons in plain English. Struct is intuitively a class of classes, and factors out similar/boring stuff -- a good practice. It could be an example of how to refactor some simple classes, if only we could follow it. I decided to give up on the idea for my tutorial, but it kept me up at night. Ruby metaclasses clearly can do anything that the sort of Struct-like metaclasses I have in my mind -- "parametric" classes, if you will -- can do, and I can dynamically define just about anything; why not make it happen? We can instantiate Class itself, but the tool we have to shape that class is singleton methods. This can certainly be abstracted away. So, I whipped something up. Before getting to it, though, let's visit a new construct in Ruby 1.9 and 1.8.7: Object#tap. Apart from the obvious debugging use described in its documentation, it makes it quite easy to factor out this pattern:
def gimme_a_thing
  thing = Thing.new
  thing.do_stuff_to_it
  thing
end
Into something closer to the style of functional or declarative programming:
def gimme_a_thing
  Thing.new.tap  thing 
    thing.do_stuff_to_it
  end
end
(Well, "do stuff" is obviously still procedural, but A for effort.) Which one is "better" could probably be the subject of much debate, but: I really prefer the second one; even though it has exactly the same effect, it looks like "what" rather than "how" (something else I try to beat into impressionable young heads. :-)), which is I think easier to write tests for. I'm going to use it here, because it's shorter. Now, Object#tap passes the object as an argument to the block; in our case, we are going to define a metaclass, so we want to work with self, instead. So we define a new version, class_tap -- by analogy with class_def, I suppose --- which class_evals the block rather than simply evaluating it:
class Class
  def class_tap(&blk)
    tap  _self  _self.class_eval &blk  
  end
end
And to do the following trickery, we make use of MetAid, written by why the lucky stiff -- it's very small, so we could always just incorporate the bits we want into the code here, but this short file provides a common vocabulary for talking about metaclass stuff which is quite valuable. Now, we can write a method to create our new classes on the fly. Here's what I came up with:
require 'metaid'
class << Class
  def meta(_super=Object, &blk)
    new.class_tap do                     # 1
      meta_def :new do  *args            # 2
        Class.new(_super).class_tap do   # 3
          class_exec *args, &blk         # 4
        end
      end
    end
  end
end
(Note the "class << Class", opening the singleton, rather than "class Class", opening Class itself. Also, the distinction between new and Class.new -- they are the same method, but from inside the meta_def we're no longer in the Class class.) The lines of meta itself mean:
  1. The value of this thing is a generated class, which we will describe thusly:
  2. Its singleton class has a new method, which gives you a value that is:
  3. Another generated class, which is defined by:
  4. the original block, which now gets run with new's arguments.
Nary an assignment in sight! The (embarrassing) caveat is that methods in the block that defines the new class instance cannot use def to create methods as normal. A def is evaluated in a totally fresh scope (I don't think I get the opinion behind this decision, to be honest), so we need to use class_def instead. This is, I must admit, rather hideous. Perhaps someday the language will change. But, first things first: now we can implement Struct in pure Ruby.
class MyStruct < Class.meta \
  do  *args 
    attr_accessor *args
    class_def :initialize do  *instance_args 
      args.zip(instance_args).each do  attr, val 
        instance_variable_set :"@# attr ", val
      end
    end
  end
end
The real Struct class does a few other nice things for you, but this is the heart of it; I can go back to that Njiiri example and just swap in MyStruct for Struct (Providing an instant performance gain of -200%... :-)). Here's a "shapes" example from my abandoned OO lesson:
class Polygon < Struct.new(:sides)
  def perimeter
    @sides.inject(&:+)
  end
end
class RegularPolygonClass < Class.meta(Polygon) \
  do  n_sides 
    class_def :initialize do  side_length 
      @sides = [side_length] * n_sides
    end
    class_def :area do
      @sides.size * @sides.first**2 / Math.tan(Math::PI / @sides.size) / 4
    end
  end
end
class Square < RegularPolygonClass.new(4); end
class Pentagon < RegularPolygonClass.new(5); end
(Note that area has no free variables and thus could actually be defined with def. It would just look funny.) You only have to change one number here to make new polygon classes, rather than accumulating parameter lint or explicitly subclassing and redefining something implicit just for the derived class [2]. In a way it the exact analogue of the imperative vs. tap style described above. There is quite a bit of aesthetics involved; one way is not "right". Apart from the syntactical wart, I like being able to do things this way. Ruby is, as they say, optimized for programmer happiness and the principle of least surprise. Still, I'm sure it is quite slow, and I don't particularly need it for any real-world application right now. For an intro to OO it's way too much complexity to have lurking unexplained beneath the surface and still requires getting bogged down in the language you happen to be using. But hey! It's neat.
[1]I basically try to do this whenever possible, anyway. Design decisions are like sex: they're better when they're free.
[2]Of course, if Ruby class variables were not leaked across the entire inheritance hierarchy, something as trivial as this one-variable example would be... trivial. At least, few people would actually miss metaprogramming features. Blub blub blub.

Jonathan McDowell: Shrinking the keyring

Apparently I'm supposed to be blogging once a day, every day, for November. I missed yesterday and doubt I'll have something to say every day, but let's try...

Today I have been playing with the export-clean and import-clean options to gnupg, in particular in conjunction with the debian-keyring. The options result in only signatures that can be verified (ie that are from keys that exist in your keyring) being allowed, and remove signatures other than the revocation from revoked keys/uids.
Why is this interesting to me? Well, a number of reasons:There's an argument that this "weakens" the web of trust (after all, we're throwing away signatures from keys), but I'm not really convinced. The full keys can still be downloaded from the keyserver network and it's not like any of the Debian infrastructure scripts make use of web of trust; all that's important is that a key is present in the keyring. I've been asked about export-minimal (ie keys + self sigs only) in the past, but I prefer this method of keeping verifiable signatures as it provides some measure of checking key trust for people importing the keyrings locally or auditing the keyring.

(Note I haven't actually rolled any of this out, it's just something I've been playing with locally at present to get a feel for the savings/benefits to be had.)

Matthew Garrett: Ultamatix

First, let me make one thing clear. This isn't constructive criticism. This is just criticism. It's directed at software that's so wrong-headed that there's no way to make it significantly better, and everyone involved would be much better spending their time doing something else instead of trying to fix any of what I'm about to describe. It's not worth it. Sit in a park or something instead. Meet new and interesting people. Take up a hobby that doesn't involve writing shell scripts for Linux. You'll be happier. I'll be happier. Everyone wins.

Anyway. I wrote about Automatix some time ago. It died and the world became a better place. More recently it's been resurrected as something called Ultamatix. In summary, don't bother. It's crap. And dangerous. But mostly crap. Again, I'm going to utterly ignore the UI code and just concentrate on what it runs.
There's almost certainly more. I got bored. The worrying thing about this is that the Ultamatix author read my criticisms of Automatix and appears to have attempted to fix all of them. The problem with this is that there's clearly a complete lack of understanding of the fundamental problem in several cases. For example, one of my criticisms of Automatix:

sudo sed -i "s/^vboxusers\(.*\):$/vboxusers\1:$AXUSER/" /etc/group

- assumes that the system isn't using some sort of user directory service.


and the Ultamatix response:

Fixed...Got rid of Virtualbox

Except exactly the same problem is present at other points in Ultamatix, as noted above. Taking a bug list and slavishly fixing or deleting all the bugs isn't helpful if you then proceed to add the same bug back in 24 other places. In that respect, it's even worse than Automatix - the author's managed to produce a huge steaming pile of shite despite having been told how to avoid doing so beforehand. He may be no newbie to programming, but if not it's a perfect example of how experience doesn't imply competence.

Don't install this package. Don't let anyone else install this package. If you see anyone advocating the installation of this package, call them a fool. There's absolutely no excuse whatsoever for the existence of this kind of crap.

Minor update:
The above was looking at 1.8.0-4. It turns out that there's a 1.8.0-5 that's not linked off the website. There's no substantive difference, but some of the numbers may be slightly different.

Russell Coker: Integrity and Mailing Lists

One significant dividing factor between mailing lists is the difference between summary lists (where the person who asks a question receives replies off-list and then sends a summary to the list) and the majority of mailing lists which are discussion lists (where every reply goes to the list by default). I have seen an argument put forward that trusting the answers on a mailing list that operates under the summary list model is inherently risky and that peer review is required. It could be argued that the process of sending a summary to the list is the peer review. I’m sure that if someone posts a summary which includes some outrageously bad idea then there will be some commentary in response. Of course the down-side to this is that it takes a few days for responses to the question to arrive and as it’s common that computer problems need to be solved in hours not days the problem will be solved (one way or another) before the summary message is written. But the idea of peer review in mailing lists seems to fall down in many other ways. The first problem with the idea of peer review is that the usual aim of mailing lists is that most people will first ask google and only ask the list if a reasonable google search fails (probably most mailing lists would fall apart under the load of repeated questions otherwise). Therefore I expect that the majority of such problems to be solved by reading a web page (with no peer review that is easily accessible). Some of those web pages contain bad advice and part of the skill involved in solving any problem relates to recognising which advice to follow. Also it’s not uncommon for a question on a discussion list to result in a discussion with two or more radically different points of view being strongly supported. I think that as a general rule there is little benefit in asking for advice if you lack any ability to determine whether the advice is any good, and which of the possible pieces of good advice actually apply to your situation. Sometimes you can recognise good advice by the people who offer it, in a small community such as a mailing list it’s easy to recognise the people who have a history of offering reasonable advice. It seems that the main disadvantage of asking google when compared to asking a mailing list is that the google results will in most cases contain links to web sites written by people who you don’t know. Sometimes the advice is easy to assess, for example if someone recommends a little-known and badly documented command-line option for a utility it’s easy to read the man page and not overly difficult to read the source to discover whether it is a useful solution. Even testing a suggested solution is usually a viable option. Also it’s often the case that doing a google search on a recommended solution will be very informative (sometimes you see web pages saying “here’s something I tried which failed”). Recommendations based on personal experience are less reliable due to statistical issues (consider the the regular disagreements about the reliability of hard disks where some people claim that RAID is not necessary due to not having seen failures while others claim that RAID-5 is inadequate because it has failed them). There are also issues of different requirements, trivial issues such as the amount of money that can be spent will often determine which (if any) of the pieces of good advice can be adopted. The fact that a large number of people (possibly the majority of Internet users) regularly forward as fact rumors that are debunked by Snopes.com (the main site for debunking urban legends) seems to indicate that it is always going to be impossible to increase the quality of advice beyond a certain level. A significant portion of the people on the net are either unwilling to spend a small amount of effort in determining the accuracy of information that they send around or are so gullible that they believe such things beyond the possibility of doubt. Consider that the next time you ask for advice on a technical issue, you may receive a response from someone who forwarded a rumor that was debunked by Snopes. Sometimes technical advice is just inherently dangerous because it is impossible to verify the integrity of some code that is being shared, or because it may be based on different versions of software. In a previous blog post I analyse some issues related to security of the Amazon EC2 service [1]. While the EC2 service is great in many ways (and implements a good well-documented set of security features on the servers) the unsigned code for managing it and the old versions of the images that they offer to customers raise some serious issues that provide avenues for attack. Getting the EC2 management tools to work correctly on Debian is not trivial, I have released patches but will not release packages for legal reasons. It seems most likely to me that someone will release packages based on my patches (either because they don’t care about the legal issues or they have legal advice suggesting that such things are OK - maybe due to residing in a different jurisdiction). Then people who download such packages will have to determine whether they trust the person who built them. They may also have the issue of Amazon offering a newer version of the software than that which is packaged for Debian (for all I know Amazon released a new version yesterday). The term integrity when applied to computers refers to either accidental or malicious damage to data [2]. In the context of mailing list discussions this means both poorly considered advice and acts of malice (which when you consider spam and undisclosed conflicts of interest are actually quite common). If you ask for advice in any forum (and I use the term in it’s broadest sense to cover web “forums”, IRC, twitter, etc) then getting a useful result will depend on having the majority of members of the forum possessing sufficient integrity and skill, being able to recognise the people whose advice should be followed, or being able to recognise good advice on it’s own. I can think of few examples of forums of which I have been involved where the level of skill was sufficient to provide quality answers (and refutations for bad answers) for all areas of discussion that were on topic. People whose advice should generally be followed will often offer advice on areas where their skills are less well developed, someone whose advice can be blindly followed in regard to topic A may not be a reliable source for advice on topic B - which can cause confusion if the topics in question are closely related. Finally a fundamental difference between “peer review” (as applied to conferences and academic journals) is that review for conferences and journals is conducted before the presentation. Not only does the work have to be good enough to pass the review, but the people doing it will never be sure what the threshold is (and will generally want to do more than a minimal effort) so the quality will be quite high. While peer review in mailing lists is mostly based around the presence or absence of flames. A message which doesn’t attract flames will either have some minimal quality or be related to a topic that is not well known (so no-one regards it as being obviously wrong). Update: The “peer review” process of publishing a post on my blog revealed that I had incorrectly used who’s instead of whose.

1 November 2008

Thomas Girard: Playing with C++0x -- tuple

C++0x is approaching, and it comes with a lot of new stuff, so I've decided to play with it. Some C++0x features are already available in g++ 4.3. Others will be available in the 4.4 release -- see this page for a summary of C++0x language support in g++. What is a tuple? It's a std::pair on stero ds: it can contain any number of elements. For the impatient, the whole sample program is available from here. It can be compiled with: g++-4.3 --std=c++0x tuple.cpp -o tuple. Now let's see how to create a tuple:
#include <string>
#include <tuple>
typedef std::tuple<int, double, std::string> my_tuple_t;
my_tuple_t a_tuple(1, 5.0);
Every element of the tuple gets initialized to its default value if it's not specified. Indeed displaying the third element:
std::cout << std::get<2>(a_tuple) << std::endl;
outputs nothing, because the string element was default-constructed to an empty string. The std::make_tuple function, like std::make_pair for std::pair, can be used to create a tuple using type deduction:
std::cout << std::get<1>(std::make_tuple(false, std::string("see"))) << std::endl;
A tuple element can be changed using the same get function:
std::get<2>(a_tuple) = "a string";
Of course, a tuple is type safe. Trying to put a string at the first element:
std::get<0>(a_tuple) = "another string";
does not compile. But there's more: you also get a compilation error when trying to access an element that does not exist. For example trying to display fourth element does not compile:
std::cout << std::get<3>(a_tuple) << std::endl;
What else can you do with tuples? You can test them for equality, or assign them:
my_tuple_t another_tuple = std::make_tuple(2, 10.0, std::string("nothing"));
std::cout << (a_tuple == another_tuple) << std::endl;
another_tuple = a_tuple;
std::cout << (a_tuple == another_tuple) << std::endl;
You can also retrieve multiple elements at once, possibly ignoring some of them:
std::string a_string;
std::tie(std::ignore, std::ignore, a_string) = another_tuple;
Last, you can concatenate two tuples into a new tuple:
std::tuple<int, double, std::string, bool, std::string> cat =
    std::tuple_cat(a_tuple, std::make_tuple(false, std::string("see")));

Uwe Hermann: Google Tech Talks: coreboot (aka LinuxBIOS): The Free/Open-Source x86 Firmware

coreboot Google Tech Talk 2 Here's a nice opportunity for everyone to learn more about coreboot, a Free Software / Open Source firmware/BIOS for x86 PCs. Ron Minnich, founder of the LinuxBIOS (now called coreboot) project, Peter Stuge of Stuge Konsult, and Stefan Reinauer of coresystems GmbH have given a presentation for the Google Tech Talks series recently. The topic was (of course) coreboot, its history, goals, features and technical details, surrounding tools and libraries such as flashrom and libpayload, as well as an automated test system for running a hardware test-suite upon every checkin in the coreboot repository. coreboot Google Tech Talk 1 A video of the talk, aptly named coreboot (aka LinuxBIOS): The Free/Open-Source x86 Firmware (134 MB), is available from Youtube, get it for instance via:
  $ apt-get install youtube-dl
  $ youtube-dl http://www.youtube.com/watch?v=X72LgcMpM9k
The talk includes various demos of coreboot and various payloads you can use with coreboot. One nice example is the TINT payload, a Tetris-like game for Linux (apt-get install tint for the curious), which has been reworked to be usable as a coreboot payload. coreboot Google Tech Talk 3 So, yes, you can now put Tetris in your BIOS ROM chip and play it from there (no hard drive required). Other demos included some cluster nodes with coreboot, and a "normal" x86 desktop board booting coreboot + Linux in a very few seconds (much room left for optimizing there though, if you really want to get into fast booting). Check out the full talk for more infos, and if you're willing to give it a try (see the list of currently supported boards), contact us on the mailing list or join the #coreboot IRC channel on Freenode.

Next.

Previous.