Re: Extensions Infrastructure Work



Recap from last time:

It seems like everything we discussed yesterday has gotten positive
responses. If you have any ideas or concerns about this, please don't
hesitate to ask.

If you're curious, all the code that I demoed last time, including
both the Stateful/Stateless approaches is indeed working. I've mainly
been testing with the "Hello, World" extension, but I've hacked up the
Places Menu and the Drive Menu extensions as well. Implementation is
left as an exercise for the reader.

The code to do all this magic is in two places[0][1]. Disclaimer: it's
extremely messy. You have been warned. I don't want these in GNOME Git
yet because I'm rebasing, squashing patches, and force pushing often.
That should slow down soon, but right now it's my baby. When it's all
grown up, I'll move it into GNOME GIt proper.

Here's some technical details about what I went over last time:

For those curious, the website's partner in crime is
gnome-shell-extension-tool[2]. There's an option that runs a small
HTTP server which the web site can talk to. The HTTP server is
basically a dummy proxy so that the website can talk to DBus. Before
this lands, I'll rewrite the HTTP server so it's not based on
BaseHTTPServer and move it into its own script. Maybe I'll rewrite it
in gjs+libsoup instead, because I'm not aware of any light-weight,
solid HTTP servers in Python... I don't want to install Twisted on a
user's desktop machine, even though I'd love to.

For all intents and purposes, the mimetype handler approach is dead. I
may work on it to be a fallback for browsers without the cross-domain
headers (Firefox added it in 3.5, released in 2009. That *should* be
good enough, right?), but it would be an "extra time" thing.

If I can figure out why the Shell's webm recorder and the <video> tag
in Firefox aren't cooperating, you may see a small demo video of what
I've done so far. This includes uploading, installing, enabling, and
disabling extensions, as well as a simple error prompt that allows
users to see any errors caused by the extension. Excusing the ugly
code, it's all working.

Onto the new stuff:

== Versioning and upgrading ==

Today I started working on versioning and upgrading Shell extensions.
The idea is that each Extension has a corresponding Extension Version
that's associated with one zipfile: whenever an author upload a new
zipfile, there's a new extension version. This way, if an extension
upgrade accidentally crashes the Shell, extension authors can
blacklist a version, causing the Shell's update system to rollback to
the last known version. Web administrators also have the power to
blacklist the extension in case of malice.

I'm not going to do an upgrade automatically. Instead, the user will
get a simple notification telling him that extensions can be upgraded.
Clicking on it will open the extensions.gnome.org website, where he
can upgrade at his leisure. The 'shell-version' fieldcannot lie: the
field is present for the user's benefit. If the automatic upgrading
system sees that the newer versions are incompatible with the Shell,
it won't pop up the notification or allow the user to upgrade.

If the upgrade crashes the shell and there has been a recent rollback,
the Shell will rollback and try again.

How will we do a seamless upgrade? WIth the new enable/disable
approach that I talked about last time in use, upgrading an extension
should be fairly simple, provided people are playing by the rules:

  1. Disable the extension.
  2. Delete all internal copies of extension data (the extension
module, importer object, state object and metadata object).
  3. Run a full GC.
  4. Delete the old extension directory.
  5. Install the new extension and enable it as normal.

Steps 3 and 4 are the ones I'm concerned about.

  Colin: if someone leaves some signals connected on a Shell object,
will the extension itself not collected? Is there a weakref we can add
so that signals *can* be collected? Consider this question valid for
any "s/signal/?/" you can think of.

  Extension authors: when this is implemented, you cannot create or
depend on any files in your extension dir, otherwise this just won't
work. The "helper" object I talked about last time is just some crazy
way for extensions to do extension-related tasks. I might add a
"getExtensionStorage()" method that returns a GFile with a storage
directory carved out for you that
persists between versions. For assets, I might add a
"getExtensionDataDir()", which does the same thing. "createDBus()"
might be another.

This should take me a good week and a half to do. After that, I'll
look at Shell recovery for when the Shell crashes due to an extension.

  Jasper

[0] https://github.com/magcius/sweettooth
[1] https://github.com/magcius/gnome-shell/tree/extension-work
[2] https://github.com/magcius/gnome-shell/blob/extension-work/src/gnome-shell-extension-tool.in


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]