Friday, 10 May 2013

juju switch

The switch command has recently landed in trunk, and will be included in the next juju-core release.

juju switch is another way to specify the current working environment. Current precedence for environment lookup still holds, but this now sits between the JUJU_ENV environment variable and the default value in environments.yaml.

If you have multiple environments defined, there are several different ways to tell juju which environment you mean when executing commands.

Prior to switch, there were three ways to specify the environment.

The first and default way to specify the environment is to use the default value in the environments.yaml file.  This was always the fallback position if one of the other ways was not specified.

Another way was to be explicit for some commands, and use the -e or --environment command line argument.


$ juju bootstrap -e hpcloud



There is also an environment variable that can be set which will override the default specified in the environments.yaml file.


$ export JUJU_ENV=hpcloud
$ juju bootstrap          # now bootstraps hpcloud
$ juju deploy wordpress   # deploys to hpcloud



The switch option effectively overrides what the default is for the environments.yaml file without actually changing the environments.yaml file. This means that -e and the JUJU_ENV options still override the environment defined by switch.


$ juju help switch
usage: juju switch [options] [environment name]
purpose: show or change the default juju environment name
 
options:
-l, --list  (= false)
    list the environment names
 
Show or change the default juju environment name.
 
If no command line parameters are passed, switch will output the current
environment as defined by the file $JUJU_HOME/current-environment.
 
If a command line parameter is passed in, that value will is stored in the
current environment file if it represents a valid environment name as
specified in the environments.yaml file.
 
aliases: env



It works something like this:


$ juju env
Current environment: "amazon-ap"
$ juju switch
Current environment: "amazon-ap"
$ juju switch -l
Current environment: "amazon-ap"

Environments:
        amazon
        amazon-ap
        hpcloud
        openstack
$ juju switch amazon
Changed default environment from "amazon-ap" to "amazon"
$ juju switch amazon
Current environment: "amazon"
$ juju switch
Current environment: "amazon"



If you have JUJU_ENV set, then you get told that the current environment is defined by this.  Also if you try to use switch to change the current environment when the environment is defined by JUJU_ENV, you will get an error.


$ export JUJU_ENV="amazon-ap"
$ juju switch
Current environment: "amazon-ap" (from JUJU_ENV)
$ juju switch amazon
error: Cannot switch when JUJU_ENV is overriding the environment (set to "amazon-ap")


 

Wednesday, 17 April 2013

The Go Language - My thoughts

I've been using the Go programming language for almost three months now pretty much full time. I have moved from the Desktop Experience team working on Unity, into the Juju team. One of the main reasons I moved was to learn Go. It had been too long since I had learned another language, and I felt it was better to dive in, than to just mess with it on my own time.

A friend of mine had poked around with Go during a hack fest and blogged about his thoughts. This was just before I really started poking around. Interestingly the main issues that Aldo found frustrating with the errors for unused variables and unused imports, I have found not to be such a big deal. Passingly griping, sure, but not a big issue. Having the language enforce what is often a lint checker in other languages I see as an overall benefit. Also, even though I don't agree with the Go formatting rules, enforced by gofmt, it doesn't matter. It doesn't matter because all code is formatted by the tool prior to commit. As an emacs user, I found the go-mode to be extremely helpful, as I have it formatting all my code using gofmt before saving. I never have to think about it. One thing I couldn't handle though, was the eight character tabs. Luckily emacs can hide this from me.

;; Go bits. 
(require 'go-mode-load)
(add-hook 'before-save-hook #'gofmt-before-save)
(add-hook 'go-mode-hook (lambda () (setq tab-width 4)))
 
There are some nice bits to Go. I very much approve of channels being first class objects, and the use of channels to communicate between concurrently executing code. Go routines are also nifty, although I've not used them too much myself yet. Our codebase does, but I've not poked into all the nooks and crannies yet.

However there are several things which irritate the crap out of me with Go.

Error handling

The first one I guess is a fundamental design decision which I don't really agree with. That is around error handling being in your face so you have to deal with it, as opposed to exceptions, which are all to often not thought about. Now if our codebase is in any way representative of Go code out there, this is just flat out wrong. The most repeated lines of code in the codebase would have to be:

if err != nil {
  return nil
}

This isn't error handling. This is just passing it up to the chain, which is exactly what exception propagation does, only Go makes your codebase two to three times larger due to needing these three lines after every line of code that calls into another function. This is one thing I really dislike, but unlikely to change.

As a user of a language though, there are other things that could be added at the language level to make things slightly nicer. Syntactic sugar, as it is often known, makes the code easier to read.

If the language is wanting to keep the explicit handling of errors in the current way, how about some sugar with that.

Instead of

func magic() (*type, error) {
    something, err := somefunc("blah")
    if err == nil {
        return nil, err
    }
    otherThing, err := otherfunc("blah")
    if err == nil {
        return nil, err
    }
    return foo(something, otherThing), nil 

 
we had some magic sugar, say a built-in method like raise_error, which interrogated the function signature, and returned zeroed values for all non-error types, and the error, and returned only non-error values, we could have this

func magic() (*type, error) {
    something := raise_error(somefunc("blah"))
    otherThing := raise_error(otherfunc("blah"))
    return foo(something, otherThing), nil 
}

The range function

There are several different issues I have with the range function.
  1. range returns one or two parameters, but the language doesn't allow any user defined functions to return one or two parameters, range is super special
  2. using range with a slice or array and getting a single value, doesn't give you the value, but instead the index - I never want this
  3. there is no way to define range behaviour for a user defined type
These three things are mostly equal in annoyance factor. I'd love to see this change.

No generics

Initially I accepted this as a general part of the language. Shouldn't be a big deal right? C doesn't have generics. I guess I spent too long with C++ then.
My first real annoyance was when I had two integers, and I wanted to find the maximum value of the two. I go to look in the standard library and find math.max. However that is just for the float64 type. The standard response from the team was "it is only a two line function". My response is "that's not the point".

Since there is no function overloading, nor generics, there is no way with the language at this stage to make a standard library function that determines the maximum value of two or more numeric types, and return that maximum in the same type as the parameters. Generics would help here.

A second case for generics is standard containers. The primary container in Go at this stage is the map. So many places in our codebase we have map[string]interface{}. The problem with this is that you have to cast all values retrieved from the map. There is also no set, multi_map, or multi_set. Since there is no way to provide simple iteration for user defined types, you can't easily define your own set type and have simple iteration using range.

Interfaces that aren't explicitly marked as being implemented help in some ways to provide features provided by generic types and functions, but it is a poor substitute.

So far...

Learning Go has been an interesting experience so far. I like learning new things, and I'm going to be using Go for some time now with the current project. No doubt I'll have more to write about later.

Tuesday, 27 March 2012

Unity 5.8 issues and workarounds

Well... with the release of Unity 5.8 and associated dependencies, we got the extra testing we were after in precise, and with it a number of bugs. The positive side to this is that with the extra information from our wonderful beta-testers we have been able to work out how to reproduce a number of the issues. As any developer would tell you, being able to reproduce your user's problems is often the biggest hurdle.

Over the weekend I noticed a number of issues around the release of Unity 5.8, and this morning while going through the bug reports, I was happy to notice that we had some way to work around most of them.

Unity 5.8: Flickering and corruption on Unity UI elements - a fix for many is "unity --reset". The cause appears to be how compiz is dealing with plug-ins that are no longer around. For some there have been plug-ins that existed with Oneiric that are no longer around in Precise, and the reset caused them to be removed from the list to load.

Unity 5.8: Login to blank screen (all black or just wallpaper) - some have been fixed by "unity --reset", but the underlying cause of this one is still a bit of a mystery.

Unity 5.8: Can't login to Unity since upgrade to 5.8 - some have found that disabling "Unity MT Grab Handles" compiz plug-in fixes this issue. We still need to work out what the underlying problem is.

white box randomly shows up at top left corner blocking applications from using stuff under it - this one appears to be triggered by chromium desktop notifications. There have been reports that disabling the animations plug-in in compiz, and then re-enabling it fixes this. We are still investigating why.

If you are getting these issues, you can try the workarounds suggested here.

Monday, 20 February 2012

Guilt reduction

So it is now Monday morning and I'm sitting next to Thomi.  We are going to pair program on this test stuff.  Partly because I think that pair programming is really cool, and partly due to Thomi knowing the autopilot test infrastructure really well, and that'll make this go much faster.

The bug in question related to the launcher getting into a very confused state where it thought there were multiple active applications.  And clicking on a launcher icon that was in this confused state caused a new application to be started rather than switching to the one that was running.

The first step in making all this work then, is to create a branch that is based off a revision that was before the fix.  This way we can write a test that fails first.  A key part of tests is to make sure they fail first.  Then when they start passing, you know it isn't by mistake, and that you have tested what you think, not just created something that passes.

Firstly, find that revision...

$ bzr log | less

The fix is revision 1977, so lets make a branch of trunk from revision 1976.

$ bzr cbranch trunk -r 1976 hud-ap-test
$ cd hud-ap-test/
$ bzr revno
1976


I use light weight checkouts for the unity repo, hence cbranch rather than branch.

At this revision, there is a HUD test that really just checks the reveal. Lets make sure it passes...

$ cd tests/autopilot/
$ python -m testtools.run autopilot.tests.test_hud
Tests running...
No handlers could be found for logger "autopilot.emulators.X11"

Ran 1 test in 4.238s
OK


I deleted a bunch of gtk warnings, they don't add any value for what I'm trying to show here.  Would be great if someone fixed them though :-)

Now I need to actually build and run my local unity (and test the autopilot test again).

Found out that my machine was failing to build for other reasons, so we switched to Thomi's.  The existing test still passed (of course it did), so the next step was to write a test that encapsulated the broken behaviour that we had found during the many hours of analysis.

That can be found at lp:~thomir/unity/autopilot-hud-triple-hit.

The test failed with the old revision, we then merged trunk, rebuilt, and ran the test again.  Test passed.  Job done.

Saturday, 18 February 2012

That guilty feeling

Today had been a frustrating day.  I had been quick to anger and my family bore the brunt of that. It wasn't until I was confronted with this that I actually took a minute to think why I was feeling this way.  It came back to something I read on IRC this morning, where I read that some people I deeply respect were disappointed with the test coverage with Unity 5.4.

I took this disappointment the way people often take it from their parents.  Remember when as a child, one of the worst things you could feel was the disappointment of your parents.  Well I guess that is how I felt.

I took over the engineering manager position of the unity team at the end of last year, and I tend to take criticism of the project and team personally.

So... why the guilty feeling?

Well, back around the time I took over managing the team, the general acceptance criteria for getting Canonical projects into Ubuntu changed.  This includes Unity.  There were a number of automated tests for Unity, and a series of distro acceptance tests that were manually executed.  What we needed to do was to really change the team culture to one where tests were not only written, but expected.  New features needed test coverage, bug fixes needed test coverage.  The idea here, for all those that understand test driven development, and automated testing, was to make sure that bugs that were fixed, and new features, didn't get broken accidentally by new changes.

The guilt really came from knowing that I had allowed code reviews through the process without enforcing the need for tests.  And that as a senior person on the team, others took a lead from what I did.  If I was letting things through, so would others.  This is where the feeling really came from.

It is very easy to land fixes to crashes quickly when under pressure.  Especially when you've spent the last eight hours debugging in gdb, and auditing all the recently landed code looking for that change that would contribute to the broken behaviour that you have been trying to fix.  When you finally find that one line fix, it is so tempting to just commit the one line.  You know it works, you've just spent the last freaking eight hours looking at the weird behaviour.  What you haven't done however, is stopped it from happening again, by encapsulating the behaviour in an automated test.

I plan to spend some of Monday going back and adding an automated test to cover the particular behaviour that we fixed the other day.  I'll also write up what, and how this test gets written.  Hopefully by writing this, not only will Unity get better test coverage, but I'll personally feel better knowing that I've done the right thing.

Sunday, 30 October 2011

6 months on Unity

We have just finished another design sprint prior to UDS-P.

While talking with some others I realise that I have worked on Unity for six months, and not changed a single pixel on the output.  No graphical changes, no moving widgets, no changing colours.

So what have I been doing?

First step was getting some new coding standards accepted by the team, which was much easier than I was expecting.

I added some property classes to nux, and did some general clean up in the code of nux and unity.

Refactored the indicator internals for the panel service which started off the shared unity core library for sharing code between the 2D and 3D code-bases.

Then I focused primarily on fixing memory leaks and crashes.

Once we hit final freeze, I did a little more refactoring internally, and now we are on to Precise Pangolin.

Monday, 11 July 2011

Properties in C++

Once you have done any development in a language that natively supports properties, like Python or C#, going back to C++ and not having them often feels like a real pain. I've just proposed my second attempt at C++ properties for the nux library.

This change leans heavily on a paper written by Lois Goldthwaite: SC22/WG21/N1615 - C++ Properties -- a Library Solution. I added change notifications using sigc++. I found that using sigc::slot was nicer than templating the properties on the class and member function pointer. This also meant that I could provide a way for a simple property to get its own custom setter method while still having a sensible default.

Compiling C++ templates still gives absolutely horrendous error message that can take a while to mentally parse. I guess one advantage of having done a lot of template programming in the past is that I don't get too phased by copious quantities of error messages, especially for templates, as for one example today, I had just forgotten to change a template arg in a test function, and got way too many lines to sensibly look at. One benefit of that was it caused me to look at what I was doing, and I ended up simplifying my tests a little more.

Thank you Lois for the time you spent writing up the C++ properties proposal, it was a fantastic starting point for me.