For home-grown modules that have grown organically, you are likely to have at least some site-specific data mixed in with the code. Before publishing, you’ll need to abstract this out. I recommend using parametrised classes with sane defaults for your inputs. If necessary, you can have a local wrapper class to pass site-specific values into your module.

The vast majority of Puppet modules are on GitHub, but this isn’t actually a requirement. GitHub offers public collaboration and issue tracking, but you can keep your code wherever you like.

Before you can publish, you need to include some metadata with your module. Look at the output of puppet module generate. If you’re starting from scratch, this command is an excellent place to start. If you’re patching up an old module for publication, run it in a different location and selectively copy the useful files into your module. The mandatory files are metadata.json and README.md.

When you’re ready to publish, run puppet module build. This creates a tarball of your module and metadata which is ready to upload to Puppet Forge.

Create an account on Puppet Forge and upload your tarball. It will automatically fill in the metadata.

GitHub is an excellent tool for code-sharing, but it has the major disadvantage of being fully public. You probably don’t want to put your confidential stuff and shared secrets in there! You can pay for private repositories, but the issue still stands that we shouldn’t be putting confidential UoB things in a non-approved cloud provider.

I briefly investigated several self-hosted pointy-clicky Git interfaces, including Gitorious, Gitolite, GitLab, Phabricator and Stash. They all have their relative merits but they all seem to be a total pain to install and run in a production environment, often requiring that we randomly git clone something into the webroot and then not providing a sane upgrade mechanism. Many of them have dependencies on modules not included with the enterprise Linux distributions

In the end, the easiest-to-deploy option seemed to be to use the GitLab Omnibus installer. This bundles the GitLab application with all its dependencies in a single RPM for ease of deployment. There’s also a Puppet Forge module called spuder/gitlab which makes it nice and easy to install on a Puppet-managed node.

Copy the RPM to a local web-accessible location as a mirror, and use this as the location for the gitlab_download_link class parameter

This seems to have allowed it to work fine!(Caveat: I had some strange behaviour with whether it would run the gitlab instance correctly, but I’m not sure if that’s because of left-overs from a previous install attempt. Needs more testing!)

We wanted to find out what sort of devices are active on the wireless network, and the vendor tools we’ve got don’t quite give us the level of detail we were after.

However, everything which hits our wireless network gets a DHCP lease from our dhcp servers. With a bit of dhcpd.conf magic, you can make it profile each client when it requests or renews a lease and record a fingerprint in the logs.

Now every time a device interacts with our DHCP server, we get a FINGERPRINT line appearing in our logs along with the mac address which requested the lease.

So far, so good. Now we need to process those logs into something anonymous, but meaningful.

Data Prep
The easiest approach is to cat our logfile, strip out just the fields we’re interested in (mac address and fingerprint) then sort them to remove duplicates (we only want to count each machine once!) and then finally throw away the mac addresses (because all we really want are the fingerprints)

There are probably more elegant ways to do it, but the above isn’t really the interesting bit. All you get out of it is a list of fingerprints. The magic is in converting those into something meaningful.

Chewing on your fingerprints
To process, identify and count these fingerprints, we need the help of the fingerbank project who have collected DHCP fingerprints from all over the place.

So here’s a slightly shonky perl script to parse the config file and produce a CSV summary of the output. This is probably not as elegantly done as it could be, please don’t judge too harshly! I’ve tried to make it readable, but some of the datastructures are a bit on the deep side. If you want to see what’s going on, make plenty of use of “Data::Dumper” – I know I had to when writing it.

It assumes dhcp_fingerprints.conf is in the same folder as the script, and expects to be fed fingerprints over STDIN one line at a time – so you can stick it on the end of the pipeline I mentioned earlier.

If I let that chew on a decent chunk of todays logs (from about 7am to 2pm) it spits out the following:

Class

OS

Count

Smartphones/PDAs/Tablets

Samsung Galaxy Tab 3 7.0 SM-T210R

39

Home Audio/Video Equipment

Slingbox

49

Dead OSes

OS/2 Warp

1

Gaming Consoles

Xbox 360

6

Windows

Microsoft Windows Vista/7 or Server 2008

1694

Printers

Lexmark Printer

1

Network Boot Agents

Novell Netware Client

1

Macintosh

Mac OS X Lion

2783

Misc

Eye-Fi Wireless Memory Card

1

Printers

Kyocera Printer

1

unknown

unknown

40

Smartphones/PDAs/Tablets

LG Nexus 5 & 7

1797

Printers

HP Printer

54

CD-Based OSes

PHLAK

1

Smartphones/PDAs/Tablets

Nokia

13

Smartphones/PDAs/Tablets

Motorola Android

2

Macintosh

Mac OS X

145

Smartphones/PDAs/Tablets

Generic Android

2989

Gaming Consoles

Playstation 2

1

Linux

Chrome OS

39

Linux

Ubuntu/Debian 5/Knoppix 6

5

Routers and APs

Cisco Wireless Access Point

69

Linux

Generic Linux

7

Linux

Ubuntu 11.04

21

Windows

Microsoft Windows 8

1792

Routers and APs

Apple Airport

2

Routers and APs

DD-WRT Router

3

Smartphones/PDAs/Tablets

Sony Ericsson Android

1

Linux

Debian-based Linux

51

Smartphones/PDAs/Tablets

Symbian OS

2

Storage Devices

LaCie NAS

27

Windows

Microsoft Windows XP

30

Smartphones/PDAs/Tablets

Android Tablet

24

Monitoring Devices

Tripplite UPS

1

Smartphones/PDAs/Tablets

Apple iPod, iPhone or iPad

12289

Smartphones/PDAs/Tablets

Samsung S5260 Star II

2

Smartphones/PDAs/Tablets

RIM BlackBerry

63

I’m not sure I 100% believe the above (OS/2 Warp? Really?) but the bits I disbelieve are largely in the noise.

Chewing on the above stats a bit, shows us that the wireless network is roughly 27% laptops and 72% mobile devices (tablets etc). Amongst the laptops, Windows is just about in the lead with 53%, and OSX is close behind at 44% (which is probably higher than a lot of people think) Linux laptops are trailing behind at only 2%.

The mobile device landscape is less evenly split, with 71% iOS and 28% Android.

Although I wouldn’t read too much into the above analysis, as it represents a comparatively small time slice (and only 23775 of the 37000 devices we see on the wireless each week)

Who knows, perhaps we’ve got 13K windows phones owned by people who just don’t come onto campus on a Monday…

Update 2015-05-11: I’ve been asked under what license I’ve released the perl script in this post. I didn’t put any thought into licenses at the time (I was just trying to solve a problem and answer a question I’d been asked!) but I’ll put my hand up, part of the script is based on prior-art.

As I understand it, under the terms of the GPLv2 license, that means that the script above should also be distributed under the GPLv2 license (which I’m OK with) and that under the terms of that license it should be distributed along with a copy of the GPLv2 license… which can be found here: https://www.gnu.org/licenses/gpl-2.0.html