Using the LXD API from Python

After our recent splash at ODS in Vancouver, it seems that there is a lot of interest in writing some python code to drive LXD to do various things. The first option is to use pylxd, a project maintained by a friend of mine at Canonical named Chuck Short. However, the primary client of this is OpenStack, and thus it is python2. We also don't want to add a lot of dependencies in this module, so we're using raw python urllib and friends, which as you know can sometimes be...painful :)

Another option would be to use python's awesome requests module, which is considerably more user friendly. However, since LXD uses client certificates, it can be a bit challenging to get the basic bits going. Here's a small program that just does some GETs to the API, to see how it might work:

import os.path

import requests

conf_dir = os.path.expanduser('~/.config/lxc')
crt = os.path.join(conf_dir, 'client.crt')
key = os.path.join(conf_dir, 'client.key')

print(requests.get('https://127.0.0.1:8443/1.0', verify=False, cert=(crt, key)).text)

which gives me (piped through jq for sanity):

$ python3 lxd.py | jq .
{
  "type": "sync",
  "status": "Success",
  "status_code": 200,
  "metadata": {
    "api_compat": 1,
    "auth": "trusted",
    "config": {
      "trust-password": true
    },
    "environment": {
      "backing_fs": "ext4",
      "driver": "lxc",
      "kernel_version": "3.19.0-15-generic",
      "lxc_version": "1.1.2",
      "lxd_version": "0.9"
    }
  }
}

It just piggy backs on the lxc client generated certificates for now, but it would be great to have some python code that could generate those as well!

Another bit I should point out for people is lxd's --debug flag, which prints out every request it receives and response that it sends. I found this useful while developing the default lxc client, and it will probably be useful to those of you out there who are developing your own clients.

Happy hacking!

Qtile's crazy 0.9.0 changes have landed

We have re-written a lot of the underlying code that powers qtile, in order to support python2/3, pypi, as well as getting rid of several memory leaks. This work is now done and on the development branch, see the mailing list announcement for more info.

Qtile 0.8.0 tagged!

I've just tagged version 0.8.0 of Qtile! See the changelog for full release details, and the release announcement for other detials. This release of Qtile also comes with a sleek new website, courtesy of Derek Payton.

xcffib 0.1.0 released!

I'm excited to announce today that I've tagged the first release of xcffib, v0.1.0. The testing of xcffib with qtile has been mostly successful, and I'm comfortable now tagging a release. Special thanks to Sean Vig who has done a lot of work on the python3 side of xcffib. Happy hacking!

CFFI-based Qtile!

For the past while I've been working on a reimplementation of xpyb in cffi. There are several reasons to want to do this:

. xpyb has at least one more memory leak (but probably others)

. The xpyb upstream is inactive, and there is no sign of a python 3 port

. It would be uber cool to be able to run qtile in pypy.

Using cffi soves 2 and 3 pretty easily, and I've made sure that xcffib's test suite runs through valgrind with no definite leaks, hopefully mitigating 1. However, even if we have xcffib, there is still a lot of work that needed to happen to make qtile run on top of it. I'm writing this post to announce that some of that work is done, and late last night I was able to boot qtile running on top of xffib! There are still lots of bugs, and lots of testing needs to be done, but we're most of the way there I think, and running qtile on python3 and pypy without memory leaks is no longer a pipe dream :-).

To install, you'll need:

. sudo apt-get install xcb-proto libpango1.0-dev libcairo2-dev (or whatever

the equivalent packages are on your distro)

. Follow the installation instructions for xcffib.

. Install the xcffib branch of tych0/cairocffi

. Install the cffi branch of tych0/qtile

I have not tried to test qtile on python 3 yet, so there may be some work that needs to be done to successfully run things on python 3. However, both xcffib and cairocffi run their test suites on python 3, and so the only work that needs to be done is probably in qtile, if any. pypy is another story however, as xcffib does not currently pass its test suite on pypy. I plan to fix that at some point, but I'd like to get qtile running completely before that happens.

Finally, there are some bugs that manifest with qtile right now:

. The systray doesn't work. This is probably due to a bug in the way xcffib

unpacks ClientMessage events.

. Most of the text-based widgets don't work. This is probably due to a bug in

the pangocffi binding I wrote for qtile. I thing it is just an incompleteness, and I will try and fix it either today or tomorrow. Basic text widgets like the clock or the volume widget work just fine.

. Lots of other things are probably broken :-). Bug reports welcome.

Happy hacking!

Ubuntu 14.04 Trusty Tahr packages for Qtile

Just posting to let everyone know that I've published packages for the latest Qtile release on Ubuntu 14.10. See the mailing list announcement for more details. Additionally, we will be doing a 0.7 release shortly, so please let me know if there are any release blocking bugs!

Ubuntu 13.10 Saucy Salamander packages for Qtile

Just posting to let everyone know that I've published packages for the latest Qtile release on Ubuntu 13.10. See the mailing list announcement for more details.

Manage passwords without state

A few years ago I had a problem: I had a bunch of accounts that I accessed once a year when tax time came around, and I kept forgetting the passwords. Often I'd try a few before locking myself out, and then I'd have to spend an hour on the phone with customer service getting my account unlocked, which meant if I was doing my taxes on the last weekend possible, I wouldn't be able to complete them until the next business day. The obvious solution to this problem is to store the passwords in some kind of password manager -- lots of them exist for all kinds of platforms: phone, computer, browser, etc.

The problem with password manager is that they typically require some kind of state file. They store the mapping between site and cleartext password in some file, and then they decrypt it with some secret from you when you want to access it. Thus, you have to 1. trust the person who is doing the encrypting and decrypting that they are doing it correctly so that when your laptop gets stolen your passwords aren't leaked, and 2. you have to have access to the machine that the passwords are stored on when you want to use them. If you've left your laptop at home or you forgot to back up your password file when you got a new computer, you're SOL.

What's the solution? A password manager without state, of course! Since we're assuming the user can remember at least one pretty good password, we can use that as our "state", so we end up with the algorithm as follows:

hash = sha512(user_secret + "example.org")
base64encode(hash)[:10]

Here, we're using the domain to salt the user secret so the generated passwords are different for each site. sha512 provides randomness, although we are only using the first 60 bits of the output here (10 base64 characters, each character encodes six bits of entropy), there are significantly more bits of entropy here than in your typical English character, making it a much stronger password. Further, the algorithm is very simple, and you could re-implement it on any computer that has your favorite programming language environment available. Thus, you can use it in a pinch, since all you need to remember are the algorithm and your user_secret. I've published a python script that implements this mechanism, so you don't even have to remember the algorithm

Qtile 0.6 released!

I have just tagged and released qtile 0.6! This release comes exactly 6 months after our last release (not intentionally, it just happened to work out that way). You can check out the full release notes for a list of most of the changes.

I thought I'd discuss a bit about the breaking config changes we made. A few of them were long standing TODOs in the code, but the major one (and the one that motivated cleaning up all the rest) was creating a new config module where all of the objects used in configuration live. The primary motivation for this change was to remove a lot of crazy hacks we had in the test system to get around circular imports, since the configuration objects and main manager were all in the same file. However, it also makes sense from a code organization standpoint, because manager.py was getting huge. I think user impact will be minimal, because configs can be updated with a simple regex. That said, I will only be updating the Ubuntu 13.04 packages, so as not to break configs for existing users on older packages with a simple dselect-upgrade.

As always, questions or comments are welcome on qtile-dev!

Qtile 0.5 released!

Hello! Today, I'm proud to announce the release of Qtile 0.5. A wildly incomplete changelog is available here. Qtile 0.5 comes more than two years after the release of 0.4. There have been many major improvements and bugfixes by nearly 50 contributors. Many thanks to everyone who was involved, and long live tiling window managers!

Qtile 0.5 packages for 12.10

Ahoy! I've updated the packages in my Ubuntu 12.10 PPA to be version 0.5. Please let qtile-dev know if you have any problems!

Qtile packages for Ubuntu 12.10 (Quantal Quetzal)

Ahoy! I have put up new packages for qtile for 12.10, so I thought I'd write a bit about what's actually in the packages. First, they're available via the standard:

sudo apt-add-repository ppa:tycho-s/ppa
sudo apt-get update
sudo apt-get install qtile

A few things to note about these packages. First: they now install a qtile.desktop file, so any compliant freedesktop.org login manager should see qtile as a login option. Note that this just invokes qtile directly with no arguments, so you'll have to put your configs in the standard location. If you want to run a custom .xsession, you'll still need to set that up yourself.

Second, these packages no longer depend on xpyb-ng, but depend on xpyb (1.3.1) directly. I did this for a few reasons. I've had several users report that 1.3.1 works directly for them (i.e. xpyb-ng is not actually required to run qtile). If there is no problem with using the stock implementation, I felt like we should switch to that. Naturally, if problems come up and we need to move back to our fork, I'm happy to rebuild, however, I think that's unlikely.

Third, which hash are these packages based on? They're based on 87dc6924cb, which is on the development branch. I've been running this code both at home and at work for several months now, as well as several other people. While there are still several bugs (patches welcome!), I feel that it's much more stable and user friendly than the master branch.

Fourth, based on some statistics that Launchpad provides, it looks like there were about 100 installs of the Ubuntu PPA. One or two of those were probably my test VMs, but that means there were a fair number of other people who checked qtile out. Very cool!

Feel free to e-mail me or qtile-dev with any feedback! (Unfortunately, I've been inadvertently banned from qtile-dev somehow. Still waiting on a resolution to that, so if you find a bug with the packages, go ahead and just file it on the github tracker and I'll fix it ASAP.)

Qtile packages for Ubuntu 11.10 (Oneiric Ocelot)

By not-so-popular demand (:-), I have built some packages for qtile and its dependencies for 11.10. You can now install my branch of qtile via:

sudo apt-add-repository ppa:tycho-s/ppa
sudo apt-get update
sudo apt-get install qtile

Feel free to e-mail me or qtile-dev with any feedback!

Viridian/Ampache local control

Recently at work I've been using Viridan to listen to music at work. It has its warts, but generally works pretty well. There's even an XMLRPC server built in, so you can control it remotely. However, there's not a huge number of clients out there, so I wrote my own little script so that I could start and stop it from a Qtile keybinding, and I thought I'd put it up here for anyone else who is interested. Here's an example session:

smitten:~$ ./vif.py 
./vif.py [rpc_call(s)]
   availible methods are:
     get_current_song
     get_state
     get_volume
     next
     play_pause
     prev
     set_volume
     volume_down
     volume_up
smitten:~$ ./vif.py get_current_song
{'artist_name': 'Meshuggah','song_title': 'Stengah', ...}
smitten:~$ ./vif.py next
True

Hopefully someone else finds it useful :-)

Installing Qtile on Ubuntu 11.10 (Oneiric Ocelot)

Recently, there has been some discussion on qtile-dev about installing the latest and greatest version of qtile. Unfortunately, the install process has historically been a journey into dependency hell, since distributions didn't have the latest versions of some libraries required by qtile. The good news is that this has mostly been fixed (although very few documents anywhere state this), so it's hard to know what to install by hand and what you can use packages for.

To complicate matters more, there are several versions of xpyb floating around, none of which have working build systems! If you knew enough about pkg-config and weren't afraid of manually installing files, you could get everything to work, but it did bar the "normal user" from installing qtile. Hopefully this blog post will clarify a few things.

First, what dependencies do you need to install? Contrary to what the docs say, in 11.10 (and presumably later versions of Ubuntu), you don't need to build your own cairo or xcb. You can simply:

sudo apt-get install xcb-proto libxcb1-dev python-xcbgen
libcairo2-dev

You will have to build three things by hand: xpyb, py2cairo, and qtile itself. The other day I sat down and fixed the build system for xpyb, so you should be able to just:

git clone git://github.com/tych0/xpyb-ng.git
cd xpyb-ng
sudo python setup.py install

After that, you'll need to install py2cairo. The waf based build doesn't appear to detect xpyb correctly, so you'll need to go the autoconf route. Even with autoconf, the build system is slightly broken, so you'll need to be explicit about what directories to look in for xpyb.h. If you used the above build of xpyb, you can:

git clone git://git.cairographics.org/git/py2cairo
cd py2cairo
CFLAGS=-I/usr/local/include/python2.7/xpyb ./configure
sudo make install

Then, you can clone your favorite qtile repo and everything should Just Work! If you want to clone my copy of qtile (which includes several bug fixes and enhancements):

git clone https://github.com/tych0/qtile
cd qtile
sudo python setup.py install

If you have any questions or problems, feel free to mail qtile-dev or me directly. I am going to try and package qtile and put it in a PPA, but I doubt I will get to that for another few weeks. This should help anyone who is interested enough to build it in the meantime, though!

Python "binding" for Ampache

Ahoy!

Just writing a quick post to pimp my new Ampache "bindings", which are called ampyche, naturally ;-). I slapped them together one afternoon mostly to get an understanding of the Ampache API, so that's why I used my native language. I have no specific plans for any python applications using them, but I'm interested in improving the stability of Android-based Ampache clients, as well as adding support for Ampache to Clementine, so I thought this would be a good place to start.

In any case, I hope someone finds them useful! Happy hacking!

Google Voice ncurses interface

For a while I have been using a Google Voice number as my primary texting number since it doesn't cost any money and has the additional benefit that when I'm at a computer, I can type text messages on a regular keyboard instead of on my tiny phone keyboard. This is all well and good, except I don't particularly care for the web interface; not because it's bad, but simply because it requires you to have a web browser open.

To solve this, I wrote an ncurses based "chat" client, gvchat. It provides and instant messaging interface for the most recent text message your GV account has received. When someone new texts you, it seamlessly switches to that new thread. At this point there is no way to initiate new texts, but I plan on growing the feature set in the coming months. However, for now it fits my needs so I thought I'd put it up for other people in the same boat.

Additionally, the client has a class 'Chat', which implements a crude ncurses based chat interface. As this improves, my hope is to add an XMPP backend for it as well. Any ncurses tips and tricks (or pointers to libraries which already have this functionality and are built on top of ncurses) are much appreciated!!

A Tiling Window Manger

Ahoy! At the recommendation of one of my friends, I've recently begun using a tiling window manger. Although he recommended xmonad, I decided to instead to go with a different project, qtile. I got myself a github account, since that is the primary avenue for qtile development. This means you can run the same WM code as I do :-). (I also posted the code for the framework that powers this blog, something I've been meaning to do for a while but have not gotten around to.)

I wrote a widget for displaying the currently playing track from your favorite player which implements MPRIS, and I would be interested in any feedback other qtile users have, so feel free to send me or qtile-dev e-mail if you play with it! The widget can be found in both my fork of qtile and in the main fork. It depends on python-dbus, things like Ubuntu's update-manager do too, so it's probably installed for most users. To use it, you can simply put

widget.Mpris(objname='org.mpris.awesome_mpris_player')

in your qtile config.py. objname should be whatever the name of your MPRIS player is. You can figure out what this is by running dbus-notify and starting your player, and see what name it requests when it issues RequestName. For example, Clementine's is org.mpris.clementine (and is also the default).

Happy hacking!

Gmail, Conky, and libnotify

Several years ago I discovered a fantastic system monitor named conky. Over the years I've been tweaking my .conkyrc and it has really evolved into a little command center all on it's own. However, I read my e-mail through a mutt, and thus to check it I have to open mutt and look and see if I have any new mail. This is often obnoxious, because I'll either forget to check and miss something until later, or I'll check a lot and not get any e-mail. Today it occurred to me "hey, computers are good at repetitive tasks!", so I decided to automatically check my e-mail and render the results in conky. I also have heard lots of noise about libnotify, and how wonderful it is, so I decided to use that as well. The result is a script which checks a user's Gmail (using a password stored in a keyring), updates conky, and shows a libnotify notification if necessary. It also supports querying of arbitrary Gmail labels, allowing you to display unread counts for other e-mail addresses you might possibly have mapped to your Gmail account.

You can get your own copy to play around with if you like. It's fairly well documented, but I'll answer any questions anyone has. The dependencies (at least on Ubuntu) are python-notify python-keyring and your favorite of: python-keyring-gnome or python-keyring-kwallet.

I've released it under a beerware style license, in hopes that someone, somewhere, might find it useful. Feedback is appreciated!

Gmail Atom Feed Authentication

Perhaps the most complicated part of the application in my recent post was the authentication with Gmail. Although my final method boils down to only a few lines of python, Google describes several different ways to authenticate (additionally, putting the username and password directly in the URL). I didn't like any of these options, as some seemed much too complicated for what I wanted to do, some didn't work, and some were too insecure. However, it turns out that the atom feed supports HTTP's basic access authentication. In python, this is fairly easy to do:

$ python
>>> import urllib2, base64
>>> username = "me@gmail.com"; password = "secret"
>>> url = "https://mail.google.com/mail/feed/atom/"
>>> req = urllib2.Request(url)
>>> authstr = base64.encodestring("%s:%s" % (username, password))[:-1]
>>> req.add_header("Authorization", "Basic " + authstr)
>>> urllib2.urlopen(req).read()

Note that the above also works for Google apps users you just have to stick "/a/example.com" in the appropriate spot in the URL. Hopefully this will help out someone else who is hopelessly bashing Google's servers with failed login attempts ;-)