<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8086027361681461014</id><updated>2012-02-03T23:59:35.633-08:00</updated><category term='linux'/><category term='objc'/><category term='dotcloud'/><category term='openstack'/><category term='nontech'/><category term='guide'/><category term='rackspace'/><category term='personal'/><category term='java'/><category term='hr'/><category term='macosx'/><category term='gogrid'/><category term='ports'/><category term='cloud'/><category term='laptop fail'/><category term='software fail'/><category term='trip'/><category term='libcloud'/><category term='с++'/><category term='bike'/><category term='skytap'/><category term='lc-tools'/><category term='mutt'/><category term='gutsy'/><category term='homepage'/><category term='powerpc'/><category term='python'/><category term='thoughts'/><category term='celery'/><category term='us'/><category term='freebsd'/><category term='mox'/><category term='fail'/><category term='ubuntu'/><category term='health'/><category term='rant'/><title type='text'>Roma's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>67</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7005890066704186843</id><published>2012-01-03T04:17:00.000-08:00</published><updated>2012-01-03T04:41:37.941-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><title type='text'>lc-tools 0.7.1.0 released!</title><content type='html'>I'm happy to announce new lc-tools release: &lt;b&gt;0.7.1.0&lt;/b&gt;!&lt;br /&gt;&lt;br /&gt;It doesn't have new features, but was updated to work with libcloud 0.7.x (earlier libcloud versions are no longer supported!). All the kudos go to &lt;i&gt;Pavel Vozdvizhenskiy&lt;/i&gt; for noticing problems and testing.&lt;br /&gt;&lt;br /&gt;You can install the new version using either easy_install:&lt;br /&gt;&lt;br /&gt;easy_install lctools&lt;br /&gt;&lt;br /&gt;or by downloading and installing it by hands:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/novel/lc-tools/lctools-0.7.1.0.tar.gz"&gt;lctools-0.7.1.0.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SHA256 (lctools-0.7.1.0.tar.gz) = 7f65c29cda06d256c02f6544b4957ca984f34f1cfed5b24558c3b4338f87dd9c&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7005890066704186843?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7005890066704186843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2012/01/lc-tools-0710-released.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7005890066704186843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7005890066704186843'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2012/01/lc-tools-0710-released.html' title='lc-tools 0.7.1.0 released!'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2513039902325985110</id><published>2011-12-21T23:51:00.001-08:00</published><updated>2011-12-22T00:45:21.355-08:00</updated><title type='text'>Bug Prediction</title><content type='html'>Recently I've read a very interesting post about &lt;a href="http://google-engtools.blogspot.com/2011/12/bug-prediction-at-google.html"&gt;Bug Prediction&lt;/a&gt; on &lt;a href="http://google-engtools.blogspot.com/"&gt;Google Engineering Tools&lt;/a&gt; blog and decided to inspect FreeBSD source tree in the same manner.&lt;br /&gt;&lt;p&gt;The question is how to determine if the given commit is a bug fix. I decided to start with a security fixes first and filtered commit messages by "Security:" tag in them. The result is the following:&lt;/p&gt;&lt;table&gt;&lt;tr&gt;&lt;th style="text-align: left"&gt;Filename&lt;/th&gt;&lt;th style="text-align: left"&gt;Score&lt;/th&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/s3_srvr.c&lt;/td&gt;&lt;td&gt;1.12807360699&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/s3_clnt.c&lt;/td&gt;&lt;td&gt;1.12546730725&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/openssl.spec&lt;/td&gt;&lt;td&gt;0.914805209201&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/NEWS&lt;/td&gt;&lt;td&gt;0.914805209201&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/CHANGES&lt;/td&gt;&lt;td&gt;0.914805209201&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/README&lt;/td&gt;&lt;td&gt;0.914805209201&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/crypto/opensslv.h&lt;/td&gt;&lt;td&gt;0.914805209201&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/Makefile&lt;/td&gt;&lt;td&gt;0.914805209201&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/FAQ&lt;/td&gt;&lt;td&gt;0.914805209201&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/apps/speed.c&lt;/td&gt;&lt;td&gt;0.707204148366&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/t1_lib.c&lt;/td&gt;&lt;td&gt;0.696806056187&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/s3_lib.c&lt;/td&gt;&lt;td&gt;0.663083892748&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/crypto/md32_common.h&lt;/td&gt;&lt;td&gt;0.578509821664&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/crypto/ocsp/ocsp_prn.c&lt;/td&gt;&lt;td&gt;0.578509821664&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/engines/e_chil.c&lt;/td&gt;&lt;td&gt;0.578509821664&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/d1_pkt.c&lt;/td&gt;&lt;td&gt;0.51304099663&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/crypto/pqueue/pqueue.c&lt;/td&gt;&lt;td&gt;0.51304099663&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/d1_both.c&lt;/td&gt;&lt;td&gt;0.51304099663&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;contrib/ntp/ntpd/ntp_crypto.c&lt;/td&gt;&lt;td&gt;0.505424173077&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/crypto/asn1/tasn_dec.c&lt;/td&gt;&lt;td&gt;0.482876843456&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/compat/linux/linux_socket.c&lt;/td&gt;&lt;td&gt;0.477720395098&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;usr.bin/compress/zopen.c&lt;/td&gt;&lt;td&gt;0.462407652214&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;usr.bin/gzip/zuncompress.c&lt;/td&gt;&lt;td&gt;0.462407652214&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/kern/uipc_usrreq.c&lt;/td&gt;&lt;td&gt;0.462407652214&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/ssltest.c&lt;/td&gt;&lt;td&gt;0.460574251046&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/s2_srvr.c&lt;/td&gt;&lt;td&gt;0.460574251046&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/apps/x509.c&lt;/td&gt;&lt;td&gt;0.460574251046&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;crypto/openssl/ssl/s3_pkt.c&lt;/td&gt;&lt;td&gt;0.456096100304&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c&lt;/td&gt;&lt;td&gt;0.44243544619&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c&lt;/td&gt;&lt;td&gt;0.44243544619&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;There results appeared not very interesting though. This kind of matches &lt;a href="http://www.freebsd.org/security/advisories.html"&gt;security advisories&lt;/a&gt;, but given that there are not very much of them (luckily!), it's not very representative.&lt;br /&gt;&lt;br /&gt;I also tried to run the script with "[\t ]+[Bb]ug" regular expression instead of "Security:", and got the following result:&lt;br /&gt;&lt;br /&gt;&lt;table class="report"&gt;&lt;tr&gt;&lt;th style="text-align: left"&gt;Filename&lt;/th&gt;&lt;th style="text-align: left"&gt;Score&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_output.c&lt;/td&gt;&lt;td&gt;7.66251938944&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_pcb.c&lt;/td&gt;&lt;td&gt;7.2065885975&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctputil.c&lt;/td&gt;&lt;td&gt;6.80461378901&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/dev/bge/if_bge.c&lt;/td&gt;&lt;td&gt;6.50257671046&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_input.c&lt;/td&gt;&lt;td&gt;5.62524237411&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_indata.c&lt;/td&gt;&lt;td&gt;5.25336437345&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_usrreq.c&lt;/td&gt;&lt;td&gt;5.11155404498&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_timer.c&lt;/td&gt;&lt;td&gt;3.67543247047&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_structs.h&lt;/td&gt;&lt;td&gt;2.99517512907&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/conf/files&lt;/td&gt;&lt;td&gt;2.89041302648&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_asconf.c&lt;/td&gt;&lt;td&gt;2.79978400331&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_constants.h&lt;/td&gt;&lt;td&gt;2.79452724525&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/dev/bge/if_bgereg.h&lt;/td&gt;&lt;td&gt;2.62852430236&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/dev/msk/if_msk.c&lt;/td&gt;&lt;td&gt;2.31771522145&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctputil.h&lt;/td&gt;&lt;td&gt;2.19989952769&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;contrib/bind9/CHANGES&lt;/td&gt;&lt;td&gt;2.15204576684&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;contrib/bind9/version&lt;/td&gt;&lt;td&gt;2.15204576684&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/kern/kern_fork.c&lt;/td&gt;&lt;td&gt;2.12687393752&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/in.c&lt;/td&gt;&lt;td&gt;2.09501338006&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_sysctl.c&lt;/td&gt;&lt;td&gt;2.06560623664&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet6/sctp6_usrreq.c&lt;/td&gt;&lt;td&gt;1.92839801197&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/netinet/sctp_var.h&lt;/td&gt;&lt;td&gt;1.91990472478&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/conf/NOTES&lt;/td&gt;&lt;td&gt;1.79166008565&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/dev/mxge/if_mxge.c&lt;/td&gt;&lt;td&gt;1.74628407608&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;contrib/bind9/bin/named/query.c&lt;/td&gt;&lt;td&gt;1.74336559317&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;contrib/bind9/lib/dns/rbtdb.c&lt;/td&gt;&lt;td&gt;1.74336559317&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c&lt;/td&gt;&lt;td&gt;1.7287195258&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/i386/xen/pmap.c&lt;/td&gt;&lt;td&gt;1.68724079063&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sys/powerpc/aim/mmu_oea64.c&lt;/td&gt;&lt;td&gt;1.68644933665&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;contrib/bind9/lib/dns/validator.c&lt;/td&gt;&lt;td&gt;1.6676964412&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;This is somewhat more interesting result. It shows that most 'dangerous' sits in SCTP implementation, NIC drivers (bge, msk, mxge) and also some bits in zfs and bind. I wonder how accurate is that?&lt;br /&gt;&lt;br /&gt;The script is available &lt;a href="https://gist.github.com/1507152"&gt;here&lt;/a&gt;. It's designed to use git repository. I used freebsd git mirror on github: &lt;a href="https://github.com/freebsd/freebsd-head"&gt;https://github.com/freebsd/freebsd-head&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2513039902325985110?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2513039902325985110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/12/bug-prediction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2513039902325985110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2513039902325985110'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/12/bug-prediction.html' title='Bug Prediction'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2490029815605856821</id><published>2011-10-23T19:39:00.000-07:00</published><updated>2011-10-23T20:08:20.210-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><category scheme='http://www.blogger.com/atom/ns#' term='powerpc'/><title type='text'>Apple keyboard on FreeBSD</title><content type='html'>Recently I bought an iBook G4 just for fun and of course installed FreeBSD on it. Installation goes pretty smooth starting with 9.0: I've started with 9.0-BETA3 and later updated to 10-CURRENT. I used it as a toy mostly but on Thursday my main laptop (which also runs FreeBSD, but amd64/8-STABLE) died and I had to use iBook as my main system and some problems became noticable.&lt;br /&gt;&lt;br /&gt;There are two annoying problems with Apple keyboards:&lt;br /&gt;&lt;br /&gt;1. Function keys (F1, F2, ...) work as they supposed to work only when pressing them with FN key. I rely on virtual desktops a lot and I use Ctrl-Fx to switch between them, so you imagine how annoying is that to use Ctrl-Fn-Fx to switch a desktop.&lt;br /&gt;&lt;br /&gt;2. Apple keyboard misses 'Insert' key completely, so you cannot use Ctrl-Insert for pasting, so it's extremely annoying also.&lt;br /&gt;&lt;br /&gt;Fortunately, both problems could be easily solved.&lt;br /&gt;&lt;br /&gt;Several days ago Nathan Whitehorn ⟨&lt;i&gt;nwhitehorn@&lt;/i&gt;) committed a support for &lt;u&gt;dev.akbd.%d.fn_keys_function_as_primary&lt;/u&gt; which allows you to configure F-keys behavior. In order to make the keys look as F1,F2,... without pressing FN, execute:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;sysctl dev.akbd.0.fn_keys_function_as_primary=1&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The Insert key problem could be solved on X level: I've used &lt;b&gt;xmodmap&lt;/b&gt; (&lt;i&gt;x11/xmodmap&lt;/i&gt;) to remap F11 to Insert, which is a good solution for me because I don't use F11 key and it's located quite close to a place where you'd expect to have 'Insert' key on a typical keyboard.&lt;br /&gt;&lt;br /&gt;So I've created ~/.Xmodmap file:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;keycode 95 = Insert&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And added execution of "&lt;i&gt;xmodmap ~/.Xmodmap&lt;/i&gt;" on X session start.&lt;br /&gt;&lt;br /&gt;I'm not sure if F11 has keycode 95 on every Apple keyboard, it's easy to figure out keycode using &lt;b&gt;xev&lt;/b&gt; (&lt;i&gt;x11/xev&lt;/i&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2490029815605856821?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2490029815605856821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/10/apple-keyboard-on-freebsd.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2490029815605856821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2490029815605856821'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/10/apple-keyboard-on-freebsd.html' title='Apple keyboard on FreeBSD'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7481111830461271452</id><published>2011-07-28T11:11:00.000-07:00</published><updated>2011-07-28T11:25:58.297-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='bike'/><title type='text'>the bike</title><content type='html'>&lt;img src="http://novel.evilcoder.org/photo/357_2.jpg"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://novel.evilcoder.org/photo/357_1.jpg"&gt;&lt;br /&gt;&lt;br /&gt;frame: blkmrkt three57&lt;br /&gt;fork: marzocchi dj2 '09 100mm&lt;br /&gt;handlebar: blkmrkt badaboom&lt;br /&gt;stem: ns quark pro '11&lt;br /&gt;seat: blkMrkt brass knuckles (--&gt; leaf cycles symboll pivotal soon-ish)&lt;br /&gt;seat post: blkmrkt riot stick (--&gt; code pivotal 135mm)&lt;br /&gt;sprocket: federal street 25t&lt;br /&gt;pedals: ns aerial '11&lt;br /&gt;cranks: crmo 3pc, 48 splined&lt;br /&gt;chain: kmc&lt;br /&gt;front hub: ns rotary 20 '11&lt;br /&gt;rear hub: ns rotary single '11 10t&lt;br /&gt;tires: kenda 26x2.10"&lt;br /&gt;spokes: mach&lt;br /&gt;&lt;br /&gt;photos are so-so and bike config is not perfect I guess, but it's good starting point.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7481111830461271452?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7481111830461271452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/07/bike.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7481111830461271452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7481111830461271452'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/07/bike.html' title='the bike'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2447908231591505733</id><published>2011-07-12T06:53:00.000-07:00</published><updated>2012-01-26T04:32:49.415-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>fusefs-cloudstorage: accessing cloud storage using libcloud and fusefs</title><content type='html'>Few weeks after cloud storage support appeared in &lt;a href="http://libcloud.apache.org"&gt;libcloud&lt;/a&gt; I started playing with it by creating a fusefs filesystem based on it. Finally the first version is almost ready, so it's time to write a few words about it.&lt;br /&gt;&lt;br /&gt;So, for example, you have a cloud files account and want to mount it as it were a local filesystem. You do it this way:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;novel@ritual:~/code/fusefs-cloudstorage/test %&gt; cloudstorage.py -o driver=CLOUDFILES_US -o access_id=foo -o secret=acbd18db4cc2f85cedef654fccc4a4d8 ./test&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;where &lt;b&gt;foo&lt;/b&gt; is your &lt;i&gt;access id&lt;/i&gt; and this hash is the secret key. Filesystem will be mounted to &lt;b&gt;test&lt;/b&gt; sub-directory of the current directory.&lt;br /&gt;&lt;br /&gt;A list of directories at top level of this filesystem represents a list of containers on your account and looks like this:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;novel@ritual:~/code/fusefs-cloudstorage/test %&gt; ls -1&lt;br /&gt;backups&lt;br /&gt;cloudservers&lt;br /&gt;event_logs&lt;br /&gt;mir_package&lt;br /&gt;novel@ritual:~/code/fusefs-cloudstorage/test %&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Listing each of these directories will (as you might have guessed already) show a list of objects that belong to a corresponding container. For example:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;novel@ritual:~/code/fusefs-cloudstorage/test %&gt; ls -1 backups&lt;br /&gt;1345b96a-ae25-11e0-94a9-40401629a6e1.sql.gz&lt;br /&gt;135dbf74-ae25-11e0-94a9-40401629a6e1.sql.gz&lt;br /&gt;27ed5e4e-7faf-11e0-bbcc-40401629a6e1.sql.gz&lt;br /&gt;4fbb5e06-ae14-11e0-aace-40401629a6e1.sql.gz&lt;br /&gt;4fd6274a-ae14-11e0-aace-40401629a6e1.sql.gz&lt;br /&gt;645e7cde-7f9e-11e0-8a43-40401629a6e1.sql.gz&lt;br /&gt;b181ef6c-ae1c-11e0-a6b9-40401629a6e1.sql.gz&lt;br /&gt;b19dcbba-ae1c-11e0-a6b9-40401629a6e1.sql.gz&lt;br /&gt;c626402a-7fa6-11e0-bb13-40401629a6e1.sql.gz&lt;br /&gt;f460c934-9b2f-11e0-89ce-40401629a6e1.sql.gz&lt;br /&gt;novel@ritual:~/code/fusefs-cloudstorage/test %&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;You can create containers using &lt;tt&gt;mkdir&lt;tt&gt; command, copy files in using &lt;tt&gt;cp&lt;/tt&gt;, remove them with &lt;tt&gt;rm&lt;/tt&gt; and so on. You might want to check a shell script test that tests basic features for more examples: &lt;a href="https://github.com/novel/fusefs-cloudstorage/blob/master/test.sh"&gt;https://github.com/novel/fusefs-cloudstorage/blob/master/test.sh&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;However, it seems that it's not that easy and quick tasks to implement such a filesystem.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Why is it hard to make such kind of filesystem fast?&lt;/h3&gt;&lt;br /&gt;My implementation is pretty dumb -- it just does things in a straight-forward way that doesn't work well in this case because filesystem usage patters doesn't match cloud storage usage patterns well.&lt;br /&gt;&lt;br /&gt;A couple of examples: cloud storage doesn't support doing writes or reads with offset, so if you want to append a line to a text file, you have to remove the old one and create a new one with the new content. This gets especially slow when we're modifying large files.&lt;br /&gt;&lt;br /&gt;Other thing that it looks like vfs design generally assumes it's easy to obtain meta-information about the files, but with cloud storage every single simple operation like checking if file exists, involves issuing an API call, which is slow.&lt;br /&gt;&lt;br /&gt;It looks like we can speedup things dramatically if we introduce caching for both meta-data and file contents. But the hard thing with cache is that we don't have an exclusive access to the API. I.e. we can cache things in our filesystem driver and some user at the same time might open up Web Dashboard and remove or upload new files and we will never know about it unless re-request all the data.&lt;br /&gt;&lt;br /&gt;At this point I consider this project more like "just for fun" type of thing than something really useful, but probably I will implement caching to make it more or less fast if I decide it will be useful.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Links&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/novel/fusefs-cloudstorage"&gt;fusefs-cloudstorage on github&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.rackspace.com/cloud/cloud_hosting_products/files/"&gt;Rackspace Cloud Files&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://aws.amazon.com/s3/"&gt;Amazon S3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://libcloud.apache.org"&gt;Libcloud&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2447908231591505733?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2447908231591505733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/07/fusefs-cloudstorage-accessing-cloud.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2447908231591505733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2447908231591505733'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/07/fusefs-cloudstorage-accessing-cloud.html' title='fusefs-cloudstorage: accessing cloud storage using libcloud and fusefs'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6909147429382068534</id><published>2011-05-30T05:01:00.000-07:00</published><updated>2011-06-02T01:53:19.357-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><title type='text'>lc-tools 0.5.0.0 released!</title><content type='html'>A lot of time passed since the latest lc-tools release, and now it's almost summer, so it's time for updates!&lt;br /&gt;&lt;br /&gt;The first news is that &lt;a href="http://libcloud.apache.org"&gt;libcloud&lt;/a&gt; is now an &lt;a href="https://blogs.apache.org/foundation/entry/the_apache_software_foundation_announces12"&gt;Apache Top Level Project (TLP)&lt;/a&gt; and new version 0.5.0 has been released with some new features, bug fixes and new support for working with storage and load balancers. And it's a perfect time for new lc-tools release!&lt;br /&gt;&lt;br /&gt;There are not so many new features in this &lt;tt&gt;lc-tools&lt;/tt&gt; release, most of the changes were to chase internal libcloud changes. Additionally, I've changed versioning scheme a little and now it looks like &lt;tt&gt;$libcloud_version$lctools_version&lt;/tt&gt;, where &lt;tt&gt;$libcloud_version&lt;/tt&gt; is the version of &lt;tt&gt;libcloud&lt;/tt&gt; current release was targeted and tested with.&lt;br /&gt;&lt;br /&gt;The only new major change is the addition of &lt;tt&gt;lb-*&lt;/tt&gt; scripts to manage load balancers. You can get more information on them from &lt;a href="http://novel.github.com/lc-tools/doc/0.5.0.0/tutorial/node18.html"&gt;Documnetation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can install the new version using either &lt;tt&gt;easy_install&lt;/tt&gt;:&lt;br /&gt;&lt;br /&gt;easy_install lctools&lt;br /&gt;&lt;br /&gt;or by downloading and installing it by hands:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/novel/lc-tools/lctools-0.5.0.0.tar.gz"&gt;lctools-0.5.0.0.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SHA256 (lctools-0.5.0.0.tar.gz) = f09629664a5209be687c56cfe07e123939e28b18070b719436307a74b823f10b&lt;br /&gt;&lt;br /&gt;Happy hacking on the cloud stuff!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6909147429382068534?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6909147429382068534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/05/lc-tools-0500-released.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6909147429382068534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6909147429382068534'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/05/lc-tools-0500-released.html' title='lc-tools 0.5.0.0 released!'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6886750024816590441</id><published>2011-05-18T03:39:00.000-07:00</published><updated>2011-05-18T04:29:54.355-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ports'/><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><title type='text'>Dealing with pkg-config detection of FreeBSD's base OpenSSL</title><content type='html'>Recently I spotted a software that uses &lt;tt&gt;pkg-config&lt;/tt&gt; to find OpenSSL on the system. This way doesn't work on FreeBSD: it does have OpenSSL in base system, but it doesn't supply '*.pc' file, unfortunately. So, when &lt;tt&gt;configure&lt;/tt&gt; script tries to execute &lt;tt&gt;pkg-config openssl&lt;/tt&gt; it fails, obviously.&lt;br /&gt;&lt;br /&gt;There were a number of solutions suggested for this problem on &lt;tt&gt;#bsdports&lt;/tt&gt; like replacing 'pkg-config openssl' with 'pkg-config pkg-config', depending on openssl from ports etc, but the cleanest solution is to define &lt;tt&gt;libssl_LIBS&lt;/tt&gt; and &lt;tt&gt;libssl_CFLAGS&lt;/tt&gt; environment variables, as was suggested by bapt@. In port's Makefile it would look something like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;USE_OPENSSL=yes&lt;br /&gt;CONFIGURE_ENV+=libssl_CFLAGS="-I${OPENSSLINC}" libssl_LIBS="-L${OPENSSLLIB} -lssl"&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Yes, &lt;tt&gt;configure&lt;/tt&gt; will not call pkg-config if we define these 'libssl_*' variables. While it looks quite simple, this issue took surprisingly a lot time to figure everything out. :(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6886750024816590441?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6886750024816590441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/05/dealing-with-pkg-config-detection-of.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6886750024816590441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6886750024816590441'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/05/dealing-with-pkg-config-detection-of.html' title='Dealing with pkg-config detection of FreeBSD&apos;s base OpenSSL'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-243818856636135669</id><published>2011-05-06T02:32:00.000-07:00</published><updated>2011-05-06T03:09:04.141-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstack'/><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Managing OpenStack using libcloud and lc-tools</title><content type='html'>OpenStack is getting more and more popular and number of its installation increases day by day. We've got one as well. :-) While there are quite a number of bindings and tools to connecting to its API I prefer use familiar proven tools like &lt;a href="http://libcloud.org"&gt;libcloud&lt;/a&gt; and &lt;a href="http://github.com/novel/lc-tools"&gt;lc-tools&lt;/a&gt;. And since OpenStack supports both EC2-compatible and Rackspace-compatible APIs, there are two ways connecting to it.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;EC2 API&lt;/h4&gt;&lt;br /&gt;To use EC2-compatible API, pick &lt;tt&gt;EUCALYPTUS&lt;/tt&gt; driver like that:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/958696.js?file=libcloud_openstack_ec2.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;You need to define &lt;tt&gt;EC2_ACCESS_KEY&lt;/tt&gt; and &lt;tt&gt;EC2_SECRET_KEY&lt;/tt&gt; variables to match your setup. Hostname, port and path arguments which are passed to constructor could be extracted from your &lt;tt&gt;EC2_URL&lt;/tt&gt; environment variable.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; if you're not using &lt;u&gt;trunk&lt;/u&gt; version of libcloud, you will need to adjust imports a little, i.e. strip &lt;i&gt;compute.&lt;/i&gt; part from them.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Rackspace API&lt;/h4&gt;&lt;br /&gt;To use Rackspace-compatible API you will to check out &lt;u&gt;trunk&lt;/u&gt; version of libcloud (please refer &lt;a href="http://incubator.apache.org/libcloud/devinfo.html"&gt;here&lt;/a&gt; to obtain it) which provides &lt;tt&gt;OPENSTACK&lt;/tt&gt; driver, which could be used in a similar fashion:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/958704.js?file=llbcloud_openstack_rs.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Again, here you will need to redefine &lt;tt&gt;NOVA_API_KEY&lt;/tt&gt; and &lt;tt&gt;NOVA_USERNAME&lt;/tt&gt; for your setup and grab host and port from &lt;tt&gt;NOVA_URL&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;Let me remind you once again that you need &lt;u&gt;trunk&lt;/u&gt; version of libcloud to make it working. One more thing: OpenStack is not fully compatible with Rackspace API, so not everything will work smooth.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;lc-tools&lt;/h4&gt;&lt;br /&gt;lc-tools is a set of command line tools on top of libcloud to manage your cloud servers. Git version of lc-tools supports working with OpenStack both through EC2 and Rackspace compatible APIs. Here's config samples for both:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[ec2compat]&lt;br /&gt;driver = eucalyptus&lt;br /&gt;access_id = CHANGE_ME&lt;br /&gt;secret_key = CHANGE_ME&lt;br /&gt;extra = { "host": "127.0.0.1", "secure": False, "port": 8773, "path": "/services/Cloud" }&lt;br /&gt;&lt;br /&gt;[rscompat]&lt;br /&gt;driver = openstack&lt;br /&gt;access_id = nova_admin&lt;br /&gt;secret_key = CHANGE_ME&lt;br /&gt;extra = {"host": "127.0.0.1", "port": 8774}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And just check if it works by executing &lt;tt&gt;lc-node-list -p ec2compat&lt;/tt&gt; and &lt;tt&gt;lc-node-list -p rscompat&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;References&lt;/h4&gt; * &lt;a href="http://libcloud.org"&gt;libcloud&lt;/a&gt;&lt;br /&gt; * &lt;a href="http://github.com/novel/lc-tools"&gt;lc-tools&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-243818856636135669?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/243818856636135669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/05/managing-openstack-using-libcloud-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/243818856636135669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/243818856636135669'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/05/managing-openstack-using-libcloud-and.html' title='Managing OpenStack using libcloud and lc-tools'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-790949904080958345</id><published>2011-04-28T15:12:00.000-07:00</published><updated>2011-04-29T17:44:09.888-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='dotcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='celery'/><title type='text'>Trying DotCloud for Django/Python deployment</title><content type='html'>&lt;h3&gt;About dotcloud&lt;/h3&gt;&lt;br /&gt;The first time I heard about &lt;a href="http://dotcloud.com"&gt;DotCloud&lt;/a&gt; was about two months ago, in the beginning of 2011. I was very tempted to try it as soon as possible but it seems there were a very lengthy queue of people like me so I had to wait for quite some time. But finally I've got my account activated few days ago.&lt;br /&gt;&lt;br /&gt;I was so happy about that so initially I didn't even know what application to try to develop on it, as I wanted to cover as much services as possible that DotCloud offers. After all, I decided to go with a frontend Django application and several workers communicating with each other using messaging as it seems to be a good basis for a lot of things I have to do these days.&lt;br /&gt;&lt;br /&gt;Originally I wanted to use RabbitMQ server, but unfortunately it's not working for some reason, which made me take a look at celery with redis backend. I have never used neither celery nor redis so it was even more interesting to learn these things as well.&lt;br /&gt;&lt;br /&gt;So I came up to a scheme like these.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Sample Application&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://people.freebsd.org/~novel/misc/dotping.png"&gt;&lt;br /&gt;&lt;br /&gt;* &lt;i&gt;Django Web Application&lt;/i&gt; provides a user interface for issuing tasks and obtaining their results&lt;br /&gt;* &lt;i&gt;MySQL&lt;/i&gt; is used to keep history of issued tasks&lt;br /&gt;* &lt;i&gt;Celery&lt;/i&gt; handles all task-related operations. It passes tasks to &lt;i&gt;Workers&lt;/i&gt; for execution using &lt;i&gt;Redis&lt;/i&gt; as transport layer and results are stored also in &lt;i&gt;Redis&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;As for the task, I choose a really simple one: just sending 60 ICMP ECHO_REQUEST packets to determine if a host specified by user up or down. Use case is simple: user opens up a page, specifies a host to ping and then waits for result and it appears to him after some time.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Workers Implementation&lt;/h4&gt;&lt;br /&gt;I have started with workers implementation. I followed &lt;a href="http://docs.dotcloud.com/tutorials/celery/"&gt;Tutorial&lt;/a&gt; on DotCloud web site to create my first Celery worker and it worked alright, but I had step from it several times for the following reasons:&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;RabbitMQ service problems&lt;/h5&gt;&lt;br /&gt;When I created a rabbitmq service it for some reason had empty ports list, like that:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ dotcloud info bublick.rabbitmq&lt;br /&gt;cluster: wolverine&lt;br /&gt;config:&lt;br /&gt;    password: password&lt;br /&gt;    rabbitmq_management: true&lt;br /&gt;    user: root&lt;br /&gt;created_at: 1303573502.963711&lt;br /&gt;name: foo.rabbitmq&lt;br /&gt;namespace: foo&lt;br /&gt;ports: []&lt;br /&gt;state: running&lt;br /&gt;type: rabbitmq&lt;br /&gt;$&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;I thought it was some glitch, especially considering that this happened not long ago after EC2 outage (and DotCloud runs on top of EC2). So I tried to drop this service and deploy a new one. Alas, everything was same. I joined an IRC channel -- &lt;tt&gt;#dotcloud&lt;/tt&gt; on freenode -- to ask what's wrong with that and it appeared that it's a known problem and is going to be fixed soon.&lt;br /&gt;&lt;br /&gt;It's not a big deal though, because Celery supports a lot of brokers in addition to RabbitMQ, so I decided to go with &lt;tt&gt;Redis&lt;/tt&gt; and use it to store results as well. So I just changed &lt;tt&gt;celeryconfig.py&lt;/tt&gt; to point to Redis instead of RabbmitMQ:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist-it.appspot.com/github/novel/dotcloud-sample-app/raw/master/worker/celeryconfig.py"&gt;&lt;/script&gt;&lt;br /&gt;Then I implemented actual task which pings a given host:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist-it.appspot.com/github/novel/dotcloud-sample-app/raw/master/worker/ping.py"&gt;&lt;/script&gt;&lt;br /&gt;As you see, it's pretty trivial.&lt;br /&gt;&lt;br /&gt;However, I've spotted a problem when I tried to push the code, basically it said that 'celeryd' could not be started.&lt;br /&gt;&lt;br /&gt;So I've logged in to VM running celery using the command 'dotcloud ssh foo.celery' (where &lt;tt&gt;foo.celery&lt;/tt&gt; is a name of deployment) and tried executing 'celeryd' by hand, and it failed with 'Permission denied' error. I asked on IRC channel again and it was a known problem also, and it was quickly fixed for my deployment.&lt;br /&gt;&lt;br /&gt;After that my worker was fully functional, you can check sources and its celery configuration here: https://github.com/novel/dotcloud-sample-app/tree/master/worker.&lt;br /&gt;&lt;br /&gt;Then I moved to web application.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Web Application&lt;/h4&gt;&lt;br /&gt;As it was mentioned, I wanted to use Django framework for web application. Luckily, there's a &lt;a href="http://docs.dotcloud.com/tutorials/django/"&gt;tutorial&lt;/a&gt; on django deployment on dotcloud as well. I followed this tutorial step by step and sample django application deployed smoothly.&lt;br /&gt;&lt;br /&gt;Then I needed to add celery integration. As I deployed code separately I didn't want to import actual task code but call by name. Also, I wanted task status to be fetched only when user actually requests it, so I had to find tasks by id.&lt;br /&gt;&lt;br /&gt;The first steps is to configure django application to use celery. It's done by adding &lt;tt&gt;django-celery&lt;/tt&gt; and &lt;tt&gt;redis&lt;/tt&gt; dependencies to &lt;tt&gt;requirements.txt&lt;/tt&gt; and defining celery stuff in &lt;tt&gt;settings.py&lt;/tt&gt;:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist-it.appspot.com/github/novel/dotcloud-sample-app/raw/master/www/frontend/settings.py"&gt;&lt;/script&gt;.&lt;br /&gt;&lt;br /&gt;And finally set of simple views to schedule tasks and report their status:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist-it.appspot.com/github/novel/dotcloud-sample-app/raw/master/www/frontend/ping/views.py"&gt;&lt;/script&gt;&lt;br /&gt;You can also see a view which provides a list of active workers. Now, if you deploy your web application and the worker thing should work fine. Additionally, you can add extra workers seamlessly. For example, if you named your worker 'foo.celery', you can add more workers exactly the same way, just use e.g. foo.celery2 etc for &lt;tt&gt;dotcloud deploy&lt;/tt&gt; and &lt;tt&gt;dotcloud push&lt;/tt&gt; commands.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Things to keep in mind&lt;/h3&gt;&lt;br /&gt;* PYTHONPATH contains only top level project directory by default, so one either should add django application to PYTHONPATH or use full path for modules, e.g. pay attention I have my 'ping' application listed in &lt;tt&gt;settings.py&lt;/tt&gt; as 'frontend.ping' for example, otherwise it won't work&lt;br /&gt;* You don't have to add database drivers like &lt;tt&gt;mysqldb-python&lt;/tt&gt; to &lt;tt&gt;requirements.txt&lt;/tt&gt; since they're available by default&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;DotCloud first impressions&lt;/h3&gt;&lt;br /&gt;* Documentation is good, fairly complete, I haven't seen an outdated or misleading information&lt;br /&gt;* DotCloud guys are very helpful, all the questions get addressed very quickly on the IRC channel&lt;br /&gt;* Great jobs done with the services. For example, I have never ever used &lt;tt&gt;redis&lt;/tt&gt; and I have no idea how to set it up and configure. All I had to do is to run &lt;tt&gt;dotcloud deploy -t redis foo.redis&lt;/tt&gt; and it's there, very good. The same goes for wsgi deployment -- it's a shame, but I've never did such type of deployment myself, I just use 'manage.py runserver' for local testing... it's good to have a deployment engineer on the team! :) So, it also went seamlessly, I don't even have to know where logs are located, I just do 'dotcloud logs foo.www'.&lt;br /&gt;* Some services are unstable or not working, like RabbitMQ (which is unusable) and Celery (which needs some manual actions from support team to work fine). That doesn't seem to be a serious problem to me though, considering that DotCloud is at beta stage currently, and more over they must have been very busy last few days recovering from EC2 outage.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Things I'm curious about&lt;/h3&gt;&lt;br /&gt;* Currently, there's no way to install system-level package (like, say, &lt;a href="http://www.imagemagick.org/script/index.php"&gt;ImageMagick&lt;/a&gt;. It way mentioned on IRC that popular packages like that will be eventually included into base images based on users requests. I'm curious how it will be done without letting images spreading out.&lt;br /&gt;* I need to research how scaling is implemented and choosing scaling strategy looks like&lt;br /&gt;* I wonder how upgrade strategy looks like. FAQ says that upgrades are "prudent and thoroughly tested" (c) but everyone knows that things can always break in some totally unexpected ways and what are the procedures for rolling back, sticking to specific version of the components and so on. &lt;br /&gt;* I wasn't able to find if there are any monitoring facilities provided. Also it's not clear what's going to happen if some critical component or VM goes down.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;It was fun to experiment with DotCloud and I'm going to spend some more time on it. It differs from services that I worked with before. I've got an impression that its abstraction level is somewhere higher that IaaS but lower that a typical PaaS. On the one hand, you don't have to worry about things you usually have to worry on IaaS, like installation and configuration of services like MySQL and so on. On the other hand, you still have to do a fair amount of deployment-related things, like creating databases, configuring users, manually running &lt;tt&gt;syncdb&lt;/tt&gt; commands and other things you typically don't do on PaaS. Also, you can view almost everything you might need as you have ssh access to every VM, but you cannot change almost anything since it's not root access.&lt;br /&gt;&lt;br /&gt;So I'm definitely interested to see how DotCloud evolves and hope to spend some more time using and learning it.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;References&lt;/h3&gt;&lt;br /&gt;&lt;h4&gt;Sample Application&lt;/h4&gt;Sample application I've used as a sample could be found on github: &lt;a href="https://github.com/novel/dotcloud-sample-app"&gt;https://github.com/novel/dotcloud-sample-app&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clone it:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;git clone git://github.com/novel/dotcloud-sample-app.git&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;All you need to run it now is to put credentials for you mysql and celery services and deploy it on DotCloud. Have fun!&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Further Reading&lt;/h4&gt;* &lt;a href="http://docs.dotcloud.com/faq/"&gt;DotCloud FAQ&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://docs.dotcloud.com/tutorials/django/"&gt;DotCloud Django Tutorial&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://docs.dotcloud.com/tutorials/celery/"&gt;DotCloud Celery Tutorial&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://ask.github.com/celery/index.html"&gt;Celery Documentation&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://ask.github.com/django-celery/"&gt;Django-celery Documentation&lt;/a&gt;&lt;br /&gt;* &lt;a href="https://github.com/novel/dotcloud-sample-app"&gt;Sample App&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-790949904080958345?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/790949904080958345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/04/trying-dotcloud-for-djangopython.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/790949904080958345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/790949904080958345'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/04/trying-dotcloud-for-djangopython.html' title='Trying DotCloud for Django/Python deployment'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6616258733136885038</id><published>2011-04-25T15:14:00.000-07:00</published><updated>2011-04-25T15:42:54.299-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>A tiny client for lingvo.yandex.ru</title><content type='html'>I've been using &lt;a href="http://lingvo.yandex.ru"&gt;lingvo.yandex.ru&lt;/a&gt; translation service for several years now for Russian&lt;-&gt;English translation, and was quite happy about it. In my opinion, it's one of the best online translation services and provides better quality translations (esp. for phrases) than e.g. Google Translate. The only thing I've been missing is an API so I, as a console geek, could have a cli tool to craft translations. Not so long they've added complete-as-you-type feature. So... firebug, 10 minutes and script is ready:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://people.freebsd.org/~novel/misc/yaslov.png"&gt;&lt;br /&gt;&lt;br /&gt;I wouldn't typically post a blog entry about 50-lines Python script, but I've figured out that it became my one of most used CLI tool (not counting basic ones, obviously, like &lt;tt&gt;cd&lt;/tt&gt; or &lt;tt&gt;ls&lt;/tt&gt;).&lt;br /&gt;&lt;br /&gt;To try it just do:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;# easy_install yaslov&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;and start using it! Like:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;$ yaslov gnome&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;Thanks to Yandex for a wonderful services and especially for the exposed suggestion script.&lt;br /&gt;&lt;br /&gt;PS If you liked that, you might also want to check my similar script for &lt;a href="http://urbandictionary.com"&gt;urbandictionary&lt;/a&gt;: &lt;a href="http://pypi.python.org/pypi/py-urbandict/0.1"&gt;py-urbandict&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6616258733136885038?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6616258733136885038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/04/tiny-client-for-lingvoyandexru.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6616258733136885038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6616258733136885038'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/04/tiny-client-for-lingvoyandexru.html' title='A tiny client for lingvo.yandex.ru'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-1666157019658380873</id><published>2011-04-21T10:02:00.000-07:00</published><updated>2011-04-21T11:34:06.763-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='gogrid'/><category scheme='http://www.blogger.com/atom/ns#' term='rackspace'/><title type='text'>Overview of GoGrid and Rackspace Load Balancing Services</title><content type='html'>&lt;h3&gt;Overview&lt;/h3&gt;Load Balancing is a technology to spread workload between several computers. These days one of the most popular application of this technology is load balancing for Web sites, such as balancing HTTP/HTTPS traffic across several Web servers (such as Apache httpd).&lt;br /&gt;&lt;br /&gt;A lot of web deployments are moving to the cloud, so load balancers do. I'll give an overview of Load Balancing services provided by Rackspace and GoGrid.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;GoGrid&lt;/h4&gt;Load Balancer service is a part of GoGrid's Cloud offering and was there from the version 1.0 of the API, so it's about 2008.&lt;br /&gt;&lt;br /&gt;GoGrid uses &lt;tt&gt;F5&lt;/tt&gt; hardware Load Balancers, as stated in the &lt;a href="https://wiki.gogrid.com/wiki/index.php/(F5)_Load_Balancer"&gt;documentation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Rackspace&lt;/h4&gt;Rackspace's Load Balancer service is a separate stand alone service as opposite to GoGrid's one.&lt;br /&gt;&lt;br /&gt;The service is relatively young: private beta was &lt;a href="http://www.rackspace.com/cloud/blog/2010/11/09/announcing-cloud-load-balancing-private-beta/"&gt;announced&lt;/a&gt; in November, 2010 and the final release happened in April, 2011, just few days ago at time of writing. Generally, I have started using it from the first private beta and it became quite stable already in the beginning of 2011.&lt;br /&gt;&lt;br /&gt;Rackspace offering is based on &lt;a href="http://www.zeus.com/"&gt;Zeus&lt;/a&gt; software.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;API&lt;/h3&gt;Like a theatre begins with hanger, services begins with API. Let's overview what API allows us to do with Load Balancers.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;GoGrid&lt;/h4&gt;As it was mentioned above, Load Balancer API is just a subset of GoGrid API with all its pros and cons. It provides CRUD (create, read, update, delete) operations support for load balancers.&lt;br /&gt;&lt;br /&gt;Actually, it's not very close to REST concept as:&lt;br /&gt;&lt;br /&gt; * It doesn't use HTTP any method but &lt;tt&gt;GET&lt;/tt&gt;, so e.g. to add a new balancer you make GET request on URL like 'loadbalancer/add' instead of POST on 'loadbalancer' and to delete it you call GET on 'loadbalancer/delete' instead of DELETE, etc&lt;br /&gt; * It doesn't have a concept of element URIs, only collections. So, to get details on a balancer you request 'loadbalancers/get?id=bal_id' instead of 'loadbalancers/bal_id/'&lt;br /&gt; * It uses GET arguments for passing options instead of serialised object in request body&lt;br /&gt;&lt;br /&gt;It's not good or bad that it doesn't follow REST closely, REST is not a standard after all, and actually the fact that one doesn't need to bother with HTTP methods other than GET and serialisation might be beneficial for somebody. I will provide some analysis as API usability from programmers point of view later in the post.&lt;br /&gt;&lt;br /&gt;So, what is it all about? You create a balancer and you have to specify IPs and ports of nodes to share the load. Important thing to know that you have to use IP addresses assigned to your GoGrid account, otherwise it will fail with not very descriptive internal error.&lt;br /&gt;&lt;br /&gt;Besides specifying IP list, you can tweak some load balancer options, such as &lt;b&gt;type&lt;/b&gt; and &lt;b&gt;persistence&lt;/b&gt;. Currently GoGrid supports two types of load balancing:&lt;br /&gt;&lt;br /&gt; * Round Robin (default)&lt;br /&gt; * Least Connect&lt;br /&gt;&lt;br /&gt;And for persistence, the options are:&lt;br /&gt;&lt;br /&gt; * No persistence (default)&lt;br /&gt; * SSL Sticky&lt;br /&gt; * By source address&lt;br /&gt;&lt;br /&gt;Once a balancer has been created, you can change only list of IPs and ports it balances load for. One caveat is that you have to pass a complete list of IPs, not just incrementally add or remove them one by one, so be careful not to run into race condition.&lt;br /&gt;&lt;br /&gt;With GoGrid you can have up to 6 load balancers per account and up to 3 load balancers for a data center.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Rackspace&lt;/h4&gt;Rackspace Load Balancer API is, obviously, centered around CRUD operations for load balancer objects as well, though it supports far more than that.&lt;br /&gt;&lt;br /&gt;It seems to follow REST quite precisely: uses collection and elements URI, correct HTTP semantics and content types.&lt;br /&gt;&lt;br /&gt;When creating a balancer, you can specify not only IPs that belong to your Rackspace account, but basically any IP you want. Actually, I think it makes a lot of sense to provide such a flexibility if you're running a hybrid setup, and, say, have part of the nodes in your data center and part of them running on the cloud.&lt;br /&gt;&lt;br /&gt;Additionally, you can tweak quite a lot of options. Let's check details for the most important ones, such as balancing type and persistence. As for balancing type, it provides a wide range of options:&lt;br /&gt;&lt;br /&gt; * Round Robin&lt;br /&gt; * Least Connect&lt;br /&gt; * Random&lt;br /&gt; * Weighted Least Connect&lt;br /&gt; * Weighted Round Robin&lt;br /&gt;&lt;br /&gt;For the last two options node weight (which you can assign to node) is taken into account. Type has to be specified at creation time, so no default value marked.&lt;br /&gt;&lt;br /&gt;As for session persistence, only HTTP cookie persistence is supported.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Programming Specifics&lt;/h3&gt;There is a specific thing about building something on top of load balancing API. The thing is that unlike dealing with cloud servers, where you work mostly with atomic objects (like server itself), with load balancers you have a collection of nodes you want to balance between. And here two race conditions possible.&lt;br /&gt;&lt;br /&gt;The first one is caused by the fact that load balancer needs to be reconfigured after you add or remove a node. And when you try to modify nodes list during the process of re-configuration, you'll get an error. Moreover, GoGrid doesn't have a special state which says that balancer is being re-configured at the moment. Rackspace has such a state, but race condition is still possible, image the following scenario:&lt;br /&gt;&lt;br /&gt; * Balancer B is in 're-configuring' state&lt;br /&gt; * Apps A1 and A2 want to add a new node to B&lt;br /&gt; * Apps A1 and A2 see that B is immutable and start polling its status while it's not 'Ready'&lt;br /&gt; * A1 becomes first&lt;br /&gt; * A2 fails&lt;br /&gt;&lt;br /&gt;This is not very serious problem, but it make coding a little more complicated.&lt;br /&gt;&lt;br /&gt;The second possible race condition is GoGrid implementation specific because of its model of keeping IP list as a whole, without support of adding/removing individual IPs. Imagine a slightly modified version of the previous scenario:&lt;br /&gt;&lt;br /&gt; * Balancer B is in 're-configuring' state&lt;br /&gt; * App A1 wants to add IP I1 to B, so the IP list would be [B.ips] + [I1]&lt;br /&gt; * App A2 wants to add IP I2 to B, so the IP list would be [B.ips] + [I2]&lt;br /&gt; * Apps A1 and A2 tries to make a request until it succeeds&lt;br /&gt; * App A1 becomes first, B.ips becomes [B.old_ips] + [I1]&lt;br /&gt; * App A2 still fails because B turns 're-configuring' again&lt;br /&gt; * App A2 finally succeeds with it's request and updates list of Ips to [B.old_ips] + [I2]&lt;br /&gt; * As a result, I1 that should have been added is actually missing&lt;br /&gt;&lt;br /&gt;Again, it's not like this is not solvable problem, but it's quite an effort to solve it.&lt;br /&gt;&lt;br /&gt;And finally some numbers. I took Rackspace and GoGrid Load Balancer drivers from &lt;a href="http://libcloud.org"&gt;libcloud&lt;/a&gt; trunk which implement the same common interface and gathered these metrics:&lt;br /&gt;&lt;br /&gt; * Driver's lines of code (loc)&lt;br /&gt; * Unit-tests' lines of code (test loc)&lt;br /&gt; * Lines of fixtures (i.e. content of responses)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://people.freebsd.org/~novel/misc/libcloud_lb_stats.png"&gt;&lt;br /&gt;&lt;br /&gt;You know that there are lies, damned lies, and statistics, so it's up to you to analyse these numbers. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-1666157019658380873?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/1666157019658380873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/04/comparison-of-gogrid-and-rackspace-load.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1666157019658380873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1666157019658380873'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/04/comparison-of-gogrid-and-rackspace-load.html' title='Overview of GoGrid and Rackspace Load Balancing Services'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7268585395063938523</id><published>2011-04-12T16:43:00.000-07:00</published><updated>2011-04-12T21:20:19.093-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gogrid'/><category scheme='http://www.blogger.com/atom/ns#' term='rackspace'/><title type='text'>libcloud load balancers feature status</title><content type='html'>&lt;h4&gt;Background&lt;/h4&gt;&lt;p&gt;If you follow &lt;a href="http://libcloud.org"&gt;libcloud&lt;/a&gt; maillist, you probably aware that I've started working on adding load balancers support. If not, please give &lt;a href="http://mail-archives.apache.org/mod_mbox/incubator-libcloud/201104.mbox/&lt;20110404221031.GA26577@reemsky&gt;"&gt;it&lt;/a&gt; a quick view.&lt;/p&gt;&lt;h4&gt;Current status&lt;/h4&gt;&lt;p&gt;At this point I have implemented almost all features I've planned, namely:&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Defined a common interface&lt;/li&gt;&lt;li&gt;Implemented drivers for &lt;a href="http://rackspace.com"&gt;Rackspace&lt;/a&gt; and &lt;a href="http://gogrid.com"&gt;GoGrid&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Covered basic functionality with unit tests&lt;/li&gt;&lt;li&gt;Implemented load balancer support in &lt;a href="http://novel.github.com/lc-tools/"&gt;lc-tools&lt;/a&gt; and run-time tested it&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Currently interface is pretty basic and supports only main operations, like: CREATE/READ/DELETE for balancers and ADD/LIST/REMOVE operations for their nodes. Obviously, there are far more operations on load balancers that could be useful such as balancing algorithm and session handing options, but I need some time to play around with these things to understand how to plug it better.&lt;/p&gt;&lt;p&gt;One more thing I'm considering is adding support for blocking operations. It's quite common situation when you find balancer in immutable state: for example, when you add new node to balancer it needs some time to perform initial configuration and during that period you cannot perform operations on it, such as removing or adding more nodes. My current implementation just throws and exception in such case so user can figure out that object is immutable and try after some time.&lt;/p&gt;&lt;p&gt;However, it might be not very convenient for user to wrap any call to catch such situations, so I'm thinking about adding support for blocking mode, where function will block until operation succeeds or timeout reaches; blocking/non-blocking mode could be specified at driver init time.  Most likely it's the way things will be done.&lt;/p&gt;&lt;h4&gt;Examples&lt;/h4&gt;&lt;p&gt;Meanwhile, take a look at this example to understand how things look like at the moment:&lt;/p&gt;&lt;a href="https://github.com/novel/libcloud/blob/balancers/example_lb.py"&gt;example_lb.py&lt;/a&gt;&lt;p&gt;Also, as I've mentioned above, I've added basic support for balancer manipulation to &lt;a href="http://novel.github.com/lc-tools/"&gt;lc-tools&lt;/a&gt;. Will cover this topic a bit later when things settle down a little, but here's a quick overview how it feels like:&lt;/p&gt;&lt;script src="https://gist.github.com/916731.js?file=gistfile1.txt"&gt;&lt;/script&gt;&lt;h4&gt;Giving it a try&lt;/h4&gt;&lt;p&gt;To give it a try checkout &lt;tt&gt;balancers&lt;/tt&gt; branch of my &lt;a href="https://github.com/novel/libcloud/tree/balancers"&gt;libcloud fork on github&lt;/a&gt;:&lt;/p&gt;&lt;code&gt;&lt;br /&gt;git clone git://github.com/novel/libcloud.git --branch balancers&lt;br /&gt;&lt;/code&gt;&lt;p&gt;and then install it like you usually do. The example file mentioned above would be useful to get started. Additionally, it might be useful to look at &lt;tt&gt;lb-*&lt;/tt&gt; scripts in lc-tools &lt;a href="https://github.com/novel/lc-tools/tree/lb"&gt;lb branch&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Further reading&lt;/h4&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;a href="http://mail-archives.apache.org/mod_mbox/incubator-libcloud/201104.mbox/&lt;20110404221031.GA26577@reemsky&gt;"&gt;Original announce on the maillist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://wiki.gogrid.com/wiki/index.php/API"&gt;GoGrid Balancers API (part of their main API) reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://broadcast.rackspace.com/downloads/pdfs/Rackspace_Cloud_Load_Balancers.pdf"&gt;Rackspace Balancers API reference (PDF)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7268585395063938523?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7268585395063938523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/04/libcloud-load-balancers-feature-status.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7268585395063938523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7268585395063938523'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/04/libcloud-load-balancers-feature-status.html' title='libcloud load balancers feature status'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7065708917791319065</id><published>2011-03-24T12:41:00.000-07:00</published><updated>2011-03-24T14:43:02.008-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='hr'/><title type='text'>Poor recruiting</title><content type='html'>I receive invitations for job interviews for various positions time to time, as probably a lot of software engineers who have public profiles on linkedin (and similar) do, usually it's nothing interesting, but this time it was a new experience for me.&lt;br /&gt;&lt;br /&gt;This time it was &lt;a href="http://en.wikipedia.org/wiki/Epam"&gt;Epam&lt;/a&gt; &amp;ndash; an outsourcing company, almost nothing special. So they had some Python position at New-York with H1B visa. As you probably know from reading my blog that I do some Python programming and feel quite good about it and I'm quite interested in migration also, that's why I said I was generally interested.&lt;br /&gt;&lt;br /&gt;The first (and the most) surprising thing is that they didn't provide much info on the technical side of the vacancy. Yes, Python, yes, some company that does advertising on the internet, that's all. I thought, ok, I'll probably figure out more details during an interview. I had an non-tech interview with their HR and I wasn't able to find out anything new.&lt;br /&gt;&lt;br /&gt;On the next day after an interview he goes like 'hey, please skype to "some_skype_id" here, he'll provide more info, I made him aware that you'll contact him." I wondered why I should bother contacting anybody as I basically don't know anything about the vacancy and therefore not interested &lt;b&gt;that much&lt;/b&gt;. So I asked if that guy could contact me himself on what HR replied something like "no, please contact him yourself" and was like "I've arranged this possibility so you could get more technical details." and it sounded like he made a huge favor for me already so I could talk to this person. At this point I decided I don't want to work at this company already.&lt;br /&gt;&lt;br /&gt;So I'm trying to understand point of view of such recruiting managers. They work in a company that doesn't have a reputation as a good place for engineers (unlike Google and similar). Moreover, they have an office in my hometown and even there it's not the best place to work at. Then, they try to recruit a person who has a job already and doesn't state anywhere that he's looking for job. And finally they offer a candidate (which is not really a candidate strictly speaking because at that point it's not clear if the job worth it or not) to drive himself through information gathering for the vacancy on his own.&lt;br /&gt;&lt;br /&gt;So I'm wondering who are they expect to find. A programmer who's only interested in obtaining H1B? A programmer who's not very interested what he's going to do (even if it is legacy Python 2.2 code support or maybe shell-like scripting in Python)? I don't get it.&lt;br /&gt;&lt;br /&gt;PS Don't think I'm such an asshole. Once I traveled to a different city on my own expense for an interview because I saw a potential in the job, more on that later I think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7065708917791319065?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7065708917791319065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/03/poor-recruiting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7065708917791319065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7065708917791319065'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/03/poor-recruiting.html' title='Poor recruiting'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7856229101415479308</id><published>2011-03-11T10:11:00.000-08:00</published><updated>2011-03-11T10:39:00.010-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Treating security loosely</title><content type='html'>I don't want to sound like a grumpy old man, but anyway sometimes I get really surprised how people treat security these days.&lt;br /&gt;&lt;br /&gt;I was going to try &lt;a href="https://github.com/nvie/gitflow"&gt;gitflow&lt;/a&gt; (which seems to be quite interesting thing to adopt by the way) today and was reading &lt;a href=https://github.com/nvie/gitflow/blob/develop/README.mdown"&gt;documentation&lt;/a&gt; on the installation process. Believe it or not, the suggested installation way on linux system is:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ wget --no-check-certificate -q -O - https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | sudo sh&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Yes, you're right, it's like that: downloading a random script from the internet and executing it from 'root' without extra checks. Certainly, it's up to you if you trust the source and sure that it doesn't have any malicios code (generally, it's better not to trust). But anyway, such installation schema should be improved:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;SSL verification shouldn't be disabled, so you're sure that you're actually downloading your file from github, not from some source &lt;i&gt;identifying itself as github&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Control checksums should be provided or the file should be signed with gpg to make sure you're downloading exactly the same thing as author uploaded&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Without it executing such a command seems to be plain dangerous.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7856229101415479308?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7856229101415479308/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/03/treating-security-loosely.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7856229101415479308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7856229101415479308'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/03/treating-security-loosely.html' title='Treating security loosely'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6173538454878847560</id><published>2011-02-27T03:08:00.000-08:00</published><updated>2011-02-27T08:09:48.680-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Some Python3 fun</title><content type='html'>I wasn't feeling very productive today so decided to take a look at Python 3.2 and specifically understand how hard would it be to create a development environment not affecting Python 2.6 related stuff and also how much time would it take to port a simple 2.x script to 3.x.&lt;br /&gt;&lt;br /&gt;Luckily, Python 3.x is available in FreeBSD ports tree and, moreover, it doesn't conflict with python2.x stuff, so all I had to do is to &lt;tt&gt;cd /usr/ports/lang/python32 &amp;&amp; sudo make install clean&lt;/tt&gt; (actually I've spotted a &lt;a href="http://docs.freebsd.org/cgi/getmsg.cgi?fetch=208058+0+current/freebsd-python"&gt;minor problem&lt;/a&gt; with the port, but it doesn't affect anything, for me at least). Viola, it's already there.&lt;br /&gt;&lt;br /&gt;Then I decided to pick some simple script and see how much effort it will take to make it run with 3.2. A script that I created some time ago to parse &lt;a href="http://urbandictionary.com"&gt;urbandictionary&lt;/a&gt;'s output seemed like a good fit for this task.&lt;br /&gt;&lt;br /&gt;I've ran &lt;tt&gt;2to3&lt;/tt&gt; over my old script and it generated a patch which I successfully applied. Apart from that I had to fix bytes/string problem (not really hard and there are lots of information on it on the net) and my script just worked!&lt;br /&gt;&lt;br /&gt;So it looks like things are not very hard with 2-to-3 migration. Obviously, things are harder for the larger projects, but with larger projects everything is harder anyway.&lt;br /&gt;&lt;br /&gt;The only thing I haven't figured out yet is how to have different versions of easy_install for both 2.6 and 3.2 on FreeBSD, though I haven't spent much time digging into it.&lt;br /&gt;&lt;br /&gt;PS I went further with the urbandictionary script, created a package for it, &lt;a href="http://pypi.python.org/pypi/py-urbandict/0.1"&gt;uploaded&lt;/a&gt; on PyPI, improved formatting and made it easier to use from python. Here's a screenshot:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://people.freebsd.org/~novel/misc/urbandicli.png"/&gt;&lt;br /&gt;&lt;br /&gt;Check it out on &lt;a href="https://github.com/novel/py-urbandict"&gt;github&lt;/a&gt; if you're interested.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6173538454878847560?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6173538454878847560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/02/some-python3-fun.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6173538454878847560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6173538454878847560'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/02/some-python3-fun.html' title='Some Python3 fun'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-254708156450234937</id><published>2011-02-24T10:15:00.000-08:00</published><updated>2011-02-24T10:34:04.133-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><title type='text'>ChangeLog / NEWS importance</title><content type='html'>I was scanning &lt;a href="http://portscout.org/"&gt;portscout&lt;/a&gt; recently and noticed new version of &lt;a href="http://xplanet.sourceforge.net/"&gt;xplanet&lt;/a&gt; released.&lt;br /&gt;&lt;br /&gt;As usual, I've grabbed new version tarball and started compilation, meanwhile checking &lt;tt&gt;ChangeLog&lt;/tt&gt; and &lt;tt&gt;NEWS&lt;/tt&gt; for list of changes in the new version. I was a bit disappointed when I wasn't able to find anything I was looking for. I thought I probably could find some announcement on the forums or project's website, but had no luck with this as well. Now it's not even funny.&lt;br /&gt;&lt;br /&gt;Of course, I can do &lt;tt&gt;diff -ruN&lt;/tt&gt; against the old version, but it's not quite easy to understand what's been changed without knowing context and it won't work for all users. So, it's quite strange situation for a typical user as he has no clue why he should upgrade.&lt;br /&gt;&lt;br /&gt;While providing a list of changes for the release is a very simple thing, it's very important from user perspective and unfortunately keeps getting forgotten sometimes.&lt;br /&gt;&lt;br /&gt;PS I almost forgot to mention I've tried to check project's svn, but &lt;a href="http://sourceforge.net"&gt;sourceforge&lt;/a&gt; is slow as hell or even slower, so I wasn't able neither checkout sources nor view them from the website.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-254708156450234937?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/254708156450234937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/02/changelog-news-importance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/254708156450234937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/254708156450234937'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/02/changelog-news-importance.html' title='ChangeLog / NEWS importance'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-611126873684302514</id><published>2011-02-12T06:07:00.000-08:00</published><updated>2011-02-12T07:32:30.505-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Argument-based methods synchronization in Python</title><content type='html'>I've been implementing yet another client for a REST-like service and I've spotted a problem I typically haven't faced while working with REST services. I needed to modify some resource -- meaning issuing a &lt;em&gt;PUT&lt;/em&gt; request on resource &lt;tt&gt;/api/resource/id&lt;/tt&gt; -- for which changes didn't apply immediately but it rather went into 'building' state or something like that. I had a method like &lt;tt&gt;modify_bar(self, resource_id)&lt;/tt&gt; and things worked great for a single thread, but caused problems with multiple active threads. Obviously, I checked that &lt;tt&gt;resource_id&lt;/tt&gt; is ready for operations, but in the middle of the end of the check and starting of actual work another thread could get in and cause troubles.&lt;br /&gt;&lt;br /&gt;Let's check sample code:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/823797.js?file=example.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;And its output:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(14:46) novel@nov-testing2:~/sync %&gt; ./sync.py  &lt;br /&gt;working on bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;(14:47) novel@nov-testing2:~/sync %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;But the result I wanted to achieve:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(14:46) novel@nov-testing2:~/sync %&gt; ./sync.py  &lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;(14:47) novel@nov-testing2:~/sync %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I've been thinking how to do it without class redesign and API changes and after some time came up with a synchronization solution for methods based on their arguments.&lt;br /&gt;&lt;br /&gt;Implementation looks like this:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/823797.js?file=example2.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Basically, we keep a list of ids of objects we're working with. When we want to start working with some object we check the list first, if its id in the list it means it's currently being worked on and we have to wait, otherwise we push the id to the list and start working.&lt;br /&gt;&lt;br /&gt;And the result is:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(15:09) novel@nov-testing2:~/sync %&gt; ./sync2.py &lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;(15:10) novel@nov-testing2:~/sync %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For the sake of experiment let's start another thread with different &lt;tt&gt;bar_id&lt;/tt&gt; value to make sure it's not blocked:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/823797.js?file=example3.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;And the output now:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(15:13) novel@nov-testing2:~/sync %&gt; ./sync2.py&lt;br /&gt;working on bar id = 1&lt;br /&gt;working on bar id = 0&lt;br /&gt;done with bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt; done with bar id = 0&lt;br /&gt;done with bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;working on bar id = 1&lt;br /&gt;done with bar id = 1&lt;br /&gt;(15:14) novel@nov-testing2:~/sync %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As you can see, things are now working as expected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-611126873684302514?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/611126873684302514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/02/methods-synchronization-for-individual.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/611126873684302514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/611126873684302514'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/02/methods-synchronization-for-individual.html' title='Argument-based methods synchronization in Python'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-3979233576039678652</id><published>2011-02-04T06:59:00.000-08:00</published><updated>2011-02-04T11:57:28.437-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='mox'/><title type='text'>Mocking libcloud using Mox</title><content type='html'>If you're using &lt;a href="http://libcloud.org"&gt;libcloud&lt;/a&gt; to interact with cloud providers, you probably would like to cover this code with tests if you haven't done so already.&lt;br /&gt;&lt;br /&gt;However, most likely you don't want &lt;tt&gt;libcloud&lt;/tt&gt; to do any real calls to the cloud provider API service as it could create additional noise on your account, add extra load and cost you money (esp. if tests are being run on a regular basis on a Continues Integration server).&lt;br /&gt;&lt;br /&gt;One possible solution is to mock these things up using &lt;a href="http://code.google.com/p/pymox/"&gt;Mox&lt;/a&gt; mocking framework. Libcloud uses 2-step initialisation process for a connection class -- first you obtain driver class and then initiate it -- and I seem to always forgot how to mock it right, so decided to write it down.&lt;br /&gt;&lt;br /&gt;For example, we have a simple class that returns a list of names of currently available nodes:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/811604.js?file=example.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;And we want to test it without making actual API calls. Let's see how the test code will look for this task. For the sake of simplicity default &lt;tt&gt;unittest&lt;/tt&gt; framework will be used.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/811604.js?file=test_example.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Basically, what we are doing here in the test:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Create a mock for &lt;tt&gt;RackspaceNodeDriver&lt;/tt&gt; class and record &lt;tt&gt;list_nodes()&lt;/tt&gt; call for it; we also make it return two node objects. Actually, we create fake objects using &lt;a href="http://docs.python.org/library/functions.html#type"&gt;type()&lt;/a&gt;, so we don't have to bother with creation of real Node objects which need a way more properties to be set when constructing that we don't care about&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Use mox's &lt;tt&gt;StubOutWithMock&lt;/tt&gt; routine (please check &lt;a href="http://code.google.com/p/pymox/wiki/MoxDocumentation"&gt;mox docs&lt;/a&gt; for details on that) to stub out libcloud.providers module. Here, in &lt;tt&gt;get_driver()&lt;/tt&gt; we pass &lt;tt&gt;lambda&lt;/tt&gt; because &lt;tt&gt;get_driver()&lt;/tt&gt; returns class itself, not an instance of the class, and using lambda here seems to be more clear than recording &lt;tt&gt;__call__()&lt;/tt&gt; for a class&lt;/li&gt;&lt;br /&gt; &lt;li&gt;All the standard &lt;tt&gt;ReplayAll&lt;/tt&gt;/&lt;tt&gt;VerifyAll&lt;/tt&gt; mox routines&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;For the sake of experiment, you can replace actual &lt;tt&gt;node_names()&lt;/tt&gt; method of the &lt;tt&gt;Example&lt;/tt&gt; class with just &lt;code&gt;return ["node1", "node2"]&lt;/code&gt;. The &lt;tt&gt;assertEqual()&lt;/tt&gt; will pass, but mox will complain that &lt;tt&gt;list_nodes()&lt;/tt&gt; wasn't called and test will fail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-3979233576039678652?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/3979233576039678652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/02/mocking-libcloud-using-mox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/3979233576039678652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/3979233576039678652'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/02/mocking-libcloud-using-mox.html' title='Mocking libcloud using Mox'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-372150476641079389</id><published>2011-01-30T09:15:00.000-08:00</published><updated>2011-01-31T11:14:21.713-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><title type='text'>REST service on top of Marcuscom Tinderbox</title><content type='html'>Like many people who work on &lt;a href="http://www.freebsd.org/ports/"&gt;FreeBSD Ports&lt;/a&gt; I've been using great &lt;a href="http://tinderbox.marcuscom.com/"&gt;Marcuscom Tinderbox&lt;/a&gt; to verify my changes. Some time ago I started to realise that it's quite a boring task to schedule a lot of builds using web interface again and again and finally I've managed to make myself start making the process a little bit easier. &lt;br /&gt;&lt;br /&gt;It seems that building a REST service on top on the existing is a nice way to go, so that's what I've been doing last few days and finally I have a prototype now.&lt;br /&gt;&lt;br /&gt;As I didn't want to patch original tinderbox's webui sources, I just created a sub-directory in it called 'api' and started there. To my surprise, I wasn't able to find any ready to use solution to implement REST service in PHP (maybe I've missed something though), so ended up with a few php scripts and rewrite rules to make URLs feel RESTy. It was a quite hard part of the task since I haven't been coding in PHP for years and don't feel comfortable with it even after few days of practice.&lt;br /&gt;&lt;br /&gt;Simultaneously I've started coding a client for which I choose Python.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Workflow&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The goal was to support minimum but most important (for me at least) scenario -- testing an update for a port. Let's assume the port being tested is &lt;b&gt;security/gnutls-devel&lt;/b&gt;. The process looks like that:&lt;br /&gt;&lt;br /&gt;1. Produce a patch and apply it to the tree (can be done via ssh, or nfs, whatever, and could be easily scripted up)&lt;br /&gt;2. Check builds we have:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(21:33) novel@fsol:~ %&gt; tbc build                               &lt;br /&gt; id           name     status   current port updated&lt;br /&gt;  1    8.x-FreeBSD       IDLE           None 2011-01-30 14:05:25&lt;br /&gt;(21:40) novel@fsol:~ %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So, we see an idle build here with id &lt;tt&gt;1&lt;/tt&gt;. Not so much choices, so let's use it, but first let's see what's in the queue:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(21:40) novel@fsol:~ %&gt; tbc queue&lt;br /&gt; id   username                 port        build pri     status            enqueued           completed&lt;br /&gt; 10      novel      security/gnutls  8.x-FreeBSD  10    SUCCESS 2011-01-30 13:54:43 2011-01-30 14:05:27&lt;br /&gt;(21:45) novel@fsol:~ %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now adding a port to the queue:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(21:46) novel@fsol:~ %&gt; tbc queue add -b 1 security/gnutls-devel&lt;br /&gt;(21:46) novel@fsol:~ %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Let's check if new port build added successfully:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(21:46) novel@fsol:~ %&gt; tbc queue                         &lt;br /&gt; id   username                 port        build pri     status            enqueued           completed&lt;br /&gt; 10      novel      security/gnutls  8.x-FreeBSD  10    SUCCESS 2011-01-30 13:54:43 2011-01-30 14:05:27&lt;br /&gt; 11      novel      security/gnutls-devel  8.x-FreeBSD  10   ENQUEUED 2011-01-30 21:46:20                None&lt;br /&gt;(21:46) novel@fsol:~ %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Cool, it's here! Now we can see that our build turned into &lt;i&gt;PREPARE&lt;/i&gt; state:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(21:48) novel@fsol:~ %&gt; tbc build&lt;br /&gt; id           name     status   current port updated&lt;br /&gt;  1    8.x-FreeBSD    PREPARE           None 2011-01-30 21:48:15&lt;br /&gt;(21:48) novel@fsol:~ %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;All we have to do now is wait and poll for changes. Now we can see it's building:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(21:59) novel@fsol:~ %&gt; tbc build&lt;br /&gt; id           name     status   current port updated&lt;br /&gt;  1    8.x-FreeBSD  PORTBUILD gnutls-devel-2.11.5 2011-01-30 22:00:25&lt;br /&gt;(22:00) novel@fsol:~ %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And finally we see it's done:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(22:07) novel@fsol:~ %&gt; tbc queue&lt;br /&gt; id   username                 port        build pri     status            enqueued           completed&lt;br /&gt; 11      novel      security/gnutls  8.x-FreeBSD  10    SUCCESS 2011-01-30 21:46:20 2011-01-30 21:57:18&lt;br /&gt; 12      novel security/gnutls-devel  8.x-FreeBSD  10    SUCCESS 2011-01-30 21:50:54 2011-01-30 22:09:22&lt;br /&gt;(22:15) novel@fsol:~ %&gt; tbc queue 11&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For everyone who's interested I've uploaded sources on github:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;a href="https://github.com/novel/mcom-tinderbox-rest"&gt;service&lt;/a&gt; (&lt;a href="https://github.com/novel/mcom-tinderbox-rest/blob/master/README.markdown"&gt;README&lt;/a&gt;, &lt;a href="https://github.com/novel/mcom-tinderbox-rest/blob/master/APIREF.markdown"&gt;API Reference&lt;/a&gt;)&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;a href="https://github.com/novel/mcom-tinderbox-client"&gt;client&lt;/a&gt; (&lt;a href="https://github.com/novel/mcom-tinderbox-client/blob/master/README.markdown"&gt;README&lt;/a&gt;)&lt;br /&gt;  &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;NOTICE&lt;/b&gt;: it's an early work in progress! The code is unstable and lacks a lot of features. Anyway, any feedback about an idea and implementation is welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-372150476641079389?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/372150476641079389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/01/rest-service-on-top-of-marcuscom.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/372150476641079389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/372150476641079389'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/01/rest-service-on-top-of-marcuscom.html' title='REST service on top of Marcuscom Tinderbox'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2309619042226212455</id><published>2011-01-22T05:45:00.000-08:00</published><updated>2011-01-22T05:55:47.473-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><title type='text'>lc-tools 0.1.4 released!</title><content type='html'>I'm happy to announce release of lc-tools 0.1.4.&lt;br /&gt;&lt;br /&gt;This release is based on libcould 0.4.2 which was released not so long ago. Changes from the previous version include support of the brand new SSL handling in libcloud, some custom features for Rackspace and GoGrid drivers and minor bugfixes. Please check &lt;a href="https://github.com/novel/lc-tools/blob/0.1.4/NEWS"&gt;NEWS file&lt;/a&gt; for a full list of changes.&lt;br /&gt;&lt;br /&gt;There are some non-function changes as well: lc-tools got &lt;a href="http://novel.github.com/lc-tools/"&gt;its own website&lt;/a&gt; and also a &lt;a href="http://novel.github.com/lc-tools/doc/latest/tutorial/"&gt;tutorial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can install the new version using either &lt;tt&gt;easy_install&lt;/tt&gt;:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;easy_install lctools&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;or by downloading and installing it by hands:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/downloads/novel/lc-tools/lctools-0.1.4.tar.gz"&gt;lctools-0.1.4.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SHA256 (lctools-0.1.4.tar.gz) = 407ce1f29f0e869219ffff2f866fb6de226b693bf925817b6b43a612120b1ff7&lt;br /&gt;&lt;br /&gt;Happy hacking on the cloud stuff!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2309619042226212455?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2309619042226212455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2011/01/lc-tools-014-released.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2309619042226212455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2309619042226212455'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2011/01/lc-tools-014-released.html' title='lc-tools 0.1.4 released!'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-5460637324194714687</id><published>2010-12-13T10:37:00.001-08:00</published><updated>2010-12-16T11:03:49.794-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gogrid'/><title type='text'>GoGrid locations support in libcloud</title><content type='html'>&lt;a href="http://www.gogrid.com"&gt;GoGrid&lt;/a&gt; added support for locations (US-West-1 and US-East-1) quite some time ago and I finally managed to implement this feature for &lt;a href="http://libcloud.org"&gt;libcloud&lt;/a&gt;'s GoGrid driver. Fortunately, libcloud API already takes into account that cloud providers could have more than one location, so the most important part was there already.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Examples&lt;/h4&gt;&lt;br /&gt;&lt;h5&gt;libcloud&lt;/h5&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/743794.js?file=libcloud_locations.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;lc-tools&lt;/h5&gt;&lt;br /&gt;Some of the &lt;tt&gt;lc-tools&lt;/tt&gt; support '-l' flag to specify location id. Here's how a typical sequence would look like:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/743795.js?file=gistfile1.sh"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Few notes here: you probably noticed that we filter images by locations but don't do it for sizes. Strictly speaking, sizes might differ for various providers and this is also accounted by libcloud API; but for GoGrid sizes are same for both locations, so I skipped this step.&lt;br /&gt;&lt;br /&gt;And the second thing: all these features are available in &lt;a href="http://incubator.apache.org/libcloud/devinfo.html"&gt;svn version of libcloud&lt;/a&gt; and &lt;a href="https://github.com/novel/lc-tools"&gt;git version of lc-tools&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Also the thing I should have been mentioned for some time already: GoGrid provided me with an account and it is quite helpful for various testing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-5460637324194714687?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/5460637324194714687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/12/gogrid-locations-support-in-libcloud.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5460637324194714687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5460637324194714687'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/12/gogrid-locations-support-in-libcloud.html' title='GoGrid locations support in libcloud'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6539930060095441722</id><published>2010-09-27T11:30:00.000-07:00</published><updated>2010-10-01T22:28:26.153-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='homepage'/><title type='text'>New website version</title><content type='html'>For a long time my &lt;a href="http://novel.evilcoder.org"&gt;website&lt;/a&gt; was just a set of random links. Recently I decided to give it some structure and make it look like more like an extended visit card instead of just a collection of random links. So, here's the result: &lt;a href="http://novel.evilcoder.org"&gt;http://novel.evilcoder.org&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I used &lt;a href="http://github.com/lakshmivyas/hyde"&gt;Hyde&lt;/a&gt; for static generation of the site and I've put the sources on github: &lt;a href="http://github.com/novel/novel.evilcoder.org"&gt;http://github.com/novel/novel.evilcoder.org&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It helped a lot to look at Steve Losh's sources of his site which are hosted on github as well: &lt;a href="http://github.com/sjl/stevelosh"&gt;http://github.com/sjl/stevelosh&lt;/a&gt; (actual site being: &lt;a href="http://stevelosh.com/"&gt;http://stevelosh.com&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Anyway, there is a lot of work ahead, I need add some more content and learn and work on html/css/design stuff, at which I'm not very good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6539930060095441722?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6539930060095441722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/09/new-website-version.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6539930060095441722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6539930060095441722'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/09/new-website-version.html' title='New website version'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6278970079030429059</id><published>2010-08-26T05:56:00.000-07:00</published><updated>2010-09-08T10:43:28.430-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Installing Man Pages with Distutils</title><content type='html'>People who read my blog probably remember that I started small project &lt;a href="http://github.com/novel/lc-tools"&gt;lc-tools&lt;/a&gt; which is based on &lt;a href="http://incubator.apache.org/libcloud/"&gt;libcloud&lt;/a&gt; and provides facilities to control clouds. Since the whole project is basically several Python scripts, I though it would make sense to provide a manual page for each.&lt;br /&gt;&lt;br /&gt;At first I had to choose format to use for manual pages. I remember dealing with groff several years ago and decided it's too bothersome for me and will require as much effort as writing all the other Python code. :]&lt;br /&gt;&lt;br /&gt;Fortunately, I've spotted &lt;a href="http://rtomayko.github.com/ronn/"&gt;ronn&lt;/a&gt; which allows to use Markdown for formatting manual pages, and it's a great thing as it allows one to think about content, not the formatting.&lt;br /&gt;&lt;br /&gt;Using &lt;tt&gt;ronn&lt;/tt&gt; I created all the man pages quite quickly but then faced another problem: &lt;tt&gt;distutils&lt;/tt&gt; doesn't have facilities to install man pages. That is. &lt;br /&gt;&lt;br /&gt;I've managed to implement a temporary (will explain why it is temporary later) solution. The idea is to override default install target this way:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/551355.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;So we just execute &lt;tt&gt;install.sh&lt;/tt&gt; after default 'install' target did its job. One important thing is to pass "PREFIX" to make sure that man pages will be installed in correct place. &lt;br /&gt;&lt;br /&gt;The &lt;tt&gt;install.sh&lt;/tt&gt; script is pretty trivial (19 lines length) and you can see it &lt;a href="http://github.com/novel/lc-tools/blob/master/man/install.sh"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ok, so what's wrong with this solution? It forces users to have &lt;tt&gt;ronn&lt;/tt&gt; installed to be able to install man pages. While it's OK for people who clone things from git, it's definitely not OK for people downloading the package from PyPI to force them installing ruby, ronn and friends. So the plan is to modify bdist targets to include generated manpages and modify install target to be able to install cached versions if &lt;tt&gt;ronn&lt;/tt&gt; is not installed on the system.&lt;br /&gt;&lt;br /&gt;That doesn't seem to be hard to do, though. I think I will implement it and release a new version. &lt;br /&gt;&lt;br /&gt;BTW, &lt;tt&gt;ronn&lt;/tt&gt; allows you create HTML man pages easily, so probably it's time to create a site for lc-tools with extensive documentation.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;: I've &lt;a href="http://stackoverflow.com/questions/3657209/python-installing-man-pages-in-distutils-based-project"&gt;asked this question&lt;/a&gt; on stackoverflow and haven't got any responses so far.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6278970079030429059?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6278970079030429059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/08/installing-man-pages-with-distutils.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6278970079030429059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6278970079030429059'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/08/installing-man-pages-with-distutils.html' title='Installing Man Pages with Distutils'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-1777822852699667338</id><published>2010-07-30T10:16:00.000-07:00</published><updated>2010-07-30T11:42:01.931-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='gogrid'/><category scheme='http://www.blogger.com/atom/ns#' term='skytap'/><title type='text'>On Skytap</title><content type='html'>I've ranted about &lt;a href="http://gogrid.com"&gt;GoGrid&lt;/a&gt; a bit in my previous post and now it's &lt;a href="http://skytap.com"&gt;Skytap&lt;/a&gt;'s time to receive its fair amount of rant. OK, just kidding, will sure my experience of working with it. &lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Concept&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;The general concept is quite different from all the cloud providers I worked with. What I've usually seen is the main abstraction of the cloud providers was a &lt;i&gt;'Server'&lt;/i&gt; (or node, or vm, whatever) -- just a single VM with properties like RAM size, CPU power etc, and which is created based on some &lt;i&gt;'Template'&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Skytap does things differently: &lt;i&gt;'Server'&lt;/i&gt; model doesn't play the main role. The thing all the stuff's built around is &lt;i&gt;'Configuration'&lt;/i&gt;, which is basically a collection of VMs. Configuration is created from 'Template' which is also actually a collection of VM templates. You cannot directly add a VM to configuration, you have to merge the template with a VM.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I haven't decided if I like this way of representing things or not. Surely, in some situation it's convenient to be able to group VMs and work with them as with single object and we've even implemented a similar scenario at work on top of other cloud provider. On the other hand, when you need to work on single VM level it's a bit confusing and cumbersome. &lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Web UI&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;It's ok but has some usability problems IMO. Well, I'm not a usability expert by any means, but these things just seem wrong to me.&lt;br /&gt;&lt;br /&gt;For example: a way to API doc: Dashboard -&gt; Support -&gt; API -&gt; 'How do I access API' solution -&gt; link to developers page -&gt; link to pdf guide. 5 steps from dashboard, not very good IMHO.&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;API&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;I have an impression that a lot of people treats any http service as REST service, that's obviously wrong. Skytap is good at this matter and their REST service is really RESTful. They even use all these fancy HTTP methods like PUT or DELETE.&lt;br /&gt;&lt;br /&gt;Based on some error messages and headers, I assume API is powered by Rails and Mongrel. The tutorial suggests using XML, but it looks like the API supports JSON as well, but not for all resources though. Having full JSON support would be really nice. Moreover, I've been playing with Firebug on web ui and noticed that AJAX is actually using JSON to communicate with the API, so it's strange why JSON is not fully supported.&lt;br /&gt;&lt;br /&gt;Also, API gives quite a low lever control to VMs. I.e. if you want to assign an IP address to a VM, you have to think not on VM level (like "assign address A to VM 'alice'") but on VM's OS network interface level (like "asign address A to the first network interface of VM 'alice'"). &lt;br /&gt;&lt;br /&gt;This forces you to make more API calls to get things done.&lt;br /&gt;&lt;br /&gt;Let's look at the quite typical task: create a VM with some of public IP available on our account.&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;th&gt;GoGrid&lt;/th&gt;&lt;br /&gt;    &lt;th&gt;Skytap&lt;/th&gt;&lt;br /&gt;  &lt;/tr&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;br /&gt;      &lt;ul&gt;&lt;br /&gt;        &lt;li&gt;find an unassigned IP&lt;/li&gt;&lt;br /&gt;        &lt;li&gt;create node from some template and use the IP from the previous step&lt;/li&gt;&lt;br /&gt;      &lt;/ul&gt;&lt;br /&gt;    &lt;/td&gt;&lt;br /&gt;    &lt;td&gt;&lt;br /&gt;      &lt;ul&gt;&lt;br /&gt;        &lt;li&gt;create a configuration from template&lt;/li&gt;&lt;br /&gt;        &lt;li&gt;find available IP&lt;/li&gt;&lt;br /&gt;        &lt;li&gt;assign an IP from the pevious step&lt;/li&gt;&lt;br /&gt;        &lt;li&gt;manually start the configuration&lt;/li&gt;&lt;br /&gt;      &lt;/ul&gt;&lt;br /&gt;    &lt;/td&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;So Skytap forces you to make twice more API calls than GoGrid. On the other hand, the feature of assigning public IPs wasn't documented at all in the API reference, so probably it will be changed in future and will become better. I've figured out how this works using Firebug. One more thing I haven't figured out how to handle better is the definition of term 'available IP' by Skytap. Basically, it treats IP as 'available' if it's not used by a &lt;u&gt;running&lt;/u&gt; VM. Sooo... you can assign the same IP to several VMs. You will be able to start one of these VMs even, but other VMs with the same IP will fail to start.&lt;br /&gt;&lt;br /&gt;There is one more thing that makes me feel quite worried: it looks like the credentials are stored in per template basis. So, if you create two configrations from the same, say, RHEL public template, the root passwords of VMs in both of your configurations will be same. I really really hope to be wrong on that or maybe that passwords are generated on per-account basis (which I cannot check as I have only one account).&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Conclusion&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;Summarising things up I have a strong feeling that I probably don't quite understand philosophy behind Skytap and probably it's targeted for the use cases where API is not very important.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-1777822852699667338?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/1777822852699667338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/07/on-skytap.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1777822852699667338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1777822852699667338'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/07/on-skytap.html' title='On Skytap'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6218250374566575864</id><published>2010-07-17T07:47:00.000-07:00</published><updated>2010-07-17T08:27:08.848-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='gogrid'/><title type='text'>About GoGrid Support</title><content type='html'>Let's discuss &lt;a href="http://gogrid.com"&gt;GoGrid&lt;/a&gt; support today. As an example I will take recent '&amp;lt;h1&amp;gt;596 Service Not Found&amp;lt;/h1&amp;gt;' error.&lt;br /&gt;&lt;br /&gt;This error arises about every 15-20th request to the API, and it's quite often. The fact that this error is not well formatted JSON or XML with GoGrid API exception and therefore might not be handled well by some libs makes it even more annoying. Yeah, and this error was noticed by at least two more people on different accounts.&lt;br /&gt;&lt;br /&gt;So the natural thing to do was to start a case and try to find out what's wrong (as it's obviously not a normal behaviour). I did that and I got an answer like "Yeah, we know about this error, if you spot it try waiting 5 minutes and try again". It's just ridiculous. Imagine an engine of your car stops after each hour of driving, you come to the service and being told like wait 5 minutes then start the engine again and your problem is fixed!&lt;br /&gt;&lt;br /&gt;You'd unlikely want to visit such a service again and the same goes for support. Correct me if I'm wrong, but the first thing that customer wants from support is getting his problem fixed and if the problem cannot be fixed right away get estimates and details why it cannot be fixed. And who needs workarounds, especially for such obvious cases?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6218250374566575864?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6218250374566575864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/07/about-gogrid-support.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6218250374566575864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6218250374566575864'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/07/about-gogrid-support.html' title='About GoGrid Support'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-5902524800020100362</id><published>2010-07-14T10:49:00.000-07:00</published><updated>2011-04-14T13:07:33.101-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lc-tools'/><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Announcing lc-tools: command line tools on top of libcloud</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://github.com/novel/lc-tools/raw/master/media/logo_128x128.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 128px; height: 128px;" src="http://github.com/novel/lc-tools/raw/master/media/logo_128x128.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Looks like it's time to announce &lt;a href="http://github.com/novel/lc-tools"&gt;lc-tools&lt;/a&gt;! What is it? Basically, it's just a few command line tools to manage your clouds based on &lt;a href="http://incubator.apache.org/libcloud/"&gt;libcloud&lt;/a&gt;. What advantages does it give? Well, it supports as many cloud providers as libcloud supports (ec2, rackspace, gogrid and many others) and you can manage them all with a single tool.&lt;br /&gt;&lt;br /&gt;Look and feel is pretty similar to &lt;a href="http://github.com/novel/gg"&gt;gg&lt;/a&gt;'s one as it seems to be quite comfortable and I used gg more than year on a regular basis and haven't had any issues with it.&lt;br /&gt;&lt;br /&gt;Currently lc-tools covers almost all functionality provided by libcloud, but I've only tested it with GoGrid. &lt;br /&gt;&lt;br /&gt;Some examples so you can check look and feel of the application:&lt;h5&gt;Listing available node images&lt;/h5&gt;&lt;code&gt;$ lc-image-list|grep -i centos&lt;br /&gt;image CentOS 5.2 (32-bit) w/ RightScale (id = 62)&lt;br /&gt;image CentOS 5.2 (64-bit) w/ RightScale (id = 63)&lt;br /&gt;image CentOS 5.3 (32-bit) w/ None (id = 1531)&lt;br /&gt;image CentOS 5.3 (64-bit) w/ None (id = 1532)&lt;br /&gt;&lt;/code&gt;&lt;h5&gt;... and sizes&lt;/h5&gt;&lt;code&gt;$ lc-sizes-list&lt;br /&gt;size 512MB (id=512MB, ram=512, disk=30 bandwidth=None)&lt;br /&gt;size 4GB (id=4GB, ram=4096, disk=240 bandwidth=None)&lt;br /&gt;size 2GB (id=2GB, ram=2048, disk=120 bandwidth=None)&lt;br /&gt;size 8GB (id=8GB, ram=8192, disk=480 bandwidth=None)&lt;br /&gt;size 1GB (id=1GB, ram=1024, disk=60 bandwidth=None)&lt;/code&gt;&lt;br /&gt;&lt;h5&gt;Creating a new node&lt;/h5&gt;&lt;code&gt;lc-node-add -i 62 -s 1GB -n mynewnode&lt;/code&gt;&lt;br /&gt;&lt;p&gt;Pay attention to values &lt;b&gt;62&lt;/b&gt; and &lt;b&gt;1GB&lt;/b&gt; -- they are ids of image and size respectively (from previous examples).&lt;/p&gt;&lt;h5&gt;Listing nodes&lt;/h5&gt;&lt;code&gt;$ lc-node-list&lt;br /&gt;100xxx  mynode1     173.204.xx.yy  Running&lt;br /&gt;100xxx  mynode2    173.204.xx.zz  Running&lt;/code&gt;&lt;h5&gt;Destroying nodes&lt;/h5&gt;&lt;code&gt;$ lc-node-do -i node_id destroy&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Project's github page contains a README file with documentation enough to get started, but if you have any problems or suggestions feel free to contact me via github, blog or email.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-5902524800020100362?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/5902524800020100362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/07/announcing-lc-tools.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5902524800020100362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5902524800020100362'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/07/announcing-lc-tools.html' title='Announcing lc-tools: command line tools on top of libcloud'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-4666683055457634681</id><published>2010-07-08T21:22:00.000-07:00</published><updated>2010-07-08T23:02:33.702-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><title type='text'>Kharkov</title><content type='html'>Posting from a &lt;a href="http://www.hotel-viva.com.ua/"&gt;hotel&lt;/a&gt; in Kharkov. The trip to Kharkov is quite short, standing only for one night; so already going to check out soon. Bad thing is transportation that takes 2 nights (and two different trains) to get there, so actually have to spend 4 nights in trains for the sake of one night here.&lt;br /&gt;&lt;br /&gt;The city looks clean and accurate, most buildings are in old classical style, at least at the central part and I have an impression that central part is quite large. There's a subway here also, though city is not very large (population is 1.5 millions).&lt;br /&gt;&lt;br /&gt;Now it's time to pack my bags...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-4666683055457634681?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/4666683055457634681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/07/kharkov.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4666683055457634681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4666683055457634681'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/07/kharkov.html' title='Kharkov'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-4289415728197970836</id><published>2010-06-24T12:38:00.000-07:00</published><updated>2010-06-24T12:40:36.140-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Motivation</title><content type='html'>I'm analysing some things happening in my life and wondering how... well, subjective and isolated from environment certain things could be.&lt;br /&gt;&lt;br /&gt;A good example is a car. You buy a new car and you start adjusting it the way you like: you buy wheels, suspension, maybe audio etc etc, you have a long list of things you want to install like silicon hoses, gauges, consider buying some new wheels and so on. There are of course a lot of cars better then yours and you surely can afford some of them, but you don't think about that. But one day a simple thought kicks you in a head: "I NEED this car". So you decide to sell your car and buy a new one; probably not now, probably not even this month, but you're sure you'll do it &lt;u&gt;soon&lt;/u&gt;. So... &lt;b&gt;nothing&lt;/b&gt; has changed in the environment. Just a simple idea in your head kills your passion in a second without any obvious changes in the environment and you cannot do anything about that.&lt;br /&gt;&lt;br /&gt;It scares me a little when I think about it and subconsciously I apply these thought to my programming job: what if my attitude to the certain projects or people are caused more by some ideas in my head than the environment? Well, there is nothing new in this thoughts and this subject is covered in a psychology, but despite of that it's really hard to find own base sometimes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-4289415728197970836?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/4289415728197970836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/06/motivation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4289415728197970836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4289415728197970836'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/06/motivation.html' title='Motivation'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-561814150916862107</id><published>2010-06-14T23:51:00.000-07:00</published><updated>2010-06-15T00:10:42.837-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><title type='text'>About commit messages</title><content type='html'>I noticed that top 3 commit messages on a project I'm currently working on are following:&lt;br /&gt;&lt;br /&gt;1. fixes / fix bug / fix bugs&lt;br /&gt;2. typo&lt;br /&gt;3. changes (hey, 2pac)&lt;br /&gt;&lt;br /&gt;Every time I spot such a commit message I literally see how the $EDITOR arises between the poor developer wanting to commit his changes and the repository like the magic door in front of Ali Baba and how the developer has to say 'Open sesame' to make this annoying thing go away.&lt;br /&gt;&lt;br /&gt;Anyway, I know how to fix that! If you're using git, add the following alias to your ~/.gitconfig:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;ci = commit -a -m "changes&lt;/tt&gt;"&lt;br /&gt;&lt;br /&gt;and you're all settled up! Just use &lt;tt&gt;git ci&lt;/tt&gt; to commit your stuff.&lt;br /&gt;&lt;br /&gt;For a reasonable price I can consult you how to exorcise the $EDITOR from other scms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-561814150916862107?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/561814150916862107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/06/about-commit-messages.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/561814150916862107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/561814150916862107'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/06/about-commit-messages.html' title='About commit messages'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6219130120477890866</id><published>2010-06-03T12:04:00.000-07:00</published><updated>2010-06-03T12:34:55.376-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='libcloud'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gogrid'/><title type='text'>libcloud's GoGrid driver</title><content type='html'>We have to work quite often with GoGrid quite frequently and about a year ago I wrote &lt;a href="http://novel.evilcoder.org/gg/"&gt;gg-tools&lt;/a&gt; -- a set of CLI tools and a library in Python. We've used it for a while but later decided to switch to &lt;a href="http://incubator.apache.org/libcloud/"&gt;libcloud&lt;/a&gt; to have a better portability if we decide to move to other cloud provider.&lt;br /&gt;&lt;br /&gt;However I found that some things in GoGrid driver could be improved. Specifically, there is quite annoying thing that gogrid doesn't assign an id to a node immediately after creation, but libcloud always expects to get an id for the image. As per discussion in libcloud maillist, &lt;tt&gt;create_node&lt;/tt&gt;() was patched to block until the node gets ip assigned. Also, &lt;tt&gt;ex_create_node_nowait&lt;/tt&gt;() method was added which simply adds node right away and returns id == None.&lt;br /&gt;&lt;br /&gt;While the patches are being reviewed, I created a fork on github: http://github.com/novel/libcloud&lt;br /&gt; with these changes applied. Feel free to check it out, GoGrid driver should be in a working state here as we use it on a daily basis and even if some error raises up it will be fixed quickly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6219130120477890866?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6219130120477890866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/06/libcloud-gogrids-driver.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6219130120477890866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6219130120477890866'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/06/libcloud-gogrids-driver.html' title='libcloud&apos;s GoGrid driver'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-1095287382327297378</id><published>2010-05-18T09:53:00.000-07:00</published><updated>2010-05-18T10:06:46.589-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freebsd'/><category scheme='http://www.blogger.com/atom/ns#' term='guide'/><title type='text'>Changing partition type on FreeBSD</title><content type='html'>I had an ufs partition that I've used as a swap device. I was pretty satisfied with this setup until I decided to use it as a kernel dump device. I've ran &lt;tt&gt;dumpon&lt;/tt&gt; on it and figured out it's not possible to use it as dump device. So I decided to change partition type to swap.&lt;br /&gt;&lt;br /&gt;I executed &lt;tt&gt;bsdlabel&lt;/tt&gt; and got such error: &lt;i&gt;bsdlabel: Class not found&lt;/i&gt;. I've been googling and reading quite a lot of time, lots of such questions are not answered, but finally was able to find a solution. The solution is to use &lt;tt&gt;gpart&lt;/tt&gt; tool. It appeared to be a handy tool and to change type of my &lt;i&gt;ad0s2b&lt;/i&gt; partition I executed these commands:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/405235.js?file=gpart_sample"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Works great.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-1095287382327297378?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/1095287382327297378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/05/changing-partition-type-on-freebsd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1095287382327297378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1095287382327297378'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/05/changing-partition-type-on-freebsd.html' title='Changing partition type on FreeBSD'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-65614432377221059</id><published>2010-05-02T10:11:00.000-07:00</published><updated>2010-05-02T10:53:11.002-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mutt'/><title type='text'>Introducing goocaa, or on the way to my perfect mutt setup</title><content type='html'>I've already posted &lt;a href="http://empt1e.blogspot.com/2009/10/using-mutt-with-gmail-imap-complete.html"&gt;a guide&lt;/a&gt; how I configured mutt over gmail to leverage some of gmail useful things, esp. address completion. I've used &lt;a href="http://code.google.com/p/goobook/"&gt;goobook&lt;/a&gt; for query_command. However, I don't quite like its stability, the way of its configuration and generally I prefer to avoid using software written in Python (or Ruby or any interpreted language) on my workstations.&lt;br /&gt;&lt;br /&gt;So I wrote a small tool called &lt;a href="http://github.com/novel/goocaa"&gt;goocaa&lt;/a&gt; (click on the link to check its github page). It's written in C and uses libxml2, glib2 and neon.&lt;br /&gt;&lt;br /&gt;It uses &lt;b&gt;~/.goocaarc&lt;/b&gt; configuration file and its schema looks this way:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[default]&lt;br /&gt;email = me@gmail.com&lt;br /&gt;passwd = lalala&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To start using it, just add:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;set query_command = "/usr/local/bin/goocaa %s"&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;to &lt;b&gt;~/.muttrc&lt;/b&gt; [1].&lt;br /&gt;&lt;br /&gt;One more thing that I've implemented is multi-account support. I have my work mail hosted at google also, so I forward it to my gmail account and put to a separate mailbox. For this mailbox I apply special rules, like, set "mail from" to work address, etc. One more thing that makes sense to do is to search in work's contacts instead of gmail ones. It could be done with goocaa's multi-account support. First, add additional profile to &lt;b&gt;~/.goocaarc&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[default]&lt;br /&gt;email = me@gmail.com&lt;br /&gt;passwd = lalala&lt;br /&gt;&lt;br /&gt;[mywork]&lt;br /&gt;email = me@mywork.com&lt;br /&gt;passwd = tatata&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And now use folder hooks in &lt;b&gt;~/.muttrc&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;folder-hook . 'set from = "me@gmail.com"; \&lt;br /&gt;      set query_command = "/usr/local/bin/goocaa -p default %s"&lt;br /&gt;&lt;br /&gt;folder-hook mywork 'set from = "me@mywork.com"; \&lt;br /&gt;          set query_command = "/usr/local/bin/goocaa -p mywork %s"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;All done! Now mutt will use your gmail contacts everywhere except 'mywork' folder where it will be using your work contacts.&lt;br /&gt;&lt;br /&gt;1: &lt;a href="http://www.mutt.org/doc/manual/manual-4.html#ss4.5"&gt;documentation on mutt's &lt;tt&gt;$query_command&lt;/tt&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-65614432377221059?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/65614432377221059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/05/introducing-goocaa-or-on-way-to-my.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/65614432377221059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/65614432377221059'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/05/introducing-goocaa-or-on-way-to-my.html' title='Introducing goocaa, or on the way to my perfect mutt setup'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-707771021697828325</id><published>2010-04-26T10:24:00.000-07:00</published><updated>2010-06-13T10:32:43.104-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><title type='text'>Ingeneeriing</title><content type='html'>Found some colleagues on Facebook. I think they rock:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://people.freebsd.org/~novel/misc/ingeneeriing.png" style: 2px solid black"/&gt;&lt;br /&gt;&lt;br /&gt;I think it's funny when an enginiir cannot spell word 'enginiir' right AND doesn't use a spell checker.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-707771021697828325?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/707771021697828325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/04/ingeneeriing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/707771021697828325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/707771021697828325'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/04/ingeneeriing.html' title='Ingeneeriing'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6271275328452802503</id><published>2010-03-08T12:16:00.000-08:00</published><updated>2010-03-08T12:32:06.544-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>My first magazine publication</title><content type='html'>My small article about &lt;a href="http://github.com/defunkt/cijoe"&gt;cijoe&lt;/a&gt; has been published in Russian journal &lt;a href="http://linuxformat.ru/"&gt;Linux Format&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;&lt;img src="http://people.freebsd.org/~novel/misc/lf129cijoe.png" border="1"&gt;&lt;br /&gt;&lt;br /&gt;It's a small article describing how to get cijoe up and running for a typical Django project. I am really happy to see my article published! It seems the hardest part about writing technical articles in Russian is translating not very popular technical terms into Russian. For example, I still don't know what would an adequate and elegant trasnlation for 'test runner', for example.&lt;br /&gt;&lt;br /&gt;Anyway, I want to continue writing articles and I already have an idea about my next article.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6271275328452802503?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6271275328452802503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/03/my-first-magazine-publication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6271275328452802503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6271275328452802503'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/03/my-first-magazine-publication.html' title='My first magazine publication'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-1271722221987867145</id><published>2010-02-12T09:16:00.000-08:00</published><updated>2010-02-13T23:06:56.674-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Mocking/stubbing in Django tests again</title><content type='html'>I've already wrote a bit about&lt;a href="http://empt1e.blogspot.com/2009/09/testing-in-django-and-python-in-gerenal.html"&gt;testing in python&lt;/a&gt;. Since that, I've adopted nose and &lt;a href="http://github.com/jbalogh/django-nose"&gt;django-nose&lt;/a&gt; and I'm quite satisfied with the result.&lt;br /&gt;&lt;br /&gt;However, I was still feeling frustrated as I wasn't able to find a way of mocking/stubbing certain modules in my code easily without having duplicate &lt;i&gt;settings.py&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Later I figured out that I'm missing very simple and natural solution for some reason: as views are just functions I could simply import them and do whatever I want with them! The only thing I have to do is to construct HttpRequest object. So, the typical example will look like:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/303884.js?file=gistfile1.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;This, however, doesn't make much sense without injecting some mocked stuff. Mock object could be created in setUp like that:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/303886.js?file=test.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Obviously it's also possible to just imported stubbed versions as well. Anyway, I prefer to go with mocks if I don't need to implement some complicated logic for testing, and create them on fly.&lt;br /&gt;&lt;br /&gt;In order to inject this stuff, I modify &lt;b&gt;func_globals&lt;/b&gt; property of the function:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/303887.js?file=gistfile1.py"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;So we just use our mocked version of 'foo' instead of 'foo' instead and also override some global function that makes requests to some remote service. This approach doesn't look very clean to my opinion, but it works almost fine. There are some problems with it however: if the view is decorated, we have to figure out how to reach the original function. For standard decorators like &lt;i&gt;login&lt;/i&gt; we know that view is accessible as 'view_func' property, but if there are several of them including third party ones, it could be a bit troublesome to figure out what is the original view; on the other hand I don't think it'd be hard to solve these problems.&lt;br /&gt;&lt;br /&gt;Anyway, I'm quite happy with this solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-1271722221987867145?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/1271722221987867145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/02/mockingstubbing-in-django-tests-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1271722221987867145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1271722221987867145'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/02/mockingstubbing-in-django-tests-again.html' title='Mocking/stubbing in Django tests again'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-224550655624134878</id><published>2010-01-09T02:15:00.000-08:00</published><updated>2010-01-09T02:55:24.764-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><title type='text'>Few words about December trip to CA</title><content type='html'>Stayed 2.5 weeks in CA in December, 2009. It was surprisingly cold, esp. during the first week of my stay - from 6th to 12th.&lt;br /&gt;&lt;br /&gt;This time wasn't driving around much but spent few nights in San Francisco instead. One of the place visited was &lt;a href="http://www.tommystequila.com/"&gt;Tommy's&lt;/a&gt;, tasted some tequilas and I must say that tequila is quite nice. :)&lt;br /&gt;&lt;br /&gt;Also visited &lt;a href="http://www.rubyskye.com/"&gt;Ruby Skye&lt;/a&gt; and also liked it, despite of the fact that some techno DJ (forgot the name) was performing that night and I'm not much into techno.&lt;br /&gt;&lt;br /&gt;Made the picture of it on the other day:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/7/16378547ZpD.jpg" border="1"&gt;&lt;br /&gt;&lt;br /&gt;Also visited some other places and met some FreeBSD people -- happy about that.&lt;br /&gt;&lt;br /&gt;Some random pic of San Francisco:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/3/16378553Wje.jpg" border="1"&gt;&lt;br /&gt;&lt;br /&gt;The more time I spend in SF, the more I like it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-224550655624134878?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/224550655624134878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/01/few-words-about-december-trip-to-ca.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/224550655624134878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/224550655624134878'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/01/few-words-about-december-trip-to-ca.html' title='Few words about December trip to CA'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-4537292159995573438</id><published>2010-01-02T02:59:00.000-08:00</published><updated>2010-01-09T02:56:24.533-08:00</updated><title type='text'>Bazylum -- a tool to track x11 windows activity</title><content type='html'>I was always wondering how much time per day I spend in firefox or, say, pidgin. So I finally managed to implement a tool which would track that. I called it bazylum - "lazy bum" joined together and first chars swapped. Funny, but after such a transformation it still has quite sensible meaning. :-) According to &lt;a href="urbandictionary.com"&gt;urbandict&lt;/a&gt;, &lt;a href="http://www.urbandictionary.com/define.php?term=bazy"&gt;bazy&lt;/a&gt; means being doing nothing. Lum is more ambiguous word, check it if interested as well.&lt;br /&gt;&lt;br /&gt;Getting back to the tool itself. It basically reports how much time a certain window was active, here's the sample:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(20:50) novel@dirtyvegas:~/code/bazylum[master] %&gt; ./bazylum stat&lt;br /&gt;urxvt: 9952 sec&lt;br /&gt;Navigator: 3934 sec&lt;br /&gt;gvim: 1818 sec&lt;br /&gt;xv: 1515 sec&lt;br /&gt;pidgin: 121 sec&lt;br /&gt;desktop: 10 sec&lt;br /&gt;Dialog: 6 sec&lt;br /&gt;&lt;br /&gt;avg window active time: 25 sec&lt;br /&gt;longest active time: 658 sec&lt;br /&gt;(20:50) novel@dirtyvegas:~/code/bazylum[master] %&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So, from that report I can see that the majority of time I've spent in urxvt (that is good), the second popular window is firefox (aka Navigator) and I spent only 2 minutes chatting in pidgin (also good). Also, it says that average time before window change is just &lt;b&gt;25&lt;/b&gt; seconds and the longest time when window was active is only about &lt;b&gt;11&lt;/b&gt; minutes. It means that my concentration is not very good, probably a sign that I suffer from &lt;a href="http://en.wikipedia.org/wiki/AD/HD"&gt;AD/HD&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you like the idea, you might want to take a look at the &lt;a href="http://github.com/novel/bazylum"&gt;project's github page&lt;/a&gt;. The tool is written in C and requires sqlite3 and x11 (you will need -dev packages or something like that on binary based distros). To build it, simply type 'make'. Then collector should be started using './bazylumd' -- it will fork into background and start collecting window activity information. You might pass '-f' arg to it and it will stay in the foreground. And use './bazylum stat' to view the report. The tool is obviously on its early stage of development but works alright on my desktop and laptop.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-4537292159995573438?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/4537292159995573438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2010/01/bazylum.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4537292159995573438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4537292159995573438'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2010/01/bazylum.html' title='Bazylum -- a tool to track x11 windows activity'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2448731189696847118</id><published>2009-12-30T14:46:00.000-08:00</published><updated>2009-12-30T14:58:34.070-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Happy New...</title><content type='html'>It's 31th of December, 2am. I cannot sleep, don't know why -- maybe because of jet lag or because of a bunch of not so pleasant thoughts in my head. Anyway, this year was not boring by any means.&lt;br /&gt;&lt;br /&gt;I'm not in a mood to write some lengthy general post, just want to touch professional aspect of my life. I wrote quite a lot of code this year (not very much though, but not bad at all I think). Unfortunately, most of the code ended up being a shelf-ware or ended up only on my computers with me being the only user as I cannot make the code go live because it's not usable for people other than me -- lacks docs, misses general, but not important to me features and so on.&lt;br /&gt;&lt;br /&gt;So I really hope to make a dramatic improvement in that sense in the new year.&lt;br /&gt;&lt;br /&gt;Happy Holidays to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2448731189696847118?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2448731189696847118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/12/happy-new.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2448731189696847118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2448731189696847118'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/12/happy-new.html' title='Happy New...'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-4828749480289467908</id><published>2009-12-21T21:01:00.000-08:00</published><updated>2009-12-21T21:31:36.202-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Train Girl</title><content type='html'>I've boarded the train to Moscow sometime around 4-5 pm or something like that. The only other person in a coupe was a girl. A few minutes after train departed I've started talking to her discussing some gibberish that people usually talk about in trains/planes/etc and eventually the talk became very interesting. You know this feeling, when you're talking with somebody and you have so much things to say and you feel that the person you talk with also has a lot of things to say and basically that it would be fine to have a several discussions with this person in parallel at the same time. &lt;br /&gt;&lt;br /&gt;So we've been talking until about 1am and discussed lots of topics, including some personal ones, so, about 8 hours or so, quite a lot of time.&lt;br /&gt;&lt;br /&gt;I decided that it's definitely worth not to lose a connection with this person, however I was shy to ask a number. We've agreed to go to the subway (the one that under the ground, not food) together and I though I'd ask number there, but somebody meat her right near the train so I had no chance to ask the number.&lt;br /&gt;&lt;br /&gt;So I was feeling quite impressed. I was really really angry at myself that I haven't asked her number. I wasn't able to stop thinking about her for a 4 or 5 days (and it's quite a lot of time for me to think about a girl ;]). I even managed to figure out her last name and address. &lt;br /&gt;&lt;br /&gt;But now, a bit more than two weeks later I realised that I almost stopped thinking about her. So, now I'm not sure already if I should try to contact her... blah, on one hand I definitely won't loose anything by trying to contact her, on the other hand it doesn't to be a good situation when you're not sure if you like a person or not, at least I don't like it.&lt;br /&gt;&lt;br /&gt;Will see how the stuff goes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-4828749480289467908?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/4828749480289467908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/12/train-girl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4828749480289467908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4828749480289467908'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/12/train-girl.html' title='Train Girl'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-1094522138905844266</id><published>2009-12-21T15:46:00.000-08:00</published><updated>2009-12-21T16:00:20.894-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Doing Nothing Zen</title><content type='html'>Looks like I've somehow managed to master 'doing nothing' skill. When I was flying from Moscow to SF two weaks ago (I guess it's about 12 hours + 7 hours) the time passed very quick, I wasn't even reading a book or watching movies etc, was just sitting and doing nothing. And that is quite unnatural to me, because I always feel a need to do something and sitting in the plane without an ability to move or do something interesting was a pain in a previous trips. I even thought that I have an ac/hd as it was really hard to not change things quite often.&lt;br /&gt;&lt;br /&gt;Moreover, being in bart also doesn't bother me much. I don't use laptop, I don't read books -- not because I don't bring them, I always have it in my bag, but just because I enjoy looking through the window (even though I've seen everything quite a lot of time there) and I feel totally OK about it.&lt;br /&gt;&lt;br /&gt;That's probably because I'm quite tired and my brain switched to some 'lazy' mode or something like that, or maybe I'm just getting old. :) I hope I will be feeling same on the long way home.&lt;br /&gt;&lt;br /&gt;One more thing I have to learn is how to sleep in a plane.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-1094522138905844266?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/1094522138905844266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/12/doing-nothing-zen.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1094522138905844266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1094522138905844266'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/12/doing-nothing-zen.html' title='Doing Nothing Zen'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2371124983981711354</id><published>2009-11-01T03:51:00.000-08:00</published><updated>2009-11-01T04:33:36.915-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><title type='text'>About St. Petersburg trip</title><content type='html'>Yesterday night I've returned from St. Petersburg trip I previously wrote about. It takes 25 hours on train to get there (and the same from there to home). Quite a lot of time, but really, not very painful. I've spend about 2 weeks there.&lt;br /&gt;&lt;br /&gt;Right from the train we went to the office, it's only 1 subway station away from the rails station. This part of the city is really beautiful. Here's a picture of the office building:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/5/15856745Gjf.jpg"&gt;&lt;br /&gt;&lt;br /&gt;The view of the street leading to the office:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/2/15805912tgd.jpg"&gt;&lt;br /&gt;&lt;br /&gt;Very nice. &lt;br /&gt;&lt;br /&gt;In the evening we've checked in into the hotel. The room is small but accurate:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/6/15856766fsQ.jpg"&gt;&lt;br /&gt;&lt;br /&gt;The only problem with that was the furniture. I cannot even say it is uncomfortable, but it's strange, I mean, I wasn't able to sit or lay comfortably. Also, pillows were unusually small. Anyway, it's just a whim, stuff was generally good for a hotel.&lt;br /&gt;&lt;br /&gt;Initially, I thought I will visit various interesting places in SPb - museums, parks, palaces and stuff like that. Later on, I've realized that I've visited them lots of time before but I still don't have an overview of the city. So this time I was just walking on the streets.&lt;br /&gt;&lt;br /&gt;I've made some photos of the places I like. I guess they don't have any value from the photographer's point of view, but probably they will make you want visit SPb or at least find a better photos :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/7/15805877HHV.jpg"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/0/15805890XHi.jpg"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/3/15805893WsZ.jpg"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/9/15805919vDL.jpg"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/5/15806095DrI.jpg"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/7/15806097ajS.jpg"&gt;&lt;br /&gt;&lt;br /&gt;Great city, like it so much :-)&lt;br /&gt;&lt;br /&gt;One more good thing about it -- your shoes stays clean even if it's raining everyday. Obviously, it's because the city is very clean.&lt;br /&gt;&lt;br /&gt;Ah, I definitely want to visit it again.&lt;br /&gt;&lt;br /&gt;PS Here's my bag:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://b0.imgsrc.ru/n/novel/1/15832761CIO.jpg"&gt;&lt;br /&gt;&lt;br /&gt;I've managed to cram all my stuff into it and it looks like a giant pregnant bee. Looks even more funnier on my back: imagine a person being shagged by a giant bee, haha.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2371124983981711354?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2371124983981711354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/11/about-st-petersburg-trip.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2371124983981711354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2371124983981711354'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/11/about-st-petersburg-trip.html' title='About St. Petersburg trip'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-1455982522007215916</id><published>2009-10-19T11:47:00.000-07:00</published><updated>2009-10-19T11:54:44.536-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Vacation and St. Petersburg</title><content type='html'>Looks like last week I had a first real vacation in my life. By real I mean that I took a vacation not because I had to do something important, just because I wanted to have some rest. I've been really lazy and wasn't anything. :-) Yeah, a little bit of slacking is not bad at all.&lt;br /&gt;&lt;br /&gt;Anyway, the vacation is over and today I've arrived to St. Petersburg. Haven't been there for 7 years... yeah, it's a great city. And I like it's weather too. The only that disheartens me a bit is that I don't have my car here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-1455982522007215916?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/1455982522007215916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/10/vacation-and-st-petersburg.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1455982522007215916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1455982522007215916'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/10/vacation-and-st-petersburg.html' title='Vacation and St. Petersburg'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-4627213470456920468</id><published>2009-10-13T04:10:00.000-07:00</published><updated>2010-05-24T09:32:19.040-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mutt'/><category scheme='http://www.blogger.com/atom/ns#' term='guide'/><title type='text'>Using mutt with Gmail IMAP: complete guide</title><content type='html'>There are some guides around on the net, but I wasn't able to find a complete guide to make mutt as usable as gmail web interface, so I will try to put stuff together in one single post. I will also try to explain why each certain option is needed. Also, I don't pretend it to be the most optimal or correct way of configuration, but it works in practice. :-)&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Basic IMAP configuration&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;So, the basic IMAP options follow:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set realname = "Your Name"&lt;br /&gt;set imap_user = 'yourname@gmail.com'&lt;br /&gt;set spoolfile = imaps://imap.gmail.com:993/INBOX&lt;br /&gt;set smtp_url = "smtp://yourname@smtp.gmail.com:587/"&lt;br /&gt;set folder = "imaps://imap.gmail.com:993"&lt;br /&gt;set record="+[Gmail]/Sent Mail"&lt;br /&gt;set postponed="+[Gmail]/Drafts"&lt;br /&gt;set header_cache="~/.mutt/cache/headers"&lt;br /&gt;set message_cachedir="~/.mutt/cache/bodies"&lt;br /&gt;set certificate_file=~/.mutt/certificates&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;These lines are quite obvious and could be seen in a number of guides.&lt;br /&gt;&lt;br /&gt;That's probably a minimal set of setting you need to be able to check your gmail mails using mutt. You might want to put your password to the config file in order to prevent mutt asking it all the time.&lt;br /&gt;&lt;br /&gt;Ah, yeah, and I forgot one obvious thing that you probably know about anyway, the config file is  ~/.muttrc.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;sorting&lt;/h4&gt;&lt;br /&gt;Gmail was the first app I've used that sorted threads by the date of the last message in the thread. This is quite nice, because in the times when I used mutt with POP, I sorted thread by the first message, so if somebody sends a message to some ancient thread few screens of scrolling back I could easily miss it.&lt;br /&gt;&lt;br /&gt;So, I've configured similar sorting in mutt, with the only difference that I prefer newer threads to be in the bottom, not on top.&lt;br /&gt;&lt;br /&gt;So I've added the following lines to my ~/.muttrc:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set sort=threads&lt;br /&gt;set sort_aux=last-date-received&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The first line says that messages should be grouped in thread, the second one determines the order of the threads, so in our case we sort by newest message in the thread. You might want to consult muttrc(5) manpage for other sorting options.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Address book&lt;/h4&gt;&lt;br /&gt;When I've performed configuration steps described above, I've realized I really really really miss the built in address book of Gmail! The thing is that our company uses gmail to handle its mail and all the people who have an account automatically appear in the address book, which is quite handy and I've got used to this feature very very quickly.&lt;br /&gt;&lt;br /&gt;So, in order to use the address book from mutt, &lt;tt&gt;query_command&lt;/tt&gt; feature can be used. It allows to use an external application as address book.&lt;br /&gt;&lt;br /&gt;There's a nice script which allows to be used as &lt;tt&gt;query_command&lt;/tt&gt; in mutt, it's called &lt;a href="http://code.google.com/p/goobook/"&gt;goobook&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In order to install it, create some directory, e.g. ~/opt, cd into it and execute the following command:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;svn checkout http://goobook.googlecode.com/svn/trunk/ goobook-read-only&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note: you will have to have subversion client installed.&lt;br /&gt;&lt;br /&gt;Then cd to "~/opt/goobook-read-only" (or whatever dir you used), execute:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;cp settings_example.py settings.py&lt;/code&gt;, then edit &lt;tt&gt;settings.py&lt;/tt&gt; and fill in your gmail credentials. Now while you're in the working dir of goobook, check if it's configured correctly by executing something like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;./contactos.py e&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instead of 'e' you can type any letters which you sure will match somebody's name or address in your address book. If the script output something sensible then it works.&lt;br /&gt;&lt;br /&gt;Now, teach the mutt to use this script by adding these lines to ~/.muttrc:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set query_command = '/home/user/opt/goobook-read-only/contactos.py "%s"'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now, in mutt you can type 'Q' and type some query to make sure stuff is working correctly. If it works nice, then it means you can use address book when composing new messages. For example, if you hit 'm' to create a new message, in 'To:' prompt you can type some stuff and click 'ctrl-t' and mutt will complete stuff from the address book.&lt;br /&gt;&lt;br /&gt;Yeah, one more thing about goobook. I had to insert empty 'print' right after arguments check in the contactos.py script as it seems that mutt use first line of the output to show in the status bar. So the scripts looks this way for me:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt; 74 if __name__ == '__main__':&lt;br /&gt; 75     if len(sys.argv) &lt; 2:&lt;br /&gt; 76         sys.exit(1)&lt;br /&gt; 77     print&lt;br /&gt; 78 &lt;br /&gt; 79     try:&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I haven't had time to look at mutt sources to investigate this problem, so I'm not sure if it's an expected behavior.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;New messages info&lt;/h4&gt;&lt;br /&gt;What else... the other very important option is 'imap_check_subscribed'. To make mutt automatically add all the folders to mailboxes (so you can see a number of new/unread messages in each folder, new mail confirmation in different mailboxes etc), the following setting should be made:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;set imap_check_subscribed=yes&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you're moving from Gmail or maybe some GUI MUA, you might want to see a sidebar with list of folders and mail counts. It's possible to implement in mutt as well, however it requires applying third-party patches, &lt;a href="http://www.lunar-linux.org/index.php?option=com_content&amp;task=view&amp;id=44"&gt;sidebar patch&lt;/a&gt; specifically. I don't provide instructions how to apply it as in FreeBSD it's as simple as building &lt;tt&gt;mail/mutt-devel&lt;/tt&gt; port with "-DWITH_MUTT_SIDEBAR_PATCH" flag. Configuration is as simple as adding these lines to ~/.muttrc:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set sidebar_visible=yes&lt;br /&gt;set sidebar_width=30&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Summary&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;So, here's my complete ~/.muttrc file, only 50 lines long:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set realname = "yourname"&lt;br /&gt;set imap_user = 'yourname@gmail.com'         &lt;br /&gt;set spoolfile = imaps://imap.gmail.com:993/INBOX       &lt;br /&gt;set smtp_url = "smtp://yourname@smtp.gmail.com:587/"&lt;br /&gt;set folder = "imaps://imap.gmail.com:993"&lt;br /&gt;set record="+[Gmail]/Sent Mail"&lt;br /&gt;set postponed="+[Gmail]/Drafts"                         &lt;br /&gt;set header_cache="~/.mutt/cache/headers"   &lt;br /&gt;set message_cachedir="~/.mutt/cache/bodies"&lt;br /&gt;set certificate_file=~/.mutt/certificates&lt;br /&gt;set imap_check_subscribed=yes&lt;br /&gt;set move = no   &lt;br /&gt;set delete = yes&lt;br /&gt;set edit_hdrs&lt;br /&gt;set include &lt;br /&gt;set reply_to          &lt;br /&gt;set abort_nosubject=no&lt;br /&gt;set sig_dashes = no              # don't append -- as I use only my name as a sig&lt;br /&gt;set attribution = "  %n wrote:\n"              # I don't like lengthy attributions as well&lt;br /&gt;alternates '(username|altusername)([-+].*)?@.*'                         &lt;br /&gt;set hdr_format="%4C %Z %{%m/%d} %-15.15F (%4c) %s" # format of the index&lt;br /&gt;        &lt;br /&gt;ignore *                                                  &lt;br /&gt;unignore from subject to cc date x-mailer x-url user-agent&lt;br /&gt;hdr_order from to cc date subject x-mailer user-agent&lt;br /&gt;                                                                         &lt;br /&gt;set query_command = '~/opt/goobook-read-only/contactos.py "%s"'&lt;br /&gt;                &lt;br /&gt;set sort=threads               &lt;br /&gt;set sort_aux=last-date-received&lt;br /&gt;                                      &lt;br /&gt;# see beyond for hooks explanations&lt;br /&gt;folder-hook . 'set from = "yourname@gmail.com"; \&lt;br /&gt;        set smtp_url= "smtp://yourname@smtp.gmail.com:587/"'&lt;br /&gt;                                                                       &lt;br /&gt;folder-hook my 'set from = "i@mywork.com"; \&lt;br /&gt;                        set smtp_url = "smtp://i@mywork.com@smtp.gmail.com:587/";'&lt;br /&gt;                                                    &lt;br /&gt;folder-hook foobar 'set from = "yo@example.org";'&lt;br /&gt;                             &lt;br /&gt;# colors stuff outside  &lt;br /&gt;source ~/.mutt/themes/mytheme&lt;br /&gt;     &lt;br /&gt;# gpg                &lt;br /&gt;source ~/.mutt/gpg.rc   &lt;br /&gt;set crypt_autosign = yes&lt;br /&gt;         &lt;br /&gt;# sidebar              &lt;br /&gt;set sidebar_visible=yes&lt;br /&gt;set sidebar_width=30&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Few words about the hooks. I have two mail accounts, work and personal, both hosted at gmail. As I don't want to check both accounts, I've configured my work account to forward all the mail to my personal account and configured personal account to place all such mail into a separate folder. &lt;br /&gt;&lt;br /&gt;So, the first default '.' hook just says that we generally use personal account. The second hook for 'mywork' says that when in 'mywork' folder, we change 'from' address to work address and use smtp from work account for sending (could be configured on gmail side as well to add working address for account, but I don't like this way for various reasons).&lt;br /&gt;&lt;br /&gt;The third hook is for an alias at example.org which I use for some maillists, so I change 'from' address to it so maillist software allows me to write there. In this case I've added this address to gmail account, so no special 'smtp_url' magic is required.&lt;br /&gt;&lt;br /&gt;So, it doesn't seem to be complex to configure mutt this way and I'm totally happy with such a configuration.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update @ 24th, May 2010&lt;/b&gt;: I've wrote a replacement for goobook and switched to it instead: http://empt1e.blogspot.com/2010/05/introducing-goocaa-or-on-way-to-my.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-4627213470456920468?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/4627213470456920468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/10/using-mutt-with-gmail-imap-complete.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4627213470456920468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4627213470456920468'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/10/using-mutt-with-gmail-imap-complete.html' title='Using mutt with Gmail IMAP: complete guide'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-5495744060442139062</id><published>2009-10-07T00:45:00.000-07:00</published><updated>2009-10-07T00:53:37.877-07:00</updated><title type='text'>Social networks</title><content type='html'>I've just realised that my behaviour pattern in social network looks that way:&lt;br /&gt;&lt;br /&gt;1. Register&lt;br /&gt;2. Give up on it: don't use, don't talk with people, don't add anybody, etc&lt;br /&gt;3. Some people start adding me, I add them back (why not?). This step repeats several times.&lt;br /&gt;4. When I have a plenty of people 'friended'/'connected' whatever, I realise it makes no sense as I don't really talk to anybody so...&lt;br /&gt;5. I delete the account.&lt;br /&gt;&lt;br /&gt;I guess the only interesting social network was livejournal as in state it was few years ago, because it was interesting to know what's going with people you know (but not close enough) or interesting people you don't know. But for some reason, people don't write much interesting stuff to their journals on livejournal, just post some bullshit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-5495744060442139062?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/5495744060442139062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/10/social-networks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5495744060442139062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5495744060442139062'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/10/social-networks.html' title='Social networks'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7283046815833975094</id><published>2009-09-30T12:32:00.000-07:00</published><updated>2009-10-07T00:38:51.241-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Testing in Django and Python in gerenal</title><content type='html'>When I've been programming in Java I got used to write various tests. It's good to be able to play with the API you just wrote and tests save you a lot of time as programmed tests take less time than manual testing. Especially it's handy when you have some external service your app talks to and this service is not very fast, e.g. a response could take several minutes. So if you're testing stuff manually, it can take you several minutes, and the other approach to stub this service out and use this stub in tests to test the logic and stuff.&lt;br /&gt;&lt;br /&gt;So, returning back to Java, I must admit that Java world has a plenty of great testing/mocking/etc frameworks. And the situation in the Python world really disheartens me. First of all, testing frameworks. Maybe I've missed something, but looks like the only used frameworks are &lt;tt&gt;doctest&lt;/tt&gt; and &lt;tt&gt;unittest&lt;/tt&gt;, both from standard library.&lt;br /&gt;&lt;br /&gt;I don't get this &lt;tt&gt;doctest&lt;/tt&gt; framework at all. Putting code in the comments to your code seems to be awkward to me. I don't think inline code documentation is a good place to place some examples, if your code requires examples, it's better to write up a tutorial and place all the examples here. So, it's not the way to go (IMHO).&lt;br /&gt;&lt;br /&gt;The other framework is &lt;tt&gt;unittest&lt;/tt&gt; -- a clone of some old JUnit with very limited feature set. Misses lots of vital features that could be found in TestNG for example. Specifically, I miss the following features:&lt;br /&gt;&lt;br /&gt;* Test groups/dependencies. I want to make one test depend on other. It's clear that if some basic thing fails (e.g. user auth) it makes no sense at all to test all the stuff on top of that (e.g. actions for logged in user). And all these 'EEEEE' for lots of failed tests just make it harder the reason of error&lt;br /&gt;&lt;br /&gt;* Lack of beforeSuite etc methods&lt;br /&gt;&lt;br /&gt;... and many more, lazy to recall right now.&lt;br /&gt;&lt;br /&gt;Testing in Django itself is also quite cumbersome. First of all, the concept of keeping tests in app/tests.py is not very flexible. This app-centric approach is probably good when your project consists only from Django, but I really doubt it's possible in real life: most likely you will have some kind of helpers, misc. classes that don't fit into apps and so on, and all of them require to be tested. What's the good place to place these tests? If you won't place them into tests.py of one of the apps, you will most likely have to implement your own test runner.&lt;br /&gt;&lt;br /&gt;More examples:&lt;br /&gt;&lt;br /&gt;* You cannot run an individual test using django test runner. Imagine you managed to write, say, 100 tests and it takes about 3 minutes to run all of them. Then you find that one of the tests failed. Instead of 'try to fix -&gt; run failing test' iterations you will have 'try to fix -&gt; run all the tests -&gt; wait N minutes'.&lt;br /&gt;&lt;br /&gt;* To plug some simple things, like code coverage reports, you have to override/implement own test runner. &lt;br /&gt;&lt;br /&gt;Now it's time to get back to stubbing again. Django doesn't provide any easy way to replace real libs with the stubbed ones. The only good thing about it is that it's quite easy to get separate database instance for tests and automatically upload fixtures into it.&lt;br /&gt;&lt;br /&gt;But I don't see a clean way to stub out an external lib, the trick with overriding sys.modules['modulename'] doesn't work if you do it in setUp, because the lib could be already improted, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7283046815833975094?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7283046815833975094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/09/testing-in-django-and-python-in-gerenal.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7283046815833975094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7283046815833975094'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/09/testing-in-django-and-python-in-gerenal.html' title='Testing in Django and Python in gerenal'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-5265279780031668098</id><published>2009-09-01T05:19:00.000-07:00</published><updated>2009-09-01T05:21:05.306-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><title type='text'>sendxmpp!!</title><content type='html'>sendxmpp tools is actually the worst and the most buggy program I've ever seen (considering its simplicity and size).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-5265279780031668098?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/5265279780031668098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/09/sendxmpp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5265279780031668098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5265279780031668098'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/09/sendxmpp.html' title='sendxmpp!!'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-4823706079668655703</id><published>2009-08-02T16:04:00.000-07:00</published><updated>2009-08-02T16:06:18.196-07:00</updated><title type='text'>Jet Lag</title><content type='html'>... gets me more serious than the last time. Fall asleep at 4pm yesterday and got up now at 2am. I don't think I will be able to sleep anymore this morning and looks like I'll be having hard times this evening trying to cope with sleep.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-4823706079668655703?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/4823706079668655703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/08/jet-lag.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4823706079668655703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4823706079668655703'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/08/jet-lag.html' title='Jet Lag'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7852666042858511054</id><published>2009-07-24T23:04:00.000-07:00</published><updated>2009-07-24T23:09:52.419-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><category scheme='http://www.blogger.com/atom/ns#' term='us'/><title type='text'>US Trip is almost over</title><content type='html'>My US trip is almost over - I fly back in the very early morning on Monday. Final accord would be driving to Hollywood for the weekend, then go back on the Sunday night, grab luggage and go to the airport. This trip was kinda fun and a lot of stuff happened so it wasn't boring by any means, and I feel tired and miss a lot of people I haven't seen for one month. So I look forward the Hollywood trip and getting back home then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7852666042858511054?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7852666042858511054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/07/us-trip-is-almost-over.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7852666042858511054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7852666042858511054'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/07/us-trip-is-almost-over.html' title='US Trip is almost over'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-8969105255774524402</id><published>2009-07-16T20:22:00.000-07:00</published><updated>2009-07-16T20:32:10.415-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>paramiko vs scp</title><content type='html'>I had a task to benchmark a server by measuring how much time would it take to downloaded file via ftp. It was boring to script that up in shell since the server to be benchmarked didn't support key-based auth, so I'd had to pass password to ssh and I don't know a clean way to do it. Just for fun I decided to try doing it in Python using &lt;a href="http://www.lag.net/paramiko/"&gt;Paramiko&lt;/a&gt; module, which is a pure-python implementation of SSH protocol. I though it would be slower than native scp tool, but anyway I could use it to track the dynamics of performance changes.&lt;br /&gt;&lt;br /&gt;Imagine my surprise when tests results showed that Paramiko performance is nearly equals to native 'scp' performance! I have to say it was a really pleasant surprise and makes Paramiko even more useful in my eyes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-8969105255774524402?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/8969105255774524402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/07/paramiko-vs-sftp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/8969105255774524402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/8969105255774524402'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/07/paramiko-vs-sftp.html' title='paramiko vs scp'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-5082298876646797496</id><published>2009-07-16T20:12:00.000-07:00</published><updated>2009-07-16T20:22:23.148-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='laptop fail'/><title type='text'>Lenovo X61S</title><content type='html'>... is just CRAP!!! At least for a *nix user. First of all, it has some clit instead of a touchpad. I don't like the idea to place a clitoris in a middle of laptop's keyboard. OK, since almost all apps I use are command line and I also use stuff like vimperator for non-cli apps, I don't need to use mouse often. BUT BUT BUT. The keyboard is HORRIBLE! It's totally non standard and offset between rows are not usual as well because I always type stuff with offset of 1 symbol to the left or to the right. Moreover, the Escape key is placed in a very strange place, to the top of F1 key, so I often confuse esc with f1. It has function key as a very left button of bottom row, so I confuse it with control key. It has sleep key bound to fn + f4. So if I want to switch to 4th virtual desktop I risk to press fn-f4 instead of ctrl-f4 and suspend the laptop.&lt;br /&gt;&lt;br /&gt;I don't know how much time will I need to get used to it and I see no point at all to make such a non traditional controls. I wish I just could throw it into the window...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-5082298876646797496?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/5082298876646797496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/07/lenovo-x61s.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5082298876646797496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5082298876646797496'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/07/lenovo-x61s.html' title='Lenovo X61S'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-8300278244235772480</id><published>2009-07-08T20:33:00.000-07:00</published><updated>2009-07-08T20:40:32.939-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><category scheme='http://www.blogger.com/atom/ns#' term='us'/><title type='text'>Las Vegas pwnz!</title><content type='html'>I've been in Las Vegas last weekend. Well, what can I say, it's impressive!&lt;br /&gt;&lt;br /&gt;I've attended only two shows: Blue Man Group show and KA Theatre. Both shows are really great. I'd probably visit them both again. Unfortunately, I was kinda short on money and time and haven't had a chance to try out more shows or try girls ;]&lt;br /&gt;&lt;br /&gt;By the way, there are really lots of guys who offer girls on the Strip. They stay there any time, though there are less of them in the morning. But in the evening they stay in a row (literally) and there are LOTS of them. I wonder if that's effective, because they seem to give people all the same slides. I guess the efficiency would not change if their could would be reduced 5-10 times. &lt;br /&gt;&lt;br /&gt;Anyway, I really liked Las Vegas. That's the first place in US where I'd agree to live. Probably it would get annoying after some time though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-8300278244235772480?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/8300278244235772480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/07/las-vegas-pwnz.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/8300278244235772480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/8300278244235772480'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/07/las-vegas-pwnz.html' title='Las Vegas pwnz!'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-8604815631190883547</id><published>2009-06-29T14:25:00.000-07:00</published><updated>2009-06-29T14:31:31.707-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><title type='text'>In US again</title><content type='html'>As the title says, I'm in US again. Flight and train wasn't very good this time and while I was on road I slept only for about 3-4 hours in total. But anyway, I'm here finally and have enough time to sleep.&lt;br /&gt;&lt;br /&gt;I will be staying here for quite a long time and I hope I will be able to find some fun stuff to do. I think I could start to annoy waitresses in cafeterias by not answering "Don't matter" when they ask about some options for the order, but asking them in details what each option means. Ok, just kidding, it'd be so cruel =)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-8604815631190883547?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/8604815631190883547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/06/in-us-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/8604815631190883547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/8604815631190883547'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/06/in-us-again.html' title='In US again'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2152690553227184870</id><published>2009-06-13T05:44:00.000-07:00</published><updated>2009-06-13T06:14:59.081-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thoughts'/><title type='text'>project's webpage updates automation</title><content type='html'>Currently I'm reading "The Pragmatic Programmer: From Journeyman to Master" book. And while its contents seem quite obvious and natural to me, by repeating "DRY/automate things" stuff again and again it forces my mind to re-think about possible ways of automation of various aspects of my activity.&lt;br /&gt;&lt;br /&gt;I have a number of small projects, which are not very popular, but I prefer to keep a page for them just in case if they will be useful for somebody. However, I never liked updating web-sites because it's boring (like: ftp or ssh, edit files, re-check, edit again, you know). So after reading this book I decided to try to automate that too. Recently I moved my small &lt;i&gt;pymgsrc&lt;/i&gt; project - a command line client for &lt;a href="imgsrc.ru"&gt;imgsrc.ru&lt;/a&gt; photo hosting - to github and wrote a simple script for the website update. The way it works is:&lt;br /&gt;&lt;br /&gt;- Build a release distfile&lt;br /&gt;- Load template for website (single html) page, replace %%VERSION%% with actual version (in order to update download links and info about the latest version available) and replace %%CHANGELOG%% with HTMLfied (using simple sed expression) ChangeLog entires&lt;br /&gt;- scp resulting distfile and webpage to the hosting&lt;br /&gt;- Viola, all done! Using only one command.&lt;br /&gt;&lt;br /&gt;I'm very pleased with the script and that I don't have to bother with HTML editing anymore, at least while I didn't decide to alter template.&lt;br /&gt;&lt;br /&gt;I guess the hardest part of the automation is to find pieces of work which could be automated, because sometimes you do stuff and don't understand that it could be automated, but when you finally automated it it starts to look pretty natural and you wonder why you haven't noticed it earlier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2152690553227184870?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2152690553227184870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/06/projects-webpage-updates-automation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2152690553227184870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2152690553227184870'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/06/projects-webpage-updates-automation.html' title='project&apos;s webpage updates automation'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6204326224610998942</id><published>2009-06-12T12:41:00.000-07:00</published><updated>2009-06-13T06:07:31.708-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='software fail'/><title type='text'>python subprocess module</title><content type='html'>Recent Python versions show DeprecatedWarning when using various popen functions and encourages to use subprocess module. And it's frustrating because I don't quite like the subprocess module. Let's take a simple example: executing one app and piping other app, like "dmesg|grep hda". They even have this example in the subprocess module documentation so I just took it. So, take a look:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;output=`dmesg | grep hda`&lt;br /&gt;==&gt;&lt;br /&gt;p1 = Popen(["dmesg"], stdout=PIPE)&lt;br /&gt;p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)&lt;br /&gt;output = p2.communicate()[0]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That looks lame to me. Look, original command has only 4 words used and is easy to understand. The second example has: 17 words, uses classes (who needs them here?) with some weird non intuitive constructor arguments and the final accord is "p2.communicate()[0]". What is "commmunicate()", can you guess what it does in details without looking at the docs? What does it return? What the hell is "[0]"? Seems really horrible to me.&lt;br /&gt;&lt;br /&gt;Generally, it seems quite inconvenient to execute external applications using Python. Some people call Python 'a better shell', but it doesn't seem quite true if you need to execute external apps and in _most_ of shell scripts you really do need such things. Well, probably it's good at some sense that it forces you to split your Python logic and shell-scripting logic into python and shell scripts respectively and call shell scripts from your Python scripts and vice versa, but anyway, I don't like it a lot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6204326224610998942?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6204326224610998942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/06/python-subprocess-module.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6204326224610998942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6204326224610998942'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/06/python-subprocess-module.html' title='python subprocess module'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7873790842337034863</id><published>2009-06-05T12:31:00.000-07:00</published><updated>2009-06-05T12:52:27.231-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='objc'/><title type='text'>ObjC experiments</title><content type='html'>After some experiments with iPhone development and ObjC I decided to take a look at ObjC and use it to implement some simple but useful app. &lt;br /&gt;&lt;br /&gt;As I don't use any kind of tray or docker whatever (I will elaborate on that topic) I decided to implement some app which would poll IMAP server for new messages and notify me using libnotify.&lt;br /&gt;&lt;br /&gt;If you're interested, you can check sources on &lt;a href="http://github.com/novel/imapnotify/tree/master"&gt;github&lt;/a&gt;. Actually, it's more toy than real app atm, however it seem to work alright with my gmail account. And yeah, it's pretty simple and can only work with IMAPS (IMAP with SSL).&lt;br /&gt;&lt;br /&gt;Well... ObjC impression... surprise! Nothing is looking really impressive. What can I say. The language looks pretty natural and intuitive. I guess I like it more than C++, though I cannot be quite right in that since I don't know C++ and ObjC well enough, but I just like how ObjC feels. One more thing is that I haven't read any ObjC so I don't know best practices and design principles that should be used when wring in ObjC. I think it would worth to read some good book about ObjC.&lt;br /&gt;&lt;br /&gt;I didn't use GNUstep foundation classes on purpose. First reason is my philosophy of writing tools is that a tiny tool should not bring such huge dependencies like GNUstep. The second reason is that it would be better to learn pure language before moving to high-level frameworks. And my understanding is that using foundation classes changes ObjC programming dramatically. &lt;br /&gt;&lt;br /&gt;I think I'll play with this tool a little because it contains a lot of bugs and leaks (but it's more related to the C aspect of programming), will probably try to redesign it and move to playing with GNUstep classes, just need to come up with a project which would worth it.&lt;br /&gt;&lt;br /&gt;PS Yeah, the only thing that makes me curious is "+/-" in method signatures. IIRC, they're used to distinguish class and instance methods. In the most code I've seen or wrote, most of methods were actually instance methods, class methods appear not quite often, at least for me, so I don't really get why they deserved so much attention in ObjC.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7873790842337034863?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7873790842337034863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/06/objc-experiments.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7873790842337034863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7873790842337034863'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/06/objc-experiments.html' title='ObjC experiments'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7522397882397926445</id><published>2009-05-27T03:33:00.000-07:00</published><updated>2009-05-27T04:05:40.744-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='thoughts'/><title type='text'>gmail generation</title><content type='html'>Gmail got extremely popular about 2-3 years ago. That's probably because of kinda simple and at the same time powerful web interface it has. Even my mother has a gmail account these days and uses it all the time and has no problem with it at all.&lt;br /&gt;&lt;br /&gt;But there's a bad, very bad thing about it: it makes people format messages awfully. It's been written in various places that default quoting method is top-quoting, which is really annoying in most of the time. Moreover, people who read mails sent by normal mail clients like mutt, have problems with viewing them. Because text placed after a quoted message will by most likely formatted as a quotation as well by gmail. And inline quotation must be a real PITA for gmail users.&lt;br /&gt;&lt;br /&gt;Moreover, it forces people to over-quote because it leaves all messages from the thread, not the last one.&lt;br /&gt;&lt;br /&gt;As a result, most e-mail threads in which gmail users take part look like: several lines on message and then lots of lines of the previous messages quoted. &lt;br /&gt;&lt;br /&gt;It's really painful to read and I guess anti-gmail campaign would be more actual than ascii ribbon campaign these days.&lt;br /&gt;&lt;br /&gt;PS Actually not gmail, but it's formatting, because in general service seems to be OK.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7522397882397926445?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7522397882397926445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/05/gmail-generation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7522397882397926445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7522397882397926445'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/05/gmail-generation.html' title='gmail generation'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-2351176535001054255</id><published>2009-05-25T07:18:00.000-07:00</published><updated>2009-05-25T07:21:34.722-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bike'/><title type='text'>bike again</title><content type='html'>It's raining for the second day in a row and looks like will be rainy all the week. So using car instead of a bike. Bike is a drug, really.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-2351176535001054255?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/2351176535001054255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/05/bike-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2351176535001054255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/2351176535001054255'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/05/bike-again.html' title='bike again'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7772969528097133365</id><published>2009-05-14T09:13:00.000-07:00</published><updated>2009-05-14T09:27:04.776-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bike'/><category scheme='http://www.blogger.com/atom/ns#' term='health'/><title type='text'>bike</title><content type='html'>So I've started biking more or less often: biked last weekend and started to ride at work on a bike instead of car. Actually, I have a pretty positive impression - it takes about same time as getting to work by car, maybe even faster. Road to work is almost all the way downhill, so when I came at work I don't feel tired etc. Obviously, all the way back is an uphill, but it's also nice because it trains me I guess. The only inconvenient thing about it is that I'm feeling kinda tired after getting home and I still have a jet-lag after US trip, so I go to bed early and don't have much time to do useful stuff. But I hope in a week or maybe I will adopt to uphill and cope with jet-lag.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7772969528097133365?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7772969528097133365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/05/bike.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7772969528097133365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7772969528097133365'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/05/bike.html' title='bike'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7910435591326055208</id><published>2009-05-10T18:21:00.000-07:00</published><updated>2009-05-10T18:52:28.775-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software fail'/><title type='text'>recent Xorg fashion</title><content type='html'>I've been using free *nix systems for about 10 years now and almost always used X11 servers on them. Back then it was XFree86, not Xorg. First it was something like 3.3.x and then 4.x versions of XFree86.&lt;br /&gt;&lt;br /&gt;I always wondered how X was easy to configure. Actually, I've never had problems with X configuration. It was just a matter of generating a configuration file once and forgetting about it - it just kept working after upgrades etc. Probably only once I had problem with it (not sure "problem" is a right word though) - when "keyboard" driver was renamed to "kbd" driver. And I'm not even sure it actually happened in XFree, not Xorg.&lt;br /&gt;&lt;br /&gt;But with Xorg, I have problems all the time, esp. last few months when I switched to xorg with hal support. It's like... grab Ubuntu, install it, disable gnome, start openbox and figure out that shortcut for layout switching is "shift-alt" instead of "shift-ctrl". Ok, go to xorg.conf and see that you're configured "shift-ctrl", go "wtf?" and dig into /etc to find some gnome leftover scripts which probably re-configure xkb. Fail at that, google up the problem and figure out that xkb settings in some hal xml configs override the ones in xorg.conf. WTF? I totally don't get it why to make it possible to configure single item in two different places, esp. considering that in one place configuration doesn't make any sense. It's sooooooooo linuxish so it's even frustrating. &lt;br /&gt;&lt;br /&gt;Or another example - I've installed freebsd on my laptop today and installed Xorg. When X starts, I cannot get mouse moving etc... input basically doesn't work. I go to Xorg.log and see something like "AllowEmtpyInput is not set, disabling input devices". WTF??? What kind of reasoning process made it think that I don't need input devices? I don't even care what is "AllowEmtpyInput" and I don't know why is it so critical that I should be punished for not setting it in such cruel way. SO I've added it and got stuff working.&lt;br /&gt;&lt;br /&gt;I assume it's somehow related to hal. What I don't get is: I don't need hal. I guess a lot of people don't need hal in X (I don't know any who needs it). Why the hell stuff cannot just work in a way it worked before without hal? I think it would be more fair if people who need hal would fuck with it to enable it instead of people who don't need hal having to fuck around it to get things working like they're used to see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7910435591326055208?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7910435591326055208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/05/recent-xorg-fashion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7910435591326055208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7910435591326055208'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/05/recent-xorg-fashion.html' title='recent Xorg fashion'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-1716866112544198443</id><published>2009-05-08T11:23:00.000-07:00</published><updated>2009-05-08T11:50:37.578-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='macosx'/><title type='text'>MacOS X first impressions</title><content type='html'>By occasion I had to develop stuff for iPhone whole this week and therefore used MacBook as a primary computer. I've never used MacOS before except that once I've tried to install Hackintosh on my laptop but I could not used it because it didn't support neither wifi nor ethernet.&lt;br /&gt;&lt;br /&gt;So, well, MacOS X. It seems very hard to use in default configuration. Like, MacBook screensize is 13.3" (or something like that, lazy to check), considering that it's weird that the dock consumes so much screen space. I don't know how is it supposed to be usable, because the menu bar + window title + dock in default size consumes almost 1/4 of the screen space, it's weird. The only option is to set it's size to minimum and make it auto-hide.&lt;br /&gt;&lt;br /&gt;Window manager also seems to be kinda unusual. The first strange thing is how spaces (or whatever it's called) are implemented. I wonder why "Alt-Tab" shows me windows from all spaces instead of windows from the current space only. I was told it's possible to configure it, but I don't spot such option in the preferences. I also cannot find how to move a window from one space to another. &lt;br /&gt;&lt;br /&gt;Next disappointment is xcode, and first of all, it's editor. It feels like notepad with the only difference that it has syntax highlighting. For some reason, in the default configuration when you hit 'build and go' button it doesn't just to the first error/warning line in the sources. Seems to be kinda weird as well... Other stuff made me curious as well, for example, I wasn't able to find an easy way to rename a project. &lt;br /&gt;&lt;br /&gt;I don't know if xcode is positioned as IDE, probably is, but it looks like it's missing a lot of useful features available in other IDEs, for example I wasn't able to find any refactoring stuff there, while e.g. Idea has great support of various refactoring stuff.&lt;br /&gt;&lt;br /&gt;As for hardware, keyboard is weird in macbook. The thing that makes me feel uncomfortable is the "fn" key located in usual place of "ctrl" key. Space between the keys are also kinda large and it's unusual as well.&lt;br /&gt;&lt;br /&gt;Now I have an impression that OSX is not OS of my choice, I'm happy with freebsd/openbox or linux/openbox at least and the only interesting thing to me in osx is their API, esp. the UI part of it, because it looks like it's way better than for example QT or GTK+. ObjC is also quite interesting, I think I'll play with it in the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-1716866112544198443?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/1716866112544198443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/05/macos-x-first-impressions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1716866112544198443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/1716866112544198443'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/05/macos-x-first-impressions.html' title='MacOS X first impressions'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-5780373177007863687</id><published>2009-05-07T11:13:00.000-07:00</published><updated>2009-05-07T11:28:14.518-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><category scheme='http://www.blogger.com/atom/ns#' term='us'/><title type='text'>Trip to US, part2 - food</title><content type='html'>As promised, here's a quick post about my food-related experience in US.&lt;br /&gt;&lt;br /&gt;* First, the most impressive thing is a size of portions - they _veeeeeeeeeery_ large. Like, when you order a sandwich, they bring you two of them and bring some extra stuff like cakes or probably free. It's a lot of food, esp. for the breakfast.&lt;br /&gt;&lt;br /&gt;* Coffee - coffee is very tasty. I tasted coffee in peet's, starbucks and probably something else I forgot and it was pretty good everywhere. Muffins and cakes there are also pretty yummu.&lt;br /&gt;&lt;br /&gt;* The above two items lead me to conclusion that I don't really need a traditional breakfast, I'd better grab medium size coffee and a muffin or two and it's enough for me and cheaper.&lt;br /&gt;&lt;br /&gt;* As for various kitchens, Thai and Italian are pretty good. And due to size of portions you can order chicken or pizza, eat part of it, ask for the box and use it for lunch or even for two.&lt;br /&gt;&lt;br /&gt;* This item is closer to service than to food itself. When you order food you always get asked additional questions, like "what do you want it to be served with" etc, and it's pretty hard to tell, because I learned English from UNIX manpages and then IRC and don't know all these words =)&lt;br /&gt;It's kinda problematic, because "I don't care" almost never works. But it's ok, just have to learn more food-related words :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-5780373177007863687?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/5780373177007863687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/05/trip-to-us-part2-food.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5780373177007863687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5780373177007863687'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/05/trip-to-us-part2-food.html' title='Trip to US, part2 - food'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7738769158526865049</id><published>2009-04-29T10:41:00.001-07:00</published><updated>2009-04-29T15:36:39.467-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trip'/><category scheme='http://www.blogger.com/atom/ns#' term='us'/><title type='text'>Trip to US, part 1 - general impression</title><content type='html'>It's the 3rd week of my trip to US. It's my first time to US and actually it's the very first time when I've crossed the borders of motherland. I guess I will split my story in a few posts instead of making one lengthy post. In the first post I'll write up about general impressions.&lt;br /&gt;&lt;br /&gt;The first impressive thing is that it's very clean here on the streets - almost no garbage and no dust and it's the thing I really like here.&lt;br /&gt;&lt;br /&gt;The second thing about streets - they look all the same! I've stayed at Fremont and all the streets look same here - same houses, building of the same style and color, roads and tjunctions all look the same, so it's not very easy for me to navigate here. &lt;br /&gt;&lt;br /&gt;I've been in other small cities in CA and it's the same for them too. Well, landscapes might be different for different cities, but in one city it's very easy to miss streets.&lt;br /&gt;&lt;br /&gt;There's no explicit borders between cities. You walk on the street, walk over the road and you're already in a different city! It's unusual, because in Russia if you want to get from one city to other you'll have to spend at least 30 minutes riding on a car and you will see very large signs like "city X ends here", "city Y starts here".&lt;br /&gt;&lt;br /&gt;People here like to ask you stuff like "how are you doing?" and so on, while they don't really care and I dunno why do they ask that stuff, in Russia people just don't care about you and don't ask such things. It looks like that in small cities like Fremont people prefer to stay at home after work because there's few people on the streets after 6-7pm, though maybe they just ride somewhere or something like that, I dunno. I've noticed the same in Palo Alto as well.&lt;br /&gt;&lt;br /&gt;However, there are a lot of people in San Francisco, a lot of freaks here as well ;) and it's nice. In the centre of San Francisco I've seen a slowly riding old american car (dunno the model) on large chrome wheels and loud hip-hop sounds and serious looking persons inside of it. Looked impressive, just like in a movies =)&lt;br /&gt;&lt;br /&gt;Subject for the next post is food.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7738769158526865049?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7738769158526865049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/04/trip-to-us-part-1-general-impression.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7738769158526865049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7738769158526865049'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/04/trip-to-us-part-1-general-impression.html' title='Trip to US, part 1 - general impression'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-7844096502007689381</id><published>2009-04-24T12:07:00.000-07:00</published><updated>2009-04-24T12:10:09.894-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gutsy'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>ubuntu gutsy sources.list</title><content type='html'>Decided to install some stuff on ubuntu gutsy server today and found that sources.list is outdated. It was pretty hard to find working sources.list and that's the one I've found that works fine:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;deb http://old-releases.ubuntu.com/ubuntu/ feisty main restricted universe multiverse&lt;br /&gt;deb http://old-releases.ubuntu.com/ubuntu/ feisty-updates main restricted universe multiverse&lt;br /&gt;deb http://old-releases.ubuntu.com/ubuntu/ feisty-security main restricted universe multiverse&lt;br /&gt;deb http://old-releases.ubuntu.com/ubuntu/ feisty-backports main restricted universe multiverse&lt;br /&gt;deb http://old-releases.ubuntu.com/ubuntu/ feisty-backports main/debian-installer&lt;br /&gt;deb-src http://old-releases.ubuntu.com/ubuntu/ feisty-backports main restricted universe multiverse&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-7844096502007689381?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/7844096502007689381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/04/ubuntu-gutsy-sourceslist.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7844096502007689381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/7844096502007689381'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/04/ubuntu-gutsy-sourceslist.html' title='ubuntu gutsy sources.list'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-6025551379291867809</id><published>2009-04-07T10:01:00.000-07:00</published><updated>2009-04-07T10:57:52.728-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bike'/><category scheme='http://www.blogger.com/atom/ns#' term='nontech'/><category scheme='http://www.blogger.com/atom/ns#' term='health'/><title type='text'>Bike, Health and stuff</title><content type='html'>I cannot say I was a sporty type from the childhood, but since the yearly age I've been spending a lot of time on the street and was playing soccer, basketball and other games all the time. It lasted until about 8th grade, then I changed school and a way of life a bit, I've started spending more time on computers and stuff and started to smoke and drink =) And I've started to attend gym as well. It's kinda strange combination and it resulted it gaining some strength and weight and decreasing overall stamina. &lt;br /&gt;&lt;br /&gt;Then I've entered the university and my lifestyle didn't change much: I was still spending a lot of time with computers and other time I was drinking (have tried almost every alco drinks during uni years ;]), though I quit smoking. And I was still attending gym. I did pretty well for an amateur, I did a bench press with about 105-110 kg while my own weight was about 95 kg or so.&lt;br /&gt;&lt;br /&gt;On the 3rd year of university I decided that I need more money than scholarship ;]. I've found a half-time job and was still attending most of the classes and gym, but it was kinda hard. Moreover, it turned out that halt-time job is really not very good due to various reasons, so I found other job, full time this time.&lt;br /&gt;&lt;br /&gt;So I've started working full time and was still attending most important classes. I've gave up on the gym, because I almost had no free time. However, I consider that's because I don't manage time well and it was still possible to find some room for such activities, but time management is a totally different subject and I will probably write about my problems with it later on. Oh, yeah, so I've left the gym. Then I bought a car, so I even separated myself from walking. Now I realize it wasn't very good, however the car allowed me to have some more free time.&lt;br /&gt;&lt;br /&gt;I've lived in such a mode for more than two years. I've started to realize that I feel bad without sport activities. I've gained some more weight (needless to say it wasn't a muscle weight ;]). The lack of physical activities made my stamina even more lower. Moreover, I was missing this wonderful pain that you feel after trainings.&lt;br /&gt;&lt;br /&gt;Last summer I've finally graduated. First few month I was really glad that I have a lot of free time and had no exams, tests and other annoying stuff so totally forgot about sport stuff. &lt;br /&gt;&lt;br /&gt;And just recently I've started to think about it. My first though was to start attending gym again. But then I decided that attending gym will just more increase weight (and I don't think it's good even it will be muscle weight this time) and lower stamina. I think it's possible to increase stamina by attending gym but it will be more effective to choose some more 'dynamic' physical loads.&lt;br /&gt;&lt;br /&gt;So, I've decided to by a bike. I had a bike when I was a child, it was a very simple bike, but I really enjoyed it, so I thought that bike is a great tool to get dynamic loads and increase stamina. Norco Bigfoot has became my bike of choice: it's pretty durable like most Norco bikes, has nice breaks and other stuff.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.trial-sport.ru/images/catalog/bigfoot_314109_328133.jpg"&gt;&lt;br /&gt;&lt;br /&gt;First impression: it feels pretty good. My area is a slight downhill (or uphill, depends on how you look at it ;]). I prefer to start uphill, so as soon as I get tired I could just ride back. Currently, I can do about 2-3 km uphill and then my legs get tired I have to move back. I guess it's a payment for my not balanced lifestyle during last few years. Anyway, I think I will ride 3 or 4 times a week and will increase the distance a little each time. Will see how it will go.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-6025551379291867809?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/6025551379291867809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/04/bike-health-and-stuff.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6025551379291867809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/6025551379291867809'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/04/bike-health-and-stuff.html' title='Bike, Health and stuff'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-5710909226147093060</id><published>2009-04-01T22:41:00.000-07:00</published><updated>2009-04-01T22:47:09.401-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'></title><content type='html'>&lt;a href="http://www.anthillpro.com"&gt;Anthill Pro&lt;/a&gt; CI server is a really strage thing. The tutorial is very lengthy, there are sooo much various links and buttons and menus in anthillpro UI so I still cannot figure out how to add a simple project. Seems waaayyyy too complicated. Maybe it's very powerful, however. Anyways. &lt;a href="https://hudson.dev.java.net/"&gt;Hudson&lt;/a&gt; seemed much easier to understand and manage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-5710909226147093060?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/5710909226147093060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/04/anthill-pro-ci-server-is-really-strage.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5710909226147093060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/5710909226147093060'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/04/anthill-pro-ci-server-is-really-strage.html' title=''/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-4055057398366173239</id><published>2009-03-22T11:57:00.000-07:00</published><updated>2009-03-22T12:44:27.728-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='с++'/><title type='text'>my weekend of debugging</title><content type='html'>I'm starting to learn C++. I've read 2 or 3 basic-level C++ books (really basic ones) and then decided to write some simple app. People who are more experienced with C++ suggest me to read books like EffC++ or smth like that and I will do it a bit later (as soon as I buy them) but I don't see how it should stop my experiments.&lt;br /&gt;&lt;br /&gt;About the app: it's a really basic one, a bit more than 2000 lines on code and about 10-15 classes, but it's the biggest thing I've ever done in C++. The app has a simple configuration file and uses libconfig to parse it. There's a wrapper class for libconfig I wrote to make it more simple. Last week I decided to convert it to singleton pattern and that I've started to see weird behavior: when I was reading the same config property more then once, it started to get corrupted (I was dumping config file after each read to stdout for debug purposes). I decided that I've somehow triggered some hidden libconfig problem so I wrote a simple standalone app to reproduce the problem. To my surprise, my standalone app was working like a charm.&lt;br /&gt;&lt;br /&gt;Then I've decided to try to debug this issue with gdb. The only command I've used in gdb before is 'bt' and really it was enough for me to catch problems in my or other people' C programs. So I learned how to set breakpoints and add watches, learned how to run apps in step-through mode and maybe other stuff. It turned out to be quite convenient and simple to use gdb so I'll use it in feature instead of using 'printf-technique' =) But, alas, gdb didn't help. I've stepped through the program, stepped through libconfig but it didn't help, I didn't noticed what's the reason of segfault.&lt;br /&gt;&lt;br /&gt;I've remembered that there's an app called valgrind and people say it's extremely useful. As I'm running FreeBSD, I looked for it in the ports collection. But, alas, valgrind port runs only on FreeBSD &lt;8 (and I run -CURRENT) and only on i386 (I have amd64 here). So I had to ask a person using linux to help and he provided me an output quickly. I've read "getting started" guide on valgrind site and figured out what's wrong with my app in 5 minutes (it was a malloc problem, but in totally unrelated class o_O).&lt;br /&gt;&lt;br /&gt;So I've spent about 2 days and then fixed the bug in 5 minutes.&lt;br /&gt;&lt;br /&gt;The lessons learned are:&lt;br /&gt;1. gdb is a nice and simple tool easy to use and it's better than "printf-technique", so it worth to read some basic guide on gdb &lt;br /&gt;2. valgrid seem to be a powerful tool and it looks like if some non-obvious problem occurs it makes sense to try it's memcheck tool first and then go to gdb or other stuff. It' sad, however, that it doesn't work on FreeBSD/amd64 -CURRENT. I'm not sure how to workaround this issue since I don't want to change os on my desktop. OTOH, I have an i386 laptop, so I'll probably install FreeBSD/i386 7.0 there or maybe some Linux.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-4055057398366173239?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/4055057398366173239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/03/my-weekend-of-debugging.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4055057398366173239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/4055057398366173239'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/03/my-weekend-of-debugging.html' title='my weekend of debugging'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8086027361681461014.post-961440870683263621</id><published>2009-03-21T10:43:00.000-07:00</published><updated>2009-03-21T10:52:35.086-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thoughts'/><title type='text'>first post, yay</title><content type='html'>So I've created _another_ blog. I've had (and still have) a twitter account and realized it's fun to have such a thing because you can write various stuff which is only interesting for you and at the same time train an English. But twitter is not the best service for it because it limits post length to 140 chars or something like that, which is obviously not enough for a good rant.&lt;br /&gt;&lt;br /&gt;Other funny thing about twitter is that it looks like companies follow twitter results, probably they subscribe to search results on google, or something like that, but once you write something like "$product suck!" somebody who represents "$product" starts following you and I don't feel like I like it.&lt;br /&gt;&lt;br /&gt;So let's see what's going on here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8086027361681461014-961440870683263621?l=empt1e.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://empt1e.blogspot.com/feeds/961440870683263621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://empt1e.blogspot.com/2009/03/first-post-yay.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/961440870683263621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8086027361681461014/posts/default/961440870683263621'/><link rel='alternate' type='text/html' href='http://empt1e.blogspot.com/2009/03/first-post-yay.html' title='first post, yay'/><author><name>empt1e</name><uri>http://www.blogger.com/profile/05480927125413977720</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
