Akom's Tech Ruminations

Various tech outbursts - code and solutions to practical problems

Linux Maven toolchains and puppet

Posted by Admin • Monday, August 31. 2015 • Category: DevOps, Linux
For today's trick we'll be setting up maven toolchains.xml files on Jenkins slaves that are managed by puppet. One option for doing this is to use the Jenkins Config File Provider plugin - but all that really does is push a predetermined file to the slaves before running the job (now if it only worked together with the Jenkins tool provider data...) In our case, we have Jenkins slaves with different OS versions and thus different toolchain locations - for example, minor JDK releases differ across OS's and thus the paths are not the same.

Instead, the plan is to do two things:
  1. Create a puppet custom fact with installed tool info
  2. Use it from a puppet template
Here is how

Continue reading "Maven toolchains and puppet"

Linux Getting ETVnet.com to play video on Ubuntu

Posted by Admin • Friday, June 12. 2015 • Category: Linux
In Ubuntu 15.04 it already works in Firefox as long as you have vlc installed, and you select /usr/bin/vlc the first time Firefox asks you what to do. Not so much in Chrome... Chrome uses xdg-open to determine what to launch. By default, xdg-open has no idea what to do with a mms:// style URL, so we need to set up a protocol action in xdg, as per http://askubuntu.com/questions/190895/how-to-change-what-xdg-open-does-with-ssh-userip-liniks :
xdg-mime default vlc.desktop x-scheme-handler/mms

UPDATE: I find that vlc does not gracefully recover from eTVnet's "glitches" - sound stops playing but video continues. Surprisingly, Totem does not have this issue, so I swtiched:
xdg-mime default totem.desktop x-scheme-handler/mms

Linux Simple puppet update-alternatives

Posted by Admin • Thursday, June 11. 2015 • Category: DevOps, Linux
This is a quick and dirty interface to update-alternatives on Centos/Redhat/Ubuntu for puppet. Seems to work well and doesn't require any modules.
Usage example: alternatives_update { 'java': versiongrep => '1.8' }

class my_alternatives {

  # Manipulates alternatives using update-alternatives.
  # Supports RHEL, Centos and Suse.
  # Ubuntu not tested (yet).
  # If multiple matches are available, picks the first one.
  # There is rudimentary alternatives support in the java class,
  # but it's rather limited and doesn't support most platforms and java versions.
  define update (
    $item = $title,   # the item to manage, ie "java"
    $versiongrep,     # string to pass to grep to select an alternative, ie '1.8' (1.8.*openjdk would also work)
    $optional = true,  # if false, execution will fail if the version is not found
    $altcmd   = 'update-alternatives' # command to use
  ) {

    case $::osfamily {
      'RedHat','SuSE': {

        if ! $optional {
          # verify that we have exactly 1 matching alternatives, unless it's optional
          exec { "check alternatives for ${item}":
            path    => ['/sbin','/bin','/usr/bin','/usr/sbin'],
            command => "echo Alternative for ${item} version containing ${versiongrep} was not found, or multiple found ; false",
            unless  => "test $(${altcmd} --display ${item} | grep '^/' | grep -- '$versiongrep' | wc -l) -eq 1",
            before  => Exec["update alternatives for ${item} to ${versiongrep}"],

        # Runs the update alternatives command
        #  - unless it reports that it's already set to that version
        #  - unless that version is not found via grep
        exec { "update alternatives for ${item} to ${versiongrep}":
          path    => ['/sbin','/bin','/usr/bin','/usr/sbin'],
          command => "${altcmd} --set ${item} $( ${altcmd} --display ${item} | grep '^/' | grep -- '$versiongrep' | head -n 1 | sed 's/ .*$//' ) ",
          unless  => "test -x \"$(${altcmd} --display ${item} | grep 'currently points' | grep -- '$versiongrep' | awk '{print \$NF}')\"",
          onlyif  => "${altcmd} --display ${item} | grep '^/' | grep -- '$versiongrep' ", # check that there is one (if optional and not found, this won't run)


      # Leave Ubuntu alone, this probably won't work there anyway



Linux Getting a systemd unit to read your .bashrc file for its environment

Posted by Admin • Thursday, June 11. 2015 • Category: Linux
Although it'd be nice to have all of your services not rely on their shell environment, sometimes it is unavoidable. In my case, some of the systems are still on init.d (redhat <=65, centos <=65, etc), but some are on systemd (7.0's, suse 12, etc). The old init scripts rely on the .bashrc file. In order to make the service run consistently on both flavors, I had to teach systemd to read the user's bashrc file. This is what it looks like.

# Process the normal environment files for this user by starting a login shell
# and outputting it all in a temp file.  This makes it compatible
# with the non-systemd init scripts that still rely on .bashrc
ExecStartPre=/bin/bash --login -c 'env > /tmp/.magic-environment-file'
The "-" before the filename seems to make systemd ignore the error if the file is not there (for example, on the first run of the pre command). Now, obviously, you could just set your ~some-user/.bashrc as the EnvironmentFile - but your mileage will vary. systemd will not interpolate variables and it will ignore lines starting with "export"...

Continue reading "Getting a systemd unit to read your .bashrc file for its environment"

Code and Hacks QOS settings for pfSense - optimizing Google Hangouts and SIP

Posted by Admin • Monday, June 8. 2015 • Category: Code and Hacks
pfSense router configuration for Traffic Shaping is relatively convoluted if you're not already familiar with the interface. Assuming that you've used one of the wizards to create the default queues (default, ack, voip, p2p), what you have to do is:
  1. Set the upload bandwidth (Traffic Shaper->By Interface->WAN). This may be optional if using the default PRIQ mode
  2. Create a rule to match Google Hangouts traffic. According to this helpful post, the UDP ports hangouts uses are 19302-19309 (I'm assuming that outbound UDP is open). Therefore we create a new "match" type firewall rule with these ports as destination and assign them to the voip queue. Here is an example of a Floating rule to do that:
    Example Floating Rule
  3. For SIP (if you have SIP devices or softphones), you can make a Layer 7 rule (Traffic Shaper -> Layer 7) that assigns sip traffic to the voip queue
This is, of course, just a note for myself.

Linux Wifi doesn't work after resume from suspend in Ubuntu 15.04 (Dell Latitude E4310)

Posted by Admin • Sunday, May 17. 2015 • Category: Linux
Although toggling the hardware Wi-Fi switch usually fixed this issue, it was decidedly annoying for the non-technical user of this laptop. Googling for a well-known solution turned up several, but none of these worked. I found that either running
nmcli r wifi off
nmcli r wifi on
usually worked, so I tried to stick that into /etc/pm/sleep.d - but that script was never used. I then discovered that in 15.04 Ubuntu switched to systemd, which requires a service file in /etc/systemd/system/ In the end, it turns out that the problem is intermittent, therefore it is not possible to simply toggle networking blindly and hope for the best. Half the time it will not work. The ultimate solution turned out to be a combination of a toggle and a check, and both could be done via network manager, as follows:

Continue reading "Wifi doesn't work after resume from suspend in Ubuntu 15.04 (Dell Latitude E4310)"

Hardware Hacks Increasing capacity of the PetSafe Simply Clean Litter box

Posted by Admin • Tuesday, March 10. 2015 • Category: Hardware Hacks
Although I wrote a somewhat harsh review of the PetSafe Simply Clean Litterbox on Amazon, I still felt that there was some potential to this thing. What I wanted most from it was a very low maintenance experience, and having to empty the waste bin every 3 days simply didn't seem to qualify. When I go on vacation (and please don't start a neglect flame war over this) I leave the cats alone - monitored by 4 cameras, auto feeder, 5 gallon water dispenser and many litter boxes. I don't want to bother relatives with the long drive to come over just to clean cat poo, and my cats do not take well to being moved. Or to strangers. Or to basically anything besides the quiet at-home life that is exactly like yesterday.

Therefore, what I'm looking for is a larger waste bin. The litterbox doesn't handle capacity problems well - it backs up, jamming up against the chute cover, making a mess and eventually just shutting itself off. What I need to do is to create a jam-resistant path for the waste to go, somewhat like this patent here. The idea is good but it seems a bit too complex for my taste, and of course it is intended for a rectangular raking box like the LitterMaid. So, I chose to do the simplest and most reliable thing I could think of.

Continue reading "Increasing capacity of the PetSafe Simply Clean Litter box"

Linux Building RPMs for an older version of CentOS

Posted by Admin • Thursday, November 20. 2014 • Category: Linux
If you build RPMs on Centos 6.X (6.5 in my case) and then try to install them on Centos 5.X (5.10 in my case), bad things happen. Ironically, bad things happen even though my RPM contains a single jar file, and is thus entirely platform independent. Here is what I see:
Running rpm_check_debug
ERROR with rpm_check_debug vs depsolve:
rpmlib(FileDigests) is needed by my-rpm-1.0.x86_64
rpmlib(PayloadIsXz) is needed by my-rpm-1.0.x86_64
If you google for a solution, most people suggest running a virtual with Centos 5 just so you can build the RPMs, but this is apparently not necessary in this simple case, as you can simply specify a few flags. Basically, Centos 5 can't decompress the default archive format, and doesn't support the new digest algorithm.

Since I am using maven-rpm-plugin to build RPMs, my modifications look as follows:


                      <!-- skipping irrelevant items -->

                            <!-- don't strip jar files, it takes forever and is useless -->
                            <defineStatement>__os_install_post %{nil}</defineStatement>
                            <!-- for Centos6 -> Centos5 forwards compatibility -->
                            <defineStatement>_source_filedigest_algorithm md5</defineStatement>
                            <defineStatement>_binary_filedigest_algorithm md5</defineStatement>
                            <defineStatement>_source_payload w9.bzdio</defineStatement>
                            <defineStatement>_binary_payload w9.bzdio</defineStatement>

If you're using fpm or rpmbuild, you can just take these lines and make them %define's in your spec.

Linux Backing up cPanel 11 hosted account with wget and dav/rsync

Posted by Admin • Thursday, August 21. 2014 • Category: Linux
I want to back up my hosting account regularly by retrieving everything onto my box somewhere else (my home server). By regularly, I mean every day. I want this to happen automatically. cPanel makes that hard to do, but there is always a way to script things.

First, let's break down what we want to back up:
  1. Files
  2. Databases and email forwarders
Files are fairly easy. Obviously we don't want to use the full backup functionality of cPanel because we'd be transferring your entire storage space each and every time, even if nothing has changed. In order to do it efficiently, you have a few options:
  1. FTP account using recursive wget (create an FTP account with required access and teach an ftp client of your choice to recursively transfer everything. Hopefully this client skips unchanged files)
  2. WebDAV using rsync (this is what I'm using). Just mount, back up, unmount
Databases and Email stuff is not as easy, as we do have to log into cPanel. The trick to logging in to cPanel is:
  1. Submit your login to the log-in page and save cookies
  2. Parse the resulting file, find the backup link which includes your session name in the URL and hit that
  3. Only accept .gz files (DB backups and email stuff), but avoid hitting /logout, and don't start spidering the entire website
So, how do we do this? Here is the plan

Continue reading "Backing up cPanel 11 hosted account with wget and dav/rsync"

Bash completion for tmux multi-window like cssh/mssh

Posted by Admin • Monday, May 19. 2014
Although I normally use mssh for my multi-window SSH client, sometimes I work through an non-graphical SSH connection, and tmux really comes in handy. I've been using the ssh-multi script by D.Kovalov, but since I already have "clusters" files for cssh and mssh, I figured that it should be more convenient to use them by typing aliases. The script below is the result. )

This goes into /etc/bash_completion.d/tmuxmulti

Hope it helps

Continue reading "Bash completion for tmux multi-window like cssh/mssh"

Linux mssh Bash completion

Posted by Admin • Friday, February 28. 2014 • Category: Linux
Clusterssh (cssh) is great, but I was getting a little fed up with unmanageable terminal windows. They either go all over my monitors or get lost, and they are hard to move and resize.

So I switched to mssh, which solves all that because all the terminals are in one window.... but, it doesn't read my /etc/clusters file! In fact, nobody seemed to even know what file it does read.

What to do? First of all, for the record, it reads its aliases (-a) from ~/.mssh_clusters This file is exactly like /etc/clusters, except for a colon, like so:
alias1: host host host
alias2: host host host

Now that we got that straight, let's make a bash completion file

Continue reading "mssh Bash completion "

Low Tech Hacks Importance of Small Engine Preventative Maintenance for seasonal tools

Posted by Admin • Thursday, February 13. 2014 • Category: Low Tech Hacks

Lawmowers, snowblowers, chainsaws, generators, trimmers (even motorcycles) ... I have all of these, but, obviously, they are used seasonally. That means that they spend a fair amount of time sitting around. While most preventative maintenance advice tends to focus on the maintenance of frequently used engines, I find that it is the stored machines that get overlooked. Therefore:

Preventing In-Storage Problems in just 2 steps

  1. Stabilize Your Fuel

    While people will tell you that gasoline doesn't usually break down, that's not true in my experience. After sitting around in your carburetor for a few months, the fuel does and will separate. The issue here is that one part of it will literally varnish the surfaces, either sticking moving parts together, or restricting flow. The result? Popping, backfiring, or an engine that will only run with the choke on (if it runs at all). The only solution is to take the carb apart and clean everything - perhaps even changing the seals and needle seat. In the ideal world you'd have no fuel in the carburetor at all during storage, but since you're unlikely to get it all out, this is the next best thing.

    In other words:
    • Simply add fuel stabilizer of your choice (eg Stabil) to gasoline the day you buy gasoline, and use only treated gas in seasonally used engines.
    • When you shut off the engine before storage (or any time), let it run out of fuel - either shut off the valve, or use up what's in the tank if you have no valve.

  2. End-of-season Oil Change

    Oil absorbs byproducts of combustion, which are acidic. The more the engine runs, the more acidic the oil becomes. This acidic medium, coupled with 6 months in storage means corrosion risk to all the lubricated engine surfaces.

    In other words:
    • Simply change the oil when the season is over - spring for snowblowers, fall for lawnmowers, etc.
      Warm up the engine, let it run out of fuel (see above), then change the oil. Don't start it again before storage.

That's it - you'll have years of reliable service from your engines. It's amazing how many people overlook these two steps that can and do prevent so many issues. I used a trashed lawnmower for 8 more seasons after I found it by following these steps. I've had my snowblower 12 years and it always starts on the first pull. Speaking of snowblowers, see also how to change oil without making a mess.

But wait, what about spark plugs? Air filters?

In my experience, on occasionally used engines, spark plugs never actually wear out. They can get fouled from improper carburetor adjustment or over-priming, but when the system is functioning properly - a good quality plug might outlast the engine. Go ahead and change it if it makes you feel better, but I've run my lawnmower weekly on the same plug for 8 seasons and it still looks and works just fine. As for air filters - that's another story, but their maintenance has nothing to do with seasonal use. Every once in a while it's good to check that the filter is clean enough to let some air through and that it's not torn so it's not letting dirt into the carb. Otherwise, I tend to leave them alone.

Ubuntu 13.10, Dell M4700 and Enlightenment E17 on dual monitors

Posted by Admin • Wednesday, November 20. 2013
I've been waiting a long time for E17 to become stable... and it has. But installation is not without quirks on this Dell Precision laptop. Everything works fine with a single display, but dual, or dual external monitors is not so simple.

  1. There is a choice of 3 video drivers (see Update Manager->Hardware Drivers). The open source driver is great for an environment like XFCE or LXDE, but E17 simply cannot run on that driver. I've given up trying to guess why.
  2. Using the proprietary driver ( fglrx-updates and fglrx-amdcccle-updates ), E17 now works, but you cannot use xrandr to enable the second monitor (you get the "required virtual size does not fit available size"). This driver is old school and requires a static configuration in xorg.conf ... Of course there is no xorg.conf anymore, thus you add your pieces to a xorg.conf.d directory. What you need to do is configure a virtual size according to the above error message (or calculate it as the sum-total of the resolutions of your monitors). For example:
    Section "Screen" Identifier "default Screen Section" SubSection "Display" Virtual 3840 1200 EndSubSection EndSection
  3. Now when you log in, you might even see both monitors work. If not, you can fix it with xrandr, or you can add it to your config as well, something like this:
    Section "Monitor" Identifier "VGA-0" Modeline "1280x1024_60.00" 109.00 1280 1368 1496 1712 1024 1027 1034 1063 -hsync +vsync Option "RightOf" "DVI-0" EndSection
Much gratitude to this poster for the info

Linux Upgrading pfSense fails due to low disk space

Posted by Admin • Tuesday, October 22. 2013 • Category: Linux
I have an embedded installation of pfSense 2.0.2-RELEASE running from a 512MB compact flash card via an IDE adapter. At the time this was what I had on hand, and it seemed like plenty of space - but now that I tried to upgrade to 2.1, the process failed because there wasn't enough room to download the new image...

I tried all sorts of ways including both webconfigurator upgrade and trying to scp the image to the box, but either way there simply wasn't enough space. "OK" I said, "let me install 2.1 on a new (larger) card and restore the config.xml" .... bad idea. The firewall becomes unbootable when you do this - I think that no upgrade processing is performed on the configuration, it is assumed to be a match for your software version. Not to mention that I tried a 4GB card, but the old Pentium III running the firewall can't handle anything over 2GB!

Ultimately, this is the process:
  1. Download and install the same version as what you're running on the larger card
  2. Restore your config.xml backup onto the new instance of pfSense. You can do this through webconfigurator, or if you are (like me) running on a temporary rig without multiple NIC's, you can scp it over manually
  3. Confirm that the system boots, but don't make any changes (to the interfaces, for instance). Put the card into your real system
  4. Now you can use the auto-updater as normal, and your old config.xml will be upconverted

Linux amixer toggle mutes but does not unmute

Posted by Admin • Monday, July 22. 2013 • Category: Linux
It seems that the common approach to mute the audio in Ubuntu 13.04 is amixer -q sset Master toggle ... which works great when muting, but fails to unmute. This command is, for example, the default for openbox's handling of XF86AudioPlay shortcut.

The problem, it would appear, is that muting the Master channel causes other channels (eg Headphone and Front on my machine) to be muted as well. I have no idea why this works this way and why it doesn't undo what it did... and, frankly, I don't really care that much. It's much easier to code around this, see the following workaround script:

Continue reading "amixer toggle mutes but does not unmute"