Havoc's Blog

this blog contains blog posts

Finding Your Local Network, part 2

I got a fair bit of useful feedback on my last post about local
service discovery. I also have some initial
code
up and running to illustrate the approach. (This code
requires D‑Bus 1.1.1 or higher.)

For now the code uses a straightforward but probably too inefficient
implementation, where each session connects to each other
session. Modifying it to use TXT records for everything or certain
things is possible. Hopefully the higher level of abstraction means
that the most efficient way to use Avahi can be globally worked out,
instead of per-app.

The main idea here is to make it dead easy to use local service
discovery for per-session user services (as opposed to say a printer),
without having to understand all the networking specs.

(This post was originally found at http://log.ometer.com/2007–06.html#23.3)

Finding Your Local Network

At Red Hat’s somewhat-in-the-vicinity-of-Boston offices, a few of us
have been trying to understand the local service discovery and
presence work others have been doing and figure out how we’d use it to
do cool things in apps.

Today I’ll blog ideas and questions about local service discovery and
later I have some additional questions to throw out there for the
presence experts.

I still don’t understand everything all that well, and all the docs
I’ve found assume you know a lot more about DNS than I do, but here’s
my summary of how local service discovery works. Avahi implements the
mDNS/DNS-SD/Rendezvous/Bonjour/Zeroconf/whatever set of specs, which
in combination form a system for service discovery on a local
network. There are three steps to discovering information on the
network:

  • First, you can browse services. In this stage your program gets a list of
    hostnames, one per service offered
    and that’s it. For example in
    link-local
    XMPP
    , you ask for all hostnames that end in
    “._presence._tcp.local.” and by convention those names will be
    username@machinename, so the full host is
    “johndoe@example._presence._tcp.local.” or something like that.
    The only information you get from this step is
    the “johndoe@example” for link-local XMPP, or for browsing WebDAV
    shares you might get “Havoc’s Files” for example. there is no way to
    get or provide information beyond the one string.
  • Second, you can resolve the services. This means making a request for
    each service, and getting back the service’s IP address and port so
    you can connect to it
    . You can also get some key-value pairs
    called TXT records, but there can’t be too many of these and they
    can’t be too big. In link-local XMPP, the TXT records optionally
    contain the jabber ID, email address, user name, and a hash of the
    user’s photo, among other things. As I read the specs, TXT records
    should always be optional optimizations and not required — that is,
    you should be able to get the same information by connecting to the
    service and asking. I’m not sure of the rationale here.
  • Third, you can connect to the service and talk to it using its
    application-specific protocol
    , whatever that protocol is — WebDAV,
    XMPP, or whatever. You could do this just to find out stuff missing
    from the TXT records, or you could do it in order to take a
    service-specific action such as store a file, send an XMPP message,
    or print a document.

As best I can tell, the more of these steps you do, the more expensive
it is. I don’t understand how expensive since I know zip
about networking below the session layer. But
it seems intuitive that if you had say a network of 500 machines and
all 500 made an XMPP connection to the other 499 to get user photos,
there could be some issues.

You can find the Avahi API
for the first two steps here
, or on the publish/server side, you use this
API
. The docs also have a
simple publish example
and a simple
browse example
. Note that the publish example doesn’t do
anything, it advertises services but does not create them (does not listen on any
ports or implement a protocol).

Right now you have to write a network server (potentially inventing
a new protocol) to use Avahi.
See the third step I mentioned
above. There are a few problems here; one, it’s too hard. Two, it’s a
pretty rough security footprint to audit if every app that uses local
discovery is listening on a port. Three, like me I’m sure app authors
don’t understand the performance and other issues involved in using
Avahi directly — it requires a lot of knowledge. (The Avahi API is
quite nice, but it is on the level of manually doing the
above-mentioned three steps, which are low-level steps.)

Right now services are not tied to sessions or people.
Say I browse the network and it has “Havoc’s Files” and “Bryan’s
Files” on there. It also has link-local XMPP for both Havoc and
Bryan. However, there is no way for me to associate the files with the
XMPP (as far as I know). So if I wanted to show a “See Bryan’s Files”
button next to his photo in chat, that would be challenging.

If I parsed what Dan Williams had to say, Sugar somewhat addresses
both of these issues. First, Sugar defines a “person” as a keypair
generated on each laptop. Since there’s one laptop per child, keypair
equals laptop equals person. Next, Sugar uses a hash of the keypair
for its XMPP identifiers. So it can map from server-based or local
XMPP to people. Finally, Sugar uses XMPP not only for chat but for all
IPC over the network. To avoid using XMPP directly, it tunnels
arbitrary IPC through XMPP by serializing D‑Bus messages and stuffing
them into XMPP messages (known as Tubes).

With the Sugar platform then, instead of using Avahi directly at all,
what you could do is add additional properties available via
link-local XMPP. A small number of simple properties could go in the
link-local XMPP TXT records perhaps, while larger or more complex
properties would require each client to establish an XMPP connection
and ask for the property.

What should we do for GNOME and its new improved flavor,
Online Desktop?

The API I’m thinking would be most convenient for apps is something
like the following. First, the Mugshot client for example could do:

  AddInfoToOurSession("org.mugshot.MugshotInfo",
                      { 'mugshotId' : 'whatever',
                        'name' : 'Havoc',
                        'photoUrl' : 'http://whatever' }) 

or say a video game:

  AddInfoToOurSession("org.gameserverexample.Server",
                      { 'serverName' : 'whatever',
                        'username' : 'Havoc' })

Then, any other app in this session or anywhere on the network could
ask for “info bundles” by name as follows:

  mugshot_infos = GetInfoFromOtherSessions("org.mugshot.MugshotInfo");

Where each info in the list would be a pair of two dictionaries, one
representing the session and the other representing the requested info
from that session:

  ( { 'session' : 'guid-for-session',
      'machine' : 'guid-for-machine',
      ... },
    { 'mugshotId' : 'whatever',
      'name' : 'Havoc',
      'photoUrl' : 'http://whatever' } )

(D‑Bus already provides a guid for the session and machine, if you’re
wondering where those come from.)

On the network we have a set of sessions; each session contains named
“infos” or bundles of related properties; clients can ask for a list
of all “infos” on the network of a particular kind.

This hypothetical API would allow apps to advertise information
without writing a network server or listening on a port. It would also
automatically link all advertised information to a session ID, and if
some of the info advertised identifies the user, the session can in
turn be linked to a user.

This kind of API does not offer a way to establish a connection or
communicate, though; just a way to advertise.

Something like Fast User Switching could even use this — instead of
using gdm to keep track of users to switch to, it could list sessions
on the local machine, and one of the properties of each session would
be the local username and a name/photo.

If we add features such as link-local chat, or link-local file
sharing, I would want them to work with other sessions on the same
machine, in the same way they work with sessions on other machines.

A simple API like this reduces the surface area for security
exploits in the sense that there would be only one codebase that was
network-facing. Of course, the issue of which things are safe
to publish on the local network remains, but that is unavoidably going
to be up to the judgment of app developers.

To implement an API like this I can imagine multiple approaches, and I
don’t know which is best. The three I have come up with are:

  1. No network-facing daemon, just a little daemon on the session bus that
    allows apps to register the info bundles, and then advertises each one
    with a separate hostname and puts the “info bundle” properties in TXT
    records. This is a thin convenience layer over Avahi.
  2. The same little daemon on the session bus, but it also listens on the
    network and allows clients to connect and get “info bundle”
    properties that are too large to fit in the TXT records.
  3. Link-local XMPP. Add a session ID to the link-local XMPP TXT
    records. Add special XMPP messages, or Tubes messages, to get the
    “info bundles” that each app has made available. This approach
    involves by far the most code, though much of that code is already
    written.

So the no-network-facing daemon approach would be a thing like:

  Havoc's Mugshot Stuff.mugshot.org._gnome_session.local
      TXT session=guid-for-session
      TXT machine=guid-for-machine
      TXT mugshotId=whatever
      TXT photoUrl=http://whatever
  Havoc's UNIX Account.unixinfo.gnome.org._gnome_session.local
      TXT session=guid-for-session
      TXT machine=guid-for-machine
      TXT uid=503
      TXT gecos=Havoc
  Havoc's Card Game Account.cardgame.gnome.org._gnome_session.local
      TXT session=guid-for-session
      TXT machine=guid-for-machine
      TXT game_server=http://whatever
      TXT server_username=foobar
  ...

In this approach, only small properties can be advertised. There are
lots of hostnames to browse and resolve, but no services to connect
to. The TXT records are essential (the whole approach) and not an
optimization.

Remember this approach is still implemented with a daemon, but it’s a
small service on the session bus, not a network-facing daemon.

If you make the daemon network-facing also, it can support connections
to get all the information, so only needs to advertise one time on Avahi.

  Havoc's Stuff._gnome_session.local
      TXT session=guid-for-session  (optional, could also ask service)
      TXT machine=guid-for-machine  (optional, could also ask service)

And then listening at “Havoc’s Stuff._gnome_session.local” is a custom
server that supports asking for the machine/session ID and all the
“info bundles” available from the session.

I started experimenting with this second approach by writing the small
service on the session bus, and then having it also create a custom DBusServer
(not a bus) listening on the network. Since D‑Bus took most of the
work out of writing my own network server and the Avahi API is simple,
I got it going instantly (other than a long detour to make libdbus
support anonymous clients).

The third approach is essentially equivalent to the second, except it
uses link-local XMPP instead of D‑Bus for the network-facing protocol.
With Tubes, the end result is pretty similar (the API is D‑Bus, but
the D‑Bus is pushed through XMPP behind the scenes). There is a LOT
more code involved — the Telepathy + Salut + Tubes stack is in the
tens of thousands range, vs. a couple thousand for approach 2. But if
that code is going to be used anyway for other purposes, it may not
matter.

Again here’s the simple API for apps I was thinking of:

  AddInfoToOurSession("org.mugshot.MugshotInfo",
                      { 'mugshotId' : 'whatever',
                        'name' : 'Havoc',
                        'photoUrl' : 'http://whatever' }) 

If we have that, then we could experiment with these three approaches
or the no doubt better ideas other people have without too much
trouble.

I don’t know what the performance issues with these various approaches
are. For example, is it worse to have tons of advertised services as
in approach one, or to have to connect to each service every time, as
in the second two approaches? Or are all three of these approaches
doomed in some way? On some level, it seems like 500 sessions each
loading stuff from each of the others just can’t work. What are the
tricks to make it work?

And what about change notification? Is it possible? How is it done
without causing 499 other computers to all ask my computer for new
information at once as soon as I change my user photo on a large network?

Since my blog lacks comments, feel free to send thoughts to the online desktop
group
, you don’t have to subscribe to receive mail in order to
post, and you can post from the web UI.

(This post was originally found at http://log.ometer.com/2007–06.html#14)

Source Control Insanity

I’ve been known to complain about the number of newfangled source
control systems in the past; today it’s really biting me. To build the
Telekinesis
stack requires 1) cvs 2) svn 3) git 4) darcs and 5) mercurial. I’m
thinking of writing something that uses the stack and checking it into
bzr, just for completeness. Maybe add some arch and monotone for extra
kicks.

There is just no way that the differences between git, bzr, darcs,
arch, monotone, and mercurial are interesting enough to outweigh the
disadvantage of having to deal with all of them in order to get stuff
done.

Back in the day, if you knew CVS, you could hack on any project. Sure
CVS was a bit lame, but you understood its quirks and it worked
fine most of the time. Also, we walked to school both ways uphill.

Mildly related, the other day I discovered that darcs has an
innovative new twist on the “Question? [yn]” tradition — it asks:

Shall I pull this patch? (1/129)  [ynWvpxqadjk]

This might be awesome in dialog form, too. Someone should write a GUI.

(This post was originally found at http://log.ometer.com/2007–06.html#7)

Best D‑Bus Practices

Using various D‑Bus APIs I’ve noticed all kinds of interesting
ideas for how to design them. You should avoid many of these ideas.

First, don’t overthink the basic D‑Bus concepts.

  • An object path is used to refer to an
    object. Object means object. Like GObject,
    java.lang.Object, or your choice of object. But it does not mean
    anything magic. If you have an object, then it should have an
    object path.
  • An interface is used to name an interface. For
    example, if in Java you would say “interface Introspectable”, then
    in D‑Bus you would also say “interface Introspectable.”
  • A bus name admittedly requires learning something new, but
    nothing too outrageous. It is a name assigned to a thing on the bus.
    The bus only has one thing on it: connections. A connection is a
    DBusConnection, usually each app has one connection to the bus.
    So a bus name is used to refer to an app, pretty much. Apps are
    programs. These programs contain objects.

Pulling this together, to talk to an object you need to know an
interface it has, you need an object path (equivalent to a pointer in
C or Java object reference), and you need a bus name (which you could
think of as the host name, the point is it gets your message to the
app that you want to talk to).

Here is what you should not do. Gaim (now Pidgin) has one object,
called GaimObject, one bus name, called GaimService, and one
interface, GaimInterface. The interface, which is implemented by the
object, has 499 methods on it. The methods are named things
like GaimBlistNodeIsContact(), and take an integer ID for an object as
the first arg. Let’s write this in Java:

 interface GaimInterface {
   int GaimBlistNodeIsBuddy(int blistNodeId);
   int GaimContactNew();
   String GaimContactGetAlias(int contactId);
   int GaimContactOnAccount(int contactId, int accountId);
   // ... add 494 more methods
 }

I’m just picking on Gaim because I was just coding to it. Other people
make the same mistake. You don’t need to invent a new kind of integer
ID! That is what the object path is, it’s an id for an object. Gaim
has the whole hash table from IDs to objects, but DBusConnection
already has a hash table for that (see dbus_connection_register_object_path()).

Instead of net.sf.gaim.GaimInterface.GaimBlistNodeIsBuddy(int blistNodeId), the
correct method would be net.sf.gaim.BlistNode.IsBuddy().

Anyway. Second thing to do in your D‑Bus API is follow the
naming conventions. Those are documented here.

Third recommendation is to avoid a billion little round trips. (Michael used to
endlessly try to get people to stop this with CORBA, too. He was
right.) When doing any IPC thing, your performance killer is not
size of data, but blocking for one thing before you do the next thing.
In other words you don’t want to keep having to wait for the other
end, you want to be able to dump a bunch of stuff into the socket, and
then read a bunch of stuff off the socket. You don’t want to
block at all, when you can help it, but blocking over and over is
worse. Blocking over and over happens when one method call requires
information from a first method call.

To pick on Gaim again since I was just using its D‑Bus API, its API
requires you to get the accounts, then with a separate method call get
each property of each account, then with a separate method call get
each property of each buddy. Instead, in an IPC API you should be able
to do something like get all the buddies and all their properties in a
single method call, then keep your info up-to-date by receiving change
signals. Or for example, instead of GaimBuddyIsOnline(), have
GaimBuddyGetProperties(). D‑Bus even has a standard interface for
object properties (the dbus-glib bindings will export GObject props
for you, too), and I recently proposed a “GetAll” method to be added to
that interface.

This is especially important for application startup. In designing
D‑Bus APIs that apps will call on startup, you should strive to be
sure the app can just fire off messages and then get replies only
later once the main loop is running.

A useful hint here: match your signals by well-known bus name
(“hostname”) rather than by unique bus name (“IP address”). This
avoids the need for “name resolution” and also avoids the need to
re-add the match rule when the bus name gets a new owner.

Fourth, use the bindings. If you don’t use a D‑Bus binding you
probably will not get the introspection stuff right, which messes up
interoperability with certain bindings, and also keeps your app from
showing in dbus-viewer type of tools. Bindings can also automatically
implement object properties for you and encourage you to properly use
object paths and other D‑Bus concepts.

I do think the C binding situation needs work; I don’t think we have
dbus-glib 100% sorted out yet, and probably won’t until GLib itself
has a good introspection system. In the Mugshot client I cooked
up a cheesy helper API
, which has its own set of problems, so be
careful copying it. It also relies on dbus-glib for certain hard bits
(main loop integration). But the Python bindings are in very good
shape, and afaik some of the others are as well.

(This post was originally found at http://log.ometer.com/2007–05.html#17)

Gimmie

Alex, you
heard from Bryan early on. He asked for your help/input.

Let me clarify some points:

  • You say you “first learned” about our stuff “a few weeks ago” as if
    that meant there was some secret conspiracy before that; but “a few
    weeks ago” is pretty much when we started working on it. FUDCON was in
    February, we made first design sketches right before that. That means
    the first ideas were about 8 weeks ago. It’s in the public record.
  • You say we worked “completely in private” but in fact we a) showed
    brand new mockups and ideas at FUDCON and put them all on our public
    wiki and have had all code in public SVN and b) Bryan personally
    notified you
    when we started working on it in earnest, while we
    continued to work completely in public.
  • The code used in BigBoard from Gimmie is perhaps 1% of both projects,
    it sets the _NET_WM_STRUT hint from pygtk. This is just a trivial
    piece of code that is not central to either project and bringing it up
    as if it’s significant is misleading. The rest of the code in the
    projects does not overlap and in fact has little in common.
  • All our code is and always has been GPL, and it is perfectly
    acceptable to include LGPL code in a GPL project. Moreover, if you
    want to use any of our code under LGPL, you are welcome to do so, we
    will relicense it.
  • I had no idea that Gimmie has web services stuff as an aspiration. I
    don’t know why I would have known.
  • You ask why I haven’t supported Gimmie with some kind of public
    statement; to be honest I just never thought to do that in my blog, or
    saw a thread where it looked apropos to pile on. I have had multiple
    conversations with Bryan and Jonathan of the form “Gimmie is one of
    the only interesting things anyone is working on,” though.

All in all, BigBoard is quite different from Gimmie, though yes it has
things in common (and with Google/Yahoo!/Vista sidebar, Apple dock and
dashboard, gnome-panel, Awn, and
so forth). There is nothing whatsoever wrong with having different
rapidly-developed prototypes as we try to understand what would be
awesome. The people you should flame are those people who are too
stuck in the mud to try anything new.

btw, I think Gimmie looks great and I do support it. Bryan liked the ideas
too which is why he contacted you weeks ago.

If you have a concrete set of ideas for how we can do what we’re
trying to do while working in the same codebase as Gimmie, then get on
email and send them to us or the mailing list, and we’ll talk about
it. Maybe mock up what the UI that merges the best of both would look
like, or tell us how our implementation would work into the Gimmie
codebase.

I think when you really try to draw the combined UI as a mockup, or
talk about which files from one project would go where in the other
source tree, then merging these projects starts to look impractical
and forced. Merging them may be a little “architecture astronaut” in
other words. But if you can spell out a concrete vision for how to do
it that preserves what we’re both trying to accomplish, then we’ll do
it. It’s not a big deal.

(This post was originally found at http://log.ometer.com/2007–04.html#4)

GNOME Online Desktop

The Mugshot team has been off learning what we can about all kinds of
not-traditionally-open-source technologies and audiences, but recently
we’ve started thinking about how to roll the knowledge back into the
Linux desktop. Here’s an update (all heavily biased by my personal point of
view).

Tuning for an Audience

From an interview
with Dave Neary
:

Neary says he thinks GNOME will either grow into different projects –
such as a One Laptop Per Child (OLPC) GNOME, a Home and Small Office
GNOME, and Enterprise GNOME — or the project will shrink to the GNOME
development platform, “which will then be re-used by third parties to
build the interfaces they’re interested in on top of it.

“We have already started to see this trend. Distributors cherry-pick
the applications they are interested in for their own desktop
projects, which are then themed and targeted for their core
audience. The variety of platforms and human interfaces being built
upon the GNOME platform is dazzling. These go from small-form-factor
interfaces like the Nokia N800 and the Maemo application framework and
OpenMoko and GPE through to innovative interfaces like Sugar from
OLPC, which is totally unfamiliar to someone used to the GNOME
desktop, but which is undeniably GNOME-based.”

It isn’t just the embedded or odd form-factor devices that are
customizing GNOME, says Neary. “Even the major distributions have
modified the GNOME interface to suit their needs. The openSUSE, Red
Hat Enterprise, and Ubuntu desktops all behave in different ways, and
have different target audiences.”

Several of these specializations of GNOME technology for particular
audiences are happening at Red Hat; we’re working on One Laptop Per
Child and of course the desktop for Enterprise Linux which focuses on
admins and programmers in part, and enterprise deployments of
various kinds (tech workstation, thin client, etc.) in part.

We’ve been thinking about another flavor, which we might call GNOME
Online Desktop (purely for the acronym, of course).

Online Desktop

Many people now live online and use the computer largely as an
Internet frontend, with few or no “offline” applications. Webmail is
by far the most common mail application, for example. But think also
of Flickr, IM, MySpace, YouTube, Google Docs & Spreadsheets, and
so on. I count myself in this group; without an Internet connection I
don’t even bother to turn on my laptop.

Meanwhile, my desktop is crammed with relics of stuff I don’t use. The
clock applet only speaks Evolution calendar, instead of supporting
online calendars such as Google Calendar. The Recent Documents menu
has junk I don’t care about in it, instead of my actual documents (at
Google Docs & Spreadsheets). My panel launchers are for apps I
don’t use instead of shortcuts to the web apps I do use.

Target Audience

What if we started a desktop specialization aimed at a subset
of current Linux users who:

  • Are individuals who own their own computer (not using Linux as
    part of an enterprise or organizational deployment).
  • Use Linux as a desktop, for things like web browsing and listening
    to music (not using Linux purely as a server or purely for
    workstation-type productivity).
  • Use lots of online services, such as Facebook, MySpace, YouTube, GMail, Flickr,
    IM, Google Docs & Spreadsheets, Google Calendar, and so forth.

I expect this audience would include a fair number of college
students, and also some people like me.

As important, what if this desktop specialization explicitly does NOT care about:

  • Enterprise deployments including thin client, fixed function,
    technical workstation.
  • People who use Linux primarily as a server.
  • People who avoid using online applications for whatever reason
    (strong tendency to work offline, flaky net connection, enterprise
    security, or whatever).

I say “current Linux users” for the target audience because we can get
them to try out Online Desktop first. But if we’re successful, we
could then extend the target audience to include people who aren’t
using Linux already, whether individuals or even small businesses.
At that point we’d have to start worrying about things like migration
path, marketing to these new audiences, and so forth.

Features!

If we make these assumptions about the audience, what kinds of changes
could we make in the desktop?

People

A number of services maintain online contact lists (“people I
know”), including AIM, Google Talk, GMail, Facebook, MySpace and
Mugshot. Ideally, we would somehow collect “people I know” from these
places and have the desktop be smart about who I know and who I can
interact with in various contexts — sharing a file, writing a
document, sending an IM, or whatever it is.

In technical terms, we’ll want to drop the Evolution contact
database stuff and instead have a more
free-form/aggregation-oriented/stored-online idea of who your contacts
are.

Applications

Yesterday I mentioned Mugshot applications, where
we’re building a social concept of the “universe of applications.”

Ideally, this effectively replaces
/usr/share/applications. /usr/share/applications becomes purely the
launch instructions (we’re using it for the Exec= line).

In technical terms, this means replacing application launching (panel
menus, launchers, etc.) with a new interface, and replacing the
“package tool” with Install buttons contextually available as you
browse the universe of applications.

Our “universe of applications” should also include web apps as
first-class.

Documents

Documents are ideally kept online; this can take several forms. For
documents belonging to Google Docs & Spreadsheets, they are online
inherently. For more “native” documents, we might have online folders
that backend to something like S3 and are available in the file
manager. We might also look at the AbiWord Collaboration work that
people have been doing.

The “recent documents” list should include online documents, for sure.

Photos

We can just stick photos online by default, in Picasa or
Flickr. For example, if you plug in a camera, the default action is to
upload the photos, not copy to a local folder. We could also for
example maintain a local cache with F‑Spot set up to stay in sync with
the online app. I think F‑Spot already has some Flickr integration
even (?).

Calendar

We’d just use sites like Google Calendar as a calendar,
integrating it into the desktop clock/calendar applet or wherever, as
appropriate. There should be desktop notifications of upcoming events.

Preferences

We already have a simple way to store key-value pairs on mugshot.org
and a Python script that syncs gconf to the server dynamically, this
approach means that people’s settings follow them around instead of
staying on a single computer. It needs to be productized, but this is
pretty simple to get going.

Search

Search should be nicely configured by default to include all my online
information (calendar, documents, etc.) in addition to local files.

Easy Sharing, Local or Internet

For some reason nobody has solved the problem of easily sharing a file
with someone else; email attachments remain the usual approach. But it
should be possible to simply drag a file onto someone’s photo, whether
that person is sitting next to you at a conference or half a world away.

API

Right now, there’s quite a bit of work if a desktop application wants
to integrate with online services. Typically, the app has to write a
bunch of code to talk to the service; and the app has to require the
user to configure some often-arcane parameters.

Instead, we could make this desktop-wide. Think of a simplified and
online-backed contacts API for example, so any app could easily
support getting a list of people to interact with and opening a
connection to one of them. Appropriate gvfs backends might be another
example of desktop API taking advantage of online services.

Another API goal is “pluggable services,” for example to support
multiple calendar sites, we might build an abstraction API across them.

Live CD

One way to think about an “online desktop” is that you could put in
a Live CD, log in, and automatically get all your stuff and all your
preferences. I don’t really see a live CD as the primary use-case, but
it’s a useful way to think about the design.

More Ideas

It’s easy to think of more new features to implement:

  • Integration of blogging; the Flock browser has many ideas to build
    on for good blogging support, and a blog program could be on the panel
    by default.
  • Mail notification for GMail and other web mail programs.
  • Make it easy to automatically chat with anyone using the protocol you
    have in common with them.
  • Keep browser state such as bookmarks in del.icio.us or online in other
    ways.

In short suddenly the desktop goes from “solved problem” to “whole
universe of useful new stuff we could do.”

Getting Started: How to Proceed?

Putting everything immediately upstream into core GNOME has
problems; because the Online Desktop makes assumptions suitable for
its target audience but not for many GNOME users, maintainers would
frequently bounce the patches. More importantly, it isn’t clear yet
what Online Desktop should look like or how it should work. We need to
prototype.

At the same time we should keep a low barrier to entry, so people can
easily try out Online Desktop.

Our thought, modeled on the Compiz approach, is to replace just one
component of the desktop — the panel. This way we can ship one
codebase, and to try it out you just run the new panel app.

In the short term we need not even replace the whole panel, we can do
a sidebar similar to the Yahoo!/Google/Vista sidebars on Windows. The
sidebar works fine with your existing panels.

Colin, Bryan, and I (mostly Colin and Bryan) have been working on such
a thing for a couple weeks, the code name is Big Board and you can
find more
information here
.

Big Board uses Mugshot to “fill in gaps.” That is, Mugshot is not
intended to replace services you already use (whether Flickr or
Facebook or whatever); but if we need to do something that no existing
service provides, we can stuff it in Mugshot. For example, Mugshot has
the applications browser
I mentioned, and it has prototype-quality storage for shared files and
for preferences. Mugshot in this context is an open source server
codebase that we can extend as we need to.

Mugshot also aggregates information on all the accounts and
addresses you and your friends have, so that information is available
to the desktop. In Big Board there’s a “slideshow” feature that cycles
through thumbnails from your friends’ Flickr, Picasa, and
YouTube. Mugshot means this works with zero configuration, while the
traditional alternative would be to manually type in all the friends’
accounts you wanted to include.

Big Board doesn’t talk directly to the mugshot.org server, though; it
instead uses D‑Bus APIs exported by the local Mugshot client.
Other apps could use these APIs as well.

Big Board is very much a prototype right now (for example, the search box is
just the GNOME deskbar applet, and embedding an applet in a
non-gnome-panel doesn’t quite work). The hope of course is that we’ll
evolve from prototype to something more robust as it makes sense.

We also see the goal as “online desktop” rather than only “panel/sidebar gizmo,” but
as I mentioned Big Board is somewhere to start.

Check out Big
Board so far
including early design notes.
To discuss feel free to use the Mugshot
list
or GNOME desktop-devel-list.

(This post was originally found at http://log.ometer.com/2007–04.html#3)

Find and Browse Apps

The Mugshot applications
pages show which apps people are using most on Linux.

We just updated the site and Mugshot client to add some new features:

  • If you don’t have the app installed, and Mugshot understands your
    OS, there will be an “Install Now” link right on the web page.
  • If you do have the app installed, there will be a “Run It” link
    right on the web page.
  • The application pages can be edited wiki-style to add a
    description and so forth for each app (very basic and rough UI on this
    right now).

You can probably imagine lots of interesting directions to evolve
this.

Right now, two things you might be interested in:

  • If your distribution isn’t supported, you won’t get Install and
    Run links; look
    here
    for more on how to help add support for your distribution.
  • If you maintain or have an interest in a particular application, you
    might want to update the description and other information about it.
    Go to the application’s page on Mugshot and click on the link to edit
    it (you must be logged in to Mugshot).

Feel free to ask questions or send comments to the mailing list.

(This post was originally found at http://log.ometer.com/2007–04.html#2)

How to use gnome-keyring

I was recently trying to use gnome-keyring and ended up having to ask
Alex what was going on. Here is a short explanation so anyone else
googling the subject might find it.

The keyring repository maps attribute sets (like {server=yahoo.com,foo=bar}) to
secrets. A secret is just a string that gets encrypted, typically it
would contain your password or username/login. The
(attribute-set,secret) pair is called an “item.”

There’s a ton of stuff in gnome-keyring.h. What you want to use is
create_item_sync() to create your secret, and find_items() to retrieve
it. The “network password” API is just a convenience layer that
keeps you from making up your own attribute names.

If you’re using the Python bindings, you have a problem; one of the
two functions you want to use, find_items(), just crashes.
The example
code
that comes with gnome-python-desktop jumps through some weird
hoops with gconf to work around this; it stores the id of the item in
gconf, instead of using find_items(). This example also calls the id
“auth_token” as if it were special or secret, but the id is just a
handle to the item. This example is totally wrong in a
confusing way, is what it comes down to.

The last thing to know is that there are multiple keyrings, but
you only care about two. A NULL keyring means to use the default
persistent one, and the string “session” means to use an in-memory
keyring that will be dropped on logout. find_items() searches
all keyrings, and that’s why find_items() has no keyring
argument.

I filed a
bug on the python bindings
since they aren’t really usable without
find_items() but it looks like these bindings are unmaintained (the
bug got assigned to “Nobody’s working on this”).

(This post was originally found at http://log.ometer.com/2007–03.html#9)

Whaling

From publication
526
:

Expenses of Whaling Captains
Beginning in 2005, you may be able to deduct as a charitable
contribution the reasonable and necessary whaling expenses paid during
the year in carrying out sanctioned whaling activities. The deduction
is limited to $10,000 a year. To claim the deduction, you must be
recognized by the Alaska Eskimo Whaling Commission as a whaling
captain charged with the responsibility of maintaining and carrying
out sanctioned whaling activities.
Sanctioned whaling activities are subsistence bowhead whale hunting
activities conducted under the management plan of the Alaska Eskimo
Whaling Commission.
Whaling expenses include expenses for:

  • Acquiring and maintaining whaling boats, weapons, and gear used
    in sanctioned whaling activities,
  • Supplying food for the crew and other provisions for carrying out
    these activities, and
  • Storing and distributing the catch from these activities.

To deduct these expenses, you will be required to keep records showing the time, place, date, amount, and nature of the expenses.

It would be awesome to have “whaling weapons” as an itemized deduction.

(This post was originally found at http://log.ometer.com/2007–03.html#9.2)

Wiiiiiiii!

Tomorrow our Wii is supposed to show up. According to a couple reviews
so far, such as this
one
, Twilight Princess is the best Zelda ever (which of course
means it’s in the running for best game ever, period).

Often I do some kind of coding project over Thanksgiving vacation, but
this year I guess not.

(This post was originally found at http://log.ometer.com/2006–11.html#19)