Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about linux

A week using tiling windows.

It has been a lit­tle over a week since I com­mit­ted to us­ing a tiling win­dow man­ag­er.

Sure, I am cheat­ing be­cause I am ac­tu­al­ly still us­ing KDE plus Kröhnkite but my win­dows are tiled and I am lik­ing it a lot.

Why this and not i3 or what­ev­er? Be­cause I don't want to change my lifestyle, I just want my win­dows to not over­lap gen­er­al­ly.

Kröhnkite pro­vides enough tiling func­tion­al­i­ty that I get (I think) the ben­e­fits with­out the mas­sive up­heaval of giv­ing up ev­ery­thing I am used to in my desk­top. I still use the Win­dows Key (ok, ok, the "Meta" key) to launch app­s. I still have a plas­ma pan­el with plas­moids at the bot­tom of my mon­i­tor, I can still float the win­dows if I want to! I can still use most of the short­cuts from my past 24 years us­ing KDE (yes, re­al­ly) and so on.

What are some things I had to change to adap­t?

  • I had to change to fo­­cus-­­fol­lows-­­mouse. BUT for the first time since I start­ed us­ing FVWM in 1993 I am lik­ing fo­­cus-­­fol­lows-­­mouse bet­ter than click­­-­­to-­­fo­­cus. It turns out KDE's im­­ple­­men­­ta­­tion of it is quite nice and al­­most "does what I mean". As it says in the doc­s, "like click to fo­­cus, but just don't click­­".

  • I re­­moved win­­dow dec­o­ra­­tion­s. Yes, you can keep them, but they feel out of place.

  • I set thick­­er win­­dow bor­der­s. Re­­siz­ing win­­dows via short­­­cuts is just not nice in gen­er­al, so thick­­er bor­ders help.

What are some things I have liked?

  • Fixed tiling lay­out in one mon­i­­tor and float­ing in the oth­­er is awe­­some when need­ed. And I can get it in place with one key­­press! So, in gen­er­al, dy­­nam­ic, sep­a­rate lay­outs for each screen is very, very use­­ful.

  • Hav­ing a "til­ing" wm that still re­spects most WM con­ven­­tions is good. So, pop­ups float. Yay.

  • The Al­t+En­ter short­cut to make a win­dow the "im­por­tan­t" one is neat.

  • Love how max­i­miza­­­tion/min­i­miza­­­tion work­s.

What are some things I have not liked?

  • The "tiled" lay­out has mul­ti­­ple ver­­sions you can switch be­tween with Ctr­l+I/D ... and well, some­­times none of them is ex­ac­t­­ly what I wan­t? Al­­so, the high­­er num­bered ones on­­ly are use­­ful when you have many win­­dows tiling, and if you don't they don't do any­thing.

  • Since I have no win­dow dec­o­ra­tions, the bru­tal in­con­sis­ten­cy on ap­p-quit­ting short­cuts is an­noy­ing. It can be ctr­l+q or ctr­l+x or esc or what­ev­er. I end up do­ing al­t+f4 which feels like win­dows 3.11.

  • The UX of KWin scripts is a bit lack­­ing. I in­­stalled an­oth­er one a while ago, called Quar­ter-Til­ing, and I have re­­moved ev­ery trace of it from my sys­tem... ex­­cept for its short­­­cut­s, which will ap­­par­en­t­­ly pol­­lute my con­­fig di­alogs for­ev­er.

So, ex­per­i­ment will con­tin­ue!

(Sor­ry, the video is in span­ish)

The Minimal Server

I was a sysad­min for a long time. I did that for mon­ey, so I nev­er re­al­ly want­ed to spend time do­ing the same thing in my own time, which lead to a se­vere case of cob­bler's chil­dren walk­ing bare­foot in my pri­vate serv­er.

So, to­day at lunch, I de­cid­ed to clean up my garbage. So this is what I end­ed up with, which is the min­i­mal serv­er that is good enough to be gen­er­al­ly use­ful for me.

Hosting

This is a cheap VPS pro­vid­ed by the nice folks at burst.net who are not giv­ing me any­thing to speak nice things about their ser­vice. How­ev­er, I will do it any­way:

  • Crazy cheap ($5.50 but I have a 20% dis­­­count for life)

  • Good amount of mon­th­­ly band­width

  • Lots of disk space

  • Good up­­­time

  • Fast net­­work

  • Very cheap

  • De­­cent per­­for­­mance

Distribution

I had Cen­tOS 5 in­stalled, and it stays. If burst ev­er starts of­fer­ing Ubun­tu Pre­cise, I may switch. Or, since this work­s, I may not.

What's good about Cen­tOS? It's sta­ble and bor­ing.

What's bad about Cen­tOS? It's too bor­ing. Lots of cool stuff just is­n't pack­aged.

Web Server

I need to serve a bunch of do­main­s, but I have a pe­cu­liar­i­ty: they are all stat­ic sites. I wan­t:

  • Low re­­source us­age

  • De­­cent per­­for­­mance (that most­­ly in­­­volves sup­­port­ing ranges and con­­tent ne­­go­ti­a­­tion)

  • Sta­ble

  • Sup­­port di­rec­­to­ry in­­dex­es

  • Easy con­­fig­u­ra­­tion

  • Vir­­tu­al do­­mains by name

Al­most any serv­er works well for this. Even Apache, ex­cept for the easy con­fig­u­ra­tion bit. I end­ed up with gatling be­cause it fits those cri­te­ria fair­ly well.

  • It us­es about 1.4MB of RAM , which is al­ways nice in a VPS

  • It's pret­­ty fast

  • Has not crashed in 2 hours?

  • Sup­­ports in­­dex­es

  • Here's the con­­fig­u­ra­­tion: "-c /s­rv/www -P 2M -d -v -p 80 -F -S" (yes, there is no con­­fig file at al­l)

  • Vir­­tu­al do­­mains are just fold­ers and sym­links in­­­side /s­rv/www which is the eas­i­est pos­sil­ble way to do it.

  • It sup­­ports re­­verse prox­­y­ing for when I want to try a python web app I am work­ing on.

Mail Server

No, I don't want a mail serv­er. I have gmail and/or a re­al mail serv­er for that. I want to get the mails from cron. For this, I used ssmtp and an ex­tra gmail ac­coun­t. It work­s, and here's the whole con­fig:

root=roberto.alsina@gmail.com
mailhub=smtp.gmail.com:587
UseTLS=YES
UseSTARTTLS=YES
AuthMethod=LOGIN
AuthUser=roberto.alsina.3@gmail.com
AuthPass=notputtingthetrueoneheredude

The best I can say about this con­fig­u­ra­tion is that it work­s, and does­n't in­volve run­ning a dae­mon.

Misc

For when I need to be in two places at the same time: Open­VPN rules, and there is no ar­gu­men­t. I have a squid run­ning oc­ca­sion­al­ly, and there is a Quas­sel core for IRC stuff. I in­stalled mosh to make ssh less painful, rsync han­dles file de­ploy­ment and back­up stor­age, cron sched­ules stuff, and that's it.

Status

Plen­ty of free RAM and CPU (yes, that's the full process list):

[root@burst1 ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1   2156   664 ?        Ss   22:01   0:00 init [3]
root      1135  0.0  0.1   2260   576 ?        S<s  22:01   0:00 /sbin/udevd -d
root      1518  0.0  0.1   1812   572 ?        Ss   22:01   0:00 syslogd -m 0
root      1594  0.0  0.1   7240  1032 ?        Ss   22:01   0:00 /usr/sbin/sshd
root      1602  0.0  0.2   4492  1112 ?        Ss   22:01   0:00 crond
root      1630  0.0  0.1   5684   716 ?        Ss   22:01   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a pam -n 2
root      1631  0.0  0.0   5684   444 ?        S    22:01   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a pam -n 2
root      1636  0.0  0.2   3852  1372 ?        S    22:01   0:01 /opt/diet/bin/gatling -c /srv/www -P 2M -d -v -p 80 -F -S
root      1677  0.0  0.2   4284  1232 ?        Ss   22:02   0:00 SCREEN /root/quasselcore-static-0.7.1
root      1678  0.0  2.1  36688 11148 pts/0    Ssl+ 22:02   0:03 /root/quasselcore-static-0.7.1
root      3228  1.0  0.7  12916  4196 ?        Ss   23:28   0:13 mosh-server new -s -c 8
root      3229  0.0  0.3   3848  1588 pts/2    Ss   23:28   0:00 -bash
root      3275  0.0  0.1   2532   908 pts/2    R+   23:48   0:00 ps aux
[root@burst1 ~]# w
 23:49:03 up  1:47,  1 user,  load average: 0.00, 0.01, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/2    186.153.52.253   23:28    0.00s  0.01s  0.00s w
[root@burst1 ~]# free
             total       used       free     shared    buffers     cached
Mem:        524800      49100     475700          0          0          0
-/+ buffers/cache:      49100     475700
Swap:            0          0          0

All things con­sid­ered, fair­ly hap­py with the re­sult.

Ubuntu One APIs by Example (part 1)

One of the nice things about work­ing at Canon­i­cal is that we pro­duce open source soft­ware. I, specif­i­cal­ly, work in the team that does the desk­top clients for Ubun­tu One which is a re­al­ly cool job, and a re­al­ly cool piece of soft­ware. How­ev­er, one thing not enough peo­ple know, is that we of­fer damn nice APIs for de­vel­op­er­s. We have to, since all our client code is open source, so we need those APIs for our­selves.

So, here is a small tu­to­ri­al about us­ing some of those APIs. I did it us­ing Python and PyQt for sev­er­al rea­son­s:

  • Both are great tools for pro­­to­­typ­ing

  • Both have good sup­­port for the re­quired stuff (D­Bus, HTTP, OAu­th)

  • It's what I know and en­joy. Since I did this code on a sun­­day, I am not go­ing to use oth­­er things.

Hav­ing said that, there is noth­ing python-spe­cif­ic or Qt-spe­cif­ic in the code. Where I do a HTTP re­quest us­ing Qt­Net­work, you are free to use lib­soup, or what­ev­er.

So, on to the nuts and bolt­s. The main pieces of Ubun­tu One, from a in­fra­struc­ture per­spec­tive, are Ubun­tu SSO Clien­t, that han­dles us­er reg­is­tra­tion and login, and Sync­Dae­mon, which han­dles file syn­chro­niza­tion.

To in­ter­act with them, on Lin­ux, they of­fer DBus in­ter­faces. So, for ex­am­ple, this is a frag­ment of code show­ing a way to get the Ubun­tu One cre­den­tials (this would nor­mal­ly be part of an ob­jec­t's __init__):

# Get the session bus
bus = dbus.SessionBus()

:
:
:

# Get the credentials proxy and interface
self.creds_proxy = bus.get_object("com.ubuntuone.Credentials",
                        "/credentials",
                        follow_name_owner_changes=True)

# Connect to signals so you get a call when something
# credential-related happens
self.creds_iface = dbus.Interface(self.creds_proxy,
    "com.ubuntuone.CredentialsManagement")
self.creds_proxy.connect_to_signal('CredentialsFound',
    self.creds_found)
self.creds_proxy.connect_to_signal('CredentialsNotFound',
    self.creds_not_found)
self.creds_proxy.connect_to_signal('CredentialsError',
    self.creds_error)

# Call for credentials
self._credentials = None
self.get_credentials()

You may have no­ticed that get_­cre­den­tials does­n't ac­tu­al­ly re­turn the cre­den­tial­s. What it does is, it tells Sync­Dae­mon to fetch the cre­den­tial­s, and then, when/if they are there, one of the sig­nals will be emit­ted, and one of the con­nect­ed meth­ods will be called. This is nice, be­cause it means you don't have to wor­ry about your app block­ing while Sync­Dae­mon is do­ing all this.

But what's in those meth­ods we used? Not much, re­al­ly!

def get_credentials(self):
    # Do we have them already? If not, get'em
    if not self._credentials:
        self.creds_proxy.find_credentials()
    # Return what we've got, could be None
    return self._credentials

def creds_found(self, data):
    # Received credentials, save them.
    print "creds_found", data
    self._credentials = data
    # Don't worry about get_quota yet ;-)
    if not self._quota_info:
        self.get_quota()

def creds_not_found(self, data):
    # No credentials, remove old ones.
    print "creds_not_found", data
    self._credentials = None

def creds_error(self, data):
    # No credentials, remove old ones.
    print "creds_error", data
    self._credentials = None

So, ba­si­cal­ly, self­._­cre­den­tials will hold a set of cre­den­tial­s, or None. Con­grat­u­la­tion­s, we are now logged in­to Ubun­tu One, so to speak.

So, let's do some­thing use­ful! How about ask­ing for how much free space there is in the ac­coun­t? For that, we can't use the lo­cal APIs, we have to con­nect to the server­s, who are, af­ter al­l, the ones who de­cide if you are over quo­ta or not.

Ac­cess is con­trolled via OAuth. So, to ac­cess the API, we need to sign our re­quest­s. Here is how it's done. It's not par­tic­u­lar­ly en­light­en­ing, and I did not write it, I just use it:

def sign_uri(self, uri, parameters=None):
    # Without credentials, return unsigned URL
    if not self._credentials:
        return uri
    if isinstance(uri, unicode):
        uri = bytes(iri2uri(uri))
    print "uri:", uri
    method = "GET"
    credentials = self._credentials
    consumer = oauth.OAuthConsumer(credentials["consumer_key"],
                                   credentials["consumer_secret"])
    token = oauth.OAuthToken(credentials["token"],
                             credentials["token_secret"])
    if not parameters:
        _, _, _, _, query, _ = urlparse(uri)
        parameters = dict(cgi.parse_qsl(query))
    request = oauth.OAuthRequest.from_consumer_and_token(
                                        http_url=uri,
                                        http_method=method,
                                        parameters=parameters,
                                        oauth_consumer=consumer,
                                        token=token)
    sig_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
    request.sign_request(sig_method, consumer, token)
    print "SIGNED:", repr(request.to_url())
    return request.to_url()

And how do we ask for the quo­ta us­age? By ac­cess­ing the http­s://one.ubun­tu.­com/api/quo­ta/ en­try point with the prop­er au­tho­riza­tion, we would get a JSON dic­tio­nary with to­tal and used space. So, here's a sim­ple way to do it:

    # This is on __init__
    self.nam = QtNetwork.QNetworkAccessManager(self,
        finished=self.reply_finished)

:
:
:

def get_quota(self):
    """Launch quota info request."""
    uri = self.sign_uri(QUOTA_API)
    url = QtCore.QUrl()
    url.setEncodedUrl(uri)
    self.nam.get(QtNetwork.QNetworkRequest(url))

Again, see how get_quo­ta does­n't re­turn the quo­ta? What hap­pens is that get_quo­ta will launch a HTTP re­quest to the Ubun­tu One server­s, which will, even­tu­al­ly, re­ply with the da­ta. You don't want your app to block while you do that. So, QNet­workAc­cess­Man­ag­er will call self­.re­ply_fin­ished when it gets the re­spon­se:

def reply_finished(self, reply):
    if unicode(reply.url().path()) == u'/api/quota/':
        # Handle quota responses
        self._quota_info = json.loads(unicode(reply.readAll()))
        print "Got quota: ", self._quota_info
        # Again, don't worry about update_menu yet ;-)
        self.update_menu()

What else would be nice to have? How about get­ting a call when­ev­er the sta­tus of sync­dae­mon changes? For ex­am­ple, when sync is up to date, or when you get dis­con­nect­ed? Again, those are DBus sig­nals we are con­nect­ing in our __init__:

self.status_proxy = bus.get_object(
    'com.ubuntuone.SyncDaemon', '/status')
self.status_iface = dbus.Interface(self.status_proxy,
    dbus_interface='com.ubuntuone.SyncDaemon.Status')
self.status_iface.connect_to_signal(
    'StatusChanged', self.status_changed)

# Get the status as of right now
self._last_status = self.process_status(
    self.status_proxy.current_status())

And what's sta­tus_changed?

def status_changed(self, status):
    print "New status:", status
    self._last_status = self.process_status(status)
    self.update_menu()

The pro­cess_s­ta­tus func­tion is bor­ing code to con­vert the in­fo from sync­dae­mon's sta­tus in­to a hu­man-read­able thing like "Sync is up­-­to-­date". So we store that in self­._last_s­ta­tus and up­date the menu.

What menu? Well, a QSys­tem­Tray­I­con's con­text menu! What you have read are the main pieces you need to cre­ate some­thing use­ful: a Ubun­tu One tray app you can use in KDE, XFCE or open­box. Or, if you are on uni­ty and in­stall sni-qt, a Ubun­tu One app in­di­ca­tor!

http://ubuntuone.com/7iXTbysoMM9PIUS9Ai4TNn

My Ubun­tu One in­di­ca­tor in ac­tion.

You can find the source code for the whole ex­am­ple app at my u1-­toys project in launch­pad and here is the full source code (miss­ing some icon re­sources, just get the re­po)

Com­ing soon(ish), more ex­am­ple app­s, and cool things to do with our APIs!

$HOME is where .bashrc is

I have a con­fes­sion to make. For the last year or so, my main op­er­at­ing sys­tem has been Win­dows 7. Yes, I know, it may come as a shock to some, spe­cial­ly if you have read this which is my post that had most hits in a day ev­er.

How did that hap­pen? What hap­pened to me? What was I think­ing? It's a bor­ing and un­in­ter­est­ing sto­ry.

I joined Canon­i­cal. My old note­book would­n't cut it. My new one would not take Ubun­tu with­out a fight. I said "hey, I will live in a VM!". The VM was dead­ly slow. I had to de­vel­op win­dows soft­ware (yes). Some stuff would not work right on the VM. And slow­ly, things just start­ed pil­ing up in the bare-met­al OS, which was, yes Win­dows 7 Home Pre­mi­um.

As a whole, Win­dows 7 is not hor­ri­ble. Most things work well. What it is, is a desert for a de­vel­op­er. Sure, you can get a plant to grow there, but you have to put a lot of ef­fort in­to it.

So, to­day I in­stalled Kubun­tu Oneir­ic (ab­so­lute­ly no prob­lem now!), gath­ered all the da­ta from the old note­book, the VM, the win­dows in­stal­la­tion, delet­ed win­dows, and moved in­to Lin­ux again, and made Win­dows the VM.

I missed it.

Android on x86: report

Since I ex­pect An­droid on tablets to be a big thing in 2010, I am ex­per­i­ment­ing with the clos­est thing I can get: An­droid in my eee 701 Surf 4G:

SDC14690

I got the test­ing An­droid 2.0 im­age from http://an­droid-x86.org. I had the 1.6 "stable" one but it was... well, it worked aw­ful (half the key com­bos or menu op­tions caused it to crash, re­boot or oth­er­wise au­to­com­bust).

So... how is it work­ing? Slow, but it has po­ten­tial!

The bad:

  • It boots quite fast... but my tricked full Arch Lin­ux in­­stall boots faster.

  • It works sloooooow, you can see in­­di­vid­u­al let­ters when you type in the search gad­get. I read this is a tem­po­rary prob­lem, though.

  • I am get­t­ing a "cas­­trat­ed" ex­pe­ri­ence be­­cause the open an­­droid app stores are not as well stocked as the of­­fi­­cial an­­droid mar­ket­­place (and come on, why the heck can't I get free apps from there???)

    I see ob­vi­ous holes in the app land­s­cape that I sup­­pose are well cov­­ered in the mar­ket (like, is there a Ra­­dio­­Tray re­­place­­men­t?)

    No text ed­i­­tor?

    No semi-de­­cent word pro­ces­­sor? Not even one that gen­er­ates HT­M­L?

  • The web brows­er is pa­­thet­ic. It may be nice for a phone, but for a "re­al" sys­tem? It's aw­­ful. You get the mo­­bile ver­­sions of all sites (ob­vi­ous­­ly) and many don't let you switch to the re­al ones! (even google does that, for Google Read­­er), and of course, no flash.

  • The email app is ter­ri­ble. You can't not-­­top-­­post!!!! "In-Re­­ply-­­To" is of­f-spec!

  • The WiFi set­t­ings are way too hid­­den. They should pop if you click on the wifi icon.

The good:

  • It shuts down in­­­cred­i­bly fast.

  • Some apps are quite nice, spe­­cial­­ly the Aldiko book read­­er is awe­­some (and I can share the ePub books with fbRead­­er on the arch lin­ux side.

  • The in­­­clud­ed SSH client has great ideas.

  • I love the "all your da­­ta is in the SD" ap­proach. I do the same thing with Lin­ux. In fac­t, I have the same ex­act da­­ta or­­ga­ni­za­­­tion now on both OSs :-)

  • The home screen with the slid­ing app draw­er: nice

  • The "grab­bable" sys­tem no­ti­­fi­­ca­­tions on the top bar: very nice

  • The "use the menu key to get the menu" thing? ge­nius ;-)

  • The "ev­ery­thing fullscreen all the time", thing? works on this screen.

  • App in­­stal­la­­tion is a solved prob­lem here.

  • I know I will be able to get Qt work­ing na­­tive... can't wait!

I am not sold yet, Arch is just so much faster right now, and it can do so much more, but...

  • I am get­t­ing a touch­screen for it, so I can ex­pe­ri­ence it more the way it's meant to be ex­pe­ri­enced.

  • I am us­ing it a lot to read at night in bed (Just fin­ished Mak­ers, read it, it's cool!).

  • I am us­ing it for ca­­su­al mail read­­ing (I refuse to re­­ply with that bro­ken ap­p).

  • It's a pret­­ty nice alarm clock, so it's be­­com­ing my bed­­side OS.

I'll write an­oth­er re­port once I have the touch screen or a new (hope­ful­ly faster!) ver­sion run­ning.


Contents © 2000-2020 Roberto Alsina