↓ Archives ↓

Category → git

puppet lsi hardware raid module

In response to some discussion in the gluster community, I am releasing my puppet-lsi module. It’s quite simple, but it is very useful for rebuilding machines. It could do a lot more, but I wanted to depend on the proprietary LSI tools as little as possible. Running megacli with puppet would be a very doable hack, but I’m not sure enough devops out there who would use that feature.

Usage is straightforward if you like the sensible defaults:

include lsi::msm

The general idea is that you’ve probably already setup all your “virtual drive” RAID configurations initially, and now you’re deploying your setup using cobbler and puppet-gluster. This puppet-lsi module should install all the client side LSI tools, and make sure monitoring for the hardware RAID is working. Megacli and all the (evil?) vivaldi framework stuff will be up and running after puppet has run.

I haven’t tested this on a wide array of hardware, and there might even be newer LSI gear on the market. Please don’t test it on production servers. If you want help with this, you might have to sponsor some hardware, or send me somewhere where I can hack on some, because I don’t have a gluster test rig at the moment.

I am curious to hear what kind of RAID you’re using with gluster. Hardware? Software? Details rock. SGPIO with mdadm, and you’re my hero. I want to hear about that!

https://github.com/purpleidea/puppet-lsi/

I hope this was useful to you, and in the meantime,

Happy hacking,

James

PS: The most useful feature of this module, is that it sets up monitoring of your RAID, and lets you access the management daemon through the now installed LSI services.


Code Inventory and Tracking Releases

You know by now that Code Inventory is something of an obsession with me. Like it or not, most of us, whether developers or sysadmins, work in a service industry. It’s fast and furious, and we don’t have time to build features that nobody wants. With sufficient test coverage, there’s no code that can’t be released within a day of pushing to the repository.

A couple of years ago, I showed you how to Visualize Small Batch Sizes with Git by plotting day-to-day the amount of changed source code lines that hadn’t yet been released to production. While this graph gave immediate feedback about the “drift” of development from operations (live), it’s not something easily digested by upper management. What do these guys really care about? It’s all about the releases silly!

Commits are “Units of Work”

Easily understood and very simple to calculate.
code inventory by release and git commits
Tracking number of code lines changed can easily be misleading with a copy/pasting, package refactoring or adding a new javascript library.

What was in the release?

Clicking on the release shows Pivotal Tracker stories worked on and the actual commit revision ID in github.
contents of release
The PT story types also give a good indication what the main work type was – user features, chores or bugfixes.

Cause and Effect

Now you’re able to show quite clearly to the organization how often you do releases (and even what your releasing). If tagging releases is ‘crawling’, then you are now at the ‘walking’ phase. What would it take to really stretch our legs out and get ‘running’?

Showing the impact of a release is the next logical step. Did you manage to grow traffic? Has the response time of the site improved? See any more bugs after the release? These are all fairly easy to track, and plotting them as a backdrop to the releases demonstrates the real impact your team is having on the bottom-line.

What other metrics make sense here? What would you expect to see? And what would really be kick ass? Share your thoughts on twitter using the #codeinventory hash tag!

puppet gluster module now in git

The thoughtful bodepd has been kind enough to help me get my puppet-gluster module off the ground and publicized a bit too. My first few commits have been all clean up to get my initial hacking up to snuff with the puppet style guidelines. Sadly, I love indenting my code with tabs, and this is against the puppet rules :(

I’ll be accepting patches by email, but I’d prefer discussion first, especially since I’ve got a few obvious things brewing in my mental queue that should hit master shortly.

Are you a gluster expert who’s weak at puppet? I’m keen to implement many of the common raid, file system and gluster performance optimization’s directly into the module, so that the out of box experience for new users is a fast, streamlined, experience.

Are you a puppet expert who knows a bit of gluster? I’m not sure what the best way to handle large config changes, such as expanding volumes, or replacing bricks is. I can imagine a large state diagram that would be very hard to wholly implement in puppet. So for now, I’m missing a few edge cases, but hopefully this module will be able to solve more of them over time.

I’ve included an examples/ directory in the repository, to give you an idea of how this works for now. Stay tuned for more commits!

git clone https://github.com/purpleidea/puppet-gluster.git

Happy hacking,
James


Puppet versioning like a pro

A big thanks to Atlassian for allowing me to post this series!!

There is NO reason, not to use a version control system while developing puppet manifest/modules. Stating that should be an open door. It allows you to go back in time, share things more easily and track your changes. There is a lot of information out there on how to work with git or any other system. But here a few tips that might help you developing modules:

Tip 1 : give each module it's own repo and use a superproject to join

In a lot of blogposts and even in the excellent Pro Puppet book I see people checking in their entire environment directory into version control.

I'm all for version control but if you manage your modules dir as one flat repository, you loose the way to easily update and share modules from the forge. In essence you are doing a copy that starts living it's own life.

The idea goes like this:

/etc/puppet/environments/development/modules (super-project repo)
  -- puppet-apache (sub-project repo)
  -- puppet-mysql (sub-project repo)
  ...

The super-project repo will contain links to the submodules it uses. This allows the reuse of the sub-project repos in different super-projects. F.i. puppet-modules-team1, puppet-modules-team2 could be superprojects and use different sub-modules.

Using Git

Git has the concept of submodules that allows you to link a parent repository with subprojects. Further detailed documentation can be found at http://book.git-scm.com/5_submodules.html

Using this approach with puppet is nicely described at https://we.riseup.net/riseup+tech/puppet-git-submodules, with some tips at https://labs.riseup.net/code/documents/7

I was always scared away of using submodules, because things like checking in the superproject first and forgetting the submodule, makes part of it unusable. Let alone adding the submodule directoy with a 'slash' has bitten me a few times.

It's a good approach but it requires being awake :)

Using Mercurial

At Atlassian we heavily use Mercurial version control. So I learned the power of Mercurial .

To create a development repo with a specific apache submodule

$ cd /etc/puppet/environments/
$ hg init development
$ cd development/
$ mkdir modules
$ echo 'modules/apache = [git]git://github.com/puppet-modules/puppet-apache.git' > .hgsub
$ hg add .hgsub
$ git clone git://github.com/puppet-modules/puppet-apache.git modules/apache
$ hg ci -mapache

Now if we are checking this out to our test environment, we'll see that it automatically checks out the submodules.

$ cd /etc/puppet/environments
$ hg clone development/ test
updating to branch default
resolving manifests
getting .hgsub
getting .hgsubstate
cloning subrepo modules/apache from git://github.com/puppet-modules/puppet-apache.git
remote: Counting objects: 177, done.
remote: Compressing objects: 100% (94/94), done.
remote: Total 177 (delta 59), reused 168 (delta 52)
Receiving objects: 100% (177/177), 22.97 KiB, done.
Resolving deltas: 100% (59/59), done.
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

I found this workflow:

  • less scary: no way to wrongly add directories
  • it's handy that you can add both svn, git and hg subrepositories
  • submodules are checked out by default (no git submodules init, update)

Note:

Tip 2: Think about your git workflow

In many of the examples you'll see people just commit to the 'master' branch. This works of course but if you are working on different modules/features, it's best to think about your git workflow. There are a lot of blogpost describing how to work in feature branches. Still I found it hard to remember the commands for branching, deleting old branches and so on.

Thanks to Tim Dysinger I learned about Gitflow.

It's basicly git helpers that take away a lot of the pain for working on hotfixes, features, releases. The usage is pretty easy:

# Create the master/developer/release/hotfix branches
$ git flow init

# Start working on a feature (branched from develop)
$ git flow feature start feature1
... do some work
$ git add ...somework...
$ git commit -m "somework feature1"

# This will merge feature1 back to develop
$ git flow feature finish feature1

# Now lets start a release
$ git flow release start release1
... do some work
$ git add ...somework...
$ git commit -m "release1"

# This will merge release1 into master
$ git flow release finish release1

The whole idea is described in details at http://nvie.com/posts/a-successful-git-branching-model/ . And the following video will show you how it works.

More information can also be found at:

Tip 3: Use pre/post-commit hooks

Even with the awesome editor support we previously described, it's still easy to miss a semi-column, or have an incorrect puppet syntax.

Using pre-commits

It's good practice to verify the syntax of your puppet manifests before comitting them to version control. This is well described on the puppetlabs version control page.

In essence before you commit, it will execute

puppet --parseonly
to check if the syntax is correct.

Using post-commits

A lesser used technique is to run the same check on post-commit:

Instead of running your master repository out of /etc/puppet/environment [PROD], you checkin to an intermediate repository [CHECK].

developer -> LOCAL REPO (pre-commit) -> push -> CHECK REPO -> (post-commit) -> PROD REPO

In the post commit you can:

  • also verify the syntax in case someone didn't check before commiting.
  • if all successfull push the repo to the PROD directories

This helps overcome the problem that your puppetmaster does a run while the repo is an incorrect state.

More details are described at Git workflow and Puppet Environments

More to come

The next post will be about different ways to test your puppet manifests

GitHub Puppet Face

I was looking at Jesse Newland’s excellent knife-github-cookbooks tool and thought that this would be an excellent tool to write for too. With the release of this is now incredibly easy to do. I created a tool called Puppet-GitHub-Face that allows you to install and compare from to in your Puppet module path.

Currently Puppet Faces are only supported in Puppet 2.7.0 and later (2.7.0 is currently an RC but will hopefully be out soon!) and distributing them requires placing them into Puppet’s load path. They’ll shortly be distributable as Puppet modules using pluginsync.

So to install the GitHub face for now clone the git repository:

$ git clone git://github.com/jamtur01/puppet-github-face.git

Copy the relevant files into your Puppet master’s path (for example on Debian/Ubuntu into a source-based install).

$ cp lib/puppet/application/github.rb /usr/local/lib/site_ruby/1.8/puppet/application/github.rb
$ cp lib/puppet/face/github.rb /usr/local/lib/site_ruby/1.8/puppet/face/github.rb

You can then see if the GitHub Face is installed like so:

$ puppet help

You should see the GitHub face listed in the available Puppet commands and you can now use it to install and compare installed modules. Let’s start with installing a module from Github, for example my puppet-httpauth module.

$ puppet github install --user jamtur01 --repo puppet-httpauth

This command will connect to GitHub, download the puppet-httpauth module and install it into your module path as the httpauth module (the Face automatically strips off prefix and suffix from a module, for example removing puppet-, puppet-module-, and -module from a repository name).

Warning! If a module of the same name is already in your path it’ll get deleted and replaced with this new module.

You can also compare the state of a currently installed module with its GitHub parent, like so:

$ puppet github compare --user jamtur01 --repo puppet-httpauth

This will return unified diff output showing any differences between the currently installed module and the module upstream on Github.

Hope someone finds this useful!

git, gitosis, gitweb and friends…

In case it wasn’t already obvious, I am a huge fan of git, and often prefer it over sliced bread. Recently to help a small team of programmers collaborate, I decided to setup a private git server for them to use. By no claim of mine is the following tutorial unique, however I am writing this to aid those who had trouble following other online tutorials.

Goal:
Setup a central git server for private or public source sharing, without having to give everyone a separate shell account.

Step 1:
Install git, gitosis, and gitweb by the method of your choosing. Most distributions probably have packages for all of these.

Step 2:
Create a user account named “git”, “gitosis”, or something sensible if it hasn’t already been done by some packagers install script. The shell command to do this yourself looks something like:

sudo adduser --system
--shell /bin/sh
--gecos 'git version control'
--group
--disabled-password
--home /srv/gitosis
gitosis

In my particular case, I edited the /etc/passwd file to change the automatically added account, however running sudo dpkg-reconfigure gitosis is probably an easier way to do this.

Step 3:
Authentication is done by public ssh key, and gitosis takes care of the magic relationships between a users key and the read/write access per repository. As such, gitosis needs initialization, and it needs the public key of the administrator. If you aren’t familiar with ssh public key authentication, go learn about this now.

To initialize gitosis most tutorials alledge that you should run something like:

sudo -H -u gitosis gitosis-init < SSH_KEY.pub

In my case, this didn’t work (likely due to environment variable problems, but try it first anyways) so I cut to the chase and ran:

sudo su - gitosis
gitosis-init < /tmp/SSH_KEY.pub

which worked perfectly right away. Note that you have to copy your public key to a publicly readable location like /tmp/ first.

Step 4:
Now it’s time to change the gitosis configuration file to your liking. Instead of editing the file directly on the server, the model employed is quite clever: git-clone a special repository, edit what’s necessary and commit, then push the changes back up. Once this is done, git runs a special commit-hook that generates special files needed for correct operation. The code:

git clone gitosis@SERVER:gitosis-admin.git

Step 5:
To add a new repository, and its users, into the machine, the obvious bits are done by making changes in the recently cloned git directory. Once a user has access, setup the new remote, and push.

git remote add origin gitosis@SERVER:the_repository_name.git
git push origin master:refs/heads/master

Subsequent pushes don’t need the master:refs/heads/master part, and everything else should function as normal.

Gitweb:
I still don’t have a happy gitweb+gitosis installation. I’m using apache as a webserver, and I wanted to leave the main /etc/gitweb.conf as unchanged as possible. The gitweb package that I installed, comes with an: /etc/apache2/conf.d/gitweb and all I added was:

SetEnv GITWEB_CONFIG /srv/gitosis/.gitweb.conf

between the <directory> braces. I used the template gitweb configuration file as provided by gitosis.

Gitosis:
The last small change that I needed for perfection is to store the gitweb configuration in the gitosis-admin.git directory. To do this, I added a symlink to /srv/gitosis/repositories/gitosis-admin.git/gitweb.conf from the above gitweb config location. The problem is that the file isn’t in the git repo. This would require patching gitosis to recognize it as a special file, and since the author doesn’t respond to patch offers, and since the gitweb config is usually completely static, I didn’t bother taking this any further.

Gitolite:
It seems there is a well maintained and more fine grained alternative to gitosis called gitolite. The author was very friendly and responsive, and it seems his software provides finer grained control than gitosis. If I hadn’t already setup gitosis, I would have surely investiaged this first.

Etckeeper:
If you haven’t yet used this tool, then go have a look. It can be quite useful, and I only have one addition to propose. It should keep a configurable mapping (as an etckeeper config file) with commands to run based on what gets updated. For example, if I update /etc/apache2/httpd.conf, then run /etc/init.d/apache2 reload.

Happy hacking!


Neat Git Reference

Rather than you having to wade through the Git documentation the nice people at GitHub have produced a neat reference for Git.

lecturing and git-bisect

I was recently asked to give a lecture for the PRELUDE series at McGill. Here was my abstract:

I don’t like computers, and neither should you.

We spend too much time figuring out how to talk to them, instead of having them figure out how to understand us.

There’s a big discontinuity between what software is providing, and the killer features we want!

We’re not completely lost though. There are a lot of good tools and methodologies available!

Until the feature gap closes, let me introduce you to some of these tools, and show you how I use the computer.

I spoke about a variety of topics with the intention of filling in everyone’s knowledge about the useful tools available to users and developers. I included a section about git-bisect and have posted the script in the examples section of the bash-tutor tarball. It is now available for you to download and share.

I hope everyone enjoyed the lecture, and I always appreciate feedback!