RPM packages for Toggl Desktop client

I use the toggl time-tracking service to keep track of the hours I work for my various clients.

toggl make available desktop clients for Windows, Mac, & Linux, but the Linux packages are in .deb format for Ubuntu and, until recently, they did not provide x86_64 packages.

toggl recently released the desktop client as open source so I grabbed it and have built an RPM.

SRPM: TogglDesktop-2.5.1-1.fc12.src.rpm

RPM (Fedora 12, x86_64): TogglDesktop-2.5.1-1.fc12.x86_64.rpm

Dell OMSA on CentOS 5.4 x86_64 – No Controllers found error

It seems that several people have been having problems getting Dell OMSA 6.2 to work correctly on CentOS 5.4 x86_64. Specifically, the software does not detect any storage controllers, and therefore also doesn't find any disks. eg.

[root@b034 ~]# omreport storage pdisk controller=0
Invalid controller value. Read, controller=0
No controllers found.

After a little investigation, I found the source of the problem.

It turns out that the i386 package of compat-libstdc++-33 is required, although it's not pulled in as a dependency by the srvadmin-whatever RPM.

yum install compat-libstdc++-33.i386
service dataeng restart

Now, the same command works just fine:

[root@b034 ~]# omreport storage pdisk controller=0
List of Physical Disks on Controller PERC 6/i Adapter (Slot 1)

Controller PERC 6/i Adapter (Slot 1)
ID                        : 0:0:0
Status                    : Ok
Name                      : Physical Disk 0:0:0
etc.

Building RPMs from Ruby gems

I often need to deploy Ruby gems across many CentOS servers. I prefer to use the native OS package management tools (rpm + yum) rather than using Ruby gems.

Here's how to build RPMs from Ruby gems using gem2rpm.

I am assuming you have the necessary build tools installed (if not, yum install rpmdevtools) and have already created an RPM build environment, eg:

~/rpmbuild
|-- BUILD
|-- RPMS
|-- SOURCES
|-- SPECS
`-- SRPMS

First, make sure gem2rpm is installed:

yum install rubygem-gem2rpm

Then, grab the gem you want to convert to an RPM:

cd ~/rpmbuild/SOURCES
gem fetch capistrano

This will dump the gem file in the current directory, in this case: capistrano-2.5.14.gem.

Next, create a spec file:

gem2rpm capistrano-2.5.14.gem  > ../SPECS/rubygem-capistrano.spec

Finally, build the RPM(s):

rpmbuild -ba ../SPECS/rubygem-capistrano.spec

Useful date command format string

When creating backups or log files, I like to name the files with a timestamp, ie. the date plus the time.

I use the date command to produce timestamps in the appropriate format, but I find the format specifier a bit long-winded and difficult to remember – is %m minutes or month?

There is a better way… date -I

To make the strings sort in a sane manner, I find it best to use a format with the timestamp elements in descending order of size, eg. YYYYMMDDhhmmss which is produced with a format specifier like this:

# date +%Y%m%d%H%M%S
20100202130818

But as I've mentioned, I find that to be a pain to remember. Wouldn't it be great if there was a single switch that produced a suitable timestamp format?

Well, it turns out that there is:  --iso-8601 or -I, with the seconds modifier:

# date -Iseconds
2010-02-02T13:07:40+0000

According to NEWS in the coreutils distribution:

  date accepts the new option --rfc-3339=TIMESPEC.  The old --iso-8602 (-I)
  option is deprecated; it still works, but new applications should avoid it.
  date, du, ls, and pr's time formats now support new %:z, %::z, %:::z
  specifiers for numeric time zone offsets like -07:00, -07:00:00, and -07.

The –rfc-3339 option is similar, but it includes a space in the output, which I prefer to avoid:

# date --rfc-3339 seconds
2010-02-02 13:16:10+00:00

So, I'll be continuing to use -Iseconds

Writing puppet manifests that can remove resources as well as adding them

I use puppet to manage the configuration of the machines I manage. So far, I've been rolling out new resources to machines but recently I've wanted to remove resources from machines. Here's how I modified my cron classes so I could remove cron jobs as well as create them.

When I first wrote my cron classes, I created a separate class for each cron job, eg.

class app::queue_processor::cron::cacheload {

    include
        user::base

    cron { cacheload:
        command => '/usr/bin/php /app/queue_processor/utils/cacheload.php account > /dev/null 2>&1',
        hour    => '0',
        minute  => '0',
        user    => 'app',
        require => User['app']
    }

}

I then created another class for each profile which includes all the required cron jobs, eg:

class profile::partition::cron {
    include
        app::queue_processor::cron::cacheload
        app::queue_processor::cron::send_move_backlog
}

This all works fine and the cron jobs are installed as required. However, I recently needed to remove the cacheload cron job from all machines.

This is simply a matter of specifying "ensure => absent" to the cron type. I therefore needed some way of passing this to the cron job classes.

I did this by creating a higher-level cron class, app::queue_processor::cron containing a definition app::queue_processor::cron::job which takes an ensure parameter that defaults to "present" if not specified. It looks like this:

class app::queue_processor::cron {}
define app::queue_processor::cron::job($ensure = present) {

    include user::base

    case $name {
        cacheload: {
            cron { $name:
                command => '/usr/bin/php /app/queue_processor/utils/cacheload.php account > /dev/null 2>&1',
                hour    => '0',
                minute  => '0',
                user    => 'app',
                require => User['app']
                ensure  => $ensure
            }
        }

        send_move_backlog: {
            cron { $name:
                # similar cron definition here
            }
        }

        default: { fail("Unknown queue_processor cron job type: $name") }
    }
}

I use this new define in the profile::partition::cron class like this:

class profile::partition::cron {
    include app::queue_processor::cron
    app::queue_processor::cron::job{ send_move_backlog: }
    app::queue_processor::cron::job{ cacheload: ensure => absent }
}

Count of denied connections with iptables

In my iptables configurations, I generally allow all traffic I am interested in and deny the rest, logging anything that is denied.

I found that this can get a bit noisy with loads of connections to udp:137 and udp:500, etc. so I decided to deny the more common ports without logging. But which are the most common ports?

A typical log line looks like this:

Jan 12 09:42:01 b003 kernel: FAILSAFE -- DENY IN=bond0 OUT= MAC=00:26:b9:3d:fb:18:00:d0:c0:52:88:00:08:00 SRC=115.177.32.129 DST=a.b.c.d LEN=40 TOS=0x00 PREC=0x00 TTL=46 ID=22118 PROTO=TCP SPT=6643 DPT=20480 WINDOW=0 RES=0x00 ACK RST URGP=0

I wrote this perl one-liner to count no. of packets blocked per port:

perl -e 'while(<>) {if ($_ =~ /PROTO=([^ ]+).*DPT=([^ ]+)/) {$proto=$1 ; $port=$2; $count{"$proto:$port"}++}} foreach $key (sort { $count{$b} <=> $count{$a} } keys %count) {print "$key: $count{$key}\n"}' /var/log/messages | head -10

Sample output:

UDP:137: 226619
UDP:500: 107056
UDP:33436: 25244
UDP:33435: 22203
UDP:33437: 16035
TCP:20480: 10782
TCP:30080: 8291
UDP:33438: 8162
UDP:33439: 7268
UDP:33440: 5885

Seeing available updates in svn repository

I've used subversion for quite a while now – I vaguely remember using CVS when working with some Sourceforge projects, but most of my experience is with subversion.

I've used the command svn status (or svn st, for short) to show me what changes there are in my working copy. However, I've occasionally thought it would be nice to see what updates are available in the repository but I've never bothered to find out how to do it. Until now…

To see what updates are available in the repository, simply use:

svn status --show-updates

or

svn st -u