lauantai 30. lokakuuta 2010

Puppet on Centos 5.5

I've been fooling around with cobbler and puppet, and I had a lot of problems when trying to get puppet running on Centos 5.5

In short, puppet supports version 1.8.6 of Ruby and ActiveRecord 2.1

Use version 1.8.6. I tried following versions without luck.
- 1.8.5 didn't support activerecord, or so I thought. Should have tried to install older version of activerecord
- 1.9.1, 1.8.7 from sources, puppet doesn't support and they don't tell you clearly what version of ruby is supported
- 1.8.6 worked, but newest activerecord doesn't support -> use active record 2.1 (gem install activerecord -v 2.1 after you've installed rubygems)

The dependency to version 1.8.6 seems to be because "exec" -function in somewhere in Ruby or in its default libraries has changed in x.z.1 release..

Dependencies for compiling ruby:
-openssl, openssl-devel
-zlib-devel, comes with openssl-devel
Just yum install openssl openssl-devel

Compiling ruby
-get sources from ftp://ftp.ruby-lang.org//pub/ruby/1.8/ruby-1.8.6.tar.gz
- ./configure && make
- make install
Install rubygems
-Just get sources from http://rubygems.org/pages/download, untar and run "ruby setup.rb"

Get puppet and facter as gems from http://puppetlabs.com/downloads/gems/
- gem install facter-x.y.z.gem
- gem install puppet-x.y.z.gem

Create user "puppet" and group "puppet"
- For me, puppetmasterd --mkusers failed when doing this, but it was because I had ruby 1.8.7 installed.
Run puppetmasterd --no-daemonize --verbose

Running puppetmasterd should create necessary configuration directories.

Using ssh to contact guest operating system in VirtualBox

From manual, page 82 '6.3.1 Configuring port forwarding with NAT'
VBoxManage modifyvm "VM name" --natpf1 "guestssh,tcp,,2222,,22"
--natpf1 is the number of interface used for NAT'ing between host and guest operating system. After this you can just 'ssh -l username_on_guest -p 2222 hostsystem'

torstai 28. lokakuuta 2010

Why Scrum sucks

Most backlogs contains a lot of waste as a inventory and in waiting. There's a lot of stories, some of which will never be implemented.

Fixed length of sprints. implementation of features isn't prioritized just for their value, but also for their size (it fits into the sprint). Fixed length sprints can also force into splitting of features which doesn't actually add any value.

Implementation of Scrum usually begins with a training session and then with "by-the-book" -implementation. This is usually a extreme change to previous work processes. Better way might be use value stream mapping and actually find out what the process is currently, and then decide what is the smallest step we can take to make it better.

So called continuous improvement, which actually is just phased improvement. It happens every two weeks, not continuously.

The value stream map for worst case if implementation goes right shows pretty well how much waste and waiting is involved in Scrum:

Idea
 |
 |
Backlog
 |
 |
Planning session (First prioritization)
 |
 |
Sprint (Idea sits in backlog)
 |
 |
Planning session (not important enough)
 |
 |
Sprint (Idea sits in backlog)
 |
 |
Planning session(made to be more important)
 |
 |
Sprint (Story sits in backlog)
 |
 |
Planning session (Didn't fit into sprint, splitted and designed)
 |
 |
Sprint (Do first half of splitted feature)
 |
 |
Planning session (do the rest)
 |
 |
Sprint

What phases did actually add value? How long did it take to from idea to release?

There's a lot good in Scrum, I wont deny it. It gives a clear structure for development and you don't have to think what you do in the beginning, you just try to implement the process. You'll probably fail, but that's life.

lauantai 9. lokakuuta 2010

Process models, methodologies and majority

When things are written down, they become laws. I've been in situations where I've been told that "you're not following the documented procedure." Reason for this was sometimes that I forgot, and sometimes it was because I thought that the documented procedure was not valid. Only thing is that in some of those situations I wrote that documented procedure. Of course, I've should've updated the documentation. But this shows how written word becomes the truth, something you cannot change.

This is one of the reasons why many software process implementations fail. They are following standardized process model, which they will follow blindly, even if they do not work on their situation.

When new process model or methodology emerges, innovators and Early Adopters usually understand the meaning and possibilities of new methodologies. They understand that the new thing might not work for them, and they are willing to try and able to modify it. Majority will check what innovators and early adopters have done, and then implement it like it's business as usual. And in this point, things will start to go downhill. Most of the majority will fail in implementation, because they wont adapt the methodology and process model.

While I was writing this post, I happened to read a blog post which was titled "How Good Becomes the Enemy of Great". It manages to say a lot more clearly what I'm trying to say here. There are no silver bullets, you must keep your eyes open and adapt to your own situation.

tiistai 28. syyskuuta 2010

Kent Beck on Software Engineering Radio

I just listened two different podcasts, an interview of Kent Beck at Software Engineering Radio and episode 1.0.3: Problems on "This Developer's Life". Few points which stuck into my mind while listening:

First on SE-Radio
- Scope of tests is something you have to decide yourself. TDD is not about unit testing. This means that you have to think about on what level you should write your tests. They can be acceptance tests, integration tests, unit tests or something else.

- Every test has costs and benefits. Costs are usually short term, and biggest benefits come on long term. So if you're doing some explorative coding, tests are not something you must write, because you might throw that code away before you can reap the benefits. But you've got to bite the bullet at some point, if you continue to use that code. So Beck isn't zealot on TDD.

-Software development is moving towards continuos deployment, and testability will become more and more important. Automated testing will become comparable to compiler, it'll give you feedback immediately.

On Problems episode, best quote was something like "Not all bugs need to be resolved". This meant that some bugs are in completely unnecessary features, so you'd be better if you threw away that troublesome feature.

Overall, both podcasts were great.

sunnuntai 19. syyskuuta 2010

Engineering management at Facebook

Yishan Wong has written a great article about engineering management at Facebook. You can read it at http://algeri-wong.com/yishan/engineering-management.html.

Some quick thoughts about some of the major points

1. Hiring is number one
I couldn't agree more. This is one point which has come up on http://manager-tools.com/ podcasts. They say pretty much the same thing: every manager should constantly look for new hires in his/hers networks. One reasons is that you don't want to be in situation where you have to hire someone, which can happen when you get a new project. That forces you to just get best one from the available candidates, whether he/she is good enough. But just like Voltaire said, "The perfect is the enemy of the good".

2. Let process be implemented by those who practice it
In Toyota Production System this is called "standardized work". But standardized doesn't mean standard. The process is constantly improved by its users, and standardization is used mainly for metrics (http://en.wikipedia.org/wiki/Takt_time). It's funny how written word becomes a word of god so easily.

3. Promotion from within
One thing missing here is how external recruiting can effect to motivation. If there's a motivated and ambitious person in organization and he/she would like to move forward on his career, it's a pretty big hit to his/hers motivation if someone from outside gets that job he/she would've wanted.

lauantai 18. syyskuuta 2010

Use normal class as message receiver in Scala

I constantly encounter the following problem when writing Scala.

If you want to use normal class as receiver for messages, you have to remember to import Actor._. Otherwise compiler will complain:


error: not found: value self

Following should print "Success"

import actors.Actor
import actors.Actor._
class Example {
case class Message(sender: Actor)
val receiver = actor {
  react {
    case Message(s: Actor) => sender ! true; exit();
  }
}

receiver ! Message(self)

self.receiveWithin(100) {
  case true => println("Success")
  case false => println("Failure")
}
}


I've been using this kind of "pattern" when testing message based communication between objects. It seems to be working pretty well, but tweaking of that timeout is important.

tiistai 14. syyskuuta 2010

MySQL changes foreign key names

Just spent few hours debugging database conversion scripts, and bumped into a "little" bug in MySQL.


CREATE TABLE `test1`(
`id` integer NOT NULL,
PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;


CREATE TABLE `test2` (
`id` integer NOT NULL,
`id2` integer DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IX_test_1` (`id`),
CONSTRAINT `FK_1` FOREIGN KEY (`id2`) REFERENCES `test1` (`id`) ) ENGINE=INNODB DEFAULT CHARSET=latin1;


INSERT INTO test2 (id, id2) VALUES (1, 44);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`test2`, CONSTRAINT `FK_1` FOREIGN KEY (`id2`) REFERENCES `test1` (`id`))


ALTER TABLE test2 DROP FOREIGN KEY `FK_1`;
ALTER TABLE test2 ADD FOREIGN KEY `FK_1` (`id2`) REFERENCES `test1` (`id`);


INSERT INTO test2 (id, id2) VALUES (1, 44);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`test2`, CONSTRAINT `test2_ibfk_1` FOREIGN KEY (`id2`) REFERENCES `test1` (`id`))

Somehow foreign key named FK_1 changed into test2_ibfk_1..

torstai 15. huhtikuuta 2010

Rollback with Hudson and Maven?

I've been thinking about implementing rollback with Hudson and Maven. Our projects consists of multiple subprojects which are packaged into .war -files. If these were deployed into Maven repository, it would be possible to use Hudson's "redeploy" artifacts to deploy older versions. After this, you could have a job in Hudson which does the actual deployment to application server.

If that deployment job had dependencies to the .war -files, Hudson might actually spot these changes and do the deployment job automatically after redeploy. I definitely have to check this out.

keskiviikko 7. huhtikuuta 2010

(Almost) Continuous deployment with Gerrit and Hudson

Here's a somewhat simplified workflow for continuous deployment when working with Gerrit and Hudson.


As you can see, features are deployed into Beta server instead of production server. This is mandatory when working with corporate clients, they don't want to have real continuous deployment.

keskiviikko 31. maaliskuuta 2010

Integrating Gerrit with Hudson, part 2

After long time of useless pondering, I finally managed to write and publish Gerrit plugin for Hudson. You can find more information about if from http://wiki.hudson-ci.org/display/HUDSON/Gerrit+Plugin .

To use it, you still need to wait for next version of Hudson's Git plugin to be released, because current version might take something like an hour to resolve what to build. Reason for this is that Gerrit uses branches for change sets. As a result, there's a lot of branches and Git plugin tries to find merge bases for every one of them.